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:
Cijo Thomas 2020-07-20 10:01:38 -07:00 committed by GitHub
parent 157495803c
commit af172a8943
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 750 additions and 1 deletions

View File

@ -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
{

View File

@ -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;
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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));
}
}
}