Add strategy EndpointLocator to help with service host/port location
This commit is contained in:
@@ -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).
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -37,9 +37,19 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-sleuth-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<artifactId>spring-boot-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -47,18 +57,6 @@
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-http</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-core-spring</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kristofa</groupId>
|
||||
<artifactId>brave-zipkin-spancollector</artifactId>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<Annotation> annotationList = createZipkinAnnotations(span, ep);
|
||||
List<BinaryAnnotation> 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.
|
||||
|
||||
Reference in New Issue
Block a user