Skip to content

Commit

Permalink
Merge pull request #13 from spring-cloud-incubator/resource_customizer
Browse files Browse the repository at this point in the history
Resource customizer
  • Loading branch information
marcingrzejszczak authored Feb 18, 2021
2 parents bbde7a0 + 3ba001a commit d3c8219
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 6 deletions.
5 changes: 5 additions & 0 deletions docs/src/main/asciidoc/project-features.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ We're providing an Slf4j integration via a `SpanProcessor` that injects to and r
If it's there on the classpath, we integrate with the `LoggingSpanExporter`.
You can disable that integration via the `spring.sleuth.otel.log.exporter.enabled=false` property.

[[features-otel-resource-customization]]
=== OpenTelemetry Resource Customization

OpenTelemetry provides a `Resource` abstraction which captures identifying information about the entities for which signals (stats or traces) are reported. If you wish to customize that `Resource` you can register as a bean an implementation of the `ResourceCustomizer` interface.

[[features-otel-opentracing]]
=== OpenTelemetry Opentracing

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,18 @@ SdkTracerProvider otelTracerProvider(SpanLimits spanLimits, ObjectProvider<List<

@Bean
@ConditionalOnMissingBean
Resource otelResource(Environment env) {
// todo: populate the resource with the right stuff (service.name, etc)
// this was the code in the zipkin exporter configuration previously:
// env.getProperty("spring.application.name", env.getProperty(
// "spring.zipkin.service.name", ZipkinSpanExporter.DEFAULT_SERVICE_NAME)
Resource otelResource(Environment env, ObjectProvider<List<ResourceCustomizer>> resourceCustomizerProvider) {
String applicationName = env.getProperty("spring.application.name");
Resource resource = defaultResource(applicationName);
List<ResourceCustomizer> resourceCustomizers = resourceCustomizerProvider.getIfAvailable(ArrayList::new);
for (ResourceCustomizer customizer : resourceCustomizers) {
Resource customized = customizer.customize(resource);
resource = resource.merge(customized);
}
return resource;
}

private Resource defaultResource(String applicationName) {
if (applicationName == null) {
return Resource.getDefault();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2013-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.cloud.sleuth.autoconfig.otel;

import io.opentelemetry.sdk.resources.Resource;

/**
* Allows to customize the {@link Resource}.
*
* @author Marcin Grzejszczak
* @since 1.0.0
*/
@FunctionalInterface
public interface ResourceCustomizer {

/**
* Customizes the resource or returns itself if there's nothing to customize.
* @param resource - resource to customize
* @return resource to be merged with the customized resource
*/
Resource customize(Resource resource);

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,19 @@

package org.springframework.cloud.sleuth.autoconfig.otel.zipkin2;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import zipkin2.reporter.Sender;

import org.springframework.beans.factory.annotation.Qualifier;
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.ConditionalOnProperty;
import org.springframework.cloud.sleuth.autoconfig.otel.ResourceCustomizer;
import org.springframework.cloud.sleuth.autoconfig.zipkin2.ZipkinAutoConfiguration;
import org.springframework.cloud.sleuth.zipkin2.DefaultZipkinRestTemplateCustomizer;
import org.springframework.cloud.sleuth.zipkin2.EndpointLocator;
Expand Down Expand Up @@ -62,11 +66,22 @@ static class ZipkinConfiguration {
@Bean
@ConditionalOnMissingBean
ZipkinSpanExporter otelZipkinSpanExporter(ZipkinProperties zipkinProperties,
@Qualifier(ZipkinAutoConfiguration.SENDER_BEAN_NAME) Sender sender, Environment env) {
@Qualifier(ZipkinAutoConfiguration.SENDER_BEAN_NAME) Sender sender) {
return ZipkinSpanExporter.builder().setEndpoint(zipkinProperties.getBaseUrl() + "api/v2/spans")
.setSender(sender).setEncoder(zipkinProperties.getEncoder()).build();
}

@Bean
ResourceCustomizer zipkinResourceCustomizer(Environment environment) {
return resource -> {
String zipkinServiceName = environment.getProperty("spring.zipkin.service.name");
if (zipkinServiceName == null) {
return resource;
}
return Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, zipkinServiceName));
};
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.springframework.cloud.sleuth.autoconfig.otel.zipkin2;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.sdk.resources.Resource;
import org.assertj.core.api.BDDAssertions;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -45,6 +47,19 @@ void should_set_sampler_to_non_off_when_zipkin_handler_on_classpath_for_otel() {
});
}

@Test
void should_set_service_name_to_zipkin_service_name() {
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withPropertyValues("spring.sleuth.tracer.mode=AUTO", "spring.application.name=foo",
"spring.zipkin.service.name=bar")
.withConfiguration(AutoConfigurations.of(TestConfig.class));

contextRunner.run(context -> {
Resource resource = context.getBean(Resource.class);
BDDAssertions.then(resource.getAttributes().get(AttributeKey.stringKey("service.name"))).isEqualTo("bar");
});
}

@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
static class TestConfig {
Expand Down

0 comments on commit d3c8219

Please sign in to comment.