Merge branch '1.0.x' into 1.1.x
This commit is contained in:
@@ -305,6 +305,21 @@ By default Sleuth assumes that when you send a span to Zipkin, you want the span
|
||||
spring.zipkin.service.name: foo
|
||||
----
|
||||
|
||||
=== Host locator
|
||||
|
||||
In order to define the host that is corresponding to a particular span we need to resolve the host name
|
||||
and port. The default approach is to take it from server properties. If those for some reason are not set
|
||||
then we're trying to retrieve the host name from the network interfaces.
|
||||
|
||||
If you have the discovery client enabled and prefer to retrieve the host address from the registered
|
||||
instance in a service registry then you have to set the property (it's applicable for both HTTP and
|
||||
Stream based span reporting).
|
||||
|
||||
[source,yaml]
|
||||
----
|
||||
spring.zipkin.locator.discovery.enabled: true
|
||||
----
|
||||
|
||||
== Span Data as Messages
|
||||
|
||||
You can accumulate and send span data over
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -52,8 +52,8 @@ public class DiscoveryClientHostLocator implements HostLocator {
|
||||
@Override
|
||||
public Host locate(Span span) {
|
||||
ServiceInstance instance = this.client.getLocalServiceInstance();
|
||||
String serviceId = StringUtils.hasText(this.zipkinProperties.getName()) ?
|
||||
this.zipkinProperties.getName() : instance.getServiceId();
|
||||
String serviceId = StringUtils.hasText(this.zipkinProperties.getService().getName()) ?
|
||||
this.zipkinProperties.getService().getName() : instance.getServiceId();
|
||||
return new Host(serviceId, getIpAddress(instance),
|
||||
instance.getPort());
|
||||
}
|
||||
|
||||
@@ -16,8 +16,14 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.stream;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.commons.util.InetUtilsProperties;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -32,30 +38,37 @@ import org.springframework.util.StringUtils;
|
||||
* <li><b>port</b> - from lazily assigned port or {@link ServerProperties}</li>
|
||||
* </ul>
|
||||
*
|
||||
* You can override the value of service id by {@link ZipkinProperties#setName(String)}
|
||||
* You can override the value of service id by {@link ZipkinProperties#getService()}
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class ServerPropertiesHostLocator implements HostLocator {
|
||||
|
||||
private static final Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass());
|
||||
|
||||
private final ServerProperties serverProperties; // Nullable
|
||||
private final String appName;
|
||||
private final InetUtils inetUtils;
|
||||
private final ZipkinProperties zipkinProperties;
|
||||
private Integer port; // Lazy assigned
|
||||
|
||||
@Deprecated
|
||||
public ServerPropertiesHostLocator(ServerProperties serverProperties,
|
||||
String appName) {
|
||||
this(serverProperties, appName, new ZipkinProperties());
|
||||
public ServerPropertiesHostLocator(ServerProperties serverProperties, String appName) {
|
||||
this(serverProperties, appName, new ZipkinProperties(),null);
|
||||
}
|
||||
|
||||
public ServerPropertiesHostLocator(ServerProperties serverProperties,
|
||||
String appName, ZipkinProperties zipkinProperties) {
|
||||
public ServerPropertiesHostLocator(ServerProperties serverProperties, String appName,
|
||||
ZipkinProperties zipkinProperties, InetUtils inetUtils) {
|
||||
this.serverProperties = serverProperties;
|
||||
this.appName = appName;
|
||||
Assert.notNull(this.appName, "appName");
|
||||
this.zipkinProperties = zipkinProperties;
|
||||
if (inetUtils == null) {
|
||||
this.inetUtils = new InetUtils(new InetUtilsProperties());
|
||||
} else {
|
||||
this.inetUtils = inetUtils;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,21 +104,24 @@ public class ServerPropertiesHostLocator implements HostLocator {
|
||||
address = this.serverProperties.getAddress().getHostAddress();
|
||||
}
|
||||
else {
|
||||
address = "127.0.0.1";
|
||||
address = this.inetUtils.findFirstNonLoopbackAddress().getHostAddress();
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
private String getServiceName(Span span) {
|
||||
String serviceName;
|
||||
if (StringUtils.hasText(this.zipkinProperties.getName())) {
|
||||
serviceName = this.zipkinProperties.getName();
|
||||
if (StringUtils.hasText(this.zipkinProperties.getService().getName())) {
|
||||
serviceName = this.zipkinProperties.getService().getName();
|
||||
} else if (span.getProcessId() != null) {
|
||||
serviceName = span.getProcessId();
|
||||
}
|
||||
else {
|
||||
serviceName = this.appName;
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Span will contain serviceName [" + serviceName + "]");
|
||||
}
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.metric.SpanMetricReporter;
|
||||
import org.springframework.cloud.sleuth.metric.TraceMetricsAutoConfiguration;
|
||||
@@ -91,7 +91,8 @@ public class SleuthStreamAutoConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingClass("org.springframework.cloud.client.discovery.DiscoveryClient")
|
||||
@ConditionalOnMissingBean(HostLocator.class)
|
||||
@ConditionalOnProperty(value = "spring.zipkin.locator.discovery.enabled", havingValue = "false", matchIfMissing = true)
|
||||
protected static class DefaultEndpointLocatorConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
@@ -100,18 +101,24 @@ public class SleuthStreamAutoConfiguration {
|
||||
@Autowired
|
||||
private ZipkinProperties zipkinProperties;
|
||||
|
||||
@Autowired
|
||||
private InetUtils inetUtils;
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
|
||||
@Bean
|
||||
public HostLocator zipkinEndpointLocator() {
|
||||
return new ServerPropertiesHostLocator(this.serverProperties, this.appName, this.zipkinProperties);
|
||||
return new ServerPropertiesHostLocator(this.serverProperties, this.appName, this.zipkinProperties,
|
||||
this.inetUtils);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(DiscoveryClient.class)
|
||||
@ConditionalOnMissingBean(HostLocator.class)
|
||||
@ConditionalOnProperty(value = "spring.zipkin.locator.discovery.enabled", havingValue = "true")
|
||||
protected static class DiscoveryClientEndpointLocatorConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
@@ -120,6 +127,9 @@ public class SleuthStreamAutoConfiguration {
|
||||
@Autowired
|
||||
private ZipkinProperties zipkinProperties;
|
||||
|
||||
@Autowired(required = false)
|
||||
private InetUtils inetUtils;
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
|
||||
@@ -131,7 +141,8 @@ public class SleuthStreamAutoConfiguration {
|
||||
if (this.client != null) {
|
||||
return new DiscoveryClientHostLocator(this.client, this.zipkinProperties);
|
||||
}
|
||||
return new ServerPropertiesHostLocator(this.serverProperties, this.appName, this.zipkinProperties);
|
||||
return new ServerPropertiesHostLocator(this.serverProperties, this.appName, this.zipkinProperties,
|
||||
this.inetUtils);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,17 +24,66 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.0.12
|
||||
*/
|
||||
@ConfigurationProperties("spring.zipkin.service")
|
||||
@ConfigurationProperties("spring.zipkin")
|
||||
public class ZipkinProperties {
|
||||
|
||||
/** The name of the service, from which the Span was sent via Stream, that should appear in Zipkin */
|
||||
private String name;
|
||||
private Service service = new Service();
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
private Locator locator = new Locator();
|
||||
|
||||
public Service getService() {
|
||||
return this.service;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
public void setService(Service service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public Locator getLocator() {
|
||||
return this.locator;
|
||||
}
|
||||
|
||||
public void setLocator(Locator locator) {
|
||||
this.locator = locator;
|
||||
}
|
||||
|
||||
public static class Service {
|
||||
/** The name of the service, from which the Span was sent via Stream, that should appear in Zipkin */
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Locator {
|
||||
|
||||
private Discovery discovery;
|
||||
|
||||
public Discovery getDiscovery() {
|
||||
return this.discovery;
|
||||
}
|
||||
|
||||
public void setDiscovery(Discovery discovery) {
|
||||
this.discovery = discovery;
|
||||
}
|
||||
|
||||
public static class Discovery {
|
||||
|
||||
/** Enabling of locating the host name via service discovery */
|
||||
private boolean enabled;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.springframework.cloud.sleuth.stream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Matcin Wielgus
|
||||
*/
|
||||
public class DiscoveryClientEndpointLocatorConfigurationTest {
|
||||
@Test
|
||||
public void endpointLocatorShouldDefaultToServerPropertiesEndpointLocator() {
|
||||
try (ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
EmptyConfiguration.class).run("--spring.main.web_environment=false")) {
|
||||
assertThat(ctxt.getBean(HostLocator.class))
|
||||
.isInstanceOf(ServerPropertiesHostLocator.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointLocatorShouldDefaultToServerPropertiesEndpointLocatorEvenWhenDiscoveryClientPresent() {
|
||||
try (ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
ConfigurationWithDiscoveryClient.class)
|
||||
.run("--spring.main.web_environment=false")) {
|
||||
assertThat(ctxt.getBean(HostLocator.class))
|
||||
.isInstanceOf(ServerPropertiesHostLocator.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointLocatorShouldRespectExistingEndpointLocator() {
|
||||
try (ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
ConfigurationWithCustomLocator.class)
|
||||
.run("--spring.main.web_environment=false")) {
|
||||
assertThat(ctxt.getBean(HostLocator.class))
|
||||
.isSameAs(ConfigurationWithCustomLocator.locator);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointLocatorShouldBeFallbackHavingEndpointLocatorWhenAskedTo() {
|
||||
try (ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
ConfigurationWithDiscoveryClient.class).run(
|
||||
"--spring.zipkin.locator.discovery.enabled=true",
|
||||
"--spring.main.web_environment=false")) {
|
||||
assertThat(ctxt.getBean(HostLocator.class))
|
||||
.isInstanceOf(DiscoveryClientHostLocator.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointLocatorShouldRespectExistingEndpointLocatorEvenWhenAskedToBeDiscovery() {
|
||||
try (ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
ConfigurationWithDiscoveryClient.class,
|
||||
ConfigurationWithCustomLocator.class).run(
|
||||
"--spring.zipkin.locator.discovery.enabled=true",
|
||||
"--spring.main.web_environment=false")) {
|
||||
assertThat(ctxt.getBean(HostLocator.class))
|
||||
.isSameAs(ConfigurationWithCustomLocator.locator);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public static class EmptyConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public static class ConfigurationWithDiscoveryClient {
|
||||
@Bean
|
||||
public DiscoveryClient getDiscoveryClient() {
|
||||
return Mockito.mock(DiscoveryClient.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public static class ConfigurationWithCustomLocator {
|
||||
static HostLocator locator = Mockito.mock(HostLocator.class);
|
||||
|
||||
@Bean
|
||||
public HostLocator getEndpointLocator() {
|
||||
return locator;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public class DiscoveryClientHostLocatorTest {
|
||||
public void should_override_the_service_name_from_properties() throws Exception {
|
||||
given(this.discoveryClient.getLocalServiceInstance()).willReturn(serviceInstanceWithValidHost());
|
||||
ZipkinProperties zipkinProperties = new ZipkinProperties();
|
||||
zipkinProperties.setName("foo");
|
||||
zipkinProperties.getService().setName("foo");
|
||||
this.discoveryClientHostLocator = new DiscoveryClientHostLocator(this.discoveryClient, zipkinProperties);
|
||||
|
||||
Host host = this.discoveryClientHostLocator.locate(null);
|
||||
|
||||
@@ -21,49 +21,57 @@ import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.commons.util.InetUtilsProperties;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ServerPropertiesHostLocatorTests {
|
||||
|
||||
public static final byte[] ADR1234 = { 1, 2, 3, 4 };
|
||||
|
||||
Span span = new Span(1, 3, "http:name", 1L, Collections.<Long>emptyList(), 2L, true, true,
|
||||
"process");
|
||||
|
||||
@Test
|
||||
public void portDefaultsTo8080() {
|
||||
public void portDefaultsTo8080() throws UnknownHostException {
|
||||
ServerPropertiesHostLocator locator = new ServerPropertiesHostLocator(
|
||||
new ServerProperties(), "unknown", new ZipkinProperties());
|
||||
new ServerProperties(), "unknown", new ZipkinProperties(),
|
||||
localAddress(ADR1234));
|
||||
|
||||
assertThat(locator.locate(this.span).getPort()).isEqualTo((short) 8080);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void portFromServerProperties() {
|
||||
public void portFromServerProperties() throws UnknownHostException {
|
||||
ServerProperties properties = new ServerProperties();
|
||||
properties.setPort(1234);
|
||||
|
||||
ServerPropertiesHostLocator locator = new ServerPropertiesHostLocator(properties,
|
||||
"unknown", new ZipkinProperties());
|
||||
"unknown", new ZipkinProperties(),localAddress(ADR1234));
|
||||
|
||||
assertThat(locator.locate(this.span).getPort()).isEqualTo((short) 1234);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void portDefaultsToLocalhost() {
|
||||
public void portDefaultsToLocalhost() throws UnknownHostException {
|
||||
ServerPropertiesHostLocator locator = new ServerPropertiesHostLocator(
|
||||
new ServerProperties(), "unknown", new ZipkinProperties());
|
||||
new ServerProperties(), "unknown", new ZipkinProperties(),
|
||||
localAddress(ADR1234));
|
||||
|
||||
assertThat(locator.locate(this.span).getAddress()).isEqualTo("127.0.0.1");
|
||||
assertThat(locator.locate(this.span).getAddress()).isEqualTo("1.2.3.4");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hostFromServerPropertiesIp() throws UnknownHostException {
|
||||
ServerProperties properties = new ServerProperties();
|
||||
properties.setAddress(InetAddress.getByAddress(new byte[] { 1, 2, 3, 4 }));
|
||||
properties.setAddress(InetAddress.getByAddress(ADR1234));
|
||||
|
||||
ServerPropertiesHostLocator locator = new ServerPropertiesHostLocator(properties,
|
||||
"unknown", new ZipkinProperties());
|
||||
"unknown", new ZipkinProperties(),localAddress(new byte[] { 1, 1, 1, 1 }));
|
||||
|
||||
assertThat(locator.locate(this.span).getAddress()).isEqualTo("1.2.3.4");
|
||||
}
|
||||
@@ -73,11 +81,18 @@ public class ServerPropertiesHostLocatorTests {
|
||||
ServerProperties properties = new ServerProperties();
|
||||
properties.setAddress(InetAddress.getByAddress(new byte[] { 1, 2, 3, 4 }));
|
||||
ZipkinProperties zipkinProperties = new ZipkinProperties();
|
||||
zipkinProperties.setName("foo");
|
||||
zipkinProperties.getService().setName("foo");
|
||||
|
||||
ServerPropertiesHostLocator locator = new ServerPropertiesHostLocator(properties,
|
||||
"unknown", zipkinProperties);
|
||||
"unknown", zipkinProperties,localAddress(ADR1234));
|
||||
|
||||
assertThat(locator.locate(this.span).getServiceName()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
private InetUtils localAddress(byte[] address) throws UnknownHostException {
|
||||
InetUtils mocked = Mockito.spy(new InetUtils(new InetUtilsProperties()));
|
||||
Mockito.when(mocked.findFirstNonLoopbackAddress())
|
||||
.thenReturn(InetAddress.getByAddress(address));
|
||||
return mocked;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.log.NoOpSpanLogger;
|
||||
import org.springframework.cloud.sleuth.log.SpanLogger;
|
||||
@@ -120,7 +121,7 @@ public class SleuthStreamAutoConfigurationTest {
|
||||
@Import({ SleuthStreamAutoConfiguration.class, TraceMetricsAutoConfiguration.class,
|
||||
TestSupportBinderAutoConfiguration.class,
|
||||
ChannelBindingAutoConfiguration.class, TraceAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
PropertyPlaceholderAutoConfiguration.class, UtilAutoConfiguration.class })
|
||||
public static class BaseConfiguration {
|
||||
@Bean
|
||||
SpanLogger spanLogger() {
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.metrics.CounterService;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanReporter;
|
||||
@@ -158,7 +159,7 @@ public class StreamSpanListenerTests {
|
||||
@Import({ ZipkinTestConfiguration.class, SleuthStreamAutoConfiguration.class,
|
||||
TraceMetricsAutoConfiguration.class, TestSupportBinderAutoConfiguration.class,
|
||||
ChannelBindingAutoConfiguration.class, TraceAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
PropertyPlaceholderAutoConfiguration.class, UtilAutoConfiguration.class })
|
||||
protected static class TestConfiguration {
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.springframework.cloud.sleuth.zipkin;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import zipkin.Endpoint;
|
||||
@@ -14,8 +12,6 @@ import zipkin.Endpoint;
|
||||
*/
|
||||
public class FallbackHavingEndpointLocator implements EndpointLocator {
|
||||
|
||||
private final AtomicReference<Endpoint> cachedEndpoint = new AtomicReference<>();
|
||||
|
||||
private static final Log log = LogFactory.getLog(FallbackHavingEndpointLocator.class);
|
||||
|
||||
private final DiscoveryClientEndpointLocator discoveryClientEndpointLocator;
|
||||
@@ -29,8 +25,7 @@ public class FallbackHavingEndpointLocator implements EndpointLocator {
|
||||
|
||||
@Override
|
||||
public Endpoint local() {
|
||||
this.cachedEndpoint.compareAndSet(null, endpoint());
|
||||
return this.cachedEndpoint.get();
|
||||
return endpoint();
|
||||
}
|
||||
|
||||
private Endpoint endpoint() {
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
package org.springframework.cloud.sleuth.zipkin;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.commons.util.InetUtilsProperties;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -47,20 +49,25 @@ public class ServerPropertiesEndpointLocator implements EndpointLocator {
|
||||
|
||||
private final ServerProperties serverProperties;
|
||||
private final String appName;
|
||||
private final InetUtils inetUtils;
|
||||
private final ZipkinProperties zipkinProperties;
|
||||
private Integer port;
|
||||
|
||||
@Deprecated
|
||||
public ServerPropertiesEndpointLocator(ServerProperties serverProperties,
|
||||
String appName) {
|
||||
this(serverProperties, appName, new ZipkinProperties());
|
||||
public ServerPropertiesEndpointLocator(ServerProperties serverProperties,String appName) {
|
||||
this(serverProperties,appName,new ZipkinProperties(), null);
|
||||
}
|
||||
|
||||
public ServerPropertiesEndpointLocator(ServerProperties serverProperties,
|
||||
String appName, ZipkinProperties zipkinProperties) {
|
||||
String appName, ZipkinProperties zipkinProperties, InetUtils inetUtils) {
|
||||
this.serverProperties = serverProperties;
|
||||
this.appName = appName;
|
||||
this.zipkinProperties = zipkinProperties;
|
||||
if (inetUtils == null) {
|
||||
this.inetUtils = new InetUtils(new InetUtilsProperties());
|
||||
} else {
|
||||
this.inetUtils = inetUtils;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,11 +104,12 @@ public class ServerPropertiesEndpointLocator implements EndpointLocator {
|
||||
}
|
||||
|
||||
private int getAddress() {
|
||||
if (this.serverProperties!=null && this.serverProperties.getAddress() != null) {
|
||||
return InetUtils.getIpAddressAsInt(this.serverProperties.getAddress().getHostAddress());
|
||||
if (this.serverProperties != null && this.serverProperties.getAddress() != null) {
|
||||
return ByteBuffer.wrap(this.serverProperties.getAddress().getAddress())
|
||||
.getInt();
|
||||
}
|
||||
else {
|
||||
return 127 << 24 | 1;
|
||||
return ByteBuffer.wrap(this.inetUtils.findFirstNonLoopbackAddress().getAddress()).getInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.SpanReporter;
|
||||
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
@@ -70,7 +70,8 @@ public class ZipkinAutoConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingClass("org.springframework.cloud.client.discovery.DiscoveryClient")
|
||||
@ConditionalOnMissingBean(EndpointLocator.class)
|
||||
@ConditionalOnProperty(value = "spring.zipkin.locator.discovery.enabled", havingValue = "false", matchIfMissing = true)
|
||||
protected static class DefaultEndpointLocatorConfiguration {
|
||||
|
||||
@Autowired(required=false)
|
||||
@@ -79,19 +80,24 @@ public class ZipkinAutoConfiguration {
|
||||
@Autowired
|
||||
private ZipkinProperties zipkinProperties;
|
||||
|
||||
@Autowired(required=false)
|
||||
private InetUtils inetUtils;
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
|
||||
@Bean
|
||||
public EndpointLocator zipkinEndpointLocator() {
|
||||
return new ServerPropertiesEndpointLocator(this.serverProperties, this.appName,
|
||||
this.zipkinProperties);
|
||||
this.zipkinProperties, this.inetUtils);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(DiscoveryClient.class)
|
||||
@ConditionalOnMissingBean(EndpointLocator.class)
|
||||
@ConditionalOnProperty(value = "spring.zipkin.locator.discovery.enabled", havingValue = "true")
|
||||
protected static class DiscoveryClientEndpointLocatorConfiguration {
|
||||
|
||||
@Autowired(required=false)
|
||||
@@ -100,6 +106,9 @@ public class ZipkinAutoConfiguration {
|
||||
@Autowired
|
||||
private ZipkinProperties zipkinProperties;
|
||||
|
||||
@Autowired(required=false)
|
||||
private InetUtils inetUtils;
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appName;
|
||||
|
||||
@@ -110,7 +119,7 @@ public class ZipkinAutoConfiguration {
|
||||
public EndpointLocator zipkinEndpointLocator() {
|
||||
return new FallbackHavingEndpointLocator(discoveryClientEndpointLocator(),
|
||||
new ServerPropertiesEndpointLocator(this.serverProperties, this.appName,
|
||||
this.zipkinProperties));
|
||||
this.zipkinProperties, this.inetUtils));
|
||||
}
|
||||
|
||||
private DiscoveryClientEndpointLocator discoveryClientEndpointLocator() {
|
||||
|
||||
@@ -34,6 +34,12 @@ public class ZipkinProperties {
|
||||
|
||||
private Service service = new Service();
|
||||
|
||||
private Locator locator = new Locator();
|
||||
|
||||
public Locator getLocator() {
|
||||
return this.locator;
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return this.baseUrl;
|
||||
}
|
||||
@@ -74,6 +80,10 @@ public class ZipkinProperties {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void setLocator(Locator locator) {
|
||||
this.locator = locator;
|
||||
}
|
||||
|
||||
/** When enabled, spans are gzipped before sent to the zipkin server */
|
||||
public static class Compression {
|
||||
|
||||
@@ -102,4 +112,31 @@ public class ZipkinProperties {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Locator {
|
||||
|
||||
private Discovery discovery;
|
||||
|
||||
public Discovery getDiscovery() {
|
||||
return this.discovery;
|
||||
}
|
||||
|
||||
public void setDiscovery(Discovery discovery) {
|
||||
this.discovery = discovery;
|
||||
}
|
||||
|
||||
public static class Discovery {
|
||||
|
||||
/** Enabling of locating the host name via service discovery */
|
||||
private boolean enabled;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ public class ZipkinSpanListener implements SpanReporter {
|
||||
return zipkinSpan.build();
|
||||
}
|
||||
|
||||
private void ensureLocalComponent(Span span, zipkin.Span.Builder zipkinSpan) {
|
||||
private void ensureLocalComponent(Span span, zipkin.Span.Builder zipkinSpan, Endpoint localEndpoint) {
|
||||
if (span.tags().containsKey(Constants.LOCAL_COMPONENT)) {
|
||||
return;
|
||||
}
|
||||
@@ -130,14 +130,14 @@ public class ZipkinSpanListener implements SpanReporter {
|
||||
.type(BinaryAnnotation.Type.STRING)
|
||||
.key("lc") // LOCAL_COMPONENT
|
||||
.value(processId)
|
||||
.endpoint(this.endpointLocator.local()).build();
|
||||
.endpoint(localEndpoint).build();
|
||||
zipkinSpan.addBinaryAnnotation(component);
|
||||
}
|
||||
|
||||
private void ensureServerAddr(Span span, zipkin.Span.Builder zipkinSpan) {
|
||||
private void ensureServerAddr(Span span, zipkin.Span.Builder zipkinSpan, Endpoint localEndpoint) {
|
||||
if (span.tags().containsKey(Span.SPAN_PEER_SERVICE_TAG_NAME)) {
|
||||
zipkinSpan.addBinaryAnnotation(BinaryAnnotation.address(Constants.SERVER_ADDR,
|
||||
this.endpointLocator.local().toBuilder().serviceName(
|
||||
localEndpoint.toBuilder().serviceName(
|
||||
span.tags().get(Span.SPAN_PEER_SERVICE_TAG_NAME)).build()));
|
||||
}
|
||||
}
|
||||
@@ -160,10 +160,10 @@ public class ZipkinSpanListener implements SpanReporter {
|
||||
}
|
||||
if (notClientOrServer) {
|
||||
// A zipkin span without any annotations cannot be queried, add special "lc" to avoid that.
|
||||
ensureLocalComponent(span, zipkinSpan);
|
||||
ensureLocalComponent(span, zipkinSpan, endpoint);
|
||||
}
|
||||
if (hasClientSend) {
|
||||
ensureServerAddr(span, zipkinSpan);
|
||||
ensureServerAddr(span, zipkinSpan, endpoint);
|
||||
}
|
||||
if (instanceIdToTag && this.environment != null) {
|
||||
setInstanceIdIfPresent(zipkinSpan, endpoint, Span.INSTANCEID);
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.springframework.cloud.sleuth.zipkin;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Matcin Wielgus
|
||||
*/
|
||||
public class DiscoveryClientEndpointLocatorConfigurationTest {
|
||||
|
||||
@Test
|
||||
public void endpointLocatorShouldDefaultToServerPropertiesEndpointLocator() {
|
||||
ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
EmptyConfiguration.class).run();
|
||||
assertThat(ctxt.getBean(EndpointLocator.class))
|
||||
.isInstanceOf(ServerPropertiesEndpointLocator.class);
|
||||
ctxt.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointLocatorShouldDefaultToServerPropertiesEndpointLocatorEvenWhenDiscoveryClientPresent() {
|
||||
ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
ConfigurationWithDiscoveryClient.class).run();
|
||||
assertThat(ctxt.getBean(EndpointLocator.class))
|
||||
.isInstanceOf(ServerPropertiesEndpointLocator.class);
|
||||
ctxt.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointLocatorShouldRespectExistingEndpointLocator() {
|
||||
ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
ConfigurationWithCustomLocator.class).run();
|
||||
assertThat(ctxt.getBean(EndpointLocator.class))
|
||||
.isSameAs(ConfigurationWithCustomLocator.locator);
|
||||
ctxt.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointLocatorShouldBeFallbackHavingEndpointLocatorWhenAskedTo() {
|
||||
ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
ConfigurationWithDiscoveryClient.class).run("--spring.zipkin.locator.discovery.enabled=true");
|
||||
assertThat(ctxt.getBean(EndpointLocator.class))
|
||||
.isInstanceOf(FallbackHavingEndpointLocator.class);
|
||||
ctxt.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void endpointLocatorShouldRespectExistingEndpointLocatorEvenWhenAskedToBeDiscovery() {
|
||||
ConfigurableApplicationContext ctxt = new SpringApplication(
|
||||
ConfigurationWithDiscoveryClient.class,ConfigurationWithCustomLocator.class).run("--spring.zipkin.locator.discovery.enabled=true");
|
||||
assertThat(ctxt.getBean(EndpointLocator.class))
|
||||
.isSameAs(ConfigurationWithCustomLocator.locator);
|
||||
ctxt.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public static class EmptyConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public static class ConfigurationWithDiscoveryClient {
|
||||
@Bean
|
||||
public DiscoveryClient getDiscoveryClient() {
|
||||
return Mockito.mock(DiscoveryClient.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public static class ConfigurationWithCustomLocator {
|
||||
static EndpointLocator locator = Mockito.mock(EndpointLocator.class);
|
||||
|
||||
@Bean
|
||||
public EndpointLocator getEndpointLocator() {
|
||||
return locator;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.commons.util.InetUtilsProperties;
|
||||
import org.springframework.cloud.sleuth.DefaultSpanNamer;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.log.NoOpSpanLogger;
|
||||
@@ -130,7 +132,7 @@ public class HttpZipkinSpanReporterTest {
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), new DefaultSpanNamer(),
|
||||
new NoOpSpanLogger(), new ZipkinSpanListener(receivedSpan::set,
|
||||
new ServerPropertiesEndpointLocator(new ServerProperties(), "foo",
|
||||
new ZipkinProperties())));
|
||||
new ZipkinProperties(), new InetUtils(new InetUtilsProperties()))));
|
||||
// tag::service_name[]
|
||||
org.springframework.cloud.sleuth.Span newSpan = tracer.createSpan("redis");
|
||||
try {
|
||||
|
||||
@@ -20,46 +20,53 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.commons.util.InetUtilsProperties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ServerPropertiesEndpointLocatorTests {
|
||||
|
||||
public static final byte[] ADDRESS1234 = { 1, 2, 3, 4 };
|
||||
|
||||
@Test
|
||||
public void portDefaultsTo8080() {
|
||||
public void portDefaultsTo8080() throws UnknownHostException {
|
||||
ServerPropertiesEndpointLocator locator = new ServerPropertiesEndpointLocator(
|
||||
new ServerProperties(), "unknown", new ZipkinProperties());
|
||||
new ServerProperties(), "unknown", new ZipkinProperties(),
|
||||
localAddress(ADDRESS1234));
|
||||
|
||||
assertThat(locator.local().port).isEqualTo((short) 8080);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void portFromServerProperties() {
|
||||
public void portFromServerProperties() throws UnknownHostException {
|
||||
ServerProperties properties = new ServerProperties();
|
||||
properties.setPort(1234);
|
||||
|
||||
ServerPropertiesEndpointLocator locator = new ServerPropertiesEndpointLocator(
|
||||
properties, "unknown", new ZipkinProperties());
|
||||
properties, "unknown", new ZipkinProperties(),localAddress(ADDRESS1234));
|
||||
|
||||
assertThat(locator.local().port).isEqualTo((short) 1234);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void portDefaultsToLocalhost() {
|
||||
public void portDefaultsToLocalhost() throws UnknownHostException {
|
||||
ServerPropertiesEndpointLocator locator = new ServerPropertiesEndpointLocator(
|
||||
new ServerProperties(), "unknown", new ZipkinProperties());
|
||||
new ServerProperties(), "unknown", new ZipkinProperties(), localAddress(ADDRESS1234));
|
||||
|
||||
assertThat(locator.local().ipv4).isEqualTo(127 << 24 | 1);
|
||||
assertThat(locator.local().ipv4).isEqualTo(1 << 24 | 2 << 16 | 3 << 8 | 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hostFromServerPropertiesIp() throws UnknownHostException {
|
||||
ServerProperties properties = new ServerProperties();
|
||||
properties.setAddress(InetAddress.getByAddress(new byte[] { 1, 2, 3, 4 }));
|
||||
properties.setAddress(InetAddress.getByAddress(ADDRESS1234));
|
||||
|
||||
ServerPropertiesEndpointLocator locator = new ServerPropertiesEndpointLocator(
|
||||
properties, "unknown", new ZipkinProperties());
|
||||
properties, "unknown", new ZipkinProperties(),
|
||||
localAddress(new byte[] { 4, 4, 4, 4 }));
|
||||
|
||||
assertThat(locator.local().ipv4).isEqualTo(1 << 24 | 2 << 16 | 3 << 8 | 4);
|
||||
}
|
||||
@@ -71,8 +78,15 @@ public class ServerPropertiesEndpointLocatorTests {
|
||||
zipkinProperties.getService().setName("foo");
|
||||
|
||||
ServerPropertiesEndpointLocator locator = new ServerPropertiesEndpointLocator(
|
||||
properties, "unknown", zipkinProperties);
|
||||
properties, "unknown", zipkinProperties,localAddress(ADDRESS1234));
|
||||
|
||||
assertThat(locator.local().serviceName).isEqualTo("foo");
|
||||
}
|
||||
|
||||
private InetUtils localAddress(byte[] address) throws UnknownHostException {
|
||||
InetUtils mocked = Mockito.spy(new InetUtils(new InetUtilsProperties()));
|
||||
Mockito.when(mocked.findFirstNonLoopbackAddress())
|
||||
.thenReturn(InetAddress.getByAddress(address));
|
||||
return mocked;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user