From 4e21bf1b35b9b849567876e7918384628d31b752 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 1 Oct 2015 11:52:28 +0100 Subject: [PATCH] Add strategy EndpointLocator to help with service host/port location --- docs/src/main/asciidoc/README.adoc | 2 +- .../src/main/resources/application.yml | 2 +- .../src/main/resources/application.yml | 2 +- .../src/main/resources/application.yml | 2 +- .../src/main/resources/application.yml | 2 +- spring-cloud-sleuth-zipkin/pom.xml | 24 ++-- .../DiscoveryClientEndpointLocator.java | 60 ++++++++++ .../cloud/sleuth/zipkin/EndpointLocator.java | 34 ++++++ .../ServerPropertiesEndpointLocator.java | 109 ++++++++++++++++++ .../zipkin/ZipkinAutoConfiguration.java | 44 ++++++- .../sleuth/zipkin/ZipkinSpanListener.java | 63 +--------- 11 files changed, 263 insertions(+), 81 deletions(-) create mode 100644 spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/DiscoveryClientEndpointLocator.java create mode 100644 spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/EndpointLocator.java create mode 100644 spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ServerPropertiesEndpointLocator.java diff --git a/docs/src/main/asciidoc/README.adoc b/docs/src/main/asciidoc/README.adoc index e21b20119..04d13871a 100644 --- a/docs/src/main/asciidoc/README.adoc +++ b/docs/src/main/asciidoc/README.adoc @@ -10,7 +10,7 @@ include::intro.adoc[] ---- logging: pattern: - console: '%d{yyyy-MM-dd HH:mm:ss.SSS} [trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}] [%15.15t] %-40.40logger{39}: %m%n' + level: '[trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}] %5p' ---- + (notice the `%X` entries from the MDC). diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/resources/application.yml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/resources/application.yml index e6aaf4075..cdc4819c2 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/resources/application.yml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/main/resources/application.yml @@ -11,7 +11,7 @@ spring: logging: pattern: - console: '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}]){yellow} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex' + level: '%clr([trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}]){yellow} %5p' sample: zipkin: diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/resources/application.yml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/resources/application.yml index 156d876d9..156bc7c88 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/resources/application.yml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-ribbon/src/main/resources/application.yml @@ -37,4 +37,4 @@ zuul: logging: pattern: - console: '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}]){yellow} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex' + level: '%clr([trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}]){yellow} %5p' diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/resources/application.yml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/resources/application.yml index 20f9a1c54..0987752d1 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/resources/application.yml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/resources/application.yml @@ -7,7 +7,7 @@ spring: logging: pattern: - console: '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}]){yellow} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex' + level: '%clr([trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}]){yellow} %5p' sample: zipkin: diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/resources/application.yml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/resources/application.yml index 5adc9a15a..4fa8dc06f 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/resources/application.yml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample/src/main/resources/application.yml @@ -11,4 +11,4 @@ spring: logging: pattern: - console: '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}]){yellow} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex' + level: '%clr([trace=%X{X-Trace-Id:-},span=%X{X-Span-Id:-}]){yellow} %5p' diff --git a/spring-cloud-sleuth-zipkin/pom.xml b/spring-cloud-sleuth-zipkin/pom.xml index 43dc240bf..736da70d3 100644 --- a/spring-cloud-sleuth-zipkin/pom.xml +++ b/spring-cloud-sleuth-zipkin/pom.xml @@ -37,9 +37,19 @@ org.springframework.cloud spring-cloud-sleuth-core + + org.springframework.cloud + spring-cloud-commons + true + org.springframework.boot - spring-boot-starter-actuator + spring-boot-actuator + true + + + org.springframework.boot + spring-boot-starter-logging true @@ -47,18 +57,6 @@ spring-boot-configuration-processor true - - com.github.kristofa - brave-core - - - com.github.kristofa - brave-http - - - com.github.kristofa - brave-core-spring - com.github.kristofa brave-zipkin-spancollector diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/DiscoveryClientEndpointLocator.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/DiscoveryClientEndpointLocator.java new file mode 100644 index 000000000..e816388d4 --- /dev/null +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/DiscoveryClientEndpointLocator.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015 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 + * + * http://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.cloud.sleuth.zipkin; + +import java.net.InetAddress; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.util.InetUtils; + +import com.twitter.zipkin.gen.Endpoint; + +/** + * An {@link EndpointLocator} that tries to find local service information from a + * {@link DiscoveryClient}. + * + * @author Dave Syer + * + */ +public class DiscoveryClientEndpointLocator implements EndpointLocator { + + private DiscoveryClient client; + + public DiscoveryClientEndpointLocator(DiscoveryClient client) { + this.client = client; + } + + @Override + public Endpoint locate(Span span) { + ServiceInstance instance = this.client.getLocalServiceInstance(); + return new Endpoint(getIpAddress(instance), + new Integer(instance.getPort()).shortValue(), instance.getServiceId()); + } + + private int getIpAddress(ServiceInstance instance) { + try { + InetAddress address = InetAddress.getByName(instance.getHost()); + return InetUtils.convert(address).getIpAddressAsInt(); + } + catch (Exception e) { + return 0; + } + } + +} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/EndpointLocator.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/EndpointLocator.java new file mode 100644 index 000000000..2d3a1bf4f --- /dev/null +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/EndpointLocator.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015 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 + * + * http://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.cloud.sleuth.zipkin; + +import org.springframework.cloud.sleuth.Span; + +import com.twitter.zipkin.gen.Endpoint; + +/** + * Strategy for locating a Brave "Endpoin" from a Spring Cloud Span (and whatever other + * environment properties might be available). + * + * @author Dave Syer + * + */ +public interface EndpointLocator { + + Endpoint locate(Span span); + +} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ServerPropertiesEndpointLocator.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ServerPropertiesEndpointLocator.java new file mode 100644 index 000000000..fcf07e54f --- /dev/null +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ServerPropertiesEndpointLocator.java @@ -0,0 +1,109 @@ +/* + * Copyright 2015 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 + * + * http://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.cloud.sleuth.zipkin; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent; +import org.springframework.cloud.sleuth.Span; +import org.springframework.context.event.EventListener; + +import com.twitter.zipkin.gen.Endpoint; + +/** + * @author Dave Syer + * + */ +public class ServerPropertiesEndpointLocator implements EndpointLocator { + + @Value("${spring.application.name:application}") + private String appName; + + private ServerProperties serverProperties; + + private Integer port; + + public ServerPropertiesEndpointLocator(ServerProperties serverProperties) { + this.serverProperties = serverProperties; + } + + @Override + public Endpoint locate(Span span) { + String serviceName = getServiceName(span); + int address = getAddress(); + Integer port = getPort(); + Endpoint ep = new Endpoint(address, port.shortValue(), serviceName); + return ep; + } + + @EventListener(EmbeddedServletContainerInitializedEvent.class) + public void grabPort(EmbeddedServletContainerInitializedEvent event) { + this.port = event.getEmbeddedServletContainer().getPort(); + } + + private Integer getPort() { + if (this.port!=null) { + return this.port; + } + Integer port; + if (this.serverProperties!=null && this.serverProperties.getPort() != null) { + port = this.serverProperties.getPort(); + } + else { + port = 8080; + } + return port; + } + + private int getAddress() { + String address; + if (this.serverProperties!=null && this.serverProperties.getAddress() != null) { + address = this.serverProperties.getAddress().getHostAddress(); + } + else { + address = "127.0.0.1"; + } + return ipAddressToInt(address); + } + + private String getServiceName(Span span) { + String serviceName; + if (span.getProcessId() != null) { + serviceName = span.getProcessId().toLowerCase(); + } + else { + serviceName = this.appName; + } + return serviceName; + } + + private int ipAddressToInt(final String ip) { + InetAddress inetAddress = null; + try { + inetAddress = InetAddress.getByName(ip); + } + catch (final UnknownHostException e) { + throw new IllegalArgumentException(e); + } + return ByteBuffer.wrap(inetAddress.getAddress()).getInt(); + } + +} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java index f3f4049c1..82b401c2b 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java @@ -16,10 +16,14 @@ package org.springframework.cloud.sleuth.zipkin; +import org.springframework.beans.factory.annotation.Autowired; 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.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -50,10 +54,42 @@ public class ZipkinAutoConfiguration { } @Bean - // @ConditionalOnProperty(value = "spring.sleuth.zipkin.braveTracer.enabled", - // havingValue = "false") - public ZipkinSpanListener sleuthTracer(SpanCollector spanCollector) { - return new ZipkinSpanListener(spanCollector); + public ZipkinSpanListener sleuthTracer(SpanCollector spanCollector, EndpointLocator endpointLocator) { + return new ZipkinSpanListener(spanCollector, endpointLocator); + } + + @Configuration + @ConditionalOnMissingClass("org.springframework.cloud.client.discovery.DiscoveryClient") + protected static class DefaultEndpointLocatorConfiguration { + + @Autowired(required=false) + private ServerProperties serverProperties; + + @Bean + public EndpointLocator zipkinEndpointLocator() { + return new ServerPropertiesEndpointLocator(this.serverProperties); + } + + } + + @Configuration + @ConditionalOnClass(DiscoveryClient.class) + protected static class DiscoveryClientEndpointLocatorConfiguration { + + @Autowired(required=false) + private ServerProperties serverProperties; + + @Autowired(required=false) + private DiscoveryClient client; + + @Bean + public EndpointLocator zipkinEndpointLocator() { + if (this.client!=null) { + return new DiscoveryClientEndpointLocator(this.client); + } + return new ServerPropertiesEndpointLocator(this.serverProperties); + } + } } diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListener.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListener.java index 82685c06e..312d7aac1 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListener.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListener.java @@ -17,16 +17,10 @@ package org.springframework.cloud.sleuth.zipkin; import java.io.UnsupportedEncodingException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TimelineAnnotation; import org.springframework.cloud.sleuth.event.ClientReceivedEvent; @@ -55,13 +49,11 @@ import lombok.extern.apachecommons.CommonsLog; public class ZipkinSpanListener { private SpanCollector spanCollector; - @Value("${spring.application.name:application}") - private String appName; - @Autowired(required=false) - private ServerProperties serverProperties; + private EndpointLocator endpointLocator; - public ZipkinSpanListener(SpanCollector spanCollector) { + public ZipkinSpanListener(SpanCollector spanCollector, EndpointLocator endpointLocator) { this.spanCollector = spanCollector; + this.endpointLocator = endpointLocator; } @EventListener @@ -117,11 +109,7 @@ public class ZipkinSpanListener { public com.twitter.zipkin.gen.Span convert(Span span) { com.twitter.zipkin.gen.Span zipkinSpan = new com.twitter.zipkin.gen.Span(); - String serviceName = getServiceName(span); - int address = getAddress(); - Integer port = getPort(); - - Endpoint ep = new Endpoint(address, port.shortValue(), serviceName); + Endpoint ep = this.endpointLocator.locate(span); List annotationList = createZipkinAnnotations(span, ep); List binaryAnnotationList = createZipkinBinaryAnnotations(span, ep); @@ -142,49 +130,6 @@ public class ZipkinSpanListener { return zipkinSpan; } - public Integer getPort() { - Integer port; - if (this.serverProperties!=null && this.serverProperties.getPort() != null) { - port = this.serverProperties.getPort(); - } - else { - port = 8080; // TODO: support random port - } - return port; - } - - public int getAddress() { - String address; - if (this.serverProperties!=null && this.serverProperties.getAddress() != null) { - address = this.serverProperties.getAddress().getHostAddress(); - } - else { - address = "127.0.0.1"; // TODO: get address from config - } - return ipAddressToInt(address); - } - - public String getServiceName(Span span) { - String serviceName; - if (span.getProcessId() != null) { - serviceName = span.getProcessId().toLowerCase(); - } - else { - serviceName = this.appName; - } - return serviceName; - } - - private int ipAddressToInt(final String ip) { - InetAddress inetAddress = null; - try { - inetAddress = InetAddress.getByName(ip); - } - catch (final UnknownHostException e) { - throw new IllegalArgumentException(e); - } - return ByteBuffer.wrap(inetAddress.getAddress()).getInt(); - } /** * Add annotations from the sleuth Span.