Basic OTel shim around Activity and associated classes. (#836)
* Basic OTel shim around Activity and associated classes. * review comments * remove Event public class. Make fluent syntax easier * cooment * cleanup sample
This commit is contained in:
parent
157495803c
commit
af172a8943
|
|
@ -39,7 +39,7 @@ namespace Samples
|
|||
/// <param name="args">Arguments from command line.</param>
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, HttpClientOptions, RedisOptions, ZPagesOptions, ConsoleOptions, OtlpOptions>(args)
|
||||
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, HttpClientOptions, RedisOptions, ZPagesOptions, ConsoleOptions, OpenTelemetryShimOptions, OtlpOptions>(args)
|
||||
.MapResult(
|
||||
(JaegerOptions options) => TestJaegerExporter.Run(options.Host, options.Port),
|
||||
(ZipkinOptions options) => TestZipkinExporter.Run(options.Uri),
|
||||
|
|
@ -48,6 +48,7 @@ namespace Samples
|
|||
(RedisOptions options) => TestRedis.Run(options.Uri),
|
||||
(ZPagesOptions options) => TestZPagesExporter.Run(),
|
||||
(ConsoleOptions options) => TestConsoleExporter.Run(options),
|
||||
(OpenTelemetryShimOptions options) => TestOTelShimWithConsoleExporter.Run(options),
|
||||
(OtlpOptions options) => TestOtlpExporter.Run(options.Endpoint),
|
||||
errs => 1);
|
||||
|
||||
|
|
@ -111,6 +112,13 @@ namespace Samples
|
|||
public bool DisplayAsJson { get; set; }
|
||||
}
|
||||
|
||||
[Verb("otelshim", HelpText = "Specify the options required to test OpenTelemetry Shim with console exporter")]
|
||||
internal class OpenTelemetryShimOptions
|
||||
{
|
||||
[Option('p', "displayasjson", HelpText = "Specify if the output should be displayed as json or not (default: false)", Default = false)]
|
||||
public bool DisplayAsJson { get; set; }
|
||||
}
|
||||
|
||||
[Verb("otlp", HelpText = "Specify the options required to test OpenTelemetry Protocol (OTLP)")]
|
||||
internal class OtlpOptions
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
// <copyright file="TestOTelShimWithConsoleExporter.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// 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.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
using OpenTelemetry.Trace.Configuration;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
internal class TestOTelShimWithConsoleExporter
|
||||
{
|
||||
internal static object Run(OpenTelemetryShimOptions options)
|
||||
{
|
||||
// Enable OpenTelemetry for the source "MyCompany.MyProduct.MyWebServer"
|
||||
// and use Console exporter.
|
||||
using var openTelemetry = OpenTelemetrySdk.EnableOpenTelemetry(
|
||||
(builder) => builder.AddActivitySource("MyCompany.MyProduct.MyWebServer")
|
||||
.SetResource(Resources.CreateServiceResource("MyServiceName"))
|
||||
.UseConsoleExporter(opt => opt.DisplayAsJson = options.DisplayAsJson));
|
||||
|
||||
// The above line is required only in applications
|
||||
// which decide to use OpenTelemetry.
|
||||
|
||||
// Following shows how to use the OpenTelemetryShim, which is a thin layer on top
|
||||
// of Activity and associated classes.
|
||||
var tracer = TracerProvider.GetTracer("MyCompany.MyProduct.MyWebServer");
|
||||
var span = tracer.StartSpan("parent span");
|
||||
span.SetAttribute("my", "value");
|
||||
span.UpdateName("parent span new name");
|
||||
|
||||
var spanChild = tracer.StartSpan("child span");
|
||||
spanChild.AddEvent("sample event").SetAttribute("ch", "value").SetAttribute("more", "attributes");
|
||||
spanChild.End();
|
||||
|
||||
span.End();
|
||||
|
||||
Console.WriteLine("Press Enter key to exit.");
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
// <copyright file="LinkNew.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// 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.
|
||||
// </copyright>
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OpenTelemetry.Trace
|
||||
{
|
||||
/// <summary>
|
||||
/// Link associated with the span.
|
||||
/// </summary>
|
||||
public readonly struct LinkNew
|
||||
{
|
||||
internal readonly ActivityLink ActivityLink;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinkNew"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="spanContext">Span context of a linked span.</param>
|
||||
public LinkNew(in SpanContextNew spanContext)
|
||||
{
|
||||
this.ActivityLink = new ActivityLink(spanContext.ActivityContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinkNew"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="spanContext">Span context of a linked span.</param>
|
||||
/// <param name="attributes">Link attributes.</param>
|
||||
public LinkNew(in SpanContextNew spanContext, IDictionary<string, object> attributes)
|
||||
{
|
||||
this.ActivityLink = new ActivityLink(spanContext.ActivityContext, attributes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the span context of a linked span.
|
||||
/// </summary>
|
||||
public SpanContextNew Context
|
||||
{
|
||||
get
|
||||
{
|
||||
return new SpanContextNew(this.ActivityLink.Context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of attributes associated with the link.
|
||||
/// </summary>
|
||||
public IEnumerable<KeyValuePair<string, object>> Attributes
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ActivityLink.Attributes;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two <see cref="LinkNew"/> for equality.
|
||||
/// </summary>
|
||||
/// <param name="link1">First link to compare.</param>
|
||||
/// <param name="link2">Second link to compare.</param>
|
||||
public static bool operator ==(LinkNew link1, LinkNew link2) => link1.Equals(link2);
|
||||
|
||||
/// <summary>
|
||||
/// Compare two <see cref="LinkNew"/> for not equality.
|
||||
/// </summary>
|
||||
/// <param name="link1">First link to compare.</param>
|
||||
/// <param name="link2">Second link to compare.</param>
|
||||
public static bool operator !=(LinkNew link1, LinkNew link2) => !link1.Equals(link2);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return this.ActivityLink.Equals(obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.ActivityLink.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
// <copyright file="SpanContextNew.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// 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.
|
||||
// </copyright>
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using OpenTelemetry.Api.Context.Propagation;
|
||||
|
||||
namespace OpenTelemetry.Trace
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that represents a span context. A span context contains the state that must propagate to
|
||||
/// child <see cref="TelemetrySpan"/> and across process boundaries. It contains the identifiers <see cref="ActivityTraceId"/>
|
||||
/// and <see cref="ActivitySpanId"/> associated with the <see cref="TelemetrySpan"/> and a set of <see cref="TraceFlags"/>.
|
||||
/// </summary>
|
||||
public readonly struct SpanContextNew
|
||||
{
|
||||
internal readonly ActivityContext ActivityContext;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SpanContextNew"/> struct with the given identifiers and options.
|
||||
/// </summary>
|
||||
/// <param name="traceId">The <see cref="ActivityTraceId"/> to associate with the <see cref="SpanContextNew"/>.</param>
|
||||
/// <param name="spanId">The <see cref="ActivitySpanId"/> to associate with the <see cref="SpanContextNew"/>.</param>
|
||||
/// <param name="traceFlags">The <see cref="TraceFlags"/> to
|
||||
/// associate with the <see cref="SpanContextNew"/>.</param>
|
||||
/// <param name="isRemote">The value indicating whether this <see cref="SpanContextNew"/> was propagated from the remote parent.</param>
|
||||
/// <param name="traceState">The traceState to associate with the <see cref="SpanContextNew"/>.</param>
|
||||
public SpanContextNew(in ActivityTraceId traceId, in ActivitySpanId spanId, ActivityTraceFlags traceFlags, bool isRemote = false, IEnumerable<KeyValuePair<string, string>> traceState = null)
|
||||
{
|
||||
this.ActivityContext = new ActivityContext(traceId, spanId, traceFlags, TracestateUtils.GetString(traceState));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SpanContextNew"/> struct with the given identifiers and options.
|
||||
/// </summary>
|
||||
/// <param name="activityContext">The activity context.</param>
|
||||
internal SpanContextNew(in ActivityContext activityContext)
|
||||
{
|
||||
this.ActivityContext = activityContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ActivityTraceId"/> associated with this <see cref="SpanContextNew"/>.
|
||||
/// </summary>
|
||||
public ActivityTraceId TraceId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ActivityContext.TraceId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ActivitySpanId"/> associated with this <see cref="SpanContextNew"/>.
|
||||
/// </summary>
|
||||
public ActivitySpanId SpanId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ActivityContext.SpanId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ActivityTraceFlags"/> associated with this <see cref="SpanContextNew"/>.
|
||||
/// </summary>
|
||||
public ActivityTraceFlags TraceFlags
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ActivityContext.TraceFlags;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="SpanContextNew" />
|
||||
/// was propagated from a remote parent.
|
||||
/// </summary>
|
||||
public bool IsRemote
|
||||
{
|
||||
get
|
||||
{
|
||||
// TODO: return this.activityContext.IsRemote;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="SpanContextNew"/> is valid.
|
||||
/// </summary>
|
||||
public bool IsValid => this.IsTraceIdValid(this.TraceId) && this.IsSpanIdValid(this.SpanId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="TraceState"/> associated with this <see cref="SpanContextNew"/>.
|
||||
/// </summary>
|
||||
public IEnumerable<KeyValuePair<string, string>> TraceState
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.ActivityContext.TraceState))
|
||||
{
|
||||
return Enumerable.Empty<KeyValuePair<string, string>>();
|
||||
}
|
||||
|
||||
var traceStateResult = new List<KeyValuePair<string, string>>();
|
||||
TracestateUtils.AppendTracestate(this.ActivityContext.TraceState, traceStateResult);
|
||||
return traceStateResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two <see cref="SpanContextNew"/> for equality.
|
||||
/// </summary>
|
||||
/// <param name="spanContextNew1">First SpanContextNew to compare.</param>
|
||||
/// <param name="spanContextNew2">Second SpanContextNew to compare.</param>
|
||||
public static bool operator ==(SpanContextNew spanContextNew1, SpanContextNew spanContextNew2) => spanContextNew1.Equals(spanContextNew2);
|
||||
|
||||
/// <summary>
|
||||
/// Compare two <see cref="SpanContextNew"/> for not equality.
|
||||
/// </summary>
|
||||
/// <param name="spanContextNew1">First SpanContextNew to compare.</param>
|
||||
/// <param name="spanContextNew2">Second SpanContextNew to compare.</param>
|
||||
public static bool operator !=(SpanContextNew spanContextNew1, SpanContextNew spanContextNew2) => !spanContextNew1.Equals(spanContextNew2);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.ActivityContext.GetHashCode();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return this.ActivityContext.Equals(obj);
|
||||
}
|
||||
|
||||
private bool IsTraceIdValid(ActivityTraceId traceId)
|
||||
{
|
||||
return traceId != default;
|
||||
}
|
||||
|
||||
private bool IsSpanIdValid(ActivitySpanId spanId)
|
||||
{
|
||||
return spanId != default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
// <copyright file="TelemetrySpanNew.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// 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.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace OpenTelemetry.Trace
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Span represents the execution of the certain span of code or span of time between two events which is part of
|
||||
/// a distributed trace and has result of execution, context of execution and other properties.</para>
|
||||
/// </summary>
|
||||
/// <remarks>Represents OpenTelemetry Span https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md#span.</remarks>
|
||||
public class TelemetrySpanNew : IDisposable
|
||||
{
|
||||
internal static readonly TelemetrySpanNew NoopInstance = new TelemetrySpanNew(null);
|
||||
private readonly Activity activity;
|
||||
|
||||
internal TelemetrySpanNew(Activity activity)
|
||||
{
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the span context.
|
||||
/// </summary>
|
||||
public SpanContextNew Context
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.activity == null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new SpanContextNew(this.activity.Context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this span will be recorded.
|
||||
/// </summary>
|
||||
public bool IsRecording
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.activity == null) ? false : this.activity.IsAllDataRequested;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the status of the span execution.
|
||||
/// </summary>
|
||||
public Status Status
|
||||
{
|
||||
set
|
||||
{
|
||||
this.activity?.SetStatus(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the <see cref="TelemetrySpanNew"/> name.
|
||||
///
|
||||
/// If used, this will override the name provided via StartSpan method overload.
|
||||
/// Upon this update, any sampling behavior based on <see cref="TelemetrySpanNew"/> name will depend on the
|
||||
/// implementation.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the span.</param>
|
||||
/// <returns>The <see cref="TelemetrySpanNew"/> instance for chaining.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew UpdateName(string name)
|
||||
{
|
||||
if (this.activity != null)
|
||||
{
|
||||
this.activity.DisplayName = name;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a new attribute on the span.
|
||||
/// </summary>
|
||||
/// <param name="key">Attribute key.</param>
|
||||
/// <param name="value">Attribute value. The value may be an <see cref="IEnumerable"/> of primitive types. An enumeration may be iterated multiple times.</param>
|
||||
/// <returns>The <see cref="TelemetrySpanNew"/> instance for chaining.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew SetAttribute(string key, string value)
|
||||
{
|
||||
this.activity?.AddTag(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a single Event to the <see cref="TelemetrySpanNew"/>.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the event.</param>
|
||||
/// <returns>The <see cref="TelemetrySpanNew"/> instance for chaining.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew AddEvent(string name)
|
||||
{
|
||||
this.activity?.AddEvent(new ActivityEvent(name));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a single Event to the <see cref="TelemetrySpanNew"/>.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the event.</param>
|
||||
/// <param name="timestamp">Timestamp of the event.</param>
|
||||
/// <returns>The <see cref="TelemetrySpanNew"/> instance for chaining.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew AddEvent(string name, DateTimeOffset timestamp)
|
||||
{
|
||||
this.activity?.AddEvent(new ActivityEvent(name, timestamp));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a single Event to the <see cref="TelemetrySpanNew"/>.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the event.</param>
|
||||
/// <param name="attributes">Attributes for the event.</param>
|
||||
/// <returns>The <see cref="TelemetrySpanNew"/> instance for chaining.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew AddEvent(string name, IDictionary<string, object> attributes)
|
||||
{
|
||||
this.activity?.AddEvent(new ActivityEvent(name, attributes));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a single Event to the <see cref="TelemetrySpanNew"/>.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the event.</param>
|
||||
/// <param name="timestamp">Timestamp of the event.</param>
|
||||
/// <param name="attributes">Attributes for the event.</param>
|
||||
/// <returns>The <see cref="TelemetrySpanNew"/> instance for chaining.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew AddEvent(string name, DateTimeOffset timestamp, IDictionary<string, object> attributes)
|
||||
{
|
||||
this.activity?.AddEvent(new ActivityEvent(name, timestamp, attributes));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// End the span.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void End()
|
||||
{
|
||||
this.activity?.Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// End the span.
|
||||
/// </summary>
|
||||
/// <param name="endTimestamp">End timestamp.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void End(DateTimeOffset endTimestamp)
|
||||
{
|
||||
this.activity?.SetEndTime(endTimestamp.UtcDateTime);
|
||||
this.activity?.Stop();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Dispose()
|
||||
{
|
||||
this.activity?.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks the span as current.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void Activate()
|
||||
{
|
||||
Activity.Current = this.activity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
// <copyright file="TracerNew.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// 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.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace OpenTelemetry.Trace
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracer to record distributed tracing information.
|
||||
/// </summary>
|
||||
public class TracerNew
|
||||
{
|
||||
private readonly ActivitySource activitySource;
|
||||
|
||||
internal TracerNew(ActivitySource activitySource)
|
||||
{
|
||||
this.activitySource = activitySource;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current span from the context.
|
||||
/// </summary>
|
||||
public TelemetrySpanNew CurrentSpan
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TelemetrySpanNew(Activity.Current);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts span.
|
||||
/// </summary>
|
||||
/// <param name="name">Span name.</param>
|
||||
/// <param name="kind">Kind.</param>
|
||||
/// <returns>Span instance.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew StartSpan(string name, SpanKind kind = SpanKind.Internal)
|
||||
{
|
||||
// TODO: Open Question - should we have both StartSpan and StartActiveSpan?
|
||||
// Or should we call this method StartActiveSpan
|
||||
// This method StartSpan is starting a Span and making it Active.
|
||||
// OTel spec calls for StartSpan, and StartActiveSpan being separate.
|
||||
// Need to see if it makes sense for .NET to strictly adhere to it.
|
||||
// Some discussions in Spec: https://github.com/open-telemetry/opentelemetry-specification/pull/485
|
||||
if (!this.activitySource.HasListeners())
|
||||
{
|
||||
return TelemetrySpanNew.NoopInstance;
|
||||
}
|
||||
|
||||
var activityKind = this.ConvertToActivityKind(kind);
|
||||
var activity = this.activitySource.StartActivity(name, activityKind);
|
||||
if (activity == null)
|
||||
{
|
||||
return TelemetrySpanNew.NoopInstance;
|
||||
}
|
||||
|
||||
return new TelemetrySpanNew(activity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts span.
|
||||
/// </summary>
|
||||
/// <param name="name">Span name.</param>
|
||||
/// <param name="kind">Kind.</param>
|
||||
/// <param name="parent">Parent for new span.</param>
|
||||
/// <returns>Span instance.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew StartSpan(string name, SpanKind kind, in SpanContextNew parent)
|
||||
{
|
||||
if (!this.activitySource.HasListeners())
|
||||
{
|
||||
return TelemetrySpanNew.NoopInstance;
|
||||
}
|
||||
|
||||
var activityKind = this.ConvertToActivityKind(kind);
|
||||
var activity = this.activitySource.StartActivity(name, activityKind, parent.ActivityContext);
|
||||
if (activity == null)
|
||||
{
|
||||
return TelemetrySpanNew.NoopInstance;
|
||||
}
|
||||
|
||||
return new TelemetrySpanNew(activity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts span.
|
||||
/// </summary>
|
||||
/// <param name="name">Span name.</param>
|
||||
/// <param name="kind">Kind.</param>
|
||||
/// <param name="parentSpan">Parent for new span.</param>
|
||||
/// <param name="attributes">Initial attributes for the span.</param>
|
||||
/// <param name="links"> <see cref="Link"/> for the span.</param>
|
||||
/// <param name="startTime"> Start time for the span.</param>
|
||||
/// <returns>Span instance.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew StartSpan(string name, SpanKind kind, in TelemetrySpanNew parentSpan, IEnumerable<KeyValuePair<string, string>> attributes = null, IEnumerable<LinkNew> links = null, DateTimeOffset startTime = default)
|
||||
{
|
||||
return this.StartSpan(name, kind, parentSpan.Context, attributes, links, startTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts span.
|
||||
/// </summary>
|
||||
/// <param name="name">Span name.</param>
|
||||
/// <param name="kind">Kind.</param>
|
||||
/// <param name="parentContext">Parent Context for new span.</param>
|
||||
/// <param name="attributes">Initial attributes for the span.</param>
|
||||
/// <param name="links"> <see cref="Link"/> for the span.</param>
|
||||
/// <param name="startTime"> Start time for the span.</param>
|
||||
/// <returns>Span instance.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew StartSpan(string name, SpanKind kind, in SpanContextNew parentContext, IEnumerable<KeyValuePair<string, string>> attributes = null, IEnumerable<LinkNew> links = null, DateTimeOffset startTime = default)
|
||||
{
|
||||
if (!this.activitySource.HasListeners())
|
||||
{
|
||||
return TelemetrySpanNew.NoopInstance;
|
||||
}
|
||||
|
||||
var activityKind = this.ConvertToActivityKind(kind);
|
||||
|
||||
IList<ActivityLink> activityLinks = null;
|
||||
if (links != null && links.Count() > 0)
|
||||
{
|
||||
activityLinks = new List<ActivityLink>();
|
||||
foreach (var link in links)
|
||||
{
|
||||
activityLinks.Add(link.ActivityLink);
|
||||
}
|
||||
}
|
||||
|
||||
var activity = this.activitySource.StartActivity(name, activityKind, parentContext.ActivityContext, attributes, activityLinks, startTime);
|
||||
if (activity == null)
|
||||
{
|
||||
return TelemetrySpanNew.NoopInstance;
|
||||
}
|
||||
|
||||
return new TelemetrySpanNew(activity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the given span as the current one.
|
||||
/// </summary>
|
||||
/// <param name="span">The span to be made current.</param>
|
||||
/// <returns>The current span.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TelemetrySpanNew WithSpan(TelemetrySpanNew span)
|
||||
{
|
||||
span.Activate();
|
||||
return span;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private ActivityKind ConvertToActivityKind(SpanKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case SpanKind.Client:
|
||||
return ActivityKind.Client;
|
||||
case SpanKind.Consumer:
|
||||
return ActivityKind.Consumer;
|
||||
case SpanKind.Internal:
|
||||
return ActivityKind.Internal;
|
||||
case SpanKind.Producer:
|
||||
return ActivityKind.Producer;
|
||||
case SpanKind.Server:
|
||||
return ActivityKind.Server;
|
||||
default:
|
||||
return ActivityKind.Internal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// <copyright file="TracerProvider.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// 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.
|
||||
// </copyright>
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OpenTelemetry.Trace
|
||||
{
|
||||
/// <summary>
|
||||
/// TracerProvider is the entry point of the OTel API. It provides access to Tracers.
|
||||
/// </summary>
|
||||
public class TracerProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a tracer with given name and version.
|
||||
/// </summary>
|
||||
/// <param name="name">Name identifying the instrumentation library.</param>
|
||||
/// <param name="version">Version of the instrumentation library.</param>
|
||||
/// <returns>Tracer instance.</returns>
|
||||
public static TracerNew GetTracer(string name, string version = null)
|
||||
{
|
||||
return new TracerNew(new ActivitySource(name, version));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue