opentelemetry-dotnet/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs

197 lines
7.7 KiB
C#

// <copyright file="TracerProviderBuilderSdk.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 OpenTelemetry.Resources;
namespace OpenTelemetry.Trace
{
/// <summary>
/// Build TracerProvider with Resource, Sampler, Processors and Instrumentation.
/// </summary>
internal class TracerProviderBuilderSdk : TracerProviderBuilder
{
private readonly List<DiagnosticSourceInstrumentationFactory> diagnosticSourceInstrumentationFactories = new List<DiagnosticSourceInstrumentationFactory>();
private readonly List<InstrumentationFactory> instrumentationFactories = new List<InstrumentationFactory>();
private readonly List<BaseProcessor<Activity>> processors = new List<BaseProcessor<Activity>>();
private readonly List<string> sources = new List<string>();
private ResourceBuilder resourceBuilder = ResourceBuilder.CreateDefault();
private Sampler sampler = new ParentBasedSampler(new AlwaysOnSampler());
internal TracerProviderBuilderSdk()
{
}
/// <summary>
/// Adds an instrumentation to the provider.
/// </summary>
/// <typeparam name="TInstrumentation">Type of instrumentation class.</typeparam>
/// <param name="instrumentationFactory">Function that builds instrumentation.</param>
/// <returns>Returns <see cref="TracerProviderBuilder"/> for chaining.</returns>
public override TracerProviderBuilder AddInstrumentation<TInstrumentation>(
Func<TInstrumentation> instrumentationFactory)
where TInstrumentation : class
{
if (instrumentationFactory == null)
{
throw new ArgumentNullException(nameof(instrumentationFactory));
}
this.instrumentationFactories.Add(
new InstrumentationFactory(
typeof(TInstrumentation).Name,
"semver:" + typeof(TInstrumentation).Assembly.GetName().Version,
instrumentationFactory));
return this;
}
/// <summary>
/// Adds given activitysource names to the list of subscribed sources.
/// </summary>
/// <param name="names">Activity source names.</param>
/// <returns>Returns <see cref="TracerProviderBuilder"/> for chaining.</returns>
public override TracerProviderBuilder AddSource(params string[] names)
{
if (names == null)
{
throw new ArgumentNullException(nameof(names));
}
foreach (var name in names)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException($"{nameof(names)} contains null or whitespace string.");
}
// TODO: We need to fix the listening model.
// Today it ignores version.
this.sources.Add(name);
}
return this;
}
/// <summary>
/// Sets sampler.
/// </summary>
/// <param name="sampler">Sampler instance.</param>
/// <returns>Returns <see cref="TracerProviderBuilder"/> for chaining.</returns>
internal TracerProviderBuilder SetSampler(Sampler sampler)
{
this.sampler = sampler ?? throw new ArgumentNullException(nameof(sampler));
return this;
}
/// <summary>
/// Sets the <see cref="Resource"/> describing the app associated with all traces. Overwrites currently set resource.
/// </summary>
/// <param name="resourceBuilder"><see cref="ResourceBuilder"/> to be associate with all traces.</param>
/// <returns>Returns <see cref="TracerProviderBuilder"/> for chaining.</returns>
internal TracerProviderBuilder SetResourceBuilder(ResourceBuilder resourceBuilder)
{
this.resourceBuilder = resourceBuilder ?? throw new ArgumentNullException(nameof(resourceBuilder));
return this;
}
/// <summary>
/// Adds processor to the provider.
/// </summary>
/// <param name="processor">Activity processor to add.</param>
/// <returns>Returns <see cref="TracerProviderBuilder"/> for chaining.</returns>
internal TracerProviderBuilder AddProcessor(BaseProcessor<Activity> processor)
{
if (processor == null)
{
throw new ArgumentNullException(nameof(processor));
}
this.processors.Add(processor);
return this;
}
internal TracerProvider Build()
{
return new TracerProviderSdk(
this.resourceBuilder.Build(),
this.sources,
this.diagnosticSourceInstrumentationFactories,
this.instrumentationFactories,
this.sampler,
this.processors);
}
/// <summary>
/// Adds a DiagnosticSource based instrumentation.
/// This is required for libraries which is already instrumented with
/// DiagnosticSource and Activity, without using ActivitySource.
/// </summary>
/// <typeparam name="TInstrumentation">Type of instrumentation class.</typeparam>
/// <param name="instrumentationFactory">Function that builds instrumentation.</param>
/// <returns>Returns <see cref="TracerProviderBuilder"/> for chaining.</returns>
internal TracerProviderBuilder AddDiagnosticSourceInstrumentation<TInstrumentation>(
Func<ActivitySourceAdapter, TInstrumentation> instrumentationFactory)
where TInstrumentation : class
{
if (instrumentationFactory == null)
{
throw new ArgumentNullException(nameof(instrumentationFactory));
}
this.diagnosticSourceInstrumentationFactories.Add(
new DiagnosticSourceInstrumentationFactory(
typeof(TInstrumentation).Name,
"semver:" + typeof(TInstrumentation).Assembly.GetName().Version,
instrumentationFactory));
return this;
}
internal readonly struct DiagnosticSourceInstrumentationFactory
{
public readonly string Name;
public readonly string Version;
public readonly Func<ActivitySourceAdapter, object> Factory;
internal DiagnosticSourceInstrumentationFactory(string name, string version, Func<ActivitySourceAdapter, object> factory)
{
this.Name = name;
this.Version = version;
this.Factory = factory;
}
}
internal readonly struct InstrumentationFactory
{
public readonly string Name;
public readonly string Version;
public readonly Func<object> Factory;
internal InstrumentationFactory(string name, string version, Func<object> factory)
{
this.Name = name;
this.Version = version;
this.Factory = factory;
}
}
}
}