Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -165,32 +165,6 @@ private static void maybeFollowOtelConfigProperties(ConfigContainer configs) {
logger.info("failed to follow Otel's log file config." + e.getMessage());
}
}

String serviceName = System.getProperty("otel.service.name");
if (serviceName == null) {
serviceName = System.getenv("OTEL_SERVICE_NAME");
}

String serviceKey = (String) configs.get(ConfigProperty.AGENT_SERVICE_KEY);
if (serviceName == null) {
if (serviceKey != null) {
String name = ServiceKeyUtils.getServiceName(serviceKey);
if (name != null) {
System.setProperty("otel.service.name", name);
}
}

} else {
if (serviceKey != null) {
try {
String key = String.format("%s:%s", ServiceKeyUtils.getApiKey(serviceKey), serviceName);
configs.put(ConfigProperty.AGENT_SERVICE_KEY, key, true);
} catch (InvalidConfigException e) {
LoggerFactory.getLogger()
.warn(String.format("Unable to update service name to %s", serviceName));
}
}
}
}

static void configureOtel(ConfigContainer container) throws InvalidConfigException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.solarwinds.joboe.config.ConfigContainer;
import com.solarwinds.joboe.config.ConfigManager;
import com.solarwinds.joboe.config.ConfigProperty;
import com.solarwinds.joboe.config.InvalidConfigException;
import com.solarwinds.joboe.config.ServiceKeyUtils;
import com.solarwinds.opentelemetry.extensions.DefaultNamingScheme;
import com.solarwinds.opentelemetry.extensions.NamingScheme;
import com.solarwinds.opentelemetry.extensions.SpanAttributeNamingScheme;
Expand Down Expand Up @@ -133,27 +131,6 @@ void testWindowsRootPath() {
assertNull(ConfigurationLoader.getRuntimeConfigFilename());
}

@Test
@ClearSystemProperty(key = "otel.service.name")
void verifyThatOtelServiceNameSystemPropertyIsWhenNotExplicitlySet()
throws InvalidConfigException {
ConfigurationLoader.load();
assertEquals(
"name" /*name is from custom/build.gradle test task*/,
System.getProperty("otel.service.name"));
}

@Test
@SetSystemProperty(key = "otel.service.name", value = "test")
void verifyThatServiceKeyIsUpdatedWithOtelServiceNameWhenSystemPropertyIsSet()
throws InvalidConfigException {
ConfigurationLoader.load();
String serviceKeyAfter = (String) ConfigManager.getConfig(ConfigProperty.AGENT_SERVICE_KEY);

assertEquals("test", ServiceKeyUtils.getServiceName(serviceKeyAfter));
assertEquals("token:test", serviceKeyAfter);
}

@Test
@ClearSystemProperty(key = "otel.exporter.otlp.endpoint")
@ClearSystemProperty(key = "otel.exporter.otlp.headers")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,32 +110,6 @@ private static void maybeFollowOtelConfigProperties(ConfigContainer configs) {
logger.info("failed to follow Otel's log file config." + e.getMessage());
}
}

String serviceName = System.getProperty("otel.service.name");
if (serviceName == null) {
serviceName = System.getenv("OTEL_SERVICE_NAME");
}

String serviceKey = (String) configs.get(ConfigProperty.AGENT_SERVICE_KEY);
if (serviceName == null) {
if (serviceKey != null) {
String name = ServiceKeyUtils.getServiceName(serviceKey);
if (name != null) {
System.setProperty("otel.service.name", name);
}
}

} else {
if (serviceKey != null) {
try {
String key = String.format("%s:%s", ServiceKeyUtils.getApiKey(serviceKey), serviceName);
configs.put(ConfigProperty.AGENT_SERVICE_KEY, key, true);
} catch (InvalidConfigException e) {
LoggerFactory.getLogger()
.warn(String.format("Unable to update service name to %s", serviceName));
}
}
}
}

static Map<String, String> mergeEnvWithSysProperties(Map<String, String> env, Properties props) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,25 @@

package com.solarwinds.opentelemetry.extensions;

import com.solarwinds.joboe.config.ConfigManager;
import com.solarwinds.joboe.config.ConfigProperty;
import com.solarwinds.joboe.config.InvalidConfigException;
import com.solarwinds.joboe.config.ServiceKeyUtils;
import com.solarwinds.joboe.logging.LoggerFactory;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.resources.ResourceBuilder;
import io.opentelemetry.semconv.ServiceAttributes;
import io.opentelemetry.semconv.incubating.CloudIncubatingAttributes;
import io.opentelemetry.semconv.incubating.ProcessIncubatingAttributes;
import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import lombok.Getter;

