Skip to content
Open
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![Status](https://img.shields.io/badge/status-stable-informational?style=for-the-badge)](https://github.com/solarwinds/apm-java)
[![OTEL](https://img.shields.io/badge/otel-2.3.0-blueviolet?style=for-the-badge)](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/tag/v2.3.0)
[![OTEL](https://img.shields.io/badge/otel-2.24.0-blueviolet?style=for-the-badge)](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/tag/v2.24.0)
[![SWO](https://img.shields.io/github/v/release/solarwinds/apm-java?include_prereleases&style=for-the-badge)](https://github.com/solarwinds/apm-java/releases)
[![SWO SDK](https://img.shields.io/maven-central/v/io.github.appoptics/solarwinds-otel-sdk?style=for-the-badge)](https://maven-badges.herokuapp.com/maven-central/io.github.appoptics/solarwinds-otel-sdk)
[![License](https://img.shields.io/badge/License-Apache_2.0-red.svg?style=for-the-badge)](https://github.com/solarwinds/apm-java/blob/main/LICENSE)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ plugins{
id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
}

val swoAgentVersion = "3.1.2"
val swoAgentVersion = "3.1.3"
extra["swoAgentVersion"] = swoAgentVersion
group = "com.solarwinds"
version = if (System.getenv("SNAPSHOT_BUILD").toBoolean()) "$swoAgentVersion-SNAPSHOT" else swoAgentVersion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,45 @@
import com.solarwinds.joboe.logging.LoggerFactory;
import com.solarwinds.opentelemetry.extensions.LoggingConfigProvider;
import com.solarwinds.opentelemetry.extensions.config.parser.yaml.DeclarativeConfigParser;
import io.opentelemetry.api.incubator.config.ConfigProvider;
import io.opentelemetry.api.incubator.ExtendedOpenTelemetry;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.javaagent.tooling.BeforeAgentListener;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil;

@AutoService(BeforeAgentListener.class)
public class DeclarativeLoader implements BeforeAgentListener {
private static final Logger logger = LoggerFactory.getLogger();

@Override
public void beforeAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) {
ConfigProvider configProvider =
AutoConfigureUtil.getConfigProvider(autoConfiguredOpenTelemetrySdk);
OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk();
if (!(openTelemetrySdk instanceof ExtendedOpenTelemetry)) {
// Shouldn't happen in practice, but just in case
logger.warn(
"OpenTelemetrySdk is not an instance of ExtendedOpenTelemetry. Declarative configuration will not be applied.");
return;
}

if (configProvider != null) {
DeclarativeConfigProperties instrumentationConfig = configProvider.getInstrumentationConfig();
ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetrySdk;
DeclarativeConfigProperties solarwinds =
extendedOpenTelemetry.getInstrumentationConfig("solarwinds");

if (instrumentationConfig != null) {
DeclarativeConfigProperties solarwinds =
instrumentationConfig
.getStructured("java", DeclarativeConfigProperties.empty())
.getStructured("solarwinds", DeclarativeConfigProperties.empty());
if (solarwinds != null && !solarwinds.getPropertyKeys().isEmpty()) {
try {
ConfigContainer configContainer = new ConfigContainer();
DeclarativeConfigParser declarativeConfigParser =
new DeclarativeConfigParser(configContainer);

try {
ConfigContainer configContainer = new ConfigContainer();
new DeclarativeConfigParser(configContainer).parse(solarwinds);
ConfigurationLoader.processConfigs(configContainer);
declarativeConfigParser.parse(solarwinds);
ConfigurationLoader.processConfigs(configContainer);

ConfigContainer agentConfig = configContainer.subset(ConfigGroup.AGENT);
LoggerFactory.init(LoggingConfigProvider.getLoggerConfiguration(agentConfig));
logger.info("Loaded via declarative config");
ConfigContainer agentConfig = configContainer.subset(ConfigGroup.AGENT);
LoggerFactory.init(LoggingConfigProvider.getLoggerConfiguration(agentConfig));
logger.info("Loaded via declarative config");

} catch (InvalidConfigException e) {
throw new RuntimeException(e);
}
} catch (InvalidConfigException e) {
throw new RuntimeException(e);
}

if (!JavaRuntimeVersionChecker.isJdkVersionSupported()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectionModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorPropertyModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorPropertyModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel;
import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -71,12 +73,14 @@ private void addResourceDetector(ResourceModel resourceModel) {
newDetectors.add(
new ExperimentalResourceDetectorModel()
.withAdditionalProperty(
ResourceComponentProvider.COMPONENT_NAME, Collections.emptyMap()));
ResourceComponentProvider.COMPONENT_NAME,
new ExperimentalResourceDetectorPropertyModel()));

newDetectors.add(
new ExperimentalResourceDetectorModel()
.withAdditionalProperty(
HostIdResourceComponentProvider.COMPONENT_NAME, Collections.emptyMap()));
HostIdResourceComponentProvider.COMPONENT_NAME,
new ExperimentalResourceDetectorPropertyModel()));
detectionDevelopment.withDetectors(newDetectors);
}

Expand All @@ -87,7 +91,7 @@ private void addProcessors(TracerProviderModel model) {
new SpanProcessorModel()
.withAdditionalProperty(
ProfilingSpanProcessorComponentProvider.COMPONENT_NAME,
Collections.emptyMap()));
new SpanProcessorPropertyModel()));

ArrayList<SpanProcessorModel> allProcessors = new ArrayList<>(model.getProcessors());
allProcessors.addAll(processors);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* © SolarWinds Worldwide, LLC. All rights reserved.
*
* 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 com.solarwinds.opentelemetry.extensions.config;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import com.solarwinds.joboe.config.ConfigManager;
import com.solarwinds.joboe.config.ConfigProperty;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationPropertyModel;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class DeclarativeLoaderTest {

@InjectMocks private DeclarativeLoader tested;

@Mock private AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdkMock;

@Mock private ExtendedOpenTelemetrySdk extendedOpenTelemetrySdkMock;

private final ExperimentalLanguageSpecificInstrumentationPropertyModel solarwinds =
new ExperimentalLanguageSpecificInstrumentationPropertyModel()
.withAdditionalProperty(
ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey(), "token:service")
.withAdditionalProperty(
ConfigProperty.AGENT_COLLECTOR.getConfigFileKey(), "apm.collector.com");

@AfterAll
public static void clearConfig() {
ConfigManager.reset();
}

@Test
public void testBeforeAgent() {
DeclarativeConfigProperties configProperties =
DeclarativeConfiguration.toConfigProperties(solarwinds);
when(autoConfiguredOpenTelemetrySdkMock.getOpenTelemetrySdk())
.thenReturn(extendedOpenTelemetrySdkMock);
when(extendedOpenTelemetrySdkMock.getInstrumentationConfig(eq("solarwinds")))
.thenReturn(configProperties);
tested.beforeAgent(autoConfiguredOpenTelemetrySdkMock);

assertNotNull(ConfigManager.getConfig(ConfigProperty.AGENT_COLLECTOR));
assertNotNull(ConfigManager.getConfig(ConfigProperty.AGENT_SERVICE_KEY));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@

import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_HOST_KEY;
import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_PORT_KEY;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -46,12 +50,19 @@ void shouldReturnSameExporterWhenProxyNotConfigured() {
}

@Test
void shouldReturnNewExporterWhenProxyConfigured() {
void shouldCallSetProxyWhenProxyConfigured() {
when(configProperties.getString(SW_OTEL_PROXY_HOST_KEY)).thenReturn("localhost");
when(configProperties.getInt(SW_OTEL_PROXY_PORT_KEY)).thenReturn(8080);

OtlpHttpLogRecordExporter originalExporter = OtlpHttpLogRecordExporter.builder().build();
LogRecordExporter result = tested.apply(originalExporter, configProperties);
assertNotSame(originalExporter, result);
OtlpHttpLogRecordExporter originalExporter = mock(OtlpHttpLogRecordExporter.class);
OtlpHttpLogRecordExporterBuilder builder = mock(OtlpHttpLogRecordExporterBuilder.class);

when(originalExporter.toBuilder()).thenReturn(builder);
when(builder.setProxyOptions(any(ProxyOptions.class))).thenReturn(builder);
when(builder.build()).thenReturn(mock(OtlpHttpLogRecordExporter.class));

tested.apply(originalExporter, configProperties);

verify(builder).setProxyOptions(any(ProxyOptions.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@

import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_HOST_KEY;
import static com.solarwinds.opentelemetry.extensions.SharedNames.SW_OTEL_PROXY_PORT_KEY;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.common.export.ProxyOptions;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -46,12 +50,18 @@ void shouldReturnSameExporterWhenProxyNotConfigured() {
}

@Test
void shouldReturnNewExporterWhenProxyConfigured() {
void shouldCallSetProxyWhenProxyConfigured() {
when(configProperties.getString(SW_OTEL_PROXY_HOST_KEY)).thenReturn("localhost");
when(configProperties.getInt(SW_OTEL_PROXY_PORT_KEY)).thenReturn(8080);

OtlpHttpSpanExporter originalExporter = OtlpHttpSpanExporter.builder().build();
SpanExporter result = tested.apply(originalExporter, configProperties);
assertNotSame(originalExporter, result);
OtlpHttpSpanExporter originalExporter = mock(OtlpHttpSpanExporter.class);
OtlpHttpSpanExporterBuilder builder = mock(OtlpHttpSpanExporterBuilder.class);

when(originalExporter.toBuilder()).thenReturn(builder);
when(builder.setProxy(any(ProxyOptions.class))).thenReturn(builder);
when(builder.build()).thenReturn(mock(OtlpHttpSpanExporter.class));

tested.apply(originalExporter, configProperties);
verify(builder).setProxy(any(ProxyOptions.class));
}
}
8 changes: 4 additions & 4 deletions dependencyManagement/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ plugins {
`java-platform`
}

val otelAgentVersion = "2.23.0"
val otelSdkVersion = "1.57.0"
val otelAgentVersion = "2.24.0"
val otelSdkVersion = "1.58.0"

val mockitoVersion = "4.11.0"
val byteBuddyVersion = "1.15.10"
val byteBuddyVersion = "1.18.4"
val joboeVersion = "10.0.27"

val opentelemetryJavaagentAlpha = "$otelAgentVersion-alpha"
Expand All @@ -15,7 +15,7 @@ val opentelemetrySemconv = "1.37.0"
val opentelemetrySemconvAlpha = "$opentelemetrySemconv-alpha"

val autoservice = "1.1.1"
val otelJavaContribVersion = "1.52.0-alpha"
val otelJavaContribVersion = "1.53.0-alpha"
val junit5 = "5.9.2"

rootProject.extra["otelAgentVersion"] = otelAgentVersion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesBuilder;
import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;

@AutoService(IgnoredTypesConfigurer.class)
public class SolarwindsIgnoredTypesConfigurer implements IgnoredTypesConfigurer {
@Override
public void configure(IgnoredTypesBuilder builder, ConfigProperties config) {
public void configure(IgnoredTypesBuilder builder) {
builder.ignoreClass("com.solarwinds.ext.");
builder.ignoreClass("com.solarwinds.joboe.");
}
Expand Down
Loading
Loading