Move Actuator Tomcat infrastructure to spring-boot-tomcat

This commit is contained in:
Stéphane Nicoll
2025-05-23 14:01:44 +02:00
committed by Phillip Webb
parent 431210d7b2
commit 01d0906cbe
21 changed files with 24 additions and 27 deletions

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.tomcat.actuate.autoconfigure.web;
import java.util.Collection;
import java.util.function.Function;
import org.apache.catalina.Valve;
import org.apache.catalina.valves.AccessLogValve;
import org.springframework.boot.actuate.autoconfigure.web.server.AccessLogCustomizer;
import org.springframework.boot.tomcat.ConfigurableTomcatWebServerFactory;
/**
* {@link AccessLogCustomizer} for Tomcat.
*
* @param <T> the type of factory that can be customized
* @author Andy Wilkinson
*/
class TomcatAccessLogCustomizer<T extends ConfigurableTomcatWebServerFactory> extends AccessLogCustomizer<T> {
private final Function<T, Collection<Valve>> engineValvesExtractor;
TomcatAccessLogCustomizer(TomcatManagementServerProperties properties,
Function<T, Collection<Valve>> engineValvesExtractor) {
super(properties.getAccesslog().getPrefix());
this.engineValvesExtractor = engineValvesExtractor;
}
@Override
public void customize(T factory) {
AccessLogValve accessLogValve = findAccessLogValve(factory);
if (accessLogValve == null) {
return;
}
accessLogValve.setPrefix(customizePrefix(accessLogValve.getPrefix()));
}
private AccessLogValve findAccessLogValve(T factory) {
for (Valve engineValve : this.engineValvesExtractor.apply(factory)) {
if (engineValve instanceof AccessLogValve accessLogValve) {
return accessLogValve;
}
}
return null;
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.tomcat.actuate.autoconfigure.web;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Properties for a Tomcat-based management server.
*
* @author Moritz Halbritter
* @since 4.0.0
*/
@ConfigurationProperties("management.server.tomcat")
public class TomcatManagementServerProperties {
private final Accesslog accesslog = new Accesslog();
public Accesslog getAccesslog() {
return this.accesslog;
}
public static class Accesslog {
/**
* Management log file name prefix.
*/
private String prefix = "management_";
public String getPrefix() {
return this.prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.tomcat.actuate.autoconfigure.web;
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.tomcat.reactive.TomcatReactiveWebServerFactory;
import org.springframework.context.annotation.Bean;
/**
* {@link ManagementContextConfiguration @ManagementContextConfiguration} for Tomcat-based
* reactive web endpoint infrastructure when a separate management context running on a
* different port is required.
*
* @author Andy Wilkinson
*/
@ConditionalOnClass(Tomcat.class)
@ConditionalOnWebApplication(type = Type.REACTIVE)
@EnableConfigurationProperties(TomcatManagementServerProperties.class)
@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false)
class TomcatReactiveManagementChildContextConfiguration {
@Bean
TomcatAccessLogCustomizer<TomcatReactiveWebServerFactory> tomcatManagementAccessLogCustomizer(
TomcatManagementServerProperties properties) {
return new TomcatAccessLogCustomizer<>(properties, TomcatReactiveWebServerFactory::getEngineValves);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.tomcat.actuate.autoconfigure.web;
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory;
import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.tomcat.autoconfigure.TomcatWebServerConfiguration;
import org.springframework.boot.tomcat.autoconfigure.reactive.TomcatReactiveWebServerAutoConfiguration;
import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory;
import org.springframework.context.annotation.Bean;
/**
* Auto-configuration for a Tomcat-based reactive management context.
*
* @author Andy Wilkinson
* @since 4.0.0
*/
@AutoConfiguration
@ConditionalOnClass({ Tomcat.class, ManagementContextFactory.class })
@ConditionalOnWebApplication(type = Type.REACTIVE)
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
public class TomcatReactiveManagementContextAutoConfiguration {
@Bean
static ManagementContextFactory reactiveWebChildContextFactory() {
return new ManagementContextFactory(WebApplicationType.REACTIVE, ReactiveWebServerFactory.class,
TomcatReactiveWebServerAutoConfiguration.class, TomcatWebServerConfiguration.class);
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.tomcat.actuate.autoconfigure.web;
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
/**
* {@link ManagementContextConfiguration @ManagementContextConfiguration} for Tomcat-based
* servlet web endpoint infrastructure when a separate management context running on a
* different port is required.
*
* @author Andy Wilkinson
*/
@ConditionalOnClass(Tomcat.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(TomcatManagementServerProperties.class)
@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false)
class TomcatServletManagementChildContextConfiguration {
@Bean
TomcatAccessLogCustomizer<TomcatServletWebServerFactory> tomcatManagementAccessLogCustomizer(
TomcatManagementServerProperties properties) {
return new TomcatAccessLogCustomizer<>(properties, TomcatServletWebServerFactory::getEngineValves);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.tomcat.actuate.autoconfigure.web;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory;
import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.tomcat.autoconfigure.TomcatWebServerConfiguration;
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
import org.springframework.boot.web.server.servlet.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
/**
* Auto-configuration for a Tomcat-based servlet management context.
*
* @author Andy Wilkinson
* @since 4.0.0
*/
@AutoConfiguration
@ConditionalOnClass(ManagementContextFactory.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
public class TomcatServletManagementContextAutoConfiguration {
@Bean
static ManagementContextFactory servletWebChildContextFactory() {
return new ManagementContextFactory(WebApplicationType.SERVLET, ServletWebServerFactory.class,
TomcatWebServerConfiguration.class, TomcatServletWebServerAutoConfiguration.class);
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Actuator Tomcat web server support.
*/
package org.springframework.boot.tomcat.actuate.autoconfigure.web;

View File

@@ -0,0 +1,2 @@
org.springframework.boot.tomcat.actuate.autoconfigure.web.TomcatReactiveManagementChildContextConfiguration
org.springframework.boot.tomcat.actuate.autoconfigure.web.TomcatServletManagementChildContextConfiguration

View File

@@ -1,2 +1,4 @@
org.springframework.boot.tomcat.actuate.autoconfigure.web.TomcatReactiveManagementContextAutoConfiguration
org.springframework.boot.tomcat.actuate.autoconfigure.web.TomcatServletManagementContextAutoConfiguration
org.springframework.boot.tomcat.autoconfigure.reactive.TomcatReactiveWebServerAutoConfiguration
org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.tomcat.actuate.autoconfigure.web;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link TomcatManagementServerProperties}.
*
* @author Andy Wilkinson
*/
class TomcatManagementServerPropertiesTests {
@Test
void accessLogsArePrefixedByDefault() {
TomcatManagementServerProperties properties = new TomcatManagementServerProperties();
assertThat(properties.getAccesslog().getPrefix()).isEqualTo("management_");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,11 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.metrics.web.tomcat;
package org.springframework.boot.tomcat.actuate.metrics;
import io.micrometer.core.instrument.MeterRegistry;
import org.junit.jupiter.api.Test;
import org.springframework.boot.tomcat.actuate.metrics.TomcatMetricsBinder;
import static org.mockito.Mockito.mock;
/**