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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
.gradle/
.DS_Store
.idea/
buildSrc/.kotlin/
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.2.0"
val swoAgentVersion = "3.2.1"
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 @@ -29,4 +29,9 @@ public class HostIdResourceProvider implements ResourceProvider {
public Resource createResource(ConfigProperties configProperties) {
return Resource.create(HostIdResourceUtil.createAttribute());
}

@Override
public int order() {
return Integer.MIN_VALUE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public class SolarwindsPropertiesSupplier implements Supplier<Map<String, String
"base2_exponential_bucket_histogram");
PROPERTIES.put(
"otel.instrumentation.runtime-telemetry.emit-experimental-jfr-metrics", "true");
PROPERTIES.put("otel.resource.providers.azure.enabled", "true");
PROPERTIES.put("otel.resource.providers.aws.enabled", "true");
} else {
PROPERTIES.put("otel.sdk.disabled", "true");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,80 +21,28 @@
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.semconv.ContainerAttributes;
import io.opentelemetry.semconv.K8sAttributes;
import io.opentelemetry.semconv.ServiceAttributes;
import io.opentelemetry.semconv.incubating.CloudIncubatingAttributes;
import io.opentelemetry.semconv.incubating.HostIncubatingAttributes;
import io.opentelemetry.semconv.incubating.ProcessIncubatingAttributes;

public final class HostIdResourceUtil {
private HostIdResourceUtil() {}

public static Attributes createAttribute() {
AttributesBuilder builder = Attributes.builder();

HostId hostId = ServerHostInfoReader.INSTANCE.getHostId();
builder.put(ContainerAttributes.CONTAINER_ID, hostId.getDockerContainerId());
builder.put(ProcessIncubatingAttributes.PROCESS_PID, (long) hostId.getPid());
builder.put(AttributeKey.stringArrayKey("mac.addresses"), hostId.getMacAddresses());

builder.put(
AttributeKey.stringKey("azure.app.service.instance.id"),
hostId.getAzureAppServiceInstanceId());
builder.put(HostIncubatingAttributes.HOST_ID, hostId.getHerokuDynoId());
builder.put(AttributeKey.stringKey("sw.uams.client.id"), hostId.getUamsClientId());
builder.put(AttributeKey.stringKey("uuid"), hostId.getUuid());
builder.put(ServiceAttributes.SERVICE_INSTANCE_ID, hostId.getUuid());

HostId.K8sMetadata k8sMetadata = hostId.getK8sMetadata();

if (k8sMetadata != null) {
builder.put(K8sAttributes.K8S_POD_UID, k8sMetadata.getPodUid());
builder.put(K8sAttributes.K8S_NAMESPACE_NAME, k8sMetadata.getNamespace());
builder.put(K8sAttributes.K8S_POD_NAME, k8sMetadata.getPodName());
}

HostId.AwsMetadata awsMetadata = hostId.getAwsMetadata();
if (awsMetadata != null) {
builder.put(HostIncubatingAttributes.HOST_ID, awsMetadata.getHostId());
builder.put(HostIncubatingAttributes.HOST_NAME, awsMetadata.getHostName());
builder.put(CloudIncubatingAttributes.CLOUD_PROVIDER, awsMetadata.getCloudProvider());

builder.put(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, awsMetadata.getCloudAccountId());
builder.put(CloudIncubatingAttributes.CLOUD_PLATFORM, awsMetadata.getCloudPlatform());
builder.put(
CloudIncubatingAttributes.CLOUD_AVAILABILITY_ZONE,
awsMetadata.getCloudAvailabilityZone());

builder.put(CloudIncubatingAttributes.CLOUD_REGION, awsMetadata.getCloudRegion());
builder.put(HostIncubatingAttributes.HOST_IMAGE_ID, awsMetadata.getHostImageId());
builder.put(HostIncubatingAttributes.HOST_TYPE, awsMetadata.getHostType());
}

HostId.AzureVmMetadata azureVmMetadata = hostId.getAzureVmMetadata();
if (azureVmMetadata != null) {
builder.put(HostIncubatingAttributes.HOST_ID, azureVmMetadata.getHostId());
builder.put(HostIncubatingAttributes.HOST_NAME, azureVmMetadata.getHostName());
builder.put(CloudIncubatingAttributes.CLOUD_PROVIDER, azureVmMetadata.getCloudProvider());

builder.put(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, azureVmMetadata.getCloudAccountId());
builder.put(CloudIncubatingAttributes.CLOUD_PLATFORM, azureVmMetadata.getCloudPlatform());
builder.put(CloudIncubatingAttributes.CLOUD_REGION, azureVmMetadata.getCloudRegion());

builder.put(AttributeKey.stringKey("azure.vm.name"), azureVmMetadata.getAzureVmName());
builder.put(AttributeKey.stringKey("azure.vm.size"), azureVmMetadata.getAzureVmSize());
builder.put(
AttributeKey.stringKey("azure.resourcegroup.name"),
azureVmMetadata.getAzureResourceGroupName());

builder.put(
AttributeKey.stringKey("azure.vm.scaleset.name"),
azureVmMetadata.getAzureVmScaleSetName());
}

builder.put(HostIncubatingAttributes.HOST_NAME, hostId.getHostname());
builder.put(CloudIncubatingAttributes.CLOUD_AVAILABILITY_ZONE, hostId.getEc2AvailabilityZone());
builder.put(HostIncubatingAttributes.HOST_ID, hostId.getEc2InstanceId());
return builder.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ public Settings getSettings() {

String tokenHeader = String.format("Bearer %s", apiToken);
Settings fetchedSettings = delegate.fetchSettings(settingsUrl, tokenHeader);
logger.debug(String.format("Got settings from http: %s", fetchedSettings));
logger.debug(
String.format(
"Got settings from http: %s, serviceName: %s, hostname: %s",
fetchedSettings, serviceName, hostname));

return fetchedSettings;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ private void addResourceDetector(ResourceModel resourceModel) {
detectors = new ArrayList<>();
}

List<ExperimentalResourceDetectorModel> newDetectors = new ArrayList<>(detectors);
// Ordering matters: SWO detectors are added first, then upstream detectors (e.g. aws/azure)
// are appended so they run last. With last-writer-wins merge semantics this lets upstream
// cloud attributes override our host-id attributes. Do not reorder without accounting for
// which detector's attributes should survive the merge.
List<ExperimentalResourceDetectorModel> newDetectors = new ArrayList<>();
Comment thread
cleverchuk marked this conversation as resolved.
newDetectors.add(
new ExperimentalResourceDetectorModel()
.withAdditionalProperty(
Expand All @@ -79,6 +83,8 @@ private void addResourceDetector(ResourceModel resourceModel) {
.withAdditionalProperty(
HostIdResourceComponentProvider.COMPONENT_NAME,
new ExperimentalResourceDetectorPropertyModel()));

newDetectors.addAll(detectors);
detectionDevelopment.withDetectors(newDetectors);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ public class ResourceComponentProvider implements ComponentProvider {

public static final String COMPONENT_NAME = "swo/resource";

@Getter @Setter private static Resource resource = null;
// Accumulated statically: create() merges into this field in place, and
// HostIdResourceComponentProvider reads it via getResource().merge(...). Assumes create() is
// invoked once; merging identical attributes is idempotent, but any new writer of this field
// must be aware the result is order-dependent.
@Getter @Setter private static Resource resource = Resource.getDefault();
Comment thread
cleverchuk marked this conversation as resolved.

@Override
public Class<Resource> getType() {
Expand All @@ -50,7 +54,7 @@ public Resource create(DeclarativeConfigProperties declarativeConfigProperties)
Attributes resourceAttributes =
Attributes.of(moduleKey, "apm", versionKey, BuildConfig.SOLARWINDS_AGENT_VERSION);

resource = Resource.create(resourceAttributes);
resource = resource.merge(Resource.create(resourceAttributes));
return resource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,16 @@

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

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.semconv.incubating.HostIncubatingAttributes;
import io.opentelemetry.semconv.incubating.ProcessIncubatingAttributes;
import java.util.List;
import org.junit.jupiter.api.Test;

class HostIdResourceUtilTest {
@Test
void testCreateAttributes() {
Attributes attribute = HostIdResourceUtil.createAttribute();
Long pid = attribute.get(ProcessIncubatingAttributes.PROCESS_PID);
String hostname = attribute.get(HostIncubatingAttributes.HOST_NAME);

assertNotNull(pid);
assertNotNull(hostname);
List<String> macAddresses = attribute.get(AttributeKey.stringArrayKey("mac.addresses"));
assertNotNull(macAddresses);
}
}
2 changes: 2 additions & 0 deletions libs/shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ dependencies {
implementation("io.opentelemetry.contrib:opentelemetry-cel-sampler") {
exclude(module = "opentelemetry-sdk", group = "io.opentelemetry") // the agent includes this
exclude(group = "com.google.code.findbugs", module = "annotations")
exclude(group = "com.google.guava", module = "guava")
exclude(group = "com.google.protobuf")
}

implementation("org.json:json")
Expand Down
Loading