From 07ccf32a254e6bbd884c7b954a90f699a9e93aa9 Mon Sep 17 00:00:00 2001 From: Charles Moulliard Date: Mon, 5 Jun 2017 17:14:33 +0200 Subject: [PATCH 1/5] Add jaeger module --- pom.xml | 2 + spring-cloud-kubernetes-dependencies/pom.xml | 31 ++++++++++ .../KubernetesJaegerDiscoveryProperties.java | 56 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/KubernetesJaegerDiscoveryProperties.java diff --git a/pom.xml b/pom.xml index c1ab936656..1965cbf599 100644 --- a/pom.xml +++ b/pom.xml @@ -79,6 +79,7 @@ spring-cloud-kubernetes-discovery spring-cloud-kubernetes-ribbon spring-cloud-kubernetes-zipkin + spring-cloud-kubernetes-jaeger spring-cloud-kubernetes-hystrix spring-cloud-kubernetes-archaius spring-cloud-starter-kubernetes @@ -86,6 +87,7 @@ spring-cloud-starter-kubernetes-netflix spring-cloud-starter-kubernetes-zipkin spring-cloud-starter-kubernetes-all + spring-cloud-starter-kubernetes-jaeger spring-cloud-kubernetes-examples diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index ccd41a62e3..0efdeaa39f 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -20,6 +20,9 @@ 0.0.12 3.0.2 1.0-groovy-2.3 + 0.19.0 + 0.22.0 + 0.0.4 @@ -74,6 +77,11 @@ ${project.version} + + org.springframework.cloud + spring-cloud-kubernetes-jaeger + ${project.version} + @@ -106,6 +114,27 @@ ${project.version} + + + io.opentracing + opentracing-noop + ${io.opentracing.version} + + + + io.opentracing.contrib + opentracing-spring-web-autoconfigure + ${io.opentracing.contrib.spring.autoconfigure.version} + + + + + com.uber.jaeger + jaeger-core + ${version.jaeger} + + + org.jboss.arquillian.junit @@ -159,6 +188,8 @@ spock-spring ${spock-spring.version} + + diff --git a/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/KubernetesJaegerDiscoveryProperties.java b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/KubernetesJaegerDiscoveryProperties.java new file mode 100644 index 0000000000..c6a03822ea --- /dev/null +++ b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/KubernetesJaegerDiscoveryProperties.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 to the original 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.kubernetes.jaeger; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author Charles Moulliard + */ +@ConfigurationProperties("spring.cloud.kubernetes.jaeger.discovery") +public class KubernetesJaegerDiscoveryProperties { + + private String tracerServerName = "jaeger-all-in-one"; + private String serviceName; + private String serviceNamespace; + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getTracerServerName() { + return tracerServerName; + } + + public void setTracerServerName(String tracerServerName) { + this.tracerServerName = tracerServerName; + } + + public String getServiceNamespace() { + return serviceNamespace; + } + + public void setServiceNamespace(String serviceNamespace) { + this.serviceNamespace = serviceNamespace; + } + +} From 60f969b89ed8ce5bfefff23f2f581e4daf1f200e Mon Sep 17 00:00:00 2001 From: Charles Moulliard Date: Tue, 6 Jun 2017 12:46:25 +0200 Subject: [PATCH 2/5] Add missing files --- spring-cloud-kubernetes-jaeger/.jdk8 | 0 spring-cloud-kubernetes-jaeger/pom.xml | 77 +++++++++++++ .../JaegerKubernetesAutoConfiguration.java | 107 ++++++++++++++++++ .../main/resources/META-INF/spring.factories | 2 + .../pom.xml | 50 ++++++++ 5 files changed, 236 insertions(+) create mode 100644 spring-cloud-kubernetes-jaeger/.jdk8 create mode 100644 spring-cloud-kubernetes-jaeger/pom.xml create mode 100644 spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java create mode 100644 spring-cloud-kubernetes-jaeger/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-starter-kubernetes-jaeger/pom.xml diff --git a/spring-cloud-kubernetes-jaeger/.jdk8 b/spring-cloud-kubernetes-jaeger/.jdk8 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cloud-kubernetes-jaeger/pom.xml b/spring-cloud-kubernetes-jaeger/pom.xml new file mode 100644 index 0000000000..676cadf91e --- /dev/null +++ b/spring-cloud-kubernetes-jaeger/pom.xml @@ -0,0 +1,77 @@ + + + + + + spring-cloud-kubernetes + org.springframework.cloud + 0.2.0.BUILD-SNAPSHOT + + 4.0.0 + + org.springframework.cloud + spring-cloud-kubernetes-jaeger + Spring Cloud Kubernetes :: Jaeger + + + + + org.springframework.cloud + spring-cloud-kubernetes-discovery + ${project.version} + + + + org.springframework.boot + spring-boot-autoconfigure + + + + org.springframework.cloud + spring-cloud-commons + + + + org.springframework.cloud + spring-cloud-context + true + + + + + io.opentracing + opentracing-noop + + + + io.opentracing.contrib + opentracing-spring-web-autoconfigure + + + + + com.uber.jaeger + jaeger-core + + + + + + diff --git a/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java new file mode 100644 index 0000000000..6a91861f9b --- /dev/null +++ b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 to the original 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.kubernetes.jaeger; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.uber.jaeger.metrics.Metrics; +import com.uber.jaeger.metrics.NullStatsReporter; +import com.uber.jaeger.metrics.StatsFactoryImpl; +import com.uber.jaeger.reporters.RemoteReporter; +import com.uber.jaeger.samplers.ProbabilisticSampler; +import com.uber.jaeger.senders.Sender; +import com.uber.jaeger.senders.UdpSender; +import io.fabric8.kubernetes.api.model.Endpoints; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.utils.Utils; +import io.opentracing.Tracer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.Assert; + +@Configuration +@EnableConfigurationProperties(KubernetesJaegerDiscoveryProperties.class) +public class JaegerKubernetesAutoConfiguration { + + @Autowired + private Tracer noopTracer; + + // TODO - Check how we can return noopTracer and avoid + /** + * *************************** + APPLICATION FAILED TO START + *************************** + + Description: + + Parameter 0 of method tracingFilter in io.opentracing.contrib.spring.web.autoconfig.ServerTracingAutoConfiguration required a single bean, but 2 were found: + - noopTracer: defined by method 'noopTracer' in class path resource [io/opentracing/contrib/spring/web/autoconfig/TracerAutoConfiguration.class] + - reporter: defined by method 'reporter' in class path resource [org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.class] + + + Action: + + Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed + */ + + @Bean + public Tracer reporter(KubernetesClient client, KubernetesJaegerDiscoveryProperties discoveryProperties) { + + String serviceName = discoveryProperties.getServiceName(); + String traceServerName = discoveryProperties.getTracerServerName(); + String serviceNamespace = Utils.isNotNullOrEmpty(discoveryProperties.getServiceNamespace()) ? discoveryProperties.getServiceNamespace() : client.getNamespace(); + + List services = getInstances(client, traceServerName, serviceNamespace); + String serviceUrl = services.stream() + .findFirst() + .map(s -> s.getUri().toString()) + .orElse(null); + + return serviceUrl == null || serviceUrl.isEmpty() + ? noopTracer + : jaegerTracer(serviceUrl, serviceName); + } + + private static List getInstances(KubernetesClient client, String name, String namespace) { + Assert.notNull(name, "[Assertion failed] - the service name must not be null"); + + return Optional.ofNullable(client.endpoints().inNamespace(namespace).withName(name).get()) + .orElse(new Endpoints()) + .getSubsets() + .stream() + .flatMap(s -> s.getAddresses().stream().map(a -> (ServiceInstance) new KubernetesServiceInstance(name, a ,s.getPorts().stream().findFirst().orElseThrow(IllegalStateException::new), false))) + .collect(Collectors.toList()); + } + + private Tracer jaegerTracer(String url, String serviceName) { + Sender sender = new UdpSender(url, 0, 0); + return new com.uber.jaeger.Tracer.Builder(serviceName, + new RemoteReporter(sender, 100, 50, + new Metrics(new StatsFactoryImpl(new NullStatsReporter()))), + new ProbabilisticSampler(1.0)) + .build(); + } + +} diff --git a/spring-cloud-kubernetes-jaeger/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-jaeger/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..598dd66e6a --- /dev/null +++ b/spring-cloud-kubernetes-jaeger/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.kubernetes.jaeger.JaegerKubernetesAutoConfiguration diff --git a/spring-cloud-starter-kubernetes-jaeger/pom.xml b/spring-cloud-starter-kubernetes-jaeger/pom.xml new file mode 100644 index 0000000000..80ee65fbf1 --- /dev/null +++ b/spring-cloud-starter-kubernetes-jaeger/pom.xml @@ -0,0 +1,50 @@ + + + + + + spring-cloud-kubernetes + org.springframework.cloud + 0.2.0.BUILD-SNAPSHOT + + 4.0.0 + + org.springframework.cloud + spring-cloud-starter-kubernetes-jaeger + Spring Cloud Kubernetes :: Starter :: Jaeger + + + + org.springframework.cloud + spring-cloud-kubernetes-core + + + + org.springframework.cloud + spring-cloud-kubernetes-discovery + + + + org.springframework.cloud + spring-cloud-kubernetes-jaeger + + + + From 3ddf95489b60f897cab6a083f274d2fc511dc4a5 Mon Sep 17 00:00:00 2001 From: Charles Moulliard Date: Tue, 6 Jun 2017 15:57:02 +0200 Subject: [PATCH 3/5] Apply patch to create correctly the NoopTracer. Add Logger --- spring-cloud-kubernetes-jaeger/pom.xml | 6 +++ .../JaegerKubernetesAutoConfiguration.java | 54 ++++++++----------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/spring-cloud-kubernetes-jaeger/pom.xml b/spring-cloud-kubernetes-jaeger/pom.xml index 676cadf91e..58c45eba64 100644 --- a/spring-cloud-kubernetes-jaeger/pom.xml +++ b/spring-cloud-kubernetes-jaeger/pom.xml @@ -43,6 +43,12 @@ spring-boot-autoconfigure + + org.springframework.boot + spring-boot-starter-logging + true + + org.springframework.cloud spring-cloud-commons diff --git a/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java index 6a91861f9b..c85838a995 100644 --- a/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java +++ b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java @@ -21,6 +21,16 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.Assert; + import com.uber.jaeger.metrics.Metrics; import com.uber.jaeger.metrics.NullStatsReporter; import com.uber.jaeger.metrics.StatsFactoryImpl; @@ -28,46 +38,23 @@ import com.uber.jaeger.samplers.ProbabilisticSampler; import com.uber.jaeger.senders.Sender; import com.uber.jaeger.senders.UdpSender; + import io.fabric8.kubernetes.api.model.Endpoints; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.utils.Utils; +import io.opentracing.NoopTracerFactory; import io.opentracing.Tracer; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.Assert; +import io.opentracing.contrib.spring.web.autoconfig.TracerAutoConfiguration; @Configuration +@AutoConfigureBefore(TracerAutoConfiguration.class) @EnableConfigurationProperties(KubernetesJaegerDiscoveryProperties.class) public class JaegerKubernetesAutoConfiguration { - @Autowired - private Tracer noopTracer; - - // TODO - Check how we can return noopTracer and avoid - /** - * *************************** - APPLICATION FAILED TO START - *************************** - - Description: - - Parameter 0 of method tracingFilter in io.opentracing.contrib.spring.web.autoconfig.ServerTracingAutoConfiguration required a single bean, but 2 were found: - - noopTracer: defined by method 'noopTracer' in class path resource [io/opentracing/contrib/spring/web/autoconfig/TracerAutoConfiguration.class] - - reporter: defined by method 'reporter' in class path resource [org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.class] - - - Action: - - Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed - */ + private static final Log LOG = LogFactory.getLog(JaegerKubernetesAutoConfiguration.class); @Bean - public Tracer reporter(KubernetesClient client, KubernetesJaegerDiscoveryProperties discoveryProperties) { + public Tracer tracer(KubernetesClient client, KubernetesJaegerDiscoveryProperties discoveryProperties) { String serviceName = discoveryProperties.getServiceName(); String traceServerName = discoveryProperties.getTracerServerName(); @@ -79,9 +66,12 @@ public Tracer reporter(KubernetesClient client, KubernetesJaegerDiscoveryPropert .map(s -> s.getUri().toString()) .orElse(null); - return serviceUrl == null || serviceUrl.isEmpty() - ? noopTracer - : jaegerTracer(serviceUrl, serviceName); + if (serviceUrl == null || serviceUrl.isEmpty()) { + LOG.info("Jaeger k8s starter creating Noop Tracer"); + return NoopTracerFactory.create(); + } + + return jaegerTracer(serviceUrl, serviceName); } private static List getInstances(KubernetesClient client, String name, String namespace) { From 049945ae1a163a0b917a448211444420be7afc41 Mon Sep 17 00:00:00 2001 From: Charles Moulliard Date: Tue, 6 Jun 2017 16:39:22 +0200 Subject: [PATCH 4/5] Extract IP and PORT --- .../jaeger/JaegerKubernetesAutoConfiguration.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java index c85838a995..6a87cc69b6 100644 --- a/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java +++ b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java @@ -17,6 +17,9 @@ package org.springframework.cloud.kubernetes.jaeger; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -54,7 +57,7 @@ public class JaegerKubernetesAutoConfiguration { private static final Log LOG = LogFactory.getLog(JaegerKubernetesAutoConfiguration.class); @Bean - public Tracer tracer(KubernetesClient client, KubernetesJaegerDiscoveryProperties discoveryProperties) { + public Tracer tracer(KubernetesClient client, KubernetesJaegerDiscoveryProperties discoveryProperties) throws Exception { String serviceName = discoveryProperties.getServiceName(); String traceServerName = discoveryProperties.getTracerServerName(); @@ -85,8 +88,9 @@ private static List getInstances(KubernetesClient client, Strin .collect(Collectors.toList()); } - private Tracer jaegerTracer(String url, String serviceName) { - Sender sender = new UdpSender(url, 0, 0); + private Tracer jaegerTracer(String serviceURL, String serviceName) throws Exception { + URL url = new URL(serviceURL); + Sender sender = new UdpSender(url.getHost(), url.getPort(), 0); return new com.uber.jaeger.Tracer.Builder(serviceName, new RemoteReporter(sender, 100, 50, new Metrics(new StatsFactoryImpl(new NullStatsReporter()))), From 857f1c05612236d603c4cd89b65188daf6b4cbb3 Mon Sep 17 00:00:00 2001 From: Charles Moulliard Date: Tue, 6 Jun 2017 17:19:41 +0200 Subject: [PATCH 5/5] Optimize imports --- .../JaegerKubernetesAutoConfiguration.java | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java index 6a87cc69b6..92b153a203 100644 --- a/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java +++ b/spring-cloud-kubernetes-jaeger/src/main/java/org/springframework/cloud/kubernetes/jaeger/JaegerKubernetesAutoConfiguration.java @@ -17,23 +17,11 @@ package org.springframework.cloud.kubernetes.jaeger; -import java.net.InetAddress; -import java.net.MalformedURLException; import java.net.URL; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.Assert; - import com.uber.jaeger.metrics.Metrics; import com.uber.jaeger.metrics.NullStatsReporter; import com.uber.jaeger.metrics.StatsFactoryImpl; @@ -41,13 +29,21 @@ import com.uber.jaeger.samplers.ProbabilisticSampler; import com.uber.jaeger.senders.Sender; import com.uber.jaeger.senders.UdpSender; - import io.fabric8.kubernetes.api.model.Endpoints; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.utils.Utils; import io.opentracing.NoopTracerFactory; import io.opentracing.Tracer; import io.opentracing.contrib.spring.web.autoconfig.TracerAutoConfiguration; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.Assert; @Configuration @AutoConfigureBefore(TracerAutoConfiguration.class)