public class ResourceCustomizer implements BiFunction<Resource, ConfigProperties, Resource> {
private static Resource resource;

@Getter private static Resource resource;

@Override
public Resource apply(Resource resource, ConfigProperties configProperties) {
Expand All @@ -51,16 +58,47 @@ public Resource apply(Resource resource, ConfigProperties configProperties) {
resourceBuilder.put(ProcessIncubatingAttributes.PROCESS_COMMAND_ARGS, args);
}

String serviceName = getServiceName(resource, configProperties);
updateServiceKey(serviceName);
resourceBuilder.put(ServiceAttributes.SERVICE_NAME, serviceName);

LoggerFactory.getLogger().info("Resolved service name: " + serviceName);
ResourceCustomizer.resource = resourceBuilder.build();
LoggerFactory.getLogger()
.debug(
String.format(
"This log line is used for validation only: service.name: %s",
resource.getAttribute(ServiceAttributes.SERVICE_NAME)));
return ResourceCustomizer.resource;
}

public static Resource getResource() {
return resource;
private String getServiceName(Resource resource, ConfigProperties configProperties) {
String serviceKeyName = null;
String serviceKey = ConfigManager.getConfigOptional(ConfigProperty.AGENT_SERVICE_KEY, null);
if (serviceKey != null) {
serviceKeyName = ServiceKeyUtils.getServiceName(serviceKey);
}

// Only allow detected name for azure app service
if (!"azure.app_service".equals(resource.getAttribute(CloudIncubatingAttributes.CLOUD_PLATFORM))
&& configProperties.getString("otel.service.name") == null) {
return serviceKeyName;
}

String serviceName = resource.getAttribute(ServiceAttributes.SERVICE_NAME);
if (serviceKeyName != null && (serviceName == null || serviceName.startsWith("unknown_"))) {
serviceName = serviceKeyName;
}

return serviceName;
}

private void updateServiceKey(String serviceName) {
if (serviceName != null) {
String serviceKey = ConfigManager.getConfigOptional(ConfigProperty.AGENT_SERVICE_KEY, ":");
String apiKey = ServiceKeyUtils.getApiKey(serviceKey);

try {
ConfigManager.setConfig(
ConfigProperty.AGENT_SERVICE_KEY, String.format("%s:%s", apiKey, serviceName));
} catch (InvalidConfigException ignore) {
LoggerFactory.getLogger().debug("Failed to update service key with name: " + serviceName);
}
}
}
Comment thread
cleverchuk marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,21 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import com.solarwinds.joboe.config.ConfigManager;
import com.solarwinds.joboe.config.ConfigProperty;
import com.solarwinds.joboe.config.InvalidConfigException;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.ServiceAttributes;
import io.opentelemetry.semconv.incubating.CloudIncubatingAttributes;
import io.opentelemetry.semconv.incubating.ProcessIncubatingAttributes;
import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
Expand All @@ -36,6 +43,11 @@ class ResourceCustomizerTest {

@InjectMocks private ResourceCustomizer tested;

@AfterEach
void tearDown() {
ConfigManager.reset();
}

private final Resource resource =
Resource.create(
Attributes.builder()
Expand Down Expand Up @@ -104,4 +116,113 @@ void verifyThatProcessCommandLineIsNotModifiedWhenServiceKeyIsNotPresentProcessC
Arrays.asList("-Duser.country=US", "-Duser.language=en"),
actual.getAttribute(ProcessIncubatingAttributes.PROCESS_COMMAND_ARGS));
}

@Test
void verifyThatServiceKeyNameIsPreferredOverDetectedNameByDefault()
throws InvalidConfigException {
ConfigManager.setConfig(ConfigProperty.AGENT_SERVICE_KEY, "token:key-service");
Resource resource =
Resource.create(
Attributes.builder().put(ServiceAttributes.SERVICE_NAME, "my-service").build());

Resource actual =
tested.apply(resource, DefaultConfigProperties.createFromMap(Collections.emptyMap()));
assertEquals("key-service", actual.getAttribute(ServiceAttributes.SERVICE_NAME));
}

@Test
void verifyThatDetectedServiceNameIsUsedForAzureAppService() throws InvalidConfigException {
ConfigManager.setConfig(ConfigProperty.AGENT_SERVICE_KEY, "token:key-service");
Resource resource =
Resource.create(
Attributes.builder()
.put(CloudIncubatingAttributes.CLOUD_PLATFORM, "azure.app_service")
.put(ServiceAttributes.SERVICE_NAME, "my-service")
.build());

Resource actual =
tested.apply(resource, DefaultConfigProperties.createFromMap(Collections.emptyMap()));
assertEquals("my-service", actual.getAttribute(ServiceAttributes.SERVICE_NAME));
}

@Test
void verifyThatServiceKeyNameIsUsedForAzureAppServiceWhenDetectedNameIsUnknown()
throws InvalidConfigException {
ConfigManager.setConfig(ConfigProperty.AGENT_SERVICE_KEY, "token:key-service");
Resource resource =
Resource.create(
Attributes.builder()
.put(CloudIncubatingAttributes.CLOUD_PLATFORM, "azure.app_service")
.put(ServiceAttributes.SERVICE_NAME, "unknown_service:java")
.build());

Resource actual =
tested.apply(resource, DefaultConfigProperties.createFromMap(Collections.emptyMap()));
assertEquals("key-service", actual.getAttribute(ServiceAttributes.SERVICE_NAME));
}

@Test
void verifyThatServiceKeyNameIsUsedForAzureAppServiceWhenDetectedNameIsNull()
throws InvalidConfigException {
ConfigManager.setConfig(ConfigProperty.AGENT_SERVICE_KEY, "token:key-service");
Resource resource =
Resource.create(
Attributes.builder()
.put(CloudIncubatingAttributes.CLOUD_PLATFORM, "azure.app_service")
.build());

Resource actual =
tested.apply(resource, DefaultConfigProperties.createFromMap(Collections.emptyMap()));
assertEquals("key-service", actual.getAttribute(ServiceAttributes.SERVICE_NAME));
}

@Test
void verifyThatServiceKeyNameIsUsedByDefaultWhenResourceHasNoServiceName()
throws InvalidConfigException {
ConfigManager.setConfig(ConfigProperty.AGENT_SERVICE_KEY, "token:key-service");
Resource resource = Resource.create(Attributes.empty());

Resource actual =
tested.apply(resource, DefaultConfigProperties.createFromMap(Collections.emptyMap()));
assertEquals("key-service", actual.getAttribute(ServiceAttributes.SERVICE_NAME));
}

@Test
void verifyThatServiceNameIsNullWhenNotInResourceAndNoServiceKeyConfigured() {
Resource resource = Resource.create(Attributes.empty());
Resource actual =
tested.apply(resource, DefaultConfigProperties.createFromMap(Collections.emptyMap()));

assertNull(actual.getAttribute(ServiceAttributes.SERVICE_NAME));
}

@Test
void verifyThatServiceKeyIsUpdatedWithConfiguredServiceNameWhenNotOnAppService()
throws InvalidConfigException {
ConfigManager.setConfig(ConfigProperty.AGENT_SERVICE_KEY, "token:old-name");
Resource resource =
Resource.create(
Attributes.builder().put(ServiceAttributes.SERVICE_NAME, "new-name").build());

tested.apply(
resource,
DefaultConfigProperties.createFromMap(
Collections.singletonMap("otel.service.name", "new-name")));
assertEquals("token:new-name", ConfigManager.getConfig(ConfigProperty.AGENT_SERVICE_KEY));
}

@Test
void verifyThatServiceKeyIsUpdatedWithServiceNameWhenOnAppService()
throws InvalidConfigException {
ConfigManager.setConfig(ConfigProperty.AGENT_SERVICE_KEY, "token:old-name");
Resource resource =
Resource.create(
Attributes.builder()
.put(CloudIncubatingAttributes.CLOUD_PLATFORM, "azure.app_service")
.put(ServiceAttributes.SERVICE_NAME, "new-name")
.build());

tested.apply(resource, DefaultConfigProperties.createFromMap(Collections.emptyMap()));
assertEquals("token:new-name", ConfigManager.getConfig(ConfigProperty.AGENT_SERVICE_KEY));
}
}
1 change: 0 additions & 1 deletion smoke-tests/src/test/java/com/solarwinds/SmokeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ public class SmokeTest {
"hostId:.*[0-9a-z-]+",
"Extension attached!",
"trace_id=[a-z0-9]+\\s+span_id=[a-z0-9]+\\s+trace_flags=[0-9a-f]{2}",
"This log line is used for validation only: service.name: java-apm-smoke-test",
"Applying instrumentation: sw-jdbc",
"Clearing transaction name buffer. Unique transaction count: \\d+",
"CONNECT otel.collector.na-01.st-ssp.solarwinds.com:443")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ public class SmokeTestV2 {
"hostId:.*[0-9a-z-]+",
"Extension attached!",
"trace_id=[a-z0-9]+\\s+span_id=[a-z0-9]+\\s+trace_flags=[0-9a-f]{2}",
"This log line is used for validation only: service.name: java-apm-smoke-test",
"Applying instrumentation: sw-jdbc",
"Clearing transaction name buffer. Unique transaction count: \\d+")
, new Slf4jLogConsumer(LoggerFactory.getLogger("k6")));
Expand Down
Loading