Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Resources in ZipkinExporter #1385

Merged
merged 6 commits into from
Oct 23, 2020
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
2 changes: 1 addition & 1 deletion src/OpenTelemetry.Exporter.Jaeger/JaegerExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ internal void ApplyLibraryResource(Resource libraryResource)
process.Tags = new Dictionary<string, JaegerTag>();
}

process.Tags[label.Key] = label.ToJaegerTag();
process.Tags[key] = label.ToJaegerTag();
}

if (serviceName != null)
Expand Down
4 changes: 2 additions & 2 deletions src/OpenTelemetry.Exporter.Jaeger/Process.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public Process(string serviceName, IEnumerable<KeyValuePair<string, object>> pro
{
}

internal Process(string serviceName, IDictionary<string, JaegerTag> processTags)
internal Process(string serviceName, Dictionary<string, JaegerTag> processTags)
: this(serviceName)
{
if (processTags != null)
Expand All @@ -46,7 +46,7 @@ internal Process(string serviceName, IDictionary<string, JaegerTag> processTags)

public string ServiceName { get; internal set; }

internal IDictionary<string, JaegerTag> Tags { get; set; }
internal Dictionary<string, JaegerTag> Tags { get; set; }

internal byte[] Message { get; set; }

Expand Down
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

* ZipkinExporter will now respect global Resource set via
`TracerProviderBuilder.SetResource`.
([#1385](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1385))

## 0.7.0-beta.1

Released 2020-Oct-16
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using OpenTelemetry.Internal;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

namespace OpenTelemetry.Exporter.Zipkin.Implementation
Expand All @@ -41,15 +40,13 @@ internal static class ZipkinActivityConversionExtensions

private static readonly string InvalidSpanId = default(ActivitySpanId).ToHexString();

private static readonly ConcurrentDictionary<string, ZipkinEndpoint> LocalEndpointCache = new ConcurrentDictionary<string, ZipkinEndpoint>();

#if !NET452
private static readonly ConcurrentDictionary<(string, int), ZipkinEndpoint> RemoteEndpointCache = new ConcurrentDictionary<(string, int), ZipkinEndpoint>();
#else
private static readonly ConcurrentDictionary<string, ZipkinEndpoint> RemoteEndpointCache = new ConcurrentDictionary<string, ZipkinEndpoint>();
#endif

internal static ZipkinSpan ToZipkinSpan(this Activity activity, ZipkinEndpoint defaultLocalEndpoint, bool useShortTraceIds = false)
internal static ZipkinSpan ToZipkinSpan(this Activity activity, ZipkinEndpoint localEndpoint, bool useShortTraceIds = false)
{
var context = activity.Context;

Expand All @@ -76,25 +73,6 @@ internal static ZipkinSpan ToZipkinSpan(this Activity activity, ZipkinEndpoint d
}
}

var localEndpoint = defaultLocalEndpoint;

var serviceName = tagState.ServiceName;

// override default service name
if (!string.IsNullOrWhiteSpace(serviceName))
{
if (!string.IsNullOrWhiteSpace(tagState.ServiceNamespace))
{
serviceName = tagState.ServiceNamespace + "." + serviceName;
}

if (!LocalEndpointCache.TryGetValue(serviceName, out localEndpoint))
{
localEndpoint = defaultLocalEndpoint.Clone(serviceName);
LocalEndpointCache.TryAdd(serviceName, localEndpoint);
}
}

ZipkinEndpoint remoteEndpoint = null;
if (activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer)
{
Expand Down Expand Up @@ -201,10 +179,6 @@ internal struct TagEnumerationState : IActivityEnumerator<KeyValuePair<string, o

public int RemoteEndpointServiceNamePriority;

public string ServiceName;

public string ServiceNamespace;

public string HostName;

public string IpAddress;
Expand Down Expand Up @@ -239,14 +213,6 @@ public bool ForEach(KeyValuePair<string, object> activityTag)
{
this.Port = port;
}
else if (key == Resource.ServiceNameKey)
{
this.ServiceName = strVal;
}
else if (key == Resource.ServiceNamespaceKey)
{
this.ServiceNamespace = strVal;
}

PooledList<KeyValuePair<string, object>>.Add(ref this.Tags, new KeyValuePair<string, object>(key, strVal));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Collections.Generic;
#if NET452
using Newtonsoft.Json;
#else
Expand All @@ -24,20 +25,22 @@ namespace OpenTelemetry.Exporter.Zipkin.Implementation
internal class ZipkinEndpoint
{
public ZipkinEndpoint(string serviceName)
: this(serviceName, null, null, null)
: this(serviceName, null, null, null, null)
{
}

public ZipkinEndpoint(
string serviceName,
string ipv4,
string ipv6,
int? port)
int? port,
Dictionary<string, object> tags)
{
this.ServiceName = serviceName;
this.Ipv4 = ipv4;
this.Ipv6 = ipv6;
this.Port = port;
this.Tags = tags;
}

public string ServiceName { get; }
Expand All @@ -48,6 +51,8 @@ public ZipkinEndpoint(

public int? Port { get; }

public Dictionary<string, object> Tags { get; }

public static ZipkinEndpoint Create(string serviceName)
{
return new ZipkinEndpoint(serviceName);
Expand All @@ -70,7 +75,8 @@ public ZipkinEndpoint Clone(string serviceName)
serviceName,
this.Ipv4,
this.Ipv6,
this.Port);
this.Port,
this.Tags);
}

#if NET452
Expand Down
20 changes: 16 additions & 4 deletions src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinSpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
#if NET452
Expand Down Expand Up @@ -188,7 +189,7 @@ public void Write(JsonWriter writer)
writer.WriteEndArray();
}

if (this.Tags.HasValue)
if (this.Tags.HasValue || this.LocalEndpoint.Tags != null)
{
writer.WritePropertyName("tags");
writer.WriteStartObject();
Expand All @@ -199,7 +200,13 @@ public void Write(JsonWriter writer)

try
{
foreach (var tag in this.Tags.Value)
foreach (var tag in this.LocalEndpoint.Tags ?? Enumerable.Empty<KeyValuePair<string, object>>())
{
writer.WritePropertyName(tag.Key);
writer.WriteValue(this.ConvertObjectToString(tag.Value));
}

foreach (var tag in this.Tags ?? Enumerable.Empty<KeyValuePair<string, object>>())
{
writer.WritePropertyName(tag.Key);
writer.WriteValue(this.ConvertObjectToString(tag.Value));
Expand Down Expand Up @@ -290,7 +297,7 @@ public void Write(Utf8JsonWriter writer)
writer.WriteEndArray();
}

if (this.Tags.HasValue)
if (this.Tags.HasValue || this.LocalEndpoint.Tags != null)
{
writer.WritePropertyName("tags");
writer.WriteStartObject();
Expand All @@ -301,7 +308,12 @@ public void Write(Utf8JsonWriter writer)

try
{
foreach (var tag in this.Tags.Value)
foreach (var tag in this.LocalEndpoint.Tags ?? Enumerable.Empty<KeyValuePair<string, object>>())
{
writer.WriteString(tag.Key, this.ConvertObjectToString(tag.Value));
}

foreach (var tag in this.Tags ?? Enumerable.Empty<KeyValuePair<string, object>>())
{
writer.WriteString(tag.Key, this.ConvertObjectToString(tag.Value));
}
Expand Down
95 changes: 73 additions & 22 deletions src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// </copyright>

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
Expand All @@ -26,9 +27,12 @@
#else
using System.Text.Json;
#endif
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using OpenTelemetry.Exporter.Zipkin.Implementation;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

namespace OpenTelemetry.Exporter.Zipkin
{
Expand All @@ -54,11 +58,10 @@ internal ZipkinExporter(ZipkinExporterOptions options, HttpClient client = null)
#if !NET452
this.maxPayloadSizeInBytes = (!options.MaxPayloadSizeInBytes.HasValue || options.MaxPayloadSizeInBytes <= 0) ? ZipkinExporterOptions.DefaultMaxPayloadSizeInBytes : options.MaxPayloadSizeInBytes.Value;
#endif
this.LocalEndpoint = this.GetLocalZipkinEndpoint();
this.httpClient = client ?? new HttpClient();
}

internal ZipkinEndpoint LocalEndpoint { get; }
internal ZipkinEndpoint LocalEndpoint { get; private set; }

/// <inheritdoc/>
public override ExportResult Export(in Batch<Activity> batch)
Expand Down Expand Up @@ -89,6 +92,71 @@ public override ExportResult Export(in Batch<Activity> batch)
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal ZipkinEndpoint EnsureLocalEndpoint(Activity activity)
{
if (this.LocalEndpoint != null)
{
return this.LocalEndpoint;
}

var hostName = ResolveHostName();

string ipv4 = null;
string ipv6 = null;
if (!string.IsNullOrEmpty(hostName))
{
ipv4 = ResolveHostAddress(hostName, AddressFamily.InterNetwork);
ipv6 = ResolveHostAddress(hostName, AddressFamily.InterNetworkV6);
}

string serviceName = null;
string serviceNamespace = null;
Dictionary<string, object> tags = null;
foreach (var label in activity.GetResource().Attributes)
{
string key = label.Key;

switch (key)
{
case Resource.ServiceNameKey:
serviceName = label.Value as string;
continue;
case Resource.ServiceNamespaceKey:
serviceNamespace = label.Value as string;
continue;
case Resource.LibraryNameKey:
case Resource.LibraryVersionKey:
continue;
}

if (tags == null)
{
tags = new Dictionary<string, object>();
}

tags[key] = label.Value;
}

if (!string.IsNullOrEmpty(serviceName))
{
serviceName = serviceNamespace != null
? serviceNamespace + "." + serviceName
: serviceName;
}
else
{
serviceName = this.options.ServiceName;
}

return this.LocalEndpoint = new ZipkinEndpoint(
serviceName,
ipv4,
ipv6,
port: null,
tags);
}

private static string ResolveHostAddress(string hostName, AddressFamily family)
{
string result = null;
Expand Down Expand Up @@ -145,25 +213,6 @@ private static string ResolveHostName()
return result;
}

private ZipkinEndpoint GetLocalZipkinEndpoint()
{
var hostName = ResolveHostName();

string ipv4 = null;
string ipv6 = null;
if (!string.IsNullOrEmpty(hostName))
{
ipv4 = ResolveHostAddress(hostName, AddressFamily.InterNetwork);
ipv6 = ResolveHostAddress(hostName, AddressFamily.InterNetworkV6);
}

return new ZipkinEndpoint(
this.options.ServiceName,
ipv4,
ipv6,
null);
}

private class JsonContent : HttpContent
{
private static readonly MediaTypeHeaderValue JsonHeader = new MediaTypeHeaderValue("application/json")
Expand Down Expand Up @@ -208,7 +257,9 @@ protected override Task SerializeToStreamAsync(Stream stream, TransportContext c

foreach (var activity in this.batch)
{
var zipkinSpan = activity.ToZipkinSpan(this.exporter.LocalEndpoint, this.exporter.options.UseShortTraceIds);
var localEndpoint = this.exporter.EnsureLocalEndpoint(activity);

var zipkinSpan = activity.ToZipkinSpan(localEndpoint, this.exporter.options.UseShortTraceIds);

zipkinSpan.Write(this.writer);

Expand Down
Loading