Commit fe1011c2 authored by Brian Clozel's avatar Brian Clozel

Add Netty memory leak detection config property

This commit adds a new `spring.netty.leak-detection` configuration
property that selects the level of memory leak detection for the Netty
engine.

This configuration is applied statically to Netty; this means all
(non-shaded) Netty usages as client or server will be impacted by this
change.

Developers might use this property during development or tests to find
causes of memory leaks when dealing with Netty buffers.

Closes gh-14338
parent 66e857f2
......@@ -72,7 +72,7 @@ public class DocumentConfigurationProperties extends DefaultTask {
.addSection("mail").withKeyPrefixes("spring.mail", "spring.sendgrid").addSection("cache")
.withKeyPrefixes("spring.cache").addSection("server").withKeyPrefixes("server").addSection("web")
.withKeyPrefixes("spring.hateoas", "spring.http", "spring.servlet", "spring.jersey", "spring.mvc",
"spring.resources", "spring.session", "spring.web", "spring.webflux")
"spring.netty", "spring.resources", "spring.session", "spring.web", "spring.webflux")
.addSection("json").withKeyPrefixes("spring.jackson", "spring.gson").addSection("rsocket")
.withKeyPrefixes("spring.rsocket").addSection("templating")
.withKeyPrefixes("spring.freemarker", "spring.groovy", "spring.mustache", "spring.thymeleaf")
......
/*
* Copyright 2012-2021 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.autoconfigure.netty;
import io.netty.util.NettyRuntime;
import io.netty.util.ResourceLeakDetector;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Netty.
*
* @author Brian Clozel
* @since 2.5.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(NettyRuntime.class)
@EnableConfigurationProperties(NettyProperties.class)
public class NettyAutoConfiguration {
public NettyAutoConfiguration(NettyProperties properties) {
if (properties.getLeakDetection() != null) {
NettyProperties.LeakDetection leakDetection = properties.getLeakDetection();
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.valueOf(leakDetection.name()));
}
}
}
/*
* Copyright 2012-2021 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.autoconfigure.netty;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* {@link ConfigurationProperties @ConfigurationProperties} for the Netty engine.
* <p>
* These properties apply globally to the Netty library, used as a client or a server.
*
* @author Brian Clozel
* @since 2.5.0
*/
@ConfigurationProperties(prefix = "spring.netty")
public class NettyProperties {
/**
* Level of leak detection for reference-counted buffers.
*/
private LeakDetection leakDetection = LeakDetection.DISABLED;
public LeakDetection getLeakDetection() {
return this.leakDetection;
}
public void setLeakDetection(LeakDetection leakDetection) {
this.leakDetection = leakDetection;
}
public enum LeakDetection {
/**
* Disable leak detection completely.
*/
DISABLED,
/**
* Detect leaks for 1% of buffers.
*/
SIMPLE,
/**
* Detect leaks for 1% of buffers and track where they were accessed.
*/
ADVANCED,
/**
* Detect leaks for 100% of buffers and track where they were accessed.
*/
PARANOID
}
}
/*
* Copyright 2012-2021 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.
*/
/**
* Auto-configuration for the Netty library.
*/
package org.springframework.boot.autoconfigure.netty;
......@@ -1770,6 +1770,10 @@
"name": "spring.webservices.wsdl-locations",
"type": "java.util.List<java.lang.String>",
"description": "Comma-separated list of locations of WSDLs and accompanying XSDs to be exposed as beans."
},
{
"name": "spring.netty.leak-detection",
"defaultValue": "disabled"
}
],
"hints": [
......
......@@ -105,6 +105,7 @@ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.netty.NettyAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
......
/*
* Copyright 2012-2021 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.autoconfigure.netty;
import io.netty.util.ResourceLeakDetector;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link NettyAutoConfiguration}.
*
* @author Brian Clozel
*/
public class NettyAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(NettyAutoConfiguration.class));
@Test
void leakDetectionShouldBeConfigured() {
this.contextRunner.withPropertyValues("spring.netty.leak-detection=paranoid").run((context) -> {
assertThat(ResourceLeakDetector.getLevel()).isEqualTo(ResourceLeakDetector.Level.PARANOID);
// reset configuration for the following tests.
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED);
});
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment