Code Cleanups (#131)

* reordered all usings (SA1208)

* Use trailing comma in multi-line initializers (SA1413)

* SA1005	Single line comment should begin with a space.

* SA1028	Code should not contain trailing whitespace

* A1101	Prefix local calls with this

* SA1500	Braces for multi-line statements should not share line

* SA1505	An opening brace should not be followed by a blank line.

* SA1513	Closing brace should be followed by blank line

* SA1517	Code should not contain blank lines at start of file

* A1507	Code should not contain multiple blank lines in a row

* SA1503	Braces should not be omitted

* SA1508	A closing brace should not be preceded by a blank line

* SA1210	Using directives should be ordered alphabetically by the namespaces

* IDE0065 Removed unnecessary usings

* SA1633    The file header is missing or not located at the top of the file.

* IDE0044    Make field readonly

* SA1311	Static readonly fields should begin with upper-case letter

* IDE0060	Remove unused parameter 'options' if it is not part of a shipped public API

* various IDE warnings cleaned up

* SA1400	Element should declare an access modifier

* SA1402	File may only contain a single type

* SA1638	File header file name documentation should match file name

* SA1629	Documentation text should end with a period

* various code uncommon style warnings fixes

* SA1137	Elements should have the same indentation
* SA1648	inheritdoc should be used with inheriting class

* SA1616	Element return value documentation should have text

* SA1310    Field should not contain an underscore

* Various documentation rule violations fixed

* SA1614	Element parameter documentation should have text
* SA1137	Elements should have the same indentation

* Various documentation rule violations fixed

* CS1574	XML comment has cref attribute that could not be
resolved
* CS1572	XML comment has a param tag for, but there is no
parameter by that name
* SA1204	Static members should appear before non-static members
* SA1201	A property should not follow a method
* SA1201	A constructor should not follow a property
* SA1202	'public' members should come before 'private' members
* SA1202	'internal' members should come before 'private' members
* SA1202	'protected' members should come before 'private' members
* CS0168	The variable 'ex' is declared but never used

* Moved to implicit version resolution, as stated in the warning from the
dotnet sdk

* various cleanups and project structure

* CS1591 disabled for the entire solution
* removed `[assembly: System.CLSCompliant(true)]` from contributed
projects
* Fixed various async snafus.

* removed version.props from proj file

* enabled TreatWarningsAsErrors
This commit is contained in:
Michael Ingold 2019-07-09 07:32:22 +02:00 committed by Sergey Kanzhelev
parent 42e9566b7b
commit 843fc3e225
108 changed files with 1150 additions and 1217 deletions

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project=".\build\Version.props" />
<ItemGroup>
<Solution Include="OpenTelemetry.sln" />

View File

@ -1,9 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="Version.props" />
<ItemGroup>
<PackageReference Include="MinVer" Version="1.1.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)/OpenTelemetry.prod.ruleset</CodeAnalysisRuleSet>
<NoWarn>$(NoWarn),1573,1591,1712</NoWarn>
<PackageOutputPath Condition="$(Build_ArtifactStagingDirectory) != ''">$(Build_ArtifactStagingDirectory)</PackageOutputPath>
<GenerateDocumentationFile Condition="$(OS) == 'Windows_NT'">true</GenerateDocumentationFile>
</PropertyGroup>
@ -13,6 +20,7 @@
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)/debug.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<DefineConstants>$(DefineConstants);SIGNED</DefineConstants>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>

View File

@ -168,5 +168,6 @@
<Rule Id="SA1649" Action="Warning" />
<Rule Id="SA1651" Action="Warning" />
<Rule Id="SA1652" Action="Warning" />
<Rule Id="CS1591" Action="None" />
</Rules>
</RuleSet>

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!--
Semantic Version. See http://semver.org for full details.
Update for every public release.
-->
<SemanticVersionMajor>0</SemanticVersionMajor>
<SemanticVersionMinor>1</SemanticVersionMinor>
<SemanticVersionPatch>0</SemanticVersionPatch>
<!--Valid values: beta1, beta2, EMPTY for stable -->
<PreReleaseMilestone>alpha</PreReleaseMilestone>
<!--
Date when Semantic Version was changed.
Update for every public release.
NOTE!!!!!! Do not update when updating PreReleaseMilestone update
as it will restart file versions so 2.4.0-beta1 may have higher
file version (like 2.4.0.2222) than 2.4.0-beta2 (like 2.4.0.1111)
-->
<SemanticVersionDate>2018-08-25</SemanticVersionDate>
<PreReleaseVersion Condition="'$(PreReleaseVersion)'==''">$([MSBuild]::Divide($([System.DateTime]::Now.Subtract($([System.DateTime]::Parse($(SemanticVersionDate)))).TotalMinutes), 5).ToString('F0'))</PreReleaseVersion>
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>$(SemanticVersionMajor).$(SemanticVersionMinor).$(SemanticVersionPatch)</VersionPrefix>
<VersionSuffix>$(PreReleaseMilestone)-$(PreReleaseVersion)</VersionSuffix>
<FileVersion Condition="'$(PreReleaseVersion)' != ''">$(SemanticVersionMajor).$(SemanticVersionMinor).$(SemanticVersionPatch).$(PreReleaseVersion)</FileVersion>
</PropertyGroup>
</Project>

View File

@ -1,11 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'OpenTelemetry.sln'))\build\Version.props" />
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'OpenTelemetry.sln'))\build\Common.prod.props" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'OpenTelemetry.sln'))/build/OpenTelemetry.prod.loose.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.3.0" />
<PackageReference Include="StackExchange.Redis" Version="2.0.519" />

View File

@ -1,43 +1,23 @@
namespace Samples
// <copyright file="Program.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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>
namespace Samples
{
using CommandLine;
using System;
[Verb("stackdriver", HelpText = "Specify the options required to test Stackdriver exporter", Hidden = false)]
class StackdriverOptions
{
[Option('p', "projectId", HelpText = "Please specify the projectId of your GCP project", Required = true)]
public string ProjectId { get; set; }
}
[Verb("zipkin", HelpText = "Specify the options required to test Zipkin exporter")]
class ZipkinOptions
{
[Option('u', "uri", HelpText = "Please specify the uri of Zipkin backend", Required = true)]
public string Uri { get; set; }
}
[Verb("appInsights", HelpText = "Specify the options required to test ApplicationInsights")]
class ApplicationInsightsOptions
{
}
[Verb("prometheus", HelpText = "Specify the options required to test Prometheus")]
class PrometheusOptions
{
}
[Verb("httpclient", HelpText = "Specify the options required to test HttpClient")]
class HttpClientOptions
{
}
[Verb("redis", HelpText = "Specify the options required to test Redis with Zipkin")]
class RedisOptions
{
[Option('u', "uri", HelpText = "Please specify the uri of Zipkin backend", Required = true)]
public string Uri { get; set; }
}
using CommandLine;
/// <summary>
/// Main samples entry point.
@ -47,10 +27,10 @@
/// <summary>
/// Main method - invoke this using command line.
/// For example:
///
///
/// Samples.dll zipkin http://localhost:9411/api/v2/spans
/// Sample.dll appInsights
/// Sample.dll prometheus
/// Sample.dll prometheus.
/// </summary>
/// <param name="args">Arguments from command line.</param>
public static void Main(string[] args)
@ -68,4 +48,44 @@
Console.ReadLine();
}
}
[Verb("stackdriver", HelpText = "Specify the options required to test Stackdriver exporter", Hidden = false)]
#pragma warning disable SA1402 // File may only contain a single type
internal class StackdriverOptions
{
[Option('p', "projectId", HelpText = "Please specify the projectId of your GCP project", Required = true)]
public string ProjectId { get; set; }
}
[Verb("zipkin", HelpText = "Specify the options required to test Zipkin exporter")]
internal class ZipkinOptions
{
[Option('u', "uri", HelpText = "Please specify the uri of Zipkin backend", Required = true)]
public string Uri { get; set; }
}
[Verb("appInsights", HelpText = "Specify the options required to test ApplicationInsights")]
internal class ApplicationInsightsOptions
{
}
[Verb("prometheus", HelpText = "Specify the options required to test Prometheus")]
internal class PrometheusOptions
{
}
[Verb("httpclient", HelpText = "Specify the options required to test HttpClient")]
internal class HttpClientOptions
{
}
[Verb("redis", HelpText = "Specify the options required to test Redis with Zipkin")]
internal class RedisOptions
{
[Option('u', "uri", HelpText = "Please specify the uri of Zipkin backend", Required = true)]
public string Uri { get; set; }
}
#pragma warning restore SA1402 // File may only contain a single type
}

View File

