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:
parent
42e9566b7b
commit
843fc3e225
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
namespace OpenTelemetry.Metrics
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using OpenTelemetry.Metrics.Implementation;
|
||||
using OpenTelemetry.Tags;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
namespace OpenTelemetry.Metrics.Implementation
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Builder for the <see cref="IMeasure"/>.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,4 @@
|
|||
<Description>OpenTelemetry .NET API abstractions</Description>
|
||||
<RootNamespace>OpenTelemetry</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Utils\AttributesWithCapacity.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
namespace OpenTelemetry.Trace.Export
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
namespace OpenTelemetry.Abstractions.Utils
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
internal static class Collections
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
namespace OpenTelemetry.Exporter.Prometheus
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Options to run prometheus exporter.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
namespace OpenTelemetry.Trace.Export
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
namespace OpenTelemetry.Trace.Export
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ namespace OpenTelemetry.Trace.Internal
|
|||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenTelemetry.Trace.Export;
|
||||
|
||||
internal sealed class BlankSpan : SpanBase
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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/>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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/>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace OpenTelemetry.Stats.Test
|
|||
using (var cts = new CancellationTokenSource())
|
||||
{
|
||||
var _ = Task.Run(
|
||||
async () =>
|
||||
() =>
|
||||
{
|
||||
while (!cts.IsCancellationRequested)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace OpenTelemetry.Stats.Test
|
|||
|
||||
public class QuickStartExampleTest
|
||||
{
|
||||
ITestOutputHelper output;
|
||||
readonly ITestOutputHelper output;
|
||||
|
||||
public QuickStartExampleTest(ITestOutputHelper output)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
namespace OpenTelemetry.Tags.Test
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using OpenTelemetry.Context;
|
||||
using OpenTelemetry.Tags.Unsafe;
|
||||
using Xunit;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
namespace OpenTelemetry.Tags.Test
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using OpenTelemetry.Context;
|
||||
using Xunit;
|
||||
|
||||
public class ScopedTagContextsTest
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
namespace OpenTelemetry.Tags.Test
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using OpenTelemetry.Context;
|
||||
using OpenTelemetry.Tags.Unsafe;
|
||||
using Xunit;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ namespace OpenTelemetry.Trace.Export.Test
|
|||
|
||||
class TestStartEndHandler : IStartEndHandler
|
||||
{
|
||||
InProcessSampledSpanStore sampleStore;
|
||||
readonly InProcessSampledSpanStore sampleStore;
|
||||
|
||||
public TestStartEndHandler(InProcessSampledSpanStore store)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
namespace OpenTelemetry.Trace.Export.Test
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
|
||||
public class NoopRunningSpanStoreTest
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue