Skip to content

Commit

Permalink
exports service.name to StackDriver if the value is present in an ins…
Browse files Browse the repository at this point in the history
…tance of OpenTelemetry.Resources.Resource (#1652)

When many services collaborate, information about a service's name can help understand which service creates which trace. Google Trace Explorer allows the display of a service name next to trace information.
  • Loading branch information
StasPerekrestov committed Apr 16, 2024
1 parent 323e7e6 commit 6566323
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

* Update OpenTelemetry SDK version to `1.8.0`.
([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635))
* When many services collaborate, information about a service's name can help understand which service creates which trace.

Check failure on line 7 in src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md

View workflow job for this annotation

GitHub Actions / lint-md / run-markdownlint

Line length

src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md:7:81 MD013/line-length Line length [Expected: 80; Actual: 123] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
Google Trace Explorer allows the display of a service name next to trace information.
Please use `services.ConfigureResource(resource => resource.AddService("my-service", "1.0.0"))` to add service name and version.

Check failure on line 9 in src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md

View workflow job for this annotation

GitHub Actions / lint-md / run-markdownlint

Line length

src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md:9:81 MD013/line-length Line length [Expected: 80; Actual: 130] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md

## 1.0.0-beta.5

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Collections.Generic;
using Google.Cloud.Trace.V2;
using OpenTelemetry.Resources;

namespace OpenTelemetry.Exporter.Stackdriver.Implementation;

internal static class ResourceExtensions
{
private static readonly HashSet<string> ExportableResourceNames =
[
ResourceSemanticConventions.AttributeServiceName,
ResourceSemanticConventions.AttributeServiceVersion
];

/// <summary>
/// Adds resource attributes to the span.
/// </summary>
/// <param name="span">Google Cloud Trace Span to be annotated.</param>
/// <param name="resource">
/// The Resource contains attributes such as "service.name" that provide metadata about the service being traced.
/// These attributes are used to annotate the Google Cloud Trace Span, enhancing the trace data available in the Google
/// Trace Explorer UI.
/// </param>
public static void AnnotateWith(this Span span, Resource resource)
{
span.Attributes ??= new Span.Types.Attributes();
foreach (var attr in resource.Attributes)
{
if (ExportableResourceNames.Contains(attr.Key))
{
span.Attributes.AttributeMap.Add(attr.Key, attr.Value.ToAttributeValue());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

namespace OpenTelemetry.Exporter.Stackdriver.Implementation;

internal class ResourceSemanticConventions
{
public const string AttributeServiceName = "service.name";
public const string AttributeServiceVersion = "service.version";
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Google.Cloud.Trace.V2;
using Grpc.Core;
using OpenTelemetry.Exporter.Stackdriver.Implementation;
using OpenTelemetry.Resources;

namespace OpenTelemetry.Exporter.Stackdriver;

Expand Down Expand Up @@ -93,12 +94,19 @@ public override ExportResult Export(in Batch<Activity> batch)
ProjectName = this.googleCloudProjectId,
};

Resource? resource = this.ParentProvider?.GetResource();
foreach (var activity in batch)
{
// It should never happen that the time has no correct kind, only if OpenTelemetry is used incorrectly.
if (activity.StartTimeUtc.Kind == DateTimeKind.Utc)
{
batchSpansRequest.Spans.Add(activity.ToSpan(this.googleCloudProjectId.ProjectId));
Span span = activity.ToSpan(this.googleCloudProjectId.ProjectId);
if (resource != null)
{
span.AnnotateWith(resource);
}

batchSpansRequest.Spans.Add(span);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Collections.Generic;
using Google.Cloud.Trace.V2;
using OpenTelemetry.Exporter.Stackdriver.Implementation;
using OpenTelemetry.Resources;
using Xunit;

namespace OpenTelemetry.Exporter.Stackdriver.Tests;

public class ResourceExtensionsTests
{
[Fact]
public void Enriches_Span_Attributes_With_Service_Name()
{
const string serviceName = "some service name";
const string serviceVersion = "2.3.4";
var resource = new Resource(new Dictionary<string, object>
{
["key1"] = "value1",
["key2"] = "value2",
[ResourceSemanticConventions.AttributeServiceName] = serviceName,
[ResourceSemanticConventions.AttributeServiceVersion] = serviceVersion,
});

var span = new Span();
span.AnnotateWith(resource);
Assert.Contains(span.Attributes.AttributeMap, kvp =>
kvp.Key == ResourceSemanticConventions.AttributeServiceName &&
kvp.Value.StringValue.Value == serviceName);

Assert.Contains(span.Attributes.AttributeMap, kvp =>
kvp.Key == ResourceSemanticConventions.AttributeServiceVersion &&
kvp.Value.StringValue.Value == serviceVersion);
}

[Fact]
public void Otel_Resource_Has_No_Service_Name()
{
var resource = new Resource(new Dictionary<string, object> { ["key1"] = "value1", ["key2"] = "value2" });

var span = new Span();
span.AnnotateWith(resource);
}
}

0 comments on commit 6566323

Please sign in to comment.