@ -1,4 +1,20 @@
namespace Samples
// <copyright file="TestApplicationInsights.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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>
namespace Samples
{
using System;
using System.Collections.Generic;
@ -14,19 +30,19 @@
internal class TestApplicationInsights
{
private static ITracer tracer = Tracing.Tracer;
private static ITagger tagger = Tags.Tagger;
private static readonly ITracer Tracer = Tracing.Tracer;
private static readonly ITagger Tagger = Tags.Tagger;
private static IStatsRecorder statsRecorder = Stats.StatsRecorder;
private static readonly IStatsRecorder StatsRecorder = Stats.StatsRecorder;
private static readonly IMeasureLong VideoSize = MeasureLong.Create("my.org/measure/video_size", "size of processed videos", "By");
private static readonly TagKey FrontendKey = TagKey.Create("my.org/keys/frontend");
private static long MiB = 1 << 20;
private static readonly long MiB = 1 << 20;
private static readonly IViewName VideoSizeViewName = ViewName.Create("my.org/views/video_size");
private static readonly IView VideoSizeView = View.Create(
VideoSizeViewName,
VideoSizeViewName,
"processed video size over time",
VideoSize,
Distribution.Create(BucketBoundaries.Create(new List<double>() { 0.0, 16.0 * MiB, 256.0 * MiB })),
@ -38,9 +54,9 @@
var exporter = new ApplicationInsightsExporter(Tracing.ExportComponent, Stats.ViewManager, TelemetryConfiguration.Active);
exporter.Start();
var tagContextBuilder = tagger.CurrentBuilder.Put(FrontendKey, TagValue.Create("mobile-ios9.3.5"));
var tagContextBuilder = Tagger.CurrentBuilder.Put(FrontendKey, TagValue.Create("mobile-ios9.3.5"));
var spanBuilder = tracer
var spanBuilder = Tracer
.SpanBuilder("incoming request")
.SetRecordEvents(true)
.SetSampler(Samplers.AlwaysSample);
@ -51,10 +67,10 @@
{
using (var scopedSpan = spanBuilder.StartScopedSpan())
{
tracer.CurrentSpan.AddEvent("Start processing video.");
Tracer.CurrentSpan.AddEvent("Start processing video.");
Thread.Sleep(TimeSpan.FromMilliseconds(10));
statsRecorder.NewMeasureMap().Put(VideoSize, 25 * MiB).Record();
tracer.CurrentSpan.AddEvent("Finished processing video.");
StatsRecorder.NewMeasureMap().Put(VideoSize, 25 * MiB).Record();
Tracer.CurrentSpan.AddEvent("Finished processing video.");
}
}

View File

@ -1,22 +1,37 @@
namespace Samples
// <copyright file="TestHttpClient.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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>
namespace Samples
{
using System;
using System.Net.Http;
using OpenTelemetry.Collector.Dependencies;
using OpenTelemetry.Exporter.Zipkin;
using OpenTelemetry.Trace;
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace.Sampler;
internal class TestHttpClient
{
private static ITracer tracer = Tracing.Tracer;
private static readonly ITracer Tracer = Tracing.Tracer;
internal static object Run()
{
Console.WriteLine("Hello World!");
var collector = new DependenciesCollector(new DependenciesCollectorOptions(), tracer, Samplers.AlwaysSample);
var collector = new DependenciesCollector(new DependenciesCollectorOptions(), Tracer, Samplers.AlwaysSample);
var exporter = new ZipkinTraceExporter(
new ZipkinTraceExporterOptions()
@ -27,8 +42,7 @@
Tracing.ExportComponent);
exporter.Start();
var scope = tracer.SpanBuilder("incoming request").SetSampler(Samplers.AlwaysSample).StartScopedSpan();
//Thread.Sleep(TimeSpan.FromSeconds(1));
var scope = Tracer.SpanBuilder("incoming request").SetSampler(Samplers.AlwaysSample).StartScopedSpan();
var client = new HttpClient();
var t = client.GetStringAsync("http://bing.com");

View File

@ -1,26 +1,42 @@
namespace Samples
// <copyright file="TestPrometheus.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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>
namespace Samples
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using OpenTelemetry.Exporter.Prometheus;
using OpenTelemetry.Stats;
using OpenTelemetry.Stats.Aggregations;
using OpenTelemetry.Stats.Measures;
using OpenTelemetry.Tags;
using OpenTelemetry.Trace;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
internal class TestPrometheus
{
private static ITracer tracer = Tracing.Tracer;
private static ITagger tagger = Tags.Tagger;
private static readonly ITracer Tracer = Tracing.Tracer;
private static readonly ITagger Tagger = Tags.Tagger;
private static IStatsRecorder statsRecorder = Stats.StatsRecorder;
private static readonly IStatsRecorder StatsRecorder = Stats.StatsRecorder;
private static readonly IMeasureLong VideoSize = MeasureLong.Create("my.org/measure/video_size", "size of processed videos", "By");
private static readonly TagKey FrontendKey = TagKey.Create("my.org/keys/frontend");
private static long MiB = 1 << 20;
private static readonly long MiB = 1 << 20;
private static readonly IViewName VideoSizeViewName = ViewName.Create("my.org/views/video_size");
@ -36,7 +52,7 @@
var exporter = new PrometheusExporter(
new PrometheusExporterOptions()
{
Url = "http://+:9184/metrics/" // "+" is a wildcard used to listen to all hostnames
Url = "http://+:9184/metrics/", // "+" is a wildcard used to listen to all hostnames
},
Stats.ViewManager);
@ -44,7 +60,7 @@
try
{
var tagContextBuilder = tagger.CurrentBuilder.Put(FrontendKey, TagValue.Create("mobile-ios9.3.5"));
var tagContextBuilder = Tagger.CurrentBuilder.Put(FrontendKey, TagValue.Create("mobile-ios9.3.5"));
Stats.ViewManager.RegisterView(VideoSizeView);
@ -58,7 +74,7 @@
using (var scopedTags = tagContextBuilder.BuildScoped())
{
r.NextBytes(values);
statsRecorder.NewMeasureMap().Put(VideoSize, values[0] * MiB).Record();
StatsRecorder.NewMeasureMap().Put(VideoSize, values[0] * MiB).Record();
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}

View File

@ -1,4 +1,20 @@
namespace Samples
// <copyright file="TestRedis.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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>
namespace Samples
{
using System;
using System.Collections.Generic;
@ -6,7 +22,6 @@
using OpenTelemetry.Collector.StackExchangeRedis;
using OpenTelemetry.Exporter.Zipkin;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Config;
using OpenTelemetry.Trace.Sampler;
using StackExchange.Redis;
@ -36,7 +51,7 @@
// but if not - you can use it as follows:
var tracer = Tracing.Tracer;
var collector = new StackExchangeRedisCallsCollector(null, tracer, null, Tracing.ExportComponent);
var collector = new StackExchangeRedisCallsCollector(tracer, null, Tracing.ExportComponent);
// connect to the server
var connection = ConnectionMultiplexer.Connect("localhost:6379");
@ -45,14 +60,13 @@
// select a database (by default, DB = 0)
var db = connection.GetDatabase();
// 4. Create a scoped span. It will end automatically when using statement ends
using (var scope = tracer.SpanBuilder("Main").StartScopedSpan())
{
Console.WriteLine("About to do a busy work");
for (var i = 0; i < 10; i++)
{
DoWork(db, i);
DoWork(db);
}
}
@ -62,7 +76,7 @@
return null;
}
private static void DoWork(IDatabase db, int i)
private static void DoWork(IDatabase db)
{
// 6. Get the global singleton Tracer object
var tracer = Tracing.Tracer;
@ -86,7 +100,6 @@
var myVal = db.StringGet("key");
Console.WriteLine(myVal);
}
catch (ArgumentOutOfRangeException e)
{
@ -95,8 +108,10 @@
}
// 7. Annotate our span to capture metadata about our operation
var attributes = new Dictionary<string, IAttributeValue>();
attributes.Add("use", AttributeValue.StringAttributeValue("demo"));
var attributes = new Dictionary<string, IAttributeValue>
{
{ "use", AttributeValue.StringAttributeValue("demo") },
};
span.AddEvent("Invoking DoWork", attributes);
}
}

View File

@ -1,4 +1,20 @@
namespace Samples
// <copyright file="TestStackdriver.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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>
namespace Samples
{
using System;
using System.Collections.Generic;
@ -13,14 +29,14 @@
internal class TestStackdriver
{
private static ITracer tracer = Tracing.Tracer;
private static ITagger tagger = Tags.Tagger;
private static readonly ITracer Tracer = Tracing.Tracer;
private static readonly ITagger Tagger = Tags.Tagger;
private static IStatsRecorder statsRecorder = Stats.StatsRecorder;
private static readonly IStatsRecorder StatsRecorder = Stats.StatsRecorder;
private static readonly IMeasureDouble VideoSize = MeasureDouble.Create("my_org/measure/video_size", "size of processed videos", "MiB");
private static readonly TagKey FrontendKey = TagKey.Create("my_org/keys/frontend");
private static long MiB = 1 << 20;
private static readonly long MiB = 1 << 20;
private static readonly IViewName VideoSizeViewName = ViewName.Create("my_org/views/video_size");
@ -34,14 +50,14 @@
internal static object Run(string projectId)
{
var exporter = new StackdriverExporter(
projectId,
projectId,
Tracing.ExportComponent,
Stats.ViewManager);
exporter.Start();
var tagContextBuilder = tagger.CurrentBuilder.Put(FrontendKey, TagValue.Create("mobile-ios9.3.5"));
var tagContextBuilder = Tagger.CurrentBuilder.Put(FrontendKey, TagValue.Create("mobile-ios9.3.5"));
var spanBuilder = tracer
var spanBuilder = Tracer
.SpanBuilder("incoming request")
.SetRecordEvents(true)
.SetSampler(Samplers.AlwaysSample);
@ -52,10 +68,10 @@
{
using (var scopedSpan = spanBuilder.StartScopedSpan())
{
tracer.CurrentSpan.AddEvent("Processing video.");
Tracer.CurrentSpan.AddEvent("Processing video.");
Thread.Sleep(TimeSpan.FromMilliseconds(10));
statsRecorder.NewMeasureMap()
StatsRecorder.NewMeasureMap()
.Put(VideoSize, 25 * MiB)
.Record();
}

View File

@ -1,11 +1,26 @@
namespace Samples
// <copyright file="TestZipkin.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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>
namespace Samples
{
using System;
using System.Collections.Generic;
using System.Threading;
using OpenTelemetry.Exporter.Zipkin;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Config;
using OpenTelemetry.Trace.Sampler;
internal class TestZipkin

View File

@ -145,7 +145,7 @@ namespace OpenTelemetry.Context.Propagation
tracestateResult = tracestateBuilder.Build();
}
}
catch (Exception ex)
catch (Exception)
{
// failure to parse tracestate should not disregard traceparent
// TODO: logging
@ -153,7 +153,7 @@ namespace OpenTelemetry.Context.Propagation
return SpanContext.Create(traceId, spanId, traceoptions, tracestateResult);
}
catch (Exception ex)
catch (Exception)
{
// TODO: logging
}

View File

@ -18,7 +18,6 @@ namespace OpenTelemetry.Metrics
{
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using OpenTelemetry.Metrics.Implementation;
using OpenTelemetry.Resources;
using OpenTelemetry.Tags;
@ -29,26 +28,26 @@ namespace OpenTelemetry.Metrics
/// </summary>
public class DefaultMeter : IMeter
{
private static CounterDoubleBuilder counterDoubleBuilder = new CounterDoubleBuilder();
private static CounterLongBuilder counterLongBuilder = new CounterLongBuilder();
private static GaugeDoubleBuilder gaugeDoubleBuilder = new GaugeDoubleBuilder();
private static GaugeLongBuilder gaugeLongBuilder = new GaugeLongBuilder();
private static MeasureBuilder measureBuilder = new MeasureBuilder();
private static readonly CounterDoubleBuilder CounterDoubleBuilderValue = new CounterDoubleBuilder();
private static readonly CounterLongBuilder CounterLongBuilderValue = new CounterLongBuilder();
private static readonly GaugeDoubleBuilder GaugeDoubleBuilderValue = new GaugeDoubleBuilder();
private static readonly GaugeLongBuilder GaugeLongBuilderValue = new GaugeLongBuilder();
private static readonly MeasureBuilder MeasureBuilderValue = new MeasureBuilder();
/// <inheritdoc/>
public ICounterDoubleBuilder GetCounterDoubleBuilder(string name) => counterDoubleBuilder;
public ICounterDoubleBuilder GetCounterDoubleBuilder(string name) => CounterDoubleBuilderValue;
/// <inheritdoc/>
public ICounterLongBuilder GetCounterLongBuilder(string name) => counterLongBuilder;
public ICounterLongBuilder GetCounterLongBuilder(string name) => CounterLongBuilderValue;
/// <inheritdoc/>
public IGaugeDoubleBuilder GetGaugeDoubleBuilder(string name) => gaugeDoubleBuilder;
public IGaugeDoubleBuilder GetGaugeDoubleBuilder(string name) => GaugeDoubleBuilderValue;
/// <inheritdoc/>
public IGaugeLongBuilder GetGaugeLongBuilder(string name) => gaugeLongBuilder;
public IGaugeLongBuilder GetGaugeLongBuilder(string name) => GaugeLongBuilderValue;
/// <inheritdoc/>
public IMeasureBuilder GetMeasureBuilder(string name) => measureBuilder;
public IMeasureBuilder GetMeasureBuilder(string name) => MeasureBuilderValue;
/// <inheritdoc/>
public void Record(IEnumerable<IMeasurement> measurements)
@ -78,15 +77,15 @@ namespace OpenTelemetry.Metrics
private class CounterDouble : ICounterDouble
{
private static CounterDoubleTimeSeries timeSeries = new CounterDoubleTimeSeries();
private static readonly CounterDoubleTimeSeries TimeSeries = new CounterDoubleTimeSeries();
public void Clear()
{
}
public ICounterDoubleTimeSeries GetDefaultTimeSeries() => timeSeries;
public ICounterDoubleTimeSeries GetDefaultTimeSeries() => TimeSeries;
public ICounterDoubleTimeSeries GetOrCreateTimeSeries(IEnumerable<string> labelValues) => timeSeries;
public ICounterDoubleTimeSeries GetOrCreateTimeSeries(IEnumerable<string> labelValues) => TimeSeries;
public void RemoveTimeSeries(IEnumerable<string> labelValues)
{
@ -99,9 +98,9 @@ namespace OpenTelemetry.Metrics
private class CounterDoubleBuilder : ICounterDoubleBuilder
{
private static CounterDouble counterDouble = new CounterDouble();
private static readonly CounterDouble CounterDouble = new CounterDouble();
public IMetric<ICounterDoubleTimeSeries> Build() => counterDouble;
public IMetric<ICounterDoubleTimeSeries> Build() => CounterDouble;
public IMetricBuilder<ICounterDoubleTimeSeries> SetComponent(string component) => this;
@ -129,15 +128,15 @@ namespace OpenTelemetry.Metrics
private class CounterLong : ICounterLong
{
private static CounterLongTimeSeries timeSeries = new CounterLongTimeSeries();
private static readonly CounterLongTimeSeries TimeSeries = new CounterLongTimeSeries();
public void Clear()
{
}
public ICounterLongTimeSeries GetDefaultTimeSeries() => timeSeries;
public ICounterLongTimeSeries GetDefaultTimeSeries() => TimeSeries;
public ICounterLongTimeSeries GetOrCreateTimeSeries(IEnumerable<string> labelValues) => timeSeries;
public ICounterLongTimeSeries GetOrCreateTimeSeries(IEnumerable<string> labelValues) => TimeSeries;
public void RemoveTimeSeries(IEnumerable<string> labelValues)
{
@ -150,9 +149,9 @@ namespace OpenTelemetry.Metrics
private class CounterLongBuilder : ICounterLongBuilder
{
private static CounterLong counterLong = new CounterLong();
private static readonly CounterLong CounterLong = new CounterLong();
public IMetric<ICounterLongTimeSeries> Build() => counterLong;
public IMetric<ICounterLongTimeSeries> Build() => CounterLong;
public IMetricBuilder<ICounterLongTimeSeries> SetComponent(string component) => this;
@ -180,15 +179,15 @@ namespace OpenTelemetry.Metrics
private class GaugeDouble : IGaugeDouble
{
private static GaugeDoubleTimeSeries timeSeries = new GaugeDoubleTimeSeries();
private static readonly GaugeDoubleTimeSeries TimeSeries = new GaugeDoubleTimeSeries();
public void Clear()
{
}
public IGaugeDoubleTimeSeries GetDefaultTimeSeries() => timeSeries;
public IGaugeDoubleTimeSeries GetDefaultTimeSeries() => TimeSeries;
public IGaugeDoubleTimeSeries GetOrCreateTimeSeries(IEnumerable<string> labelValues) => timeSeries;
public IGaugeDoubleTimeSeries GetOrCreateTimeSeries(IEnumerable<string> labelValues) => TimeSeries;
public void RemoveTimeSeries(IEnumerable<string> labelValues)
{
@ -201,9 +200,9 @@ namespace OpenTelemetry.Metrics
private class GaugeDoubleBuilder : IGaugeDoubleBuilder
{
private static GaugeDouble gaugeDouble = new GaugeDouble();
private static readonly GaugeDouble GaugeDouble = new GaugeDouble();
public IMetric<IGaugeDoubleTimeSeries> Build() => gaugeDouble;
public IMetric<IGaugeDoubleTimeSeries> Build() => GaugeDouble;
public IMetricBuilder<IGaugeDoubleTimeSeries> SetComponent(string component) => this;
@ -231,15 +230,15 @@ namespace OpenTelemetry.Metrics
private class GaugeLong : IGaugeLong
{
private static GaugeLongTimeSeries timeSeries = new GaugeLongTimeSeries();
private static readonly GaugeLongTimeSeries TimeSeries = new GaugeLongTimeSeries();
public void Clear()
{
}
public IGaugeLongTimeSeries GetDefaultTimeSeries() => timeSeries;
public IGaugeLongTimeSeries GetDefaultTimeSeries() => TimeSeries;
public IGaugeLongTimeSeries GetOrCreateTimeSeries(IEnumerable<string> labelValues) => timeSeries;
public IGaugeLongTimeSeries GetOrCreateTimeSeries(IEnumerable<string> labelValues) => TimeSeries;
public void RemoveTimeSeries(IEnumerable<string> labelValues)
{
@ -252,9 +251,9 @@ namespace OpenTelemetry.Metrics
private class GaugeLongBuilder : IGaugeLongBuilder
{
private static GaugeLong counterLong = new GaugeLong();
private static readonly GaugeLong CounterLong = new GaugeLong();
public IMetric<IGaugeLongTimeSeries> Build() => counterLong;
public IMetric<IGaugeLongTimeSeries> Build() => CounterLong;
public IMetricBuilder<IGaugeLongTimeSeries> SetComponent(string component) => this;
@ -275,18 +274,18 @@ namespace OpenTelemetry.Metrics
private class Measure : IMeasure
{
private static IMeasurement measurement = new Measurement();
private static readonly IMeasurement Measurement = new Measurement();
public IMeasurement CreateDoubleMeasurement(double value) => measurement;
public IMeasurement CreateDoubleMeasurement(double value) => Measurement;
public IMeasurement CreateLongMeasurement(long value) => measurement;
public IMeasurement CreateLongMeasurement(long value) => Measurement;
}
private class MeasureBuilder : IMeasureBuilder
{
private static Measure measure = new Measure();
private static readonly Measure Measure = new Measure();
public IMeasure Build() => measure;
public IMeasure Build() => Measure;
public IMeasureBuilder SetDescription(string description) => this;

View File

@ -16,7 +16,6 @@
namespace OpenTelemetry.Metrics
{
using System.Collections;
using System.Collections.Generic;
using OpenTelemetry.Metrics.Implementation;
using OpenTelemetry.Tags;

View File

@ -18,7 +18,6 @@ namespace OpenTelemetry.Metrics
{
using System;
using System.Collections.Generic;
using OpenTelemetry.Resources;
/// <summary>
/// Base interface for all metrics defined in this package.
@ -43,7 +42,7 @@ namespace OpenTelemetry.Metrics
/// <summary>
/// Returns a time series for a metric with all labels not set (default label values).
/// </summary>
/// <returns>A time series for a metric with all labels not set (default label values)</returns>
/// <returns>A time series for a metric with all labels not set (default label values).</returns>
T GetDefaultTimeSeries();
/// <summary>
@ -61,7 +60,7 @@ namespace OpenTelemetry.Metrics
///
/// If value is missing for one of the predefined keys null must be used for that value.
/// </summary>
/// <param name="labelValues">The list of label values</param>
/// <param name="labelValues">The list of label values.</param>
void RemoveTimeSeries(IEnumerable<string> labelValues);
/// <summary>

View File

@ -16,8 +16,6 @@
namespace OpenTelemetry.Metrics.Implementation
{
using System;
/// <summary>
/// Builder for the <see cref="IMeasure"/>.
/// </summary>

View File

@ -5,8 +5,4 @@
<Description>OpenTelemetry .NET API abstractions</Description>
<RootNamespace>OpenTelemetry</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Utils\AttributesWithCapacity.cs" />
</ItemGroup>
</Project>

View File

@ -50,7 +50,7 @@ namespace OpenTelemetry.Resources
/// <summary>
/// Returns a new <see cref="Resource"/>.
/// </summary>
/// <param name="labels">An <see cref="IDictionary{string, string}"/> of labels that describe the resource.</param>
/// <param name="labels">An <see cref="IDictionary{String, String}"/> of labels that describe the resource.</param>
/// <returns><see cref="Resource"/>.</returns>
public static Resource Create(IDictionary<string, string> labels)
{
@ -58,10 +58,10 @@ namespace OpenTelemetry.Resources
}
/// <summary>
/// Returns a new, merged <see cref="Resource"/> by merging the current <see cref="Resource"/> with the
/// Returns a new, merged <see cref="Resource"/> by merging the current <see cref="Resource"/> with the.
/// <code>other</code> <see cref="Resource"/>. In case of a collision the current <see cref="Resource"/> takes precedence.
/// </summary>
/// <param name="other">The <see cref="Resource"/> that will be merged with <code>this</code>.</param>
/// <param name="other">The <see cref="Resource"/> that will be merged with. <code>this</code>.</param>
/// <returns><see cref="Resource"/>.</returns>
public Resource Merge(Resource other)
{

View File

@ -17,7 +17,6 @@
namespace OpenTelemetry.Trace.Export
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

View File

@ -49,10 +49,10 @@ namespace OpenTelemetry.Trace
bool HasEnded { get; }
/// <summary>
/// Updates the <see cref="Span"/> name.
/// Updates the <see cref="ISpan"/> name.
///
/// If used, this will override the name provided via <see cref="ISpanBuilder"/>.
/// Upon this update, any sampling behavior based on <see cref="Span"/> name will depend on the
/// Upon this update, any sampling behavior based on <see cref="ISpan"/> name will depend on the
/// implementation.
/// </summary>
/// <param name="name">Name of the span.</param>

View File

@ -17,7 +17,6 @@
namespace OpenTelemetry.Abstractions.Utils
{
using System.Collections.Generic;
using System.Linq;
using System.Text;
internal static class Collections

View File

@ -17,10 +17,8 @@
namespace OpenTelemetry.Collector.AspNetCore
{
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Globalization;
using System.Text;
using System.Threading;
/// <summary>

View File

@ -1,17 +0,0 @@
// <copyright file="AssemblyInfo.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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>
[assembly: System.CLSCompliant(true)]

View File

@ -23,7 +23,6 @@ namespace OpenTelemetry.Collector.AspNetCore.Implementation
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using OpenTelemetry.Collector.AspNetCore.Common;
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace;
internal class HttpInListener : ListenerHandler

View File

@ -68,7 +68,7 @@ namespace OpenTelemetry.Collector.AspNetCore.Common
this.handler.OnCustom(value.Key, Activity.Current, value.Value);
}
}
catch (Exception e)
catch (Exception)
{
// Debug.WriteLine(e);
// TODO: make sure to output the handler name as part of error message
@ -80,4 +80,4 @@ namespace OpenTelemetry.Collector.AspNetCore.Common
this.Subscription?.Dispose();
}
}
}
}

View File

@ -18,12 +18,9 @@ namespace OpenTelemetry.Collector.AspNetCore
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using Microsoft.AspNetCore.Http;
using OpenTelemetry.Collector.AspNetCore.Common;
using OpenTelemetry.Collector.AspNetCore.Implementation;
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace;
/// <summary>
@ -39,7 +36,6 @@ namespace OpenTelemetry.Collector.AspNetCore
/// <param name="options">Configuration options for dependencies collector.</param>
/// <param name="tracer">Tracer to record traced with.</param>
/// <param name="sampler">Sampler to use to sample dependency calls.</param>
/// <param name="propagationComponent">Wire context propagation component.</param>
public RequestsCollector(RequestsCollectorOptions options, ITracer tracer, ISampler sampler)
{
this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(

View File

@ -19,22 +19,21 @@ namespace OpenTelemetry.Collector.AspNetCore
using System;
using Microsoft.AspNetCore.Http;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Sampler;
/// <summary>
/// Options for dependencies collector.
/// </summary>
public class RequestsCollectorOptions
{
private static Func<HttpRequest, ISampler> defaultSampler = (req) => { return null; };
private static readonly Func<HttpRequest, ISampler> DefaultSampler = (req) => { return null; };
/// <summary>
/// Initializes a new instance of the <see cref="RequestsCollectorOptions"/> class.
/// </summary>
/// <param name="sampler">Custom sampling function, if any</param>
/// <param name="sampler">Custom sampling function, if any.</param>
public RequestsCollectorOptions(Func<HttpRequest, ISampler> sampler = null)
{
this.CustomSampler = sampler ?? defaultSampler;
this.CustomSampler = sampler ?? DefaultSampler;
}
/// <summary>

View File

@ -21,7 +21,6 @@ namespace OpenTelemetry.Collector.Dependencies
using System.Net.Http;
using OpenTelemetry.Collector.Dependencies.Common;
using OpenTelemetry.Collector.Dependencies.Implementation;
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace;
/// <summary>

View File

@ -17,10 +17,8 @@
namespace OpenTelemetry.Collector.Dependencies
{
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Globalization;
using System.Text;
using System.Threading;
/// <summary>

View File

@ -26,15 +26,15 @@ namespace OpenTelemetry.Collector.Dependencies
/// </summary>
public class DependenciesCollectorOptions
{
private static Func<HttpRequestMessage, ISampler> defaultSampler = (req) => { return ((req.RequestUri != null) && req.RequestUri.ToString().Contains("zipkin.azurewebsites.net")) ? Samplers.NeverSample : null; };
private static readonly Func<HttpRequestMessage, ISampler> DefaultSampler = (req) => { return ((req.RequestUri != null) && req.RequestUri.ToString().Contains("zipkin.azurewebsites.net")) ? Samplers.NeverSample : null; };
/// <summary>
/// Initializes a new instance of the <see cref="DependenciesCollectorOptions"/> class.
/// </summary>
/// <param name="sampler">Custom sampling function, if any</param>
/// <param name="sampler">Custom sampling function, if any.</param>
public DependenciesCollectorOptions(Func<HttpRequestMessage, ISampler> sampler = null)
{
this.CustomSampler = sampler ?? defaultSampler;
this.CustomSampler = sampler ?? DefaultSampler;
}
/// <summary>

View File

@ -17,16 +17,13 @@
namespace OpenTelemetry.Collector.Dependencies.Implementation
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using OpenTelemetry.Collector.Dependencies.Common;
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Sampler;
internal class HttpHandlerDiagnosticListener : ListenerHandler
{

View File

@ -68,7 +68,7 @@ namespace OpenTelemetry.Collector.Dependencies.Common
this.handler.OnCustom(value.Key, Activity.Current, value.Value);
}
}
catch (Exception e)
catch (Exception)
{
// Debug.WriteLine(e);
// TODO: make sure to output the handler name as part of error message
@ -80,4 +80,4 @@ namespace OpenTelemetry.Collector.Dependencies.Common
this.Subscription?.Dispose();
}
}
}
}

View File

@ -17,8 +17,6 @@
using System;
using System.Runtime.CompilerServices;
[assembly:CLSCompliant(true)]
[assembly: InternalsVisibleTo("OpenTelemetry.Collector.StackExchangeRedis.Tests" + AssemblyInfo.PublicKey)]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)]
@ -34,4 +32,4 @@ internal static class AssemblyInfo
public const string PublicKey = "";
public const string MoqPublicKey = "";
}
#endif
#endif

View File

@ -44,11 +44,10 @@ namespace OpenTelemetry.Collector.StackExchangeRedis
/// <summary>
/// Initializes a new instance of the <see cref="StackExchangeRedisCallsCollector"/> class.
/// </summary>
/// <param name="options">Configuration options for dependencies collector.</param>
/// <param name="tracer">Tracer to record traced with.</param>
/// <param name="sampler">Sampler to use to sample dependnecy calls.</param>
/// <param name="exportComponent">TEMPORARY: handler to send data to.</param>
public StackExchangeRedisCallsCollector(StackExchangeRedisCallsCollectorOptions options, ITracer tracer, ISampler sampler, IExportComponent exportComponent)
public StackExchangeRedisCallsCollector(ITracer tracer, ISampler sampler, IExportComponent exportComponent)
{
this.tracer = tracer;
this.exporter = exportComponent;

View File

@ -36,119 +36,77 @@ namespace OpenTelemetry.Exporter.ApplicationInsights.Implementation
this.telemetryClient = new TelemetryClient(telemetryConfiguration);
}
public async Task ExportAsync(IEnumerable<SpanData> spanDataList)
public Task ExportAsync(IEnumerable<SpanData> spanDataList)
{
await Task.Run(async () =>
foreach (var span in spanDataList)
{
foreach (var span in spanDataList)
this.ExtractGenericProperties(
span,
out var resultKind,
out var timestamp,
out var name,
out var resultCode,
out var props,
out var traceId,
out var spanId,
out var parentId,
out var tracestate,
out var success,
out var duration);
string data = null;
string target = null;
string type = null;
string userAgent = null;
IAttributeValue spanKindAttr = null;
IAttributeValue errorAttr = null;
IAttributeValue httpStatusCodeAttr = null;
IAttributeValue httpMethodAttr = null;
IAttributeValue httpPathAttr = null;
IAttributeValue httpHostAttr = null;
IAttributeValue httpUrlAttr = null;
IAttributeValue httpUserAgentAttr = null;
IAttributeValue httpRouteAttr = null;
IAttributeValue httpPortAttr = null;
foreach (var attr in span.Attributes.AttributeMap)
{
this.ExtractGenericProperties(
span,
out var resultKind,
out var timestamp,
out var name,
out var resultCode,
out var props,
out var traceId,
out var spanId,
out var parentId,
out var tracestate,
out var success,
out var duration);
var key = attr.Key;
string data = null;
string target = null;
string type = null;
string userAgent = null;
IAttributeValue spanKindAttr = null;
IAttributeValue errorAttr = null;
IAttributeValue httpStatusCodeAttr = null;
IAttributeValue httpMethodAttr = null;
IAttributeValue httpPathAttr = null;
IAttributeValue httpHostAttr = null;
IAttributeValue httpUrlAttr = null;
IAttributeValue httpUserAgentAttr = null;
IAttributeValue httpRouteAttr = null;
IAttributeValue httpPortAttr = null;
foreach (var attr in span.Attributes.AttributeMap)
switch (attr.Key)
{
var key = attr.Key;
switch (attr.Key)
{
case "span.kind":
spanKindAttr = attr.Value;
break;
case "error":
errorAttr = attr.Value;
break;
case "http.method":
httpMethodAttr = attr.Value;
break;
case "http.path":
httpPathAttr = attr.Value;
break;
case "http.host":
httpHostAttr = attr.Value;
break;
case "http.url":
httpUrlAttr = attr.Value;
break;
case "http.status_code":
httpStatusCodeAttr = attr.Value;
break;
case "http.user_agent":
httpUserAgentAttr = attr.Value;
break;
case "http.route":
httpRouteAttr = attr.Value;
break;
case "http.port":
httpPortAttr = attr.Value;
break;
default:
var value = attr.Value.Match<string>(
(s) => { return s; },
(b) => { return b.ToString(); },
(l) => { return l.ToString(); },
(d) => { return d.ToString(); },
(obj) => { return obj.ToString(); });
AddPropertyWithAdjustedName(props, attr.Key, value);
break;
}
}
var linkId = 0;
foreach (var link in span.Links.Links)
{
AddPropertyWithAdjustedName(props, "link" + linkId + "_traceId", link.Context.TraceId.ToLowerBase16());
AddPropertyWithAdjustedName(props, "link" + linkId + "_spanId", link.Context.SpanId.ToLowerBase16());
foreach (var attr in link.Attributes)
{
AddPropertyWithAdjustedName(props, "link" + linkId + "_" + attr.Key, attr.Value.Match((s) => s, (b) => b.ToString(), (l) => l.ToString(), (d) => d.ToString(), (obj) => obj.ToString()));
}
++linkId;
}
foreach (var t in span.Events.Events)
{
var log = new TraceTelemetry(t.Event.Name);
if (t.Timestamp != null)
{
var logTimestamp = DateTimeOffset.FromUnixTimeSeconds(t.Timestamp.Seconds);
logTimestamp = logTimestamp.Add(TimeSpan.FromTicks(t.Timestamp.Nanos / 100));
log.Timestamp = logTimestamp;
}
foreach (var attr in t.Event.Attributes)
{
case "span.kind":
spanKindAttr = attr.Value;
break;
case "error":
errorAttr = attr.Value;
break;
case "http.method":
httpMethodAttr = attr.Value;
break;
case "http.path":
httpPathAttr = attr.Value;
break;
case "http.host":
httpHostAttr = attr.Value;
break;
case "http.url":
httpUrlAttr = attr.Value;
break;
case "http.status_code":
httpStatusCodeAttr = attr.Value;
break;
case "http.user_agent":
httpUserAgentAttr = attr.Value;
break;
case "http.route":
httpRouteAttr = attr.Value;
break;
case "http.port":
httpPortAttr = attr.Value;
break;
default:
var value = attr.Value.Match<string>(
(s) => { return s; },
(b) => { return b.ToString(); },
@ -156,89 +114,132 @@ namespace OpenTelemetry.Exporter.ApplicationInsights.Implementation
(d) => { return d.ToString(); },
(obj) => { return obj.ToString(); });
AddPropertyWithAdjustedName(log.Properties, attr.Key, value);
}
AddPropertyWithAdjustedName(props, attr.Key, value);
log.Context.Operation.Id = traceId;
log.Context.Operation.ParentId = string.Concat("|", traceId, ".", spanId, ".");
this.telemetryClient.Track(log);
break;
}
this.OverwriteSpanKindFromAttribute(spanKindAttr, ref resultKind);
this.OverwriteErrorAttribute(errorAttr, ref success);
this.OverwriteFieldsForHttpSpans(
httpMethodAttr,
httpUrlAttr,
httpHostAttr,
httpPathAttr,
httpStatusCodeAttr,
httpUserAgentAttr,
httpRouteAttr,
httpPortAttr,
ref name,
ref resultCode,
ref data,
ref target,
ref type,
ref userAgent);
// BUILDING resulting telemetry
OperationTelemetry result;
if (resultKind == SpanKind.Client || resultKind == SpanKind.Producer)
{
var resultD = new DependencyTelemetry();
resultD.ResultCode = resultCode;
resultD.Data = data;
resultD.Target = target;
resultD.Type = type;
result = resultD;
}
else
{
var resultR = new RequestTelemetry();
resultR.ResponseCode = resultCode;
Uri.TryCreate(data, UriKind.RelativeOrAbsolute, out var url);
resultR.Url = url;
result = resultR;
}
result.Success = success;
result.Timestamp = timestamp;
result.Name = name;
result.Context.Operation.Id = traceId;
result.Context.User.UserAgent = userAgent;
foreach (var prop in props)
{
AddPropertyWithAdjustedName(result.Properties, prop.Key, prop.Value);
}
if (parentId != null)
{
result.Context.Operation.ParentId = string.Concat("|", traceId, ".", parentId, ".");
}
// TODO: I don't understant why this concatanation is required
result.Id = string.Concat("|", traceId, ".", spanId, ".");
foreach (var ts in tracestate.Entries)
{
result.Properties[ts.Key] = ts.Value;
}
result.Duration = duration;
// TODO: deal with those:
// span.ChildSpanCount
// span.Context.IsValid;
// span.Context.TraceOptions;
this.telemetryClient.Track(result);
}
});
var linkId = 0;
foreach (var link in span.Links.Links)
{
AddPropertyWithAdjustedName(props, "link" + linkId + "_traceId", link.Context.TraceId.ToLowerBase16());
AddPropertyWithAdjustedName(props, "link" + linkId + "_spanId", link.Context.SpanId.ToLowerBase16());
foreach (var attr in link.Attributes)
{
AddPropertyWithAdjustedName(props, "link" + linkId + "_" + attr.Key, attr.Value.Match((s) => s, (b) => b.ToString(), (l) => l.ToString(), (d) => d.ToString(), (obj) => obj.ToString()));
}
++linkId;
}
foreach (var t in span.Events.Events)
{
var log = new TraceTelemetry(t.Event.Name);
if (t.Timestamp != null)
{
var logTimestamp = DateTimeOffset.FromUnixTimeSeconds(t.Timestamp.Seconds);
logTimestamp = logTimestamp.Add(TimeSpan.FromTicks(t.Timestamp.Nanos / 100));
log.Timestamp = logTimestamp;
}
foreach (var attr in t.Event.Attributes)
{
var value = attr.Value.Match<string>(
(s) => { return s; },
(b) => { return b.ToString(); },
(l) => { return l.ToString(); },
(d) => { return d.ToString(); },
(obj) => { return obj.ToString(); });
AddPropertyWithAdjustedName(log.Properties, attr.Key, value);
}
log.Context.Operation.Id = traceId;
log.Context.Operation.ParentId = string.Concat("|", traceId, ".", spanId, ".");
this.telemetryClient.Track(log);
}
this.OverwriteSpanKindFromAttribute(spanKindAttr, ref resultKind);
this.OverwriteErrorAttribute(errorAttr, ref success);
this.OverwriteFieldsForHttpSpans(
httpMethodAttr,
httpUrlAttr,
httpHostAttr,
httpPathAttr,
httpStatusCodeAttr,
httpUserAgentAttr,
httpRouteAttr,
httpPortAttr,
ref name,
ref resultCode,
ref data,
ref target,
ref type,
ref userAgent);
// BUILDING resulting telemetry
OperationTelemetry result;
if (resultKind == SpanKind.Client || resultKind == SpanKind.Producer)
{
var resultD = new DependencyTelemetry
{
ResultCode = resultCode,
Data = data,
Target = target,
Type = type,
};
result = resultD;
}
else
{
var resultR = new RequestTelemetry();
resultR.ResponseCode = resultCode;
Uri.TryCreate(data, UriKind.RelativeOrAbsolute, out var url);
resultR.Url = url;
result = resultR;
}
result.Success = success;
result.Timestamp = timestamp;
result.Name = name;
result.Context.Operation.Id = traceId;
result.Context.User.UserAgent = userAgent;
foreach (var prop in props)
{
AddPropertyWithAdjustedName(result.Properties, prop.Key, prop.Value);
}
if (parentId != null)
{
result.Context.Operation.ParentId = string.Concat("|", traceId, ".", parentId, ".");
}
// TODO: I don't understant why this concatanation is required
result.Id = string.Concat("|", traceId, ".", spanId, ".");
foreach (var ts in tracestate.Entries)
{
result.Properties[ts.Key] = ts.Value;
}
result.Duration = duration;
// TODO: deal with those:
// span.ChildSpanCount
// span.Context.IsValid;
// span.Context.TraceOptions;
this.telemetryClient.Track(result);
}
return Task.CompletedTask;
}
private static void AddPropertyWithAdjustedName(IDictionary<string, string> props, string name, string value)

View File

@ -16,8 +16,6 @@
using System.Runtime.CompilerServices;
[assembly: System.CLSCompliant(true)]
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.ApplicationInsights.Tests" + AssemblyInfo.PublicKey)]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)]
@ -33,4 +31,4 @@ internal static class AssemblyInfo
public const string PublicKey = "";
public const string MoqPublicKey = "";
}
#endif
#endif

View File

@ -28,14 +28,14 @@ namespace OpenTelemetry.Exporter.Prometheus.Implementation
{
public static readonly string ContentType = "text/plain; version = 0.0.4";
private static char[] firstCharacterNameCharset = new char[]
private static readonly char[] FirstCharacterNameCharset = new char[]
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'_', ':',
};
private static char[] nameCharset = new char[]
private static readonly char[] NameCharset = new char[]
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
@ -43,14 +43,14 @@ namespace OpenTelemetry.Exporter.Prometheus.Implementation
'_', ':',
};
private static char[] firstCharacterLabelCharset = new char[]
private static readonly char[] FirstCharacterLabelCharset = new char[]
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'_',
};
private static char[] labelCharset = new char[]
private static readonly char[] LabelCharset = new char[]
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
@ -211,7 +211,7 @@ namespace OpenTelemetry.Exporter.Prometheus.Implementation
if (!string.IsNullOrEmpty(name))
{
var firstChar = name[0];
if (firstCharacterNameCharset.Contains(firstChar))
if (FirstCharacterNameCharset.Contains(firstChar))
{
sb.Append(firstChar);
}
@ -219,7 +219,7 @@ namespace OpenTelemetry.Exporter.Prometheus.Implementation
{
firstChar = firstChar.ToString().ToLowerInvariant()[0];
if (firstCharacterNameCharset.Contains(firstChar))
if (FirstCharacterNameCharset.Contains(firstChar))
{
sb.Append(firstChar);
}
@ -235,7 +235,7 @@ namespace OpenTelemetry.Exporter.Prometheus.Implementation
{
var c = name[i];
if (nameCharset.Contains(c))
if (NameCharset.Contains(c))
{
sb.Append(c);
}
@ -266,7 +266,7 @@ namespace OpenTelemetry.Exporter.Prometheus.Implementation
if (!string.IsNullOrEmpty(name))
{
var firstChar = name[0];
if (firstCharacterLabelCharset.Contains(firstChar))
if (FirstCharacterLabelCharset.Contains(firstChar))
{
sb.Append(firstChar);
}
@ -274,7 +274,7 @@ namespace OpenTelemetry.Exporter.Prometheus.Implementation
{
firstChar = firstChar.ToString().ToLowerInvariant()[0];
if (firstCharacterLabelCharset.Contains(firstChar))
if (FirstCharacterLabelCharset.Contains(firstChar))
{
sb.Append(firstChar);
}
@ -290,7 +290,7 @@ namespace OpenTelemetry.Exporter.Prometheus.Implementation
{
var c = name[i];
if (labelCharset.Contains(c))
if (LabelCharset.Contains(c))
{
sb.Append(c);
}

View File

@ -16,8 +16,6 @@
namespace OpenTelemetry.Exporter.Prometheus
{
using System;
/// <summary>
/// Options to run prometheus exporter.
/// </summary>

View File

@ -1,4 +1,4 @@
// <copyright file="ApplicationInsightsExporter.cs" company="OpenTelemetry Authors">
// <copyright file="Constants.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -20,30 +20,30 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
internal class Constants
{
public static readonly string PACKAGE_VERSION_UNDEFINED = "undefined";
public static readonly string PackagVersionUndefined = "undefined";
public static readonly string LABEL_DESCRIPTION = "OpenTelemetry TagKey";
public static readonly string OpenTelemetry_TASK = "OpenTelemetry_task";
public static readonly string OpenTelemetry_TASK_DESCRIPTION = "OpenTelemetry task identifier";
public static readonly string LabelDescription = "OpenTelemetry TagKey";
public static readonly string OpenTelemetryTask = "OpenTelemetry_task";
public static readonly string OpenTelemetryTaskDescription = "OpenTelemetry task identifier";
public static readonly string GCP_GKE_CONTAINER = "k8s_container";
public static readonly string GCP_GCE_INSTANCE = "gce_instance";
public static readonly string AWS_EC2_INSTANCE = "aws_ec2_instance";
public static readonly string GLOBAL = "global";
public static readonly string GcpGkeContainer = "k8s_container";
public static readonly string GcpGceInstance = "gce_instance";
public static readonly string AwsEc2Instance = "aws_ec2_instance";
public static readonly string Global = "global";
public static readonly string PROJECT_ID_LABEL_KEY = "project_id";
public static readonly string OpenTelemetry_TASK_VALUE_DEFAULT = GenerateDefaultTaskValue();
public static readonly string ProjectIdLabelKey = "project_id";
public static readonly string OpenTelemetryTaskValueDefault = GenerateDefaultTaskValue();
public static readonly string GCP_GCE_INSTANCE_TYPE = "cloud.google.com/gce/instance";
public static readonly string GCP_INSTANCE_ID_KEY = "cloud.google.com/gce/instance_id";
public static readonly string GCP_ACCOUNT_ID_KEY = "cloud.google.com/gce/project_id";
public static readonly string GCP_ZONE_KEY = "cloud.google.com/gce/zone";
public static readonly string GceGcpInstanceType = "cloud.google.com/gce/instance";
public static readonly string GcpInstanceIdKey = "cloud.google.com/gce/instance_id";
public static readonly string GcpAccountIdKey = "cloud.google.com/gce/project_id";
public static readonly string GcpZoneKey = "cloud.google.com/gce/zone";
public static readonly string K8S_CONTAINER_TYPE = "k8s.io/container";
public static readonly string K8S_CLUSTER_NAME_KEY = "k8s.io/cluster/name";
public static readonly string K8S_CONTAINER_NAME_KEY = "k8s.io/container/name";
public static readonly string K8S_NAMESPACE_NAME_KEY = "k8s.io/namespace/name";
public static readonly string K8S_POD_NAME_KEY = "k8s.io/pod/name";
public static readonly string K8sContainerType = "k8s.io/container";
public static readonly string K8sClusterNameKey = "k8s.io/cluster/name";
public static readonly string K8sContainerNameKey = "k8s.io/container/name";
public static readonly string K8sNamespaceNameKey = "k8s.io/namespace/name";
public static readonly string K8sPodNameKey = "k8s.io/pod/name";
private static string GenerateDefaultTaskValue()
{
@ -51,4 +51,4 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
return $"dotnet-{System.Diagnostics.Process.GetCurrentProcess().Id}@{Environment.MachineName}";
}
}
}
}

View File

@ -1,4 +1,4 @@
// <copyright file="ApplicationInsightsExporter.cs" company="OpenTelemetry Authors">
// <copyright file="GoogleCloudResourceUtils.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -16,13 +16,12 @@
namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
using Google.Api;
using System;
using System.Collections.Generic;
using System.IO;
using Google.Api;
/// <summary>
/// Utility methods for working with Google Cloud Resources
/// Utility methods for working with Google Cloud Resources.
/// </summary>
public static class GoogleCloudResourceUtils
{
@ -30,9 +29,9 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
/// Detects Google Cloud ProjectId based on the environment on which the code runs.
/// Supports GCE/GKE/GAE and projectId tied to service account
/// In case the code runs in a different environment,
/// the method returns null
/// the method returns null.
/// </summary>
/// <returns>Google Cloud Project ID</returns>
/// <returns>Google Cloud Project ID.</returns>
public static string GetProjectId()
{
// Try to detect projectId from the environment where the code is running
@ -59,14 +58,15 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
}
/// <summary>
/// Determining the resource to which the metrics belong
/// Determining the resource to which the metrics belong.
/// </summary>
/// <returns>Stackdriver Monitored Resource</returns>
/// <param name="projectId">The project id.</param>
/// <returns>Stackdriver Monitored Resource.</returns>
public static MonitoredResource GetDefaultResource(string projectId)
{
var resource = new MonitoredResource();
resource.Type = Constants.GLOBAL;
resource.Labels.Add(Constants.PROJECT_ID_LABEL_KEY, projectId);
resource.Type = Constants.Global;
resource.Labels.Add(Constants.ProjectIdLabelKey, projectId);
// TODO - zeltser - setting monitored resource labels for detected resource
// along with all the other metadata
@ -74,4 +74,4 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
return resource;
}
}
}
}

View File

@ -1,4 +1,4 @@
// <copyright file="ApplicationInsightsExporter.cs" company="OpenTelemetry Authors">
// <copyright file="MetricsConversions.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -16,6 +16,7 @@
namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
using System.Collections.Generic;
using Google.Api;
using Google.Cloud.Monitoring.V3;
using Google.Protobuf.WellKnownTypes;
@ -24,20 +25,19 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
using OpenTelemetry.Stats.Aggregations;
using OpenTelemetry.Stats.Measures;
using OpenTelemetry.Tags;
using System.Collections.Generic;
using static Google.Api.Distribution.Types;
using static Google.Api.MetricDescriptor.Types;
/// <summary>
/// Conversion methods from OpenTelemetry Stats API to Stackdriver Metrics API
/// Conversion methods from OpenTelemetry Stats API to Stackdriver Metrics API.
/// </summary>
internal static class MetricsConversions
{
/// <summary>
/// Converts between OpenTelemetry aggregation and Stackdriver metric kind
/// Converts between OpenTelemetry aggregation and Stackdriver metric kind.
/// </summary>
/// <param name="aggregation">Stats Aggregation</param>
/// <returns>Stackdriver Metric Kind</returns>
/// <param name="aggregation">Stats Aggregation.</param>
/// <returns>Stackdriver Metric Kind.</returns>
public static MetricKind ToMetricKind(
this IAggregation aggregation)
{
@ -51,17 +51,19 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
}
/// <summary>
/// Converts from OpenTelemetry Measure+Aggregation to Stackdriver's ValueType
/// Converts from OpenTelemetry Measure+Aggregation to Stackdriver's ValueType.
/// </summary>
/// <param name="measure">OpenTelemetry Measure definition</param>
/// <param name="aggregation">OpenTelemetry Aggregation definition</param>
/// <returns></returns>
/// <param name="measure">OpenTelemetry Measure definition.</param>
/// <param name="aggregation">OpenTelemetry Aggregation definition.</param>
/// <returns><see cref="ValueType"/>.</returns>
public static ValueType ToValueType(
this IMeasure measure, IAggregation aggregation)
{
var metricKind = aggregation.ToMetricKind();
if (aggregation is IDistribution && (metricKind == MetricKind.Cumulative || metricKind == MetricKind.Gauge))
{
return ValueType.Distribution;
}
if (measure is IMeasureDouble && (metricKind == MetricKind.Cumulative || metricKind == MetricKind.Gauge))
{
@ -82,7 +84,7 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
var labelDescriptor = new LabelDescriptor();
labelDescriptor.Key = GetStackdriverLabelKey(tagKey.Name);
labelDescriptor.Description = Constants.LABEL_DESCRIPTION;
labelDescriptor.Description = Constants.LabelDescription;
// TODO - zeltser - Now we only support string tags
labelDescriptor.ValueType = LabelDescriptor.Types.ValueType.String;
@ -101,21 +103,21 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
Count = distributionData.Count,
Mean = distributionData.Mean,
SumOfSquaredDeviation = distributionData.SumOfSquaredDeviations,
Range = new Range { Max = distributionData.Max, Min = distributionData.Min }
Range = new Range { Max = distributionData.Max, Min = distributionData.Min },
};
return distribution;
}
/// <summary>
/// Creates Stackdriver MetricDescriptor from OpenTelemetry View
/// Creates Stackdriver MetricDescriptor from OpenTelemetry View.
/// </summary>
/// <param name="metricDescriptorTypeName">Metric Descriptor full type name</param>
/// <param name="view">OpenTelemetry View</param>
/// <param name="project">Google Cloud Project Name</param>
/// <param name="domain"></param>
/// <param name="displayNamePrefix"></param>
/// <returns></returns>
/// <param name="metricDescriptorTypeName">Metric Descriptor full type name.</param>
/// <param name="view">OpenTelemetry View.</param>
/// <param name="project">Google Cloud Project Name.</param>
/// <param name="domain">The Domain.</param>
/// <param name="displayNamePrefix">Display Name Prefix.</param>
/// <returns><see cref="MetricDescriptor"/>.</returns>
public static MetricDescriptor CreateMetricDescriptor(
string metricDescriptorTypeName,
IView view,
@ -136,11 +138,12 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
var labelDescriptor = tagKey.ToLabelDescriptor();
metricDescriptor.Labels.Add(labelDescriptor);
}
metricDescriptor.Labels.Add(
new LabelDescriptor
{
Key = Constants.OpenTelemetry_TASK,
Description = Constants.OpenTelemetry_TASK_DESCRIPTION,
Key = Constants.OpenTelemetryTask,
Description = Constants.OpenTelemetryTaskDescription,
ValueType = LabelDescriptor.Types.ValueType.String,
});
@ -161,59 +164,22 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
v => new TypedValue { Int64Value = v.Sum }, // Long
v => new TypedValue { Int64Value = v.Count }, // Count
v => new TypedValue { DoubleValue = v.Count }, // Mean
v => new TypedValue { DistributionValue = CreateDistribution(v, ((IDistribution)aggregation).BucketBoundaries) }, //Distribution
v => new TypedValue { DistributionValue = CreateDistribution(v, ((IDistribution)aggregation).BucketBoundaries) }, // Distribution
v => new TypedValue { DoubleValue = v.LastValue }, // LastValue Double
v => new TypedValue { Int64Value = v.LastValue }, // LastValue Long
v => new TypedValue { BoolValue = false }); // Default
}
/// <summary>
/// Create a list of counts for Stackdriver from the list of counts in OpenTelemetry
/// </summary>
/// <param name="bucketCounts">OpenTelemetry list of counts</param>
/// <returns></returns>
private static IEnumerable<long> CreateBucketCounts(IReadOnlyList<long> bucketCounts)
{
// The first bucket (underflow bucket) should always be 0 count because the Metrics first bucket
// is [0, first_bound) but Stackdriver distribution consists of an underflow bucket (number 0).
var ret = new List<long>();
ret.Add(0L);
ret.AddRange(bucketCounts);
return ret;
}
/// <summary>
/// Converts <see cref="IBucketBoundaries"/> to Stackdriver's <see cref="BucketOptions"/>
/// </summary>
/// <param name="bucketBoundaries"></param>
/// <returns></returns>
private static BucketOptions ToBucketOptions(this IBucketBoundaries bucketBoundaries)
{
// The first bucket bound should be 0.0 because the Metrics first bucket is
// [0, first_bound) but Stackdriver monitoring bucket bounds begin with -infinity
// (first bucket is (-infinity, 0))
var bucketOptions = new BucketOptions
{
ExplicitBuckets = new BucketOptions.Types.Explicit
{
Bounds = { 0.0 }
}
};
bucketOptions.ExplicitBuckets.Bounds.AddRange(bucketBoundaries.Boundaries);
return bucketOptions;
}
// Create a Metric using the TagKeys and TagValues.
/// <summary>
/// Generate Stackdriver Metric from OpenTelemetry View
/// Generate Stackdriver Metric from OpenTelemetry View.
/// </summary>
/// <param name="view"></param>
/// <param name="tagValues"></param>
/// <param name="metricDescriptor">Stackdriver Metric Descriptor</param>
/// <param name="domain"></param>
/// <returns></returns>
/// <param name="view">A <see cref="IView"/>.</param>
/// <param name="tagValues">A list of <see cref="TagValue"/>.</param>
/// <param name="metricDescriptor">Stackdriver Metric Descriptor.</param>
/// <param name="domain">The domain.</param>
/// <returns><see cref="Metric"/>.</returns>
public static Metric GetMetric(
IView view,
IReadOnlyList<TagValue> tagValues,
@ -238,7 +204,8 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
var labelKey = GetStackdriverLabelKey(key.Name);
metric.Labels.Add(labelKey, value.AsString);
}
metric.Labels.Add(Constants.OpenTelemetry_TASK, Constants.OpenTelemetry_TASK_VALUE_DEFAULT);
metric.Labels.Add(Constants.OpenTelemetryTask, Constants.OpenTelemetryTaskValueDefault);
// TODO - zeltser - make sure all the labels from the metric descriptor were fulfilled
return metric;
@ -247,11 +214,11 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
/// <summary>
/// Convert ViewData to a list of TimeSeries, so that ViewData can be uploaded to Stackdriver.
/// </summary>
/// <param name="viewData">OpenTelemetry View</param>
/// <param name="metricDescriptor">Stackdriver Metric Descriptor</param>
/// <param name="monitoredResource">Stackdriver Resource to which the metrics belong</param>
/// <param name="domain">The metrics domain (namespace)</param>
/// <returns></returns>
/// <param name="viewData">OpenTelemetry View.</param>
/// <param name="monitoredResource">Stackdriver Resource to which the metrics belong.</param>
/// <param name="metricDescriptor">Stackdriver Metric Descriptor.</param>
/// <param name="domain">The metrics domain (namespace).</param>
/// <returns><see cref="List{T}"/>.</returns>
public static List<TimeSeries> CreateTimeSeriesList(
IViewData viewData,
MonitoredResource monitoredResource,
@ -290,24 +257,6 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
return timeSeriesList;
}
private static Point ExtractPointInInterval(
System.DateTimeOffset startTime,
System.DateTimeOffset endTime,
IAggregation aggregation,
IAggregationData points)
{
return new Point
{
Value = CreateTypedValue(aggregation, points),
Interval = CreateTimeInterval(startTime, endTime)
};
}
private static TimeInterval CreateTimeInterval(System.DateTimeOffset start, System.DateTimeOffset end)
{
return new TimeInterval { StartTime = start.ToTimestamp(), EndTime = end.ToTimestamp() };
}
internal static string GetUnit(IAggregation aggregation, IMeasure measure)
{
if (aggregation is ICount)
@ -324,13 +273,68 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
}
/// <summary>
/// Creates Stackdriver Label name
/// Creates Stackdriver Label name.
/// </summary>
/// <param name="label">OpenTelemetry label</param>
/// <returns>Label name that complies with Stackdriver label naming rules</returns>
/// <param name="label">OpenTelemetry label.</param>
/// <returns>Label name that complies with Stackdriver label naming rules.</returns>
internal static string GetStackdriverLabelKey(string label)
{
return label.Replace('/', '_');
}
private static Point ExtractPointInInterval(
System.DateTimeOffset startTime,
System.DateTimeOffset endTime,
IAggregation aggregation,
IAggregationData points)
{
return new Point
{
Value = CreateTypedValue(aggregation, points),
Interval = CreateTimeInterval(startTime, endTime),
};
}
/// <summary>
/// Create a list of counts for Stackdriver from the list of counts in OpenTelemetry.
/// </summary>
/// <param name="bucketCounts">OpenTelemetry list of counts.</param>
/// <returns><see cref="IEnumerable{T}"/>.</returns>
private static IEnumerable<long> CreateBucketCounts(IReadOnlyList<long> bucketCounts)
{
// The first bucket (underflow bucket) should always be 0 count because the Metrics first bucket
// is [0, first_bound) but Stackdriver distribution consists of an underflow bucket (number 0).
var ret = new List<long>();
ret.Add(0L);
ret.AddRange(bucketCounts);
return ret;
}
/// <summary>
/// Converts <see cref="IBucketBoundaries"/> to Stackdriver's <see cref="BucketOptions"/>.
/// </summary>
/// <param name="bucketBoundaries">A <see cref="IBucketBoundaries"/> representing the bucket boundaries.</param>
/// <returns><see cref="BucketOptions"/>.</returns>
private static BucketOptions ToBucketOptions(this IBucketBoundaries bucketBoundaries)
{
// The first bucket bound should be 0.0 because the Metrics first bucket is
// [0, first_bound) but Stackdriver monitoring bucket bounds begin with -infinity
// (first bucket is (-infinity, 0))
var bucketOptions = new BucketOptions
{
ExplicitBuckets = new BucketOptions.Types.Explicit
{
Bounds = { 0.0 },
},
};
bucketOptions.ExplicitBuckets.Bounds.AddRange(bucketBoundaries.Boundaries);
return bucketOptions;
}
private static TimeInterval CreateTimeInterval(System.DateTimeOffset start, System.DateTimeOffset end)
{
return new TimeInterval { StartTime = start.ToTimestamp(), EndTime = end.ToTimestamp() };
}
}
}

View File

@ -0,0 +1,121 @@
// <copyright file="SpanExtensions.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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>
namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
using System.Linq;
using Google.Cloud.Trace.V2;
using OpenTelemetry.Exporter.Stackdriver.Utils;
using OpenTelemetry.Trace;
internal static class SpanExtensions
{
/// <summary>
/// Translating <see cref="SpanData"/> to Stackdriver's Span
/// According to <see href="https://cloud.google.com/trace/docs/reference/v2/rpc/google.devtools.cloudtrace.v2"/> specifications.
/// </summary>
/// <param name="spanData">Span in OpenTelemetry format.</param>
/// <param name="projectId">Google Cloud Platform Project Id.</param>
/// <returns><see cref="ISpan"/>.</returns>
public static Google.Cloud.Trace.V2.Span ToSpan(this SpanData spanData, string projectId)
{
var spanId = spanData.Context.SpanId.ToLowerBase16();
// Base span settings
var span = new Google.Cloud.Trace.V2.Span
{
SpanName = new SpanName(projectId, spanData.Context.TraceId.ToLowerBase16(), spanId),
SpanId = spanId,
DisplayName = new TruncatableString { Value = spanData.Name },
StartTime = spanData.StartTimestamp.ToTimestamp(),
EndTime = spanData.EndTimestamp.ToTimestamp(),
ChildSpanCount = spanData.ChildSpanCount,
};
if (spanData.ParentSpanId != null)
{
var parentSpanId = spanData.ParentSpanId.ToLowerBase16();
if (!string.IsNullOrEmpty(parentSpanId))
{
span.ParentSpanId = parentSpanId;
}
}
// Span Links
if (spanData.Links != null)
{
span.Links = new Google.Cloud.Trace.V2.Span.Types.Links
{
DroppedLinksCount = spanData.Links.DroppedLinksCount,
Link = { spanData.Links.Links.Select(l => l.ToLink()) },
};
}
// Span Attributes
if (spanData.Attributes != null)
{
span.Attributes = new Google.Cloud.Trace.V2.Span.Types.Attributes
{
DroppedAttributesCount = spanData.Attributes != null ? spanData.Attributes.DroppedAttributesCount : 0,
AttributeMap =
{
spanData.Attributes?.AttributeMap?.ToDictionary(
s => s.Key,
s => s.Value?.ToAttributeValue()),
},
};
}
return span;
}
public static Google.Cloud.Trace.V2.Span.Types.Link ToLink(this ILink link)
{
var ret = new Google.Cloud.Trace.V2.Span.Types.Link();
ret.SpanId = link.Context.SpanId.ToLowerBase16();
ret.TraceId = link.Context.TraceId.ToLowerBase16();
if (link.Attributes != null)
{
ret.Attributes = new Google.Cloud.Trace.V2.Span.Types.Attributes
{
DroppedAttributesCount = OpenTelemetry.Trace.Config.TraceParams.Default.MaxNumberOfAttributes - link.Attributes.Count,
AttributeMap =
{
link.Attributes.ToDictionary(
att => att.Key,
att => att.Value.ToAttributeValue()),
},
};
}
return ret;
}
public static Google.Cloud.Trace.V2.AttributeValue ToAttributeValue(this IAttributeValue av)
{
var ret = av.Match(
(s) => new Google.Cloud.Trace.V2.AttributeValue() { StringValue = new TruncatableString() { Value = s } },
(b) => new Google.Cloud.Trace.V2.AttributeValue() { BoolValue = b },
(l) => new Google.Cloud.Trace.V2.AttributeValue() { IntValue = l },
(d) => new Google.Cloud.Trace.V2.AttributeValue() { StringValue = new TruncatableString() { Value = d.ToString() } },
(obj) => new Google.Cloud.Trace.V2.AttributeValue() { StringValue = new TruncatableString() { Value = obj.ToString() } });
return ret;
}
}
}

View File

@ -1,4 +1,4 @@
// <copyright file="ICountData.cs" company="OpenTelemetry Authors">
// <copyright file="StackdriverStatsConfiguration.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -16,47 +16,19 @@
namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
using System;
using Google.Api;
using Google.Apis.Auth.OAuth2;
using System;
/// <summary>
/// Configuration for exporting stats into Stackdriver
/// Configuration for exporting stats into Stackdriver.
/// </summary>
public class StackdriverStatsConfiguration
{
private static readonly TimeSpan DEFAULT_INTERVAL = TimeSpan.FromMinutes(1);
private static readonly TimeSpan DefaultInterval = TimeSpan.FromMinutes(1);
/// <summary>
/// Frequency of the export operation
/// </summary>
public TimeSpan ExportInterval { get; set; }
/// <summary>
/// The prefix to append to every OpenTelemetry metric name in Stackdriver
/// </summary>
public string MetricNamePrefix { get; set; }
/// <summary>
/// Google Cloud Project Id
/// </summary>
public string ProjectId { get; set; }
/// <summary>
/// Credential used to authenticate against Google Stackdriver Monitoring APIs
/// </summary>
public GoogleCredential GoogleCredential { get; set; }
/// <summary>
/// Monitored Resource associated with metrics collection.
/// By default, the exporter detects the environment where the export is happening,
/// such as GKE/AWS/GCE. If the exporter is running on a different environment,
/// monitored resource will be identified as "general".
/// </summary>
public MonitoredResource MonitoredResource { get; set; }
/// <summary>
/// Default Stats Configuration for Stackdriver
/// Gets default Stats Configuration for Stackdriver.
/// </summary>
public static StackdriverStatsConfiguration Default
{
@ -64,7 +36,7 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
var defaultConfig = new StackdriverStatsConfiguration
{
ExportInterval = DEFAULT_INTERVAL,
ExportInterval = DefaultInterval,
ProjectId = GoogleCloudResourceUtils.GetProjectId(),
MetricNamePrefix = string.Empty,
};
@ -73,5 +45,33 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
return defaultConfig;
}
}
/// <summary>
/// Gets or sets frequency of the export operation.
/// </summary>
public TimeSpan ExportInterval { get; set; }
/// <summary>
/// Gets or sets the prefix to append to every OpenTelemetry metric name in Stackdriver.
/// </summary>
public string MetricNamePrefix { get; set; }
/// <summary>
/// Gets or sets google Cloud Project Id.
/// </summary>
public string ProjectId { get; set; }
/// <summary>
/// Gets or sets credential used to authenticate against Google Stackdriver Monitoring APIs.
/// </summary>
public GoogleCredential GoogleCredential { get; set; }
/// <summary>
/// Gets or sets monitored Resource associated with metrics collection.
/// By default, the exporter detects the environment where the export is happening,
/// such as GKE/AWS/GCE. If the exporter is running on a different environment,
/// monitored resource will be identified as "general".
/// </summary>
public MonitoredResource MonitoredResource { get; set; }
}
}
}

View File

@ -1,4 +1,4 @@
// <copyright file="ICountData.cs" company="OpenTelemetry Authors">
// <copyright file="StackdriverStatsExporter.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -16,6 +16,13 @@
namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Google.Api;
using Google.Api.Gax;
using Google.Api.Gax.Grpc;
@ -25,13 +32,6 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
using Grpc.Core;
using OpenTelemetry.Exporter.Stackdriver.Utils;
using OpenTelemetry.Stats;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
internal class StackdriverStatsExporter
{
@ -45,31 +45,48 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
private MetricServiceClient metricServiceClient;
private CancellationTokenSource tokenSource;
private const int MAX_BATCH_EXPORT_SIZE = 200;
private static readonly string DEFAULT_DISPLAY_NAME_PREFIX = "OpenTelemetry/";
private static readonly string CUSTOM_METRIC_DOMAIN = "custom.googleapis.com/";
private static readonly string CUSTOM_OpenTelemetry_DOMAIN = CUSTOM_METRIC_DOMAIN + "OpenTelemetry/";
#pragma warning disable SA1203 // Sensible grouping is more important than ordering by accessability
#pragma warning disable SA1214 // Readonly fields should appear before non-readonly fields
private const int MaxBatchExportSize = 200;
private static readonly string DefaultDisplayNamePrefix = "OpenTelemetry/";
private static readonly string CustomMetricsDomain = "custom.googleapis.com/";
private static readonly string CustomOpenTelemetryDomain = CustomMetricsDomain + "OpenTelemetry/";
private static readonly string USER_AGENT_KEY = "user-agent";
private static string USER_AGENT;
private static readonly string UserAgentKey = "user-agent";
private static readonly string UserAgent;
private readonly string domain;
private readonly string displayNamePrefix;
private bool isStarted;
/// <summary>
/// Interval between two subsequent stats collection operations
/// </summary>
private TimeSpan collectionInterval = TimeSpan.FromMinutes(1);
/// <summary>
/// Interval between two subsequent stats collection operations.
/// </summary>
private readonly TimeSpan collectionInterval = TimeSpan.FromMinutes(1);
/// <summary>
/// Interval within which the cancellation should be honored
/// from the point it was requested
/// from the point it was requested.
/// </summary>
private readonly TimeSpan cancellationInterval = TimeSpan.FromSeconds(3);
private object locker = new object();
private readonly object locker = new object();
#pragma warning restore SA1203 // Constants should appear before fields
#pragma warning restore SA1214 // Sensible grouping is more important than ordering by accessability
static StackdriverStatsExporter()
{
try
{
var assemblyPackageVersion = typeof(StackdriverStatsExporter).GetTypeInfo().Assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>().First().InformationalVersion;
UserAgent = $"OpenTelemetry-dotnet/{assemblyPackageVersion}";
}
catch (Exception)
{
UserAgent = $"OpenTelemetry-dotnet/{Constants.PackagVersionUndefined}";
}
}
public StackdriverStatsExporter(
IViewManager viewManager,
@ -84,89 +101,127 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
message: "Export interval can't be zero. Typically it's 1 minute");
this.viewManager = viewManager;
monitoredResource = configuration.MonitoredResource;
collectionInterval = configuration.ExportInterval;
project = new ProjectName(configuration.ProjectId);
credential = configuration.GoogleCredential;
this.monitoredResource = configuration.MonitoredResource;
this.collectionInterval = configuration.ExportInterval;
this.project = new ProjectName(configuration.ProjectId);
this.credential = configuration.GoogleCredential;
domain = GetDomain(configuration.MetricNamePrefix);
displayNamePrefix = GetDisplayNamePrefix(configuration.MetricNamePrefix);
}
static StackdriverStatsExporter()
{
try
{
var assemblyPackageVersion = typeof(StackdriverStatsExporter).GetTypeInfo().Assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>().First().InformationalVersion;
USER_AGENT = $"OpenTelemetry-dotnet/{assemblyPackageVersion}";
}
catch (Exception)
{
USER_AGENT = $"OpenTelemetry-dotnet/{Constants.PACKAGE_VERSION_UNDEFINED}";
}
this.domain = GetDomain(configuration.MetricNamePrefix);
this.displayNamePrefix = this.GetDisplayNamePrefix(configuration.MetricNamePrefix);
}
public void Start()
{
lock (locker)
lock (this.locker)
{
if (!isStarted)
if (!this.isStarted)
{
tokenSource = new CancellationTokenSource();
metricServiceClient = CreateMetricServiceClient(credential, tokenSource);
this.tokenSource = new CancellationTokenSource();
this.metricServiceClient = CreateMetricServiceClient(this.credential, this.tokenSource);
Task.Factory.StartNew(DoWork, tokenSource.Token);
Task.Factory.StartNew(this.DoWork, this.tokenSource.Token);
isStarted = true;
this.isStarted = true;
}
}
}
public void Stop()
{
lock (locker)
lock (this.locker)
{
if (!isStarted)
if (!this.isStarted)
{
return;
}
tokenSource.Cancel();
this.tokenSource.Cancel();
}
}
private static MetricServiceClient CreateMetricServiceClient(GoogleCredential credential, CancellationTokenSource tokenSource)
{
// Make sure to add OpenTelemetry header to every outgoing call to Stackdriver APIs
Action<Metadata> addOpenTelemetryHeader = m => m.Add(UserAgentKey, UserAgent);
var callSettings = new CallSettings(
cancellationToken: tokenSource.Token,
credentials: null,
timing: null,
headerMutation: addOpenTelemetryHeader,
writeOptions: WriteOptions.Default,
propagationToken: null);
var channel = new Channel(
MetricServiceClient.DefaultEndpoint.ToString(),
credential.ToChannelCredentials());
var metricServiceSettings = new MetricServiceSettings()
{
CallSettings = callSettings,
};
return MetricServiceClient.Create(channel, settings: metricServiceSettings);
}
private static string GetDomain(string metricNamePrefix)
{
string domain;
if (string.IsNullOrEmpty(metricNamePrefix))
{
domain = CustomOpenTelemetryDomain;
}
else
{
if (!metricNamePrefix.EndsWith("/"))
{
domain = metricNamePrefix + '/';
}
else
{
domain = metricNamePrefix;
}
}
return domain;
}
private static string GenerateMetricDescriptorTypeName(IViewName viewName, string domain)
{
return domain + viewName.AsString;
}
/// <summary>
/// Periodic operation happening on a dedicated thread that is
/// capturing the metrics collected within a collection interval
/// capturing the metrics collected within a collection interval.
/// </summary>
private void DoWork()
{
try
{
var sleepTime = collectionInterval;
var sleepTime = this.collectionInterval;
var stopWatch = new Stopwatch();
while (!tokenSource.IsCancellationRequested)
while (!this.tokenSource.IsCancellationRequested)
{
// Calculate the duration of collection iteration
stopWatch.Start();
// Collect metrics
Export();
this.Export();
stopWatch.Stop();
// Adjust the wait time - reduce export operation duration
sleepTime = collectionInterval.Subtract(stopWatch.Elapsed);
sleepTime = this.collectionInterval.Subtract(stopWatch.Elapsed);
sleepTime = sleepTime.Duration();
// If the cancellation was requested, we should honor
// that within the cancellation interval, so we wait in
// intervals of <cancellationInterval>
while (sleepTime > cancellationInterval && !tokenSource.IsCancellationRequested)
while (sleepTime > this.cancellationInterval && !this.tokenSource.IsCancellationRequested)
{
Thread.Sleep(cancellationInterval);
sleepTime = sleepTime.Subtract(cancellationInterval);
Thread.Sleep(this.cancellationInterval);
sleepTime = sleepTime.Subtract(this.cancellationInterval);
}
Thread.Sleep(sleepTime);
@ -181,14 +236,15 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
private bool RegisterView(IView view)
{
IView existing = null;
if (registeredViews.TryGetValue(view.Name, out existing))
if (this.registeredViews.TryGetValue(view.Name, out existing))
{
// Ignore views that are already registered.
return existing.Equals(view);
}
registeredViews.Add(view.Name, view);
var metricDescriptorTypeName = GenerateMetricDescriptorTypeName(view.Name, domain);
this.registeredViews.Add(view.Name, view);
var metricDescriptorTypeName = GenerateMetricDescriptorTypeName(view.Name, this.domain);
// TODO - zeltser: don't need to create MetricDescriptor for RpcViewConstants once we defined
// canonical metrics. Registration is required only for custom view definitions. Canonical
@ -196,9 +252,9 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
var metricDescriptor = MetricsConversions.CreateMetricDescriptor(
metricDescriptorTypeName,
view,
project,
domain,
displayNamePrefix);
this.project,
this.domain,
this.displayNamePrefix);
if (metricDescriptor == null)
{
@ -207,11 +263,12 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
}
// Cache metric descriptor and ensure it exists in Stackdriver
if (!metricDescriptors.ContainsKey(view))
if (!this.metricDescriptors.ContainsKey(view))
{
metricDescriptors.Add(view, metricDescriptor);
this.metricDescriptors.Add(view, metricDescriptor);
}
return EnsureMetricDescriptorExists(metricDescriptor);
return this.EnsureMetricDescriptorExists(metricDescriptor);
}
private bool EnsureMetricDescriptorExists(MetricDescriptor metricDescriptor)
@ -219,9 +276,9 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
try
{
var request = new CreateMetricDescriptorRequest();
request.ProjectName = project;
request.ProjectName = this.project;
request.MetricDescriptor = metricDescriptor;
metricServiceClient.CreateMetricDescriptor(request);
this.metricServiceClient.CreateMetricDescriptor(request);
}
catch (RpcException e)
{
@ -240,11 +297,11 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
private void Export()
{
var viewDataList = new List<IViewData>();
foreach (var view in viewManager.AllExportedViews)
foreach (var view in this.viewManager.AllExportedViews)
{
if (RegisterView(view))
if (this.RegisterView(view))
{
var data = viewManager.GetView(view.Name);
var data = this.viewManager.GetView(view.Name);
viewDataList.Add(data);
}
}
@ -253,21 +310,21 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
var timeSeriesList = new List<TimeSeries>();
foreach (var viewData in viewDataList)
{
var metricDescriptor = metricDescriptors[viewData.View];
var timeSeries = MetricsConversions.CreateTimeSeriesList(viewData, monitoredResource, metricDescriptor, domain);
var metricDescriptor = this.metricDescriptors[viewData.View];
var timeSeries = MetricsConversions.CreateTimeSeriesList(viewData, this.monitoredResource, metricDescriptor, this.domain);
timeSeriesList.AddRange(timeSeries);
}
// Perform the operation in batches of MAX_BATCH_EXPORT_SIZE
foreach (var batchedTimeSeries in timeSeriesList.Partition(MAX_BATCH_EXPORT_SIZE))
foreach (var batchedTimeSeries in timeSeriesList.Partition(MaxBatchExportSize))
{
var request = new CreateTimeSeriesRequest();
request.ProjectName = project;
request.ProjectName = this.project;
request.TimeSeries.AddRange(batchedTimeSeries);
try
{
metricServiceClient.CreateTimeSeries(request);
this.metricServiceClient.CreateTimeSeries(request);
}
catch (RpcException e)
{
@ -276,56 +333,11 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
}
}
private static MetricServiceClient CreateMetricServiceClient(GoogleCredential credential, CancellationTokenSource tokenSource)
{
// Make sure to add OpenTelemetry header to every outgoing call to Stackdriver APIs
Action<Metadata> addOpenTelemetryHeader = m => m.Add(USER_AGENT_KEY, USER_AGENT);
var callSettings = new CallSettings(
cancellationToken: tokenSource.Token,
credentials: null,
timing: null,
headerMutation: addOpenTelemetryHeader,
writeOptions: WriteOptions.Default,
propagationToken: null);
var channel = new Channel(
MetricServiceClient.DefaultEndpoint.ToString(),
credential.ToChannelCredentials());
var metricServiceSettings = new MetricServiceSettings()
{
CallSettings = callSettings
};
return MetricServiceClient.Create(channel, settings: metricServiceSettings);
}
private static string GetDomain(string metricNamePrefix)
{
string domain;
if (string.IsNullOrEmpty(metricNamePrefix))
{
domain = CUSTOM_OpenTelemetry_DOMAIN;
}
else
{
if (!metricNamePrefix.EndsWith("/"))
{
domain = metricNamePrefix + '/';
}
else
{
domain = metricNamePrefix;
}
}
return domain;
}
private string GetDisplayNamePrefix(string metricNamePrefix)
{
if (metricNamePrefix == null)
{
return DEFAULT_DISPLAY_NAME_PREFIX;
return DefaultDisplayNamePrefix;
}
else
{
@ -333,30 +345,34 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
metricNamePrefix += '/';
}
return metricNamePrefix;
}
}
private static string GenerateMetricDescriptorTypeName(IViewName viewName, string domain)
{
return domain + viewName.AsString;
}
/// <summary>
/// Comparison between two OpenTelemetry Views
/// Comparison between two OpenTelemetry Views.
/// </summary>
private class ViewNameComparer : IEqualityComparer<IView>
{
public bool Equals(IView x, IView y)
{
if (x == null && y == null)
{
return true;
}
else if (x == null || y == null)
{
return false;
}
else if (x.Name.AsString.Equals(y.Name.AsString))
{
return true;
}
else
{
return false;
}
}
public int GetHashCode(IView obj)

View File

@ -1,4 +1,4 @@
// <copyright file="ApplicationInsightsExporter.cs" company="OpenTelemetry Authors">
// <copyright file="StackdriverTraceExporter.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -28,165 +28,71 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Export;
static class SpanExtensions
{
/// <summary>
/// Translating <see cref="SpanData"/> to Stackdriver's Span
/// According to <see href="https://cloud.google.com/trace/docs/reference/v2/rpc/google.devtools.cloudtrace.v2"/> specifications
/// </summary>
/// <param name="spanData">Span in OpenTelemetry format</param>
/// <param name="projectId">Google Cloud Platform Project Id</param>
/// <returns></returns>
public static Google.Cloud.Trace.V2.Span ToSpan(this SpanData spanData, string projectId)
{
var spanId = spanData.Context.SpanId.ToLowerBase16();
// Base span settings
var span = new Google.Cloud.Trace.V2.Span
{
SpanName = new SpanName(projectId, spanData.Context.TraceId.ToLowerBase16(), spanId),
SpanId = spanId,
DisplayName = new TruncatableString { Value = spanData.Name },
StartTime = spanData.StartTimestamp.ToTimestamp(),
EndTime = spanData.EndTimestamp.ToTimestamp(),
ChildSpanCount = spanData.ChildSpanCount,
};
if (spanData.ParentSpanId != null)
{
var parentSpanId = spanData.ParentSpanId.ToLowerBase16();
if (!string.IsNullOrEmpty(parentSpanId))
{
span.ParentSpanId = parentSpanId;
}
}
// Span Links
if (spanData.Links != null)
{
span.Links = new Google.Cloud.Trace.V2.Span.Types.Links
{
DroppedLinksCount = spanData.Links.DroppedLinksCount,
Link = { spanData.Links.Links.Select(l => l.ToLink()) }
};
}
// Span Attributes
if (spanData.Attributes != null)
{
span.Attributes = new Google.Cloud.Trace.V2.Span.Types.Attributes
{
DroppedAttributesCount = spanData.Attributes != null ? spanData.Attributes.DroppedAttributesCount : 0,
AttributeMap = { spanData.Attributes?.AttributeMap?.ToDictionary(
s => s.Key,
s => s.Value?.ToAttributeValue()) },
};
}
return span;
}
public static Google.Cloud.Trace.V2.Span.Types.Link ToLink(this ILink link)
{
var ret = new Google.Cloud.Trace.V2.Span.Types.Link();
ret.SpanId = link.Context.SpanId.ToLowerBase16();
ret.TraceId = link.Context.TraceId.ToLowerBase16();
if (link.Attributes != null)
{
ret.Attributes = new Google.Cloud.Trace.V2.Span.Types.Attributes
{
DroppedAttributesCount = OpenTelemetry.Trace.Config.TraceParams.Default.MaxNumberOfAttributes - link.Attributes.Count,
AttributeMap = { link.Attributes.ToDictionary(
att => att.Key,
att => att.Value.ToAttributeValue()) }
};
}
return ret;
}
public static Google.Cloud.Trace.V2.AttributeValue ToAttributeValue(this IAttributeValue av)
{
var ret = av.Match(
(s) => new Google.Cloud.Trace.V2.AttributeValue() { StringValue = new TruncatableString() { Value = s } },
(b) => new Google.Cloud.Trace.V2.AttributeValue() { BoolValue = b },
(l) => new Google.Cloud.Trace.V2.AttributeValue() { IntValue = l },
(d) => new Google.Cloud.Trace.V2.AttributeValue() { StringValue = new TruncatableString() { Value = d.ToString() } },
(obj) => new Google.Cloud.Trace.V2.AttributeValue() { StringValue = new TruncatableString() { Value = obj.ToString() } });
return ret;
}
}
/// <summary>
/// Exports a group of spans to Stackdriver
/// Exports a group of spans to Stackdriver.
/// </summary>
internal class StackdriverTraceExporter : IHandler
{
private static string STACKDRIVER_EXPORTER_VERSION;
private static string OpenTelemetry_EXPORTER_VERSION;
private static readonly string StackdriverExportVersion;
private static readonly string OpenTelemetryExporterVersion;
private readonly Google.Api.Gax.ResourceNames.ProjectName googleCloudProjectId;
private readonly TraceServiceSettings traceServiceSettings;
public StackdriverTraceExporter(string projectId)
{
googleCloudProjectId = new Google.Api.Gax.ResourceNames.ProjectName(projectId);
// Set header mutation for every outgoing API call to Stackdriver so the BE knows
// which version of OC client is calling it as well as which version of the exporter
var callSettings = CallSettings.FromHeaderMutation(StackdriverCallHeaderAppender);
traceServiceSettings = new TraceServiceSettings();
traceServiceSettings.CallSettings = callSettings;
}
static StackdriverTraceExporter()
{
try
{
var assemblyPackageVersion = typeof(StackdriverTraceExporter).GetTypeInfo().Assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>().First().InformationalVersion;
STACKDRIVER_EXPORTER_VERSION = assemblyPackageVersion;
StackdriverExportVersion = assemblyPackageVersion;
}
catch (Exception)
{
STACKDRIVER_EXPORTER_VERSION = $"{Constants.PACKAGE_VERSION_UNDEFINED}";
StackdriverExportVersion = $"{Constants.PackagVersionUndefined}";
}
try
{
OpenTelemetry_EXPORTER_VERSION = Assembly.GetCallingAssembly().GetName().Version.ToString();
OpenTelemetryExporterVersion = Assembly.GetCallingAssembly().GetName().Version.ToString();
}
catch (Exception)
{
OpenTelemetry_EXPORTER_VERSION = $"{Constants.PACKAGE_VERSION_UNDEFINED}";
OpenTelemetryExporterVersion = $"{Constants.PackagVersionUndefined}";
}
}
public StackdriverTraceExporter(string projectId)
{
this.googleCloudProjectId = new Google.Api.Gax.ResourceNames.ProjectName(projectId);
// Set header mutation for every outgoing API call to Stackdriver so the BE knows
// which version of OC client is calling it as well as which version of the exporter
var callSettings = CallSettings.FromHeaderMutation(StackdriverCallHeaderAppender);
this.traceServiceSettings = new TraceServiceSettings();
this.traceServiceSettings.CallSettings = callSettings;
}
public async Task ExportAsync(IEnumerable<SpanData> spanDataList)
{
var traceWriter = TraceServiceClient.Create(settings: traceServiceSettings);
var traceWriter = TraceServiceClient.Create(settings: this.traceServiceSettings);
var batchSpansRequest = new BatchWriteSpansRequest
{
ProjectName = googleCloudProjectId,
Spans = { spanDataList.Select(s => s.ToSpan(googleCloudProjectId.ProjectId)) },
ProjectName = this.googleCloudProjectId,
Spans = { spanDataList.Select(s => s.ToSpan(this.googleCloudProjectId.ProjectId)) },
};
await traceWriter.BatchWriteSpansAsync(batchSpansRequest);
}
/// <summary>
/// Appends OpenTelemetry headers for every outgoing request to Stackdriver Backend
/// Appends OpenTelemetry headers for every outgoing request to Stackdriver Backend.
/// </summary>
/// <param name="metadata">The metadata that is sent with every outgoing http request</param>
/// <param name="metadata">The metadata that is sent with every outgoing http request.</param>
private static void StackdriverCallHeaderAppender(Metadata metadata)
{
metadata.Add("AGENT_LABEL_KEY", "g.co/agent");
metadata.Add("AGENT_LABEL_VALUE_STRING", $"{OpenTelemetry_EXPORTER_VERSION}; stackdriver-exporter {STACKDRIVER_EXPORTER_VERSION}");
metadata.Add("AGENT_LABEL_VALUE_STRING", $"{OpenTelemetryExporterVersion}; stackdriver-exporter {StackdriverExportVersion}");
}
}
}

View File

@ -1,5 +1,4 @@

// <copyright file="StackdriverExporter.cs" company="OpenTelemetry Authors">
// <copyright file="StackdriverExporter.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -25,7 +24,7 @@ namespace OpenTelemetry.Exporter.Stackdriver
using OpenTelemetry.Trace.Export;
/// <summary>
/// Implementation of the exporter to Stackdriver
/// Implementation of the exporter to Stackdriver.
/// </summary>
public class StackdriverExporter
{
@ -35,16 +34,16 @@ namespace OpenTelemetry.Exporter.Stackdriver
private readonly IViewManager viewManager;
private readonly string projectId;
private readonly string jsonPath;
private readonly object locker = new object();
private StackdriverStatsExporter statsExporter;
private object locker = new object();
private bool isInitialized = false;
/// <summary>
/// Initializes a new instance of the <see cref="StackdriverExporter"/> class.
/// </summary>
/// <param name="projectId">Google Cloud ProjectId that is used to send data to Stackdriver</param>
/// <param name="exportComponent">Exporter to get traces from</param>
/// <param name="viewManager">View manager to get the stats from</param>
/// <param name="projectId">Google Cloud ProjectId that is used to send data to Stackdriver.</param>
/// <param name="exportComponent">Exporter to get traces from.</param>
/// <param name="viewManager">View manager to get the stats from.</param>
public StackdriverExporter(
string projectId,
IExportComponent exportComponent,
@ -55,10 +54,10 @@ namespace OpenTelemetry.Exporter.Stackdriver
/// <summary>
/// Initializes a new instance of the <see cref="StackdriverExporter"/> class.
/// </summary>
/// <param name="projectId">Google Cloud ProjectId that is used to send data to Stackdriver</param>
/// <param name="jsonPath">File path to the json file containing the service credential used to authenticate against Stackdriver APIs</param>
/// <param name="exportComponent">Exporter to get traces from</param>
/// <param name="viewManager">View manager to get the stats from</param>
/// <param name="projectId">Google Cloud ProjectId that is used to send data to Stackdriver.</param>
/// <param name="jsonPath">File path to the json file containing the service credential used to authenticate against Stackdriver APIs.</param>
/// <param name="exportComponent">Exporter to get traces from.</param>
/// <param name="viewManager">View manager to get the stats from.</param>
public StackdriverExporter(
string projectId,
string jsonPath,
@ -74,87 +73,87 @@ namespace OpenTelemetry.Exporter.Stackdriver
}
/// <summary>
/// Starts the exporter
/// Starts the exporter.
/// </summary>
public void Start()
{
lock (locker)
lock (this.locker)
{
if (isInitialized)
if (this.isInitialized)
{
return;
}
// Register trace exporter
if (exportComponent != null)
if (this.exportComponent != null)
{
var traceExporter = new StackdriverTraceExporter(projectId);
exportComponent.SpanExporter.RegisterHandler(ExporterName, traceExporter);
var traceExporter = new StackdriverTraceExporter(this.projectId);
this.exportComponent.SpanExporter.RegisterHandler(ExporterName, traceExporter);
}
// Register stats(metrics) exporter
if (viewManager != null)
if (this.viewManager != null)
{
var credential = GetGoogleCredential();
var credential = this.GetGoogleCredential();
var statsConfig = StackdriverStatsConfiguration.Default;
statsConfig.GoogleCredential = credential;
if (statsConfig.ProjectId != projectId)
if (statsConfig.ProjectId != this.projectId)
{
statsConfig.ProjectId = projectId;
statsConfig.MonitoredResource = GoogleCloudResourceUtils.GetDefaultResource(projectId);
statsConfig.ProjectId = this.projectId;
statsConfig.MonitoredResource = GoogleCloudResourceUtils.GetDefaultResource(this.projectId);
}
statsExporter = new StackdriverStatsExporter(viewManager, statsConfig);
statsExporter.Start();
this.statsExporter = new StackdriverStatsExporter(this.viewManager, statsConfig);
this.statsExporter.Start();
}
isInitialized = true;
this.isInitialized = true;
}
}
/// <summary>
/// Stops the exporter
/// Stops the exporter.
/// </summary>
public void Stop()
{
lock (locker)
lock (this.locker)
{
if (!isInitialized)
if (!this.isInitialized)
{
return;
}
// Stop tracing exporter
if (exportComponent != null)
if (this.exportComponent != null)
{
exportComponent.SpanExporter.UnregisterHandler(ExporterName);
this.exportComponent.SpanExporter.UnregisterHandler(ExporterName);
}
// Stop metrics exporter
if (statsExporter != null)
if (this.statsExporter != null)
{
statsExporter.Stop();
this.statsExporter.Stop();
}
isInitialized = false;
this.isInitialized = false;
}
}
private GoogleCredential GetGoogleCredential()
{
GoogleCredential credential;
if (string.IsNullOrEmpty(jsonPath))
if (string.IsNullOrEmpty(this.jsonPath))
{
credential = GoogleCredential.GetApplicationDefault();
}
else
{
credential = GoogleCredential.FromFile(jsonPath)
credential = GoogleCredential.FromFile(this.jsonPath)
.CreateScoped(MetricServiceClient.DefaultScopes);
}
return credential;
}
}
}
}

View File

@ -1,4 +1,4 @@
// <copyright file="ApplicationInsightsExporter.cs" company="OpenTelemetry Authors">
// <copyright file="CommonUtils.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -16,22 +16,20 @@
namespace OpenTelemetry.Exporter.Stackdriver.Utils
{
using System;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// Common Utility Methods that are not metrics/trace specific
/// Common Utility Methods that are not metrics/trace specific.
/// </summary>
public static class CommonUtils
{
/// <summary>
/// Divide the source list into batches of lists of given size.
/// </summary>
/// <typeparam name="T">The type of the list</typeparam>
/// <param name="source">The list</param>
/// <param name="size">Size of the batch</param>
/// <returns></returns>
/// <typeparam name="T">The type of the list.</typeparam>
/// <param name="source">The list.</param>
/// <param name="size">Size of the batch.</param>
/// <returns><see cref="IEnumerable{T}"/>.</returns>
public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> source, int size)
{
using (var enumerator = source.GetEnumerator())

View File

@ -1,4 +1,4 @@
// <copyright file="ApplicationInsightsExporter.cs" company="OpenTelemetry Authors">
// <copyright file="ProtoExtensions.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -20,15 +20,15 @@ namespace OpenTelemetry.Exporter.Stackdriver.Utils
/// <summary>
/// Translation methods from OpenTelemetry structures to common
/// Protobuf structures
/// Protobuf structures.
/// </summary>
public static class ProtoExtensions
{
/// <summary>
/// Translates OpenTelemetry Timestamp to Protobuf's timestamp
/// Translates OpenTelemetry Timestamp to Protobuf's timestamp.
/// </summary>
/// <param name="timestamp">OpenTelemetry timestamp</param>
/// <returns>Protobuf's timestamp</returns>
/// <param name="timestamp">OpenTelemetry timestamp.</param>
/// <returns>Protobuf's timestamp.</returns>
public static Google.Protobuf.WellKnownTypes.Timestamp ToTimestamp(this Timestamp timestamp)
{
return new Google.Protobuf.WellKnownTypes.Timestamp { Seconds = timestamp.Seconds, Nanos = timestamp.Nanos };

View File

@ -13,7 +13,4 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System.Runtime.CompilerServices;
[assembly: System.CLSCompliant(true)]

View File

@ -21,10 +21,14 @@ namespace OpenTelemetry.Internal
public static class VarInt
{
/** Maximum encoded size of 32-bit positive integers (in bytes) */
/// <summary>
/// Maximum encoded size of 32-bit positive integers (in bytes).
/// </summary>
public const int MaxVarintSize = 5;
/** maximum encoded size of 64-bit longs, and negative 32-bit ints (in bytes) */
/// <summary>
/// maximum encoded size of 64-bit longs, and negative 32-bit ints (in bytes).
/// </summary>
public const int MaxVarlongSize = 10;
public static int VarIntSize(int i)
@ -63,6 +67,13 @@ namespace OpenTelemetry.Internal
return offset;
}
/// <summary>
/// Writes an into into an array at a specific offset.
/// </summary>
/// <param name="v">The value to write.</param>
/// <param name="sink">The array to write to.</param>
/// <param name="offset">The offset at which to place the value.</param>
/// <returns>The offset.</returns>
public static int PutVarInt(int v, byte[] sink, int offset)
{
var uv = (uint)v;
@ -78,69 +89,11 @@ namespace OpenTelemetry.Internal
return offset;
}
// public static int getVarInt(ByteBuffer src)
// {
// int tmp;
// if ((tmp = src.get()) >= 0)
// {
// return tmp;
// }
// int result = tmp & 0x7f;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 7;
// }
// else
// {
// result |= (tmp & 0x7f) << 7;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 14;
// }
// else
// {
// result |= (tmp & 0x7f) << 14;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 21;
// }
// else
// {
// result |= (tmp & 0x7f) << 21;
// result |= (tmp = src.get()) << 28;
// while (tmp < 0)
// {
// // We get into this loop only in the case of overflow.
// // By doing this, we can call getVarInt() instead of
// // getVarLong() when we only need an int.
// tmp = src.get();
// }
// }
// }
// }
// return result;
// }
// public static void putVarInt(int v, ByteBuffer sink)
// {
// while (true)
// {
// int bits = v & 0x7f;
// v >>>= 7;
// if (v == 0)
// {
// sink.put((byte)bits);
// return;
// }
// sink.put((byte)(bits | 0x80));
// }
// }
/**
* Reads a varint from the given InputStream and returns the decoded value as an int.
*
* @param inputStream the InputStream to read from
*/
/// <summary>
/// Gets an integer from a stream.
/// </summary>
/// <param name="inputStream">The stream to read from.</param>
/// <returns>The int.</returns>
public static int GetVarInt(Stream inputStream)
{
var result = 0;
@ -163,115 +116,16 @@ namespace OpenTelemetry.Internal
return result;
}
/// <summary>
/// Writes an integer to a stream.
/// </summary>
/// <param name="v">The value.</param>
/// <param name="outputStream">The stream to write to.</param>
public static void PutVarInt(int v, Stream outputStream)
{
var bytes = new byte[VarIntSize(v)];
PutVarInt(v, bytes, 0);
outputStream.Write(bytes, 0, bytes.Length);
}
public static int VarLongSize(long v)
{
var result = 0;
var uv = (ulong)v;
do
{
result++;
uv >>= 7;
}
while (uv != 0);
return result;
}
// public static long GetVarLong(ByteBuffer src)
// {
// long tmp;
// if ((tmp = src.get()) >= 0)
// {
// return tmp;
// }
// long result = tmp & 0x7f;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 7;
// }
// else
// {
// result |= (tmp & 0x7f) << 7;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 14;
// }
// else
// {
// result |= (tmp & 0x7f) << 14;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 21;
// }
// else
// {
// result |= (tmp & 0x7f) << 21;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 28;
// }
// else
// {
// result |= (tmp & 0x7f) << 28;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 35;
// }
// else
// {
// result |= (tmp & 0x7f) << 35;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 42;
// }
// else
// {
// result |= (tmp & 0x7f) << 42;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 49;
// }
// else
// {
// result |= (tmp & 0x7f) << 49;
// if ((tmp = src.get()) >= 0)
// {
// result |= tmp << 56;
// }
// else
// {
// result |= (tmp & 0x7f) << 56;
// result |= ((long)src.get()) << 63;
// }
// }
// }
// }
// }
// }
// }
// }
// return result;
// }
// public static void PutVarLong(long v, ByteBuffer sink)
// {
// while (true)
// {
// int bits = ((int)v) & 0x7f;
// v >>>= 7;
// if (v == 0)
// {
// sink.put((byte)bits);
// return;
// }
// sink.put((byte)(bits | 0x80));
// }
// }
}
}

View File

@ -64,7 +64,10 @@ namespace OpenTelemetry.Stats
}
}
/** Enable stats collection for the given {@link View}. */
/// <summary>
/// Enable stats collection for the given <see cref="IView"/>.
/// </summary>
/// <param name="view">The view.</param>
internal void RegisterView(IView view)
{
lock (this.lck)

View File

@ -192,24 +192,43 @@ namespace OpenTelemetry.Stats
return new CumulativeMutableViewData(view, start);
}
/** Record double stats with the given tags. */
/// <summary>
/// Record double stats with the given tags.
/// </summary>
/// <param name="context">The <see cref="ITagContext"/>.</param>
/// <param name="value">The value.</param>
/// <param name="timestamp">The time of recording.</param>
internal abstract void Record(ITagContext context, double value, DateTimeOffset timestamp);
/** Record long stats with the given tags. */
internal void Record(ITagContext tags, long value, DateTimeOffset timestamp)
/// <summary>
/// Record long stats with the given tags.
/// </summary>
/// <param name="tagContext">The <see cref="ITagContext"/>.</param>
/// <param name="value">The value.</param>
/// <param name="timestamp">The time of recording.</param>
internal void Record(ITagContext tagContext, long value, DateTimeOffset timestamp)
{
// TODO(songya): shall we check for precision loss here?
this.Record(tags, (double)value, timestamp);
this.Record(tagContext, (double)value, timestamp);
}
/** Convert this {@link MutableViewData} to {@link ViewData}. */
/// <summary>
/// Convert this <see cref="MutableViewData"/> to <see cref="ViewData"/>.
/// </summary>
/// <param name="now">The current time.</param>
/// <param name="state">The stats' collection state.</param>
internal abstract IViewData ToViewData(DateTimeOffset now, StatsCollectionState state);
// Clear recorded stats.
/// <summary>
/// Clear recorded stats.
/// </summary>
internal abstract void ClearStats();
// Resume stats collection, and reset Start Timestamp (for CumulativeMutableViewData), or refresh
// bucket list (for InternalMutableViewData).
/// <summary>
/// Resume stats collection, and reset Start Timestamp (for CumulativeMutableViewData), or refresh
/// bucket list (for InternalMutableViewData).
/// </summary>
/// <param name="now">The current time.</param>
internal abstract void ResumeStatsCollection(DateTimeOffset now);
}
}

View File

@ -18,9 +18,9 @@ namespace OpenTelemetry.Stats
{
public class Stats
{
private static Stats stats = new Stats();
private static readonly Stats StatsValue = new Stats();
private IStatsComponent statsComponent = new StatsComponent();
private readonly IStatsComponent statsComponent = new StatsComponent();
internal Stats()
: this(true)
@ -43,7 +43,7 @@ namespace OpenTelemetry.Stats
{
get
{
return stats.statsComponent.StatsRecorder;
return StatsValue.statsComponent.StatsRecorder;
}
}
@ -51,7 +51,7 @@ namespace OpenTelemetry.Stats
{
get
{
return stats.statsComponent.ViewManager;
return StatsValue.statsComponent.ViewManager;
}
}
@ -59,7 +59,7 @@ namespace OpenTelemetry.Stats
{
get
{
return stats.statsComponent.State;
return StatsValue.statsComponent.State;
}
}
}

View File

@ -23,29 +23,29 @@ namespace OpenTelemetry.Tags.Unsafe
{
private static readonly ITagContext EmptyTagContextInstance = new EmptyTagContext();
private static AsyncLocal<ITagContext> context = new AsyncLocal<ITagContext>();
private static readonly AsyncLocal<ITagContext> Context = new AsyncLocal<ITagContext>();
public static ITagContext CurrentTagContext
{
get
{
if (context.Value == null)
if (Context.Value == null)
{
return EmptyTagContextInstance;
}
return context.Value;
return Context.Value;
}
set
{
if (value == EmptyTagContextInstance)
{
context.Value = null;
Context.Value = null;
}
else
{
context.Value = value;
Context.Value = value;
}
}
}

View File

@ -21,13 +21,13 @@ namespace OpenTelemetry.Trace
internal static class CurrentSpanUtils
{
private static AsyncLocal<ISpan> asyncLocalContext = new AsyncLocal<ISpan>();
private static readonly AsyncLocal<ISpan> AsyncLocalContext = new AsyncLocal<ISpan>();
public static ISpan CurrentSpan
{
get
{
return asyncLocalContext.Value;
return AsyncLocalContext.Value;
}
}
@ -46,14 +46,14 @@ namespace OpenTelemetry.Trace
{
this.span = span;
this.endSpan = endSpan;
this.origContext = asyncLocalContext.Value;
asyncLocalContext.Value = span;
this.origContext = AsyncLocalContext.Value;
AsyncLocalContext.Value = span;
}
public void Dispose()
{
var current = asyncLocalContext.Value;
asyncLocalContext.Value = this.origContext;
var current = AsyncLocalContext.Value;
AsyncLocalContext.Value = this.origContext;
if (current != this.origContext)
{

View File

@ -16,7 +16,6 @@
namespace OpenTelemetry.Trace.Export
{
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

View File

@ -16,7 +16,6 @@
namespace OpenTelemetry.Trace.Export
{
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using OpenTelemetry.Common;
@ -54,9 +53,7 @@ namespace OpenTelemetry.Trace.Export
/// <inheritdoc/>
public override Task ExportAsync(SpanData export, CancellationToken token)
{
this.worker.ExportAsync(export, token);
return Task.CompletedTask;
return this.worker.ExportAsync(export, token);
}
public override void RegisterHandler(string name, IHandler handler)

View File

@ -16,7 +16,6 @@
namespace OpenTelemetry.Trace.Export
{
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

View File

@ -35,7 +35,7 @@ namespace OpenTelemetry.Trace.Export
(NumSamplesPerLatencySamples * NumLatencyBuckets)
+ (NumSamplesPerErrorSamples * NumErrorBuckets);
private static TimeSpan timeBetweenSamples = TimeSpan.FromSeconds(1);
private static readonly TimeSpan TimeBetweenSamples = TimeSpan.FromSeconds(1);
private readonly IEventQueue eventQueue;
private readonly Dictionary<string, PerSpanNameSamples> samples;
@ -245,7 +245,7 @@ namespace OpenTelemetry.Trace.Export
// Need to compare by doing the subtraction all the time because in case of an overflow,
// this may never sample again (at least for the next ~200 years). No real chance to
// overflow two times because that means the process runs for ~200 years.
if (spanEndTime - this.lastSampledTime > timeBetweenSamples)
if (spanEndTime - this.lastSampledTime > TimeBetweenSamples)
{
this.sampledSpansQueue.Add(span);
this.lastSampledTime = spanEndTime;
@ -256,7 +256,7 @@ namespace OpenTelemetry.Trace.Export
// Need to compare by doing the subtraction all the time because in case of an overflow,
// this may never sample again (at least for the next ~200 years). No real chance to
// overflow two times because that means the process runs for ~200 years.
if (spanEndTime - this.lastNotSampledTime > timeBetweenSamples)
if (spanEndTime - this.lastNotSampledTime > TimeBetweenSamples)
{
this.notSampledSpansQueue.Add(span);
this.lastNotSampledTime = spanEndTime;

View File

@ -18,7 +18,6 @@ namespace OpenTelemetry.Trace.Internal
{
using System;
using System.Collections.Generic;
using OpenTelemetry.Trace.Export;
internal sealed class BlankSpan : SpanBase
{

View File

@ -38,6 +38,7 @@ namespace OpenTelemetry.Trace.Internal
/// You might get the same values if a random is accessed from different threads.
/// Use only for unit tests...
/// </summary>
/// <param name="seed">The seeds value for the rng.</param>
internal RandomGenerator(int seed)
{
this.sameSeed = true;

View File

@ -23,8 +23,8 @@ namespace OpenTelemetry.Trace
/// </summary>
public sealed class NoopTracer : TracerBase, ITracer
{
private static IBinaryFormat binaryFormat = new BinaryFormat();
private static ITextFormat textFormat = new TraceContextFormat();
private static readonly IBinaryFormat BinaryFormatValue = new BinaryFormat();
private static readonly ITextFormat TextFormatValue = new TraceContextFormat();
internal NoopTracer()
{
@ -35,7 +35,7 @@ namespace OpenTelemetry.Trace
{
get
{
return binaryFormat;
return BinaryFormatValue;
}
}
@ -44,7 +44,7 @@ namespace OpenTelemetry.Trace
{
get
{
return textFormat;
return TextFormatValue;
}
}

View File

@ -40,6 +40,35 @@ namespace OpenTelemetry.Trace.Sampler
public long IdUpperBound { get; }
public static ProbabilitySampler Create(double probability)
{
if (probability < 0.0 || probability > 1.0)
{
throw new ArgumentOutOfRangeException("probability must be in range [0.0, 1.0]");
}
long idUpperBound;
// Special case the limits, to avoid any possible issues with lack of precision across
// double/long boundaries. For probability == 0.0, we use Long.MIN_VALUE as this guarantees
// that we will never sample a trace, even in the case where the id == Long.MIN_VALUE, since
// Math.Abs(Long.MIN_VALUE) == Long.MIN_VALUE.
if (probability == 0.0)
{
idUpperBound = long.MinValue;
}
else if (probability == 1.0)
{
idUpperBound = long.MaxValue;
}
else
{
idUpperBound = (long)(probability * long.MaxValue);
}
return new ProbabilitySampler(probability, idUpperBound);
}
public bool ShouldSample(SpanContext parentContext, TraceId traceId, SpanId spanId, string name, IEnumerable<ISpan> parentLinks)
{
// If the parent is sampled keep the sampling decision.
@ -79,7 +108,7 @@ namespace OpenTelemetry.Trace.Sampler
+ "}";
}
/// <inheritdoc/>
/// <inheritdoc/>
public override bool Equals(object o)
{
if (o == this)
@ -96,7 +125,7 @@ namespace OpenTelemetry.Trace.Sampler
return false;
}
/// <inheritdoc/>
/// <inheritdoc/>
public override int GetHashCode()
{
long h = 1;
@ -106,34 +135,5 @@ namespace OpenTelemetry.Trace.Sampler
h ^= (this.IdUpperBound >> 32) ^ this.IdUpperBound;
return (int)h;
}
public static ProbabilitySampler Create(double probability)
{
if (probability < 0.0 || probability > 1.0)
{
throw new ArgumentOutOfRangeException("probability must be in range [0.0, 1.0]");
}
long idUpperBound;
// Special case the limits, to avoid any possible issues with lack of precision across
// double/long boundaries. For probability == 0.0, we use Long.MIN_VALUE as this guarantees
// that we will never sample a trace, even in the case where the id == Long.MIN_VALUE, since
// Math.Abs(Long.MIN_VALUE) == Long.MIN_VALUE.
if (probability == 0.0)
{
idUpperBound = long.MinValue;
}
else if (probability == 1.0)
{
idUpperBound = long.MaxValue;
}
else
{
idUpperBound = (long)(probability * long.MaxValue);
}
return new ProbabilitySampler(probability, idUpperBound);
}
}
}

View File

@ -18,7 +18,6 @@ namespace OpenTelemetry.Trace
{
using System;
using System.Collections.Generic;
using OpenTelemetry.Trace.Export;
using OpenTelemetry.Utils;
/// <summary>
@ -54,7 +53,7 @@ namespace OpenTelemetry.Trace
}
/// <summary>
/// Gets the span name. Use <see cref="UpdateName"/> to explicitly set the span name.
/// Gets or sets the span name. Use <see cref="UpdateName"/> to explicitly set the span name.
/// </summary>
public abstract string Name { get; protected set; }
@ -127,7 +126,7 @@ namespace OpenTelemetry.Trace
/// <inheritdoc/>
public abstract void AddLink(ILink link);
/// <inheritdoc/>
/// <inheritdoc cref="ISpan" />
public abstract void End(EndSpanOptions options);
/// <inheritdoc/>

View File

@ -21,17 +21,17 @@ namespace OpenTelemetry.Trace
public abstract class SpanBuilderBase : ISpanBuilder
{
protected SpanBuilderBase(SpanKind kind)
{
this.Kind = kind;
}
private SpanBuilderBase()
{
}
protected SpanKind Kind { get; private set; }
protected SpanBuilderBase(SpanKind kind)
{
this.Kind = kind;
}
public abstract ISpanBuilder SetSampler(ISampler sampler);
public abstract ISpanBuilder SetParentLinks(IEnumerable<ISpan> parentLinks);

View File

@ -39,6 +39,7 @@ namespace OpenTelemetry.Trace
this.spanBuilderOptions = new SpanBuilderOptions(randomGenerator, startEndHandler, traceConfig);
this.binaryFormat = binaryFormat ?? new BinaryFormat();
this.textFormat = textFormat ?? new TraceContextFormat();
this.exportComponent = exportComponent;
}
/// <inheritdoc/>

View File

@ -43,7 +43,7 @@ namespace OpenTelemetry.Trace
public abstract ITextFormat TextFormat { get; }
/// <summary>
/// No-op tracer.
/// Gets no-op tracer.
/// </summary>
internal static NoopTracer NoopTracer
{

View File

@ -16,7 +16,6 @@
namespace OpenTelemetry.Trace
{
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Internal;
using OpenTelemetry.Trace.Config;
using OpenTelemetry.Trace.Export;
@ -27,9 +26,9 @@ namespace OpenTelemetry.Trace
/// </summary>
public sealed class Tracing
{
private static Tracing tracing = new Tracing();
private static readonly Tracing TracingValue = new Tracing();
private ITraceComponent traceComponent = null;
private readonly ITraceComponent traceComponent = null;
internal Tracing()
{
@ -39,16 +38,16 @@ namespace OpenTelemetry.Trace
/// <summary>
/// Gets the tracer to record spans.
/// </summary>
public static ITracer Tracer => tracing.traceComponent.Tracer;
public static ITracer Tracer => TracingValue.traceComponent.Tracer;
/// <summary>
/// Gets the export component to upload spans to.
/// </summary>
public static IExportComponent ExportComponent => tracing.traceComponent.ExportComponent;
public static IExportComponent ExportComponent => TracingValue.traceComponent.ExportComponent;
/// <summary>
/// Gets the tracer configuration.
/// </summary>
public static ITraceConfig TraceConfig => tracing.traceComponent.TraceConfig;
public static ITraceConfig TraceConfig => TracingValue.traceComponent.TraceConfig;
}
}

View File

@ -24,14 +24,12 @@ namespace OpenTelemetry.Collector.AspNetCore.Tests
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Config;
using OpenTelemetry.Trace.Internal;
using OpenTelemetry.Common;
using Moq;
using Microsoft.AspNetCore.TestHost;
using System;
using OpenTelemetry.Context.Propagation;
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using System.Text;
// See https://github.com/aspnet/Docs/tree/master/aspnetcore/test/integration-tests/samples/2.x/IntegrationTestsSample
public class BasicTests

View File

@ -24,7 +24,6 @@ namespace OpenTelemetry.Collector.AspNetCore.Tests
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Config;
using OpenTelemetry.Trace.Internal;
using OpenTelemetry.Common;
using Moq;
using Microsoft.AspNetCore.TestHost;
using System;
@ -74,7 +73,7 @@ namespace OpenTelemetry.Collector.AspNetCore.Tests
// Act
var response = await client.GetAsync("/api/values");
}
catch (Exception ex)
catch (Exception)
{
// ignore errors
}

View File

@ -29,7 +29,7 @@
<ProjectReference Include="..\..\src\OpenTelemetry.Collector.AspNetCore\OpenTelemetry.Collector.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\OpenTelemetry\OpenTelemetry.csproj" />
<ProjectReference Include="..\TestApp.AspNetCore.2.0\TestApp.AspNetCore.2.0.csproj" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.4" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="2.1.2" />
</ItemGroup>

View File

@ -17,7 +17,6 @@
namespace OpenTelemetry.Collector.Dependencies.Tests
{
using Moq;
using OpenTelemetry.Common;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Config;
using OpenTelemetry.Trace.Internal;

View File

@ -18,11 +18,9 @@ namespace OpenTelemetry.Collector.Dependencies.Tests
{
using Moq;
using Newtonsoft.Json;
using OpenTelemetry.Common;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Config;
using OpenTelemetry.Trace.Internal;
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace.Sampler;
using System;
using System.Collections.Generic;

View File

@ -24,7 +24,7 @@ namespace OpenTelemetry.Collector.Dependencies.Tests
public class TestServer
{
private static Random GlobalRandom = new Random();
private static readonly Random GlobalRandom = new Random();
private class RunningServer : IDisposable
{

View File

@ -18,9 +18,7 @@ namespace OpenTelemetry.Collector.StackExchangeRedis.Implementation
{
using Moq;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Export;
using OpenTelemetry.Trace.Internal;
using StackExchange.Redis.Profiling;
using System.Collections.Generic;
using Xunit;

View File

@ -24,7 +24,6 @@ namespace OpenTelemetry.Collector.StackExchangeRedis.Implementation
using System;
using OpenTelemetry.Common;
using System.Collections.Generic;
using OpenTelemetry.Trace.Export;
public class RedisProfilerEntryToSpanConverterTests
{

View File

@ -17,7 +17,6 @@
namespace OpenTelemetry.Collector.StackExchangeRedis
{
using Moq;
using OpenTelemetry.Common;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Config;
using OpenTelemetry.Trace.Internal;
@ -33,7 +32,7 @@ namespace OpenTelemetry.Collector.StackExchangeRedis
var startEndHandler = new Mock<IStartEndHandler>();
var tracer = new Tracer(new RandomGenerator(), startEndHandler.Object, new TraceConfig(), null);
using (var collector = new StackExchangeRedisCallsCollector(null, tracer, null, null))
using (var collector = new StackExchangeRedisCallsCollector(tracer, null, null))
{
var profilerFactory = collector.GetProfilerSessionsFactory();
var first = profilerFactory();

View File

@ -54,15 +54,15 @@ namespace OpenTelemetry.Exporter.Stackriver.Tests
{
Assert.NotNull(StackdriverStatsConfiguration.Default.MonitoredResource);
Assert.Equal(Constants.GLOBAL, StackdriverStatsConfiguration.Default.MonitoredResource.Type);
Assert.Equal(Constants.Global, StackdriverStatsConfiguration.Default.MonitoredResource.Type);
Assert.NotNull(StackdriverStatsConfiguration.Default.MonitoredResource.Labels);
Assert.True(StackdriverStatsConfiguration.Default.MonitoredResource.Labels.ContainsKey("project_id"));
Assert.True(StackdriverStatsConfiguration.Default.MonitoredResource.Labels.ContainsKey(Constants.PROJECT_ID_LABEL_KEY));
Assert.True(StackdriverStatsConfiguration.Default.MonitoredResource.Labels.ContainsKey(Constants.ProjectIdLabelKey));
Assert.Equal(
StackdriverStatsConfiguration.Default.ProjectId,
StackdriverStatsConfiguration.Default.MonitoredResource.Labels[Constants.PROJECT_ID_LABEL_KEY]);
StackdriverStatsConfiguration.Default.MonitoredResource.Labels[Constants.ProjectIdLabelKey]);
}
}
}

View File

@ -26,7 +26,7 @@ namespace OpenTelemetry.Impl.Resources
{
private const string keyName = "key";
private const string valueName = "value";
private static Random random = new Random();
private static readonly Random random = new Random();
[Fact]
public static void CreateResource_NullLabelCollection()

View File

@ -66,7 +66,7 @@ namespace OpenTelemetry.Stats.Test
using (var cts = new CancellationTokenSource())
{
var _ = Task.Run(
async () =>
() =>
{
while (!cts.IsCancellationRequested)
{

View File

@ -17,7 +17,6 @@
namespace OpenTelemetry.Stats.Test
{
using System.Collections.Generic;
using OpenTelemetry.Common;
using OpenTelemetry.Stats.Aggregations;
using OpenTelemetry.Stats.Measures;
using OpenTelemetry.Tags;

View File

@ -26,7 +26,7 @@ namespace OpenTelemetry.Stats.Test
public class QuickStartExampleTest
{
ITestOutputHelper output;
readonly ITestOutputHelper output;
public QuickStartExampleTest(ITestOutputHelper output)
{

View File

@ -35,9 +35,9 @@ namespace OpenTelemetry.Stats.Test
private static readonly IMeasureDouble MEASURE_DOUBLE_NO_VIEW_2 = MeasureDouble.Create("my measurement no view 2", "description", "us");
private static readonly IViewName VIEW_NAME = ViewName.Create("my view");
private StatsComponent statsComponent;
private IViewManager viewManager;
private IStatsRecorder statsRecorder;
private readonly StatsComponent statsComponent;
private readonly IViewManager viewManager;
private readonly IStatsRecorder statsRecorder;
public StatsRecorderTest()
{

View File

@ -428,11 +428,13 @@ namespace OpenTelemetry.Stats.Test
viewData.AggregationMap,
new Dictionary<TagValues, IAggregationData>()
{
// Won't Record the unregistered tag key, for missing registered keys will use default
// tag value : "unknown/not set".
{ tv,
// Should Record stats with default tag value: "KEY" : "unknown/not set".
StatsTestUtil.CreateAggregationData(DISTRIBUTION, MEASURE_DOUBLE, 10.0, 50.0) },
// Won't Record the unregistered tag key, for missing registered keys will use default
// tag value : "unknown/not set".
{
tv,
// Should Record stats with default tag value: "KEY" : "unknown/not set".
StatsTestUtil.CreateAggregationData(DISTRIBUTION, MEASURE_DOUBLE, 10.0, 50.0)
},
},
EPSILON);
}
@ -491,7 +493,7 @@ namespace OpenTelemetry.Stats.Test
{ tv1, StatsTestUtil.CreateAggregationData(DISTRIBUTION, MEASURE_DOUBLE, 1.1, 4.4) },
{ tv2, StatsTestUtil.CreateAggregationData(DISTRIBUTION, MEASURE_DOUBLE, 2.2) },
{ tv3, StatsTestUtil.CreateAggregationData(DISTRIBUTION, MEASURE_DOUBLE, 3.3)},
},
},
EPSILON);
}
@ -568,7 +570,7 @@ namespace OpenTelemetry.Stats.Test
new Dictionary<TagValues, IAggregationData>()
{
{tv, StatsTestUtil.CreateAggregationData(DISTRIBUTION, measure1, value1) },
},
},
EPSILON);
StatsTestUtil.AssertAggregationMapEquals(

View File

@ -17,7 +17,6 @@
namespace OpenTelemetry.Tags.Test
{
using System.Collections.Generic;
using OpenTelemetry.Context;
using OpenTelemetry.Tags.Unsafe;
using Xunit;

View File

@ -21,7 +21,6 @@ namespace OpenTelemetry.Tags.Test
using System.Collections.Generic;
using System.Linq;
using OpenTelemetry.Internal;
using OpenTelemetry.Tags.Propagation;
using Xunit;
public class NoopTagsTest

View File

@ -17,7 +17,6 @@
namespace OpenTelemetry.Tags.Test
{
using System.Collections.Generic;
using OpenTelemetry.Context;
using Xunit;
public class ScopedTagContextsTest

View File

@ -17,7 +17,6 @@
namespace OpenTelemetry.Tags.Test
{
using System.Collections.Generic;
using OpenTelemetry.Context;
using OpenTelemetry.Tags.Unsafe;
using Xunit;

View File

@ -28,14 +28,15 @@ namespace OpenTelemetry.Testing.Export
private readonly object monitor = new object();
private readonly List<SpanData> spanDataList = new List<SpanData>();
public async Task ExportAsync(IEnumerable<SpanData> data)
public Task ExportAsync(IEnumerable<SpanData> data)
{
lock (monitor)
{
this.spanDataList.AddRange(data);
Monitor.PulseAll(monitor);
}
return Task.CompletedTask;
}
public IEnumerable<SpanData> WaitForExport(int numberOfSpans)

View File

@ -21,7 +21,7 @@ namespace OpenTelemetry.Trace.Config.Test
public class TraceConfigBaseTest
{
ITraceConfig traceConfig = TraceConfigBase.NoopTraceConfig;
readonly ITraceConfig traceConfig = TraceConfigBase.NoopTraceConfig;
[Fact]
public void ActiveTraceParams_NoOpImplementation()

View File

@ -17,16 +17,15 @@
namespace OpenTelemetry.Trace.Test
{
using Moq;
using OpenTelemetry.Context;
using OpenTelemetry.Trace.Internal;
using Xunit;
public class CurrentSpanUtilsTest
{
private ISpan span;
private RandomGenerator random;
private SpanContext spanContext;
private SpanOptions spanOptions;
private readonly ISpan span;
private readonly RandomGenerator random;
private readonly SpanContext spanContext;
private readonly SpanOptions spanOptions;
public CurrentSpanUtilsTest()
{

View File

@ -31,7 +31,7 @@ namespace OpenTelemetry.Trace.Export.Test
private readonly ISpanExporter sampledSpansServiceExporter = SpanExporter.Create(4, Duration.Create(1, 0));
private readonly InProcessRunningSpanStore activeSpansExporter = new InProcessRunningSpanStore();
private readonly StartEndHandler startEndHandler;
private SpanOptions recordSpanOptions = SpanOptions.RecordEvents;
private readonly SpanOptions recordSpanOptions = SpanOptions.RecordEvents;
public InProcessRunningSpanStoreTest()
{

View File

@ -364,7 +364,7 @@ namespace OpenTelemetry.Trace.Export.Test
class TestStartEndHandler : IStartEndHandler
{
InProcessSampledSpanStore sampleStore;
readonly InProcessSampledSpanStore sampleStore;
public TestStartEndHandler(InProcessSampledSpanStore store)
{

View File

@ -17,7 +17,6 @@
namespace OpenTelemetry.Trace.Export.Test
{
using System;
using System.Collections.Generic;
using Xunit;
public class NoopRunningSpanStoreTest

View File

@ -43,9 +43,9 @@ namespace OpenTelemetry.Trace.Export.Test
private readonly List<ITimedEvent<IEvent>> eventList = new List<ITimedEvent<IEvent>>();
private readonly List<ILink> linksList = new List<ILink>();
private IAttributes attributes;
private ITimedEvents<IEvent> events;
private LinkList links;
private readonly IAttributes attributes;
private readonly ITimedEvents<IEvent> events;
private readonly LinkList links;
public SpanDataTest()
{

View File

@ -24,7 +24,6 @@ namespace OpenTelemetry.Trace.Export.Test
using Moq;
using OpenTelemetry.Common;
using OpenTelemetry.Internal;
using OpenTelemetry.Resources;
using OpenTelemetry.Testing.Export;
using OpenTelemetry.Trace.Config;
using OpenTelemetry.Trace.Internal;

View File

@ -37,7 +37,7 @@ namespace OpenTelemetry.Context.Propagation.Test
private static readonly Action<IDictionary<string, string>, string, string> setter = (d, k, v) => d[k] = v;
private static readonly Func<IDictionary<string, string>, string, IEnumerable<string>> getter = (d, k) => { d.TryGetValue(k, out var v); return new string[] { v }; };
ITestOutputHelper _output;
readonly ITestOutputHelper _output;
public B3FormatTest(ITestOutputHelper output)
{

View File

@ -17,17 +17,16 @@
namespace OpenTelemetry.Trace.Test
{
using System;
using System.Collections.Generic;
using Moq;
using OpenTelemetry.Trace.Internal;
using Xunit;
public class SpanBaseTest
{
private RandomGenerator random;
private SpanContext spanContext;
private SpanContext notSampledSpanContext;
private SpanOptions spanOptions;
private readonly RandomGenerator random;
private readonly SpanContext spanContext;
private readonly SpanContext notSampledSpanContext;
private readonly SpanOptions spanOptions;
public SpanBaseTest()
{

View File

@ -17,15 +17,14 @@
namespace OpenTelemetry.Trace.Test
{
using Moq;
using OpenTelemetry.Context;
using OpenTelemetry.Trace.Internal;
using Xunit;
public class SpanBuilderBaseTest
{
private ITracer tracer;
private Mock<SpanBuilderBase> spanBuilder = new Mock<SpanBuilderBase>(SpanKind.Internal);
private Mock<SpanBase> span = new Mock<SpanBase>();
private readonly ITracer tracer;
private readonly Mock<SpanBuilderBase> spanBuilder = new Mock<SpanBuilderBase>(SpanKind.Internal);
private readonly Mock<SpanBase> span = new Mock<SpanBase>();
public SpanBuilderBaseTest()
{

Some files were not shown because too many files have changed in this diff Show More