From 2020ceb6378949a7d106d1173476d65aa453338e Mon Sep 17 00:00:00 2001 From: Denis Ivanov Date: Thu, 5 Nov 2020 17:55:17 +0100 Subject: [PATCH 1/3] Initial implementation of OpenTelemetry.Extensions.Owin --- .editorconfig | 5 + OpenTelemetry.sln | 12 ++ build/Common.props | 2 + .../AppBuilderExtensions.cs | 33 ++++ .../AssemblyInfo.cs | 22 +++ .../CHANGELOG.md | 5 + .../DiagnosticsMiddleware.cs | 158 ++++++++++++++++++ .../Implementation/ActivityExtensions.cs | 122 ++++++++++++++ .../Implementation/Context.cs | 27 +++ .../HeaderDictionaryExtensions.cs | 99 +++++++++++ .../Implementation/HeaderNames.cs | 27 +++ .../OwinExtensionsEventSource.cs | 49 ++++++ .../OpenTelemetry.Extensions.Owin.csproj | 18 ++ src/OpenTelemetry.Extensions.Owin/README.md | 27 +++ .../AssemblyInfo.cs | 22 +++ .../CHANGELOG.md | 5 + .../Implementation/HttpInListener.cs | 34 ++++ .../OwinInstrumentationEventSource.cs | 29 ++++ .../OpenTelemetry.Instrumentation.Owin.csproj | 21 +++ .../OwinInstrumentation.cs | 47 ++++++ .../OwinInstrumentationOptions.cs | 25 +++ .../README.md | 27 +++ .../TracerProviderBuilderExtensions.cs | 50 ++++++ 23 files changed, 866 insertions(+) create mode 100644 src/OpenTelemetry.Extensions.Owin/AppBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Extensions.Owin/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Extensions.Owin/CHANGELOG.md create mode 100644 src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs create mode 100644 src/OpenTelemetry.Extensions.Owin/Implementation/ActivityExtensions.cs create mode 100644 src/OpenTelemetry.Extensions.Owin/Implementation/Context.cs create mode 100644 src/OpenTelemetry.Extensions.Owin/Implementation/HeaderDictionaryExtensions.cs create mode 100644 src/OpenTelemetry.Extensions.Owin/Implementation/HeaderNames.cs create mode 100644 src/OpenTelemetry.Extensions.Owin/Implementation/OwinExtensionsEventSource.cs create mode 100644 src/OpenTelemetry.Extensions.Owin/OpenTelemetry.Extensions.Owin.csproj create mode 100644 src/OpenTelemetry.Extensions.Owin/README.md create mode 100644 src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.Owin/Implementation/HttpInListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs create mode 100644 src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj create mode 100644 src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Owin/README.md create mode 100644 src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs diff --git a/.editorconfig b/.editorconfig index 489c289cad6..1b25292139a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,6 +14,11 @@ charset = utf-8 # maintain DOS/Windows style line endings in md files [*.md] end_of_line = crlf +# MSBuild files +[*.{proj,csproj,props,targets}] +indent_size = 2 +trim_trailing_whitespace = true +charset = utf-8 ############################### # .NET Coding Conventions # ############################### diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 62972e8e553..aaf3737780e 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -204,6 +204,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "extending-the-sdk", "docs\l EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Shared", "src\OpenTelemetry.Shared\OpenTelemetry.Shared.csproj", "{1E504265-1E32-4C61-8CC5-8FA373E16699}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.Owin", "src\OpenTelemetry.Instrumentation.Owin\OpenTelemetry.Instrumentation.Owin.csproj", "{7B55B64E-609F-490E-A283-AD4D85FE2F19}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Extensions.Owin", "src\OpenTelemetry.Extensions.Owin\OpenTelemetry.Extensions.Owin.csproj", "{EE939E55-B71A-4BB2-9483-635D92B1254A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -402,6 +406,14 @@ Global {1E504265-1E32-4C61-8CC5-8FA373E16699}.Debug|Any CPU.Build.0 = Debug|Any CPU {1E504265-1E32-4C61-8CC5-8FA373E16699}.Release|Any CPU.ActiveCfg = Release|Any CPU {1E504265-1E32-4C61-8CC5-8FA373E16699}.Release|Any CPU.Build.0 = Release|Any CPU + {7B55B64E-609F-490E-A283-AD4D85FE2F19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B55B64E-609F-490E-A283-AD4D85FE2F19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B55B64E-609F-490E-A283-AD4D85FE2F19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B55B64E-609F-490E-A283-AD4D85FE2F19}.Release|Any CPU.Build.0 = Release|Any CPU + {EE939E55-B71A-4BB2-9483-635D92B1254A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EE939E55-B71A-4BB2-9483-635D92B1254A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE939E55-B71A-4BB2-9483-635D92B1254A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EE939E55-B71A-4BB2-9483-635D92B1254A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/build/Common.props b/build/Common.props index 51fd551f0d3..bf569e03aa6 100644 --- a/build/Common.props +++ b/build/Common.props @@ -35,12 +35,14 @@ [2.1.0,6.0) [1.0.0,2.0) [1.0.0,2.0) + [4.1.1] [12.0.2,13.0) [0.12.1,0.13) [2.1.58,3.0) [1.1.118,2.0) [1.4.0,5.0] [5.0.0-rc.2.20475.5] + [4.3.4] [4.7.0,5.0) [4.7.0,5.0) [4.5.3,5.0) diff --git a/src/OpenTelemetry.Extensions.Owin/AppBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Owin/AppBuilderExtensions.cs new file mode 100644 index 00000000000..1931119f8cd --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/AppBuilderExtensions.cs @@ -0,0 +1,33 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Owin; + +namespace OpenTelemetry +{ + /// + /// Provides extension methods for the class. + /// + public static class AppBuilderExtensions + { + /// Adds a component to the OWIN pipeline for instrumenting incoming request with System.Diagnostics.Activity and notifying listeners with DiagnosticsSource. + /// The application builder. + /// The application builder. + public static void UseOpenTelemetry(this IAppBuilder appBuilder) + => appBuilder.Use(); + + } +} diff --git a/src/OpenTelemetry.Extensions.Owin/AssemblyInfo.cs b/src/OpenTelemetry.Extensions.Owin/AssemblyInfo.cs new file mode 100644 index 00000000000..63a1b38ade1 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/AssemblyInfo.cs @@ -0,0 +1,22 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.Owin.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.Owin.Tests")] +#endif diff --git a/src/OpenTelemetry.Extensions.Owin/CHANGELOG.md b/src/OpenTelemetry.Extensions.Owin/CHANGELOG.md new file mode 100644 index 00000000000..134621e04d9 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +* Initial release diff --git a/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs new file mode 100644 index 00000000000..88e280cefab --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs @@ -0,0 +1,158 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Microsoft.Owin; +using OpenTelemetry.Implementation; + +namespace OpenTelemetry +{ + /// + /// Instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. + /// + public sealed class DiagnosticsMiddleware : OwinMiddleware + { + private const string ActivityName = "OpenTelemetry.Extensions.Owin.HttpRequestIn"; + private const string ActivityStartKey = ActivityName + ".Start"; + private const string ActivityStopKey = ActivityName + ".Stop"; + + private readonly DiagnosticListener diagnosticListener = new DiagnosticListener("OpenTelemetry.Extensions.Owin"); + private readonly Context context = new Context(); + + /// + /// Initializes a new instance of the class. + /// + /// An optional pointer to the next component + public DiagnosticsMiddleware(OwinMiddleware next) + : base(next) + { + } + + /// + public override async Task Invoke(IOwinContext owinContext) + { + try + { + this.BeginRequest(owinContext); + await this.Next.Invoke(owinContext).ConfigureAwait(false); + this.RequestEnd(owinContext, null); + } + catch (Exception ex) + { + this.RequestEnd(owinContext, ex); + } + } + + // Based on https://github.com/dotnet/aspnetcore/blob/v5.0.0-rc.2.20475.17/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L37 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void BeginRequest(IOwinContext owinContext) + { + if (OwinExtensionsEventSource.Log.IsEnabled()) + { + this.context.EventLogEnabled = true; + } + + if (this.diagnosticListener.IsEnabled() && this.diagnosticListener.IsEnabled(ActivityName, owinContext)) + { + this.context.Activity = this.StartActivity(owinContext, out var hasDiagnosticListener); + this.context.HasDiagnosticListener = hasDiagnosticListener; + } + } + + // Based on https://github.com/dotnet/aspnetcore/blob/v5.0.0-rc.2.20475.17/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L89 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void RequestEnd(IOwinContext owinContext, Exception exception) + { + var activity = this.context.Activity; + // Always stop activity if it was started + if (activity != null) + { + this.StopActivity(owinContext, activity, this.context.HasDiagnosticListener); + } + + if (this.context.EventLogEnabled && exception != null) + { + // Non-inline + OwinExtensionsEventSource.Log.UnhandledException(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private Activity StartActivity(IOwinContext owinContext, out bool hasDiagnosticListener) + { + hasDiagnosticListener = false; + + var activity = new Activity(ActivityName); + + // Based on https://github.com/microsoft/ApplicationInsights-dotnet/blob/2.15.0/WEB/Src/Web/Web/Implementation/RequestTrackingExtensions.cs#L41 + if (!activity.Extract(owinContext.Request.Headers)) + { + // Force parsing Correlation-Context in absence of Request-Id or traceparent. + owinContext.Request.Headers.ReadActivityBaggage(activity); + } + + this.diagnosticListener.OnActivityImport(activity, owinContext); + + if (this.diagnosticListener.IsEnabled(ActivityStartKey)) + { + hasDiagnosticListener = true; + this.StartActivity(activity, owinContext); + } + else + { + activity.Start(); + } + + return activity; + } + + // These are versions of DiagnosticSource.Start/StopActivity that don't allocate strings per call (see https://github.com/dotnet/corefx/issues/37055) + private void StartActivity(Activity activity, IOwinContext owinContext) + { + activity.Start(); + this.diagnosticListener.Write(ActivityStartKey, owinContext); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void StopActivity(IOwinContext owinContext, Activity activity, bool hasDiagnosticListener) + { + if (hasDiagnosticListener) + { + this.StopActivity(activity, owinContext); + } + else + { + activity.Stop(); + } + } + + private void StopActivity(Activity activity, IOwinContext owinContext) + { + // Stop sets the end time if it was unset, but we want it set before we issue the write + // so we do it now. + if (activity.Duration == TimeSpan.Zero) + { + activity.SetEndTime(DateTime.UtcNow); + } + + this.diagnosticListener.Write(ActivityStopKey, owinContext); + activity.Stop(); // Resets Activity.Current (we want this after the Write) + } + } +} diff --git a/src/OpenTelemetry.Extensions.Owin/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Extensions.Owin/Implementation/ActivityExtensions.cs new file mode 100644 index 00000000000..069bbc81e92 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/Implementation/ActivityExtensions.cs @@ -0,0 +1,122 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Net.Http.Headers; +using Microsoft.Owin; + +namespace OpenTelemetry.Implementation +{ + internal static class ActivityExtensions + { + /// + /// Maximum length of Correlation-Context header value. + /// + private const int MaxCorrelationContextLength = 1024; + + /// + /// Reads Request-Id and Correlation-Context headers and sets ParentId and Baggage on Activity. + /// Based on the code from https://github.com/aspnet/Microsoft.AspNet.TelemetryCorrelation/blob/master/src/Microsoft.AspNet.TelemetryCorrelation/ActivityExtensions.cs#L48 + /// + /// Instance of activity that has not been started yet. + /// Request headers collection. + /// true if request was parsed successfully, false - otherwise. + public static bool Extract(this Activity activity, IHeaderDictionary requestHeaders) + { + if (activity == null) + { + OwinExtensionsEventSource.Log.ActivityExtractionError("activity is null"); + return false; + } + + if (activity.ParentId != null) + { + OwinExtensionsEventSource.Log.ActivityExtractionError("ParentId is already set on activity"); + return false; + } + + if (activity.Id != null) + { + OwinExtensionsEventSource.Log.ActivityExtractionError("Activity is already started"); + return false; + } + + var traceParents = requestHeaders.GetValues(HeaderNames.TraceParent); + if (traceParents == null || traceParents.Count == 0) + { + traceParents = requestHeaders.GetValues(HeaderNames.RequestId); + } + + if (traceParents != null && traceParents.Count > 0 && !string.IsNullOrEmpty(traceParents[0])) + { + // there may be several Request-Id or traceparent headers, but we only read the first one + activity.SetParentId(traceParents[0]); + + var traceStates = requestHeaders.GetValues(HeaderNames.TraceState); + if (traceStates != null && traceStates.Count > 0) + { + if (traceStates.Count == 1 && !string.IsNullOrEmpty(traceStates[0])) + { + activity.TraceStateString = traceStates[0]; + } + else + { + activity.TraceStateString = string.Join(",", traceStates); + } + } + + // Header format - Correlation-Context: key1=value1, key2=value2 + var baggages = requestHeaders.GetValues(HeaderNames.CorrelationContext); + if (baggages != null) + { + int correlationContextLength = -1; + + // there may be several Correlation-Context headers + foreach (var item in baggages) + { + if (correlationContextLength >= MaxCorrelationContextLength) + { + break; + } + + foreach (var pair in item.Split(',')) + { + correlationContextLength += pair.Length + 1; // pair and comma + + if (correlationContextLength >= MaxCorrelationContextLength) + { + break; + } + + if (NameValueHeaderValue.TryParse(pair, out NameValueHeaderValue baggageItem)) + { + activity.AddBaggage(baggageItem.Name, baggageItem.Value); + } + else + { + OwinExtensionsEventSource.Log.HeaderParsingError(HeaderNames.CorrelationContext, pair); + } + } + } + } + + return true; + } + + return false; + } + } +} diff --git a/src/OpenTelemetry.Extensions.Owin/Implementation/Context.cs b/src/OpenTelemetry.Extensions.Owin/Implementation/Context.cs new file mode 100644 index 00000000000..23502a4c667 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/Implementation/Context.cs @@ -0,0 +1,27 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; + +namespace OpenTelemetry.Implementation +{ + internal class Context + { + public Activity Activity { get; set; } + internal bool HasDiagnosticListener { get; set; } + public bool EventLogEnabled { get; set; } + } +} diff --git a/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderDictionaryExtensions.cs b/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderDictionaryExtensions.cs new file mode 100644 index 00000000000..6fd280a9042 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderDictionaryExtensions.cs @@ -0,0 +1,99 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Linq; +using Microsoft.Owin; + +namespace OpenTelemetry.Implementation +{ + internal static class HeaderDictionaryExtensions + { + private const int CorrelationContextHeaderMaxLength = 8192; + private const int CorrelationContextMaxPairs = 180; + + /// + /// Reads Correlation-Context and populates it on Activity.Baggage following https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/HttpCorrelationProtocol.md#correlation-context. + /// Use this method when you want force parsing Correlation-Context is absence of Request-Id or traceparent. + /// Based on the code from https://github.com/microsoft/ApplicationInsights-dotnet/blob/2.15.0/WEB/Src/Common/WebHeaderCollectionExtensions.cs#L135 + /// + /// Header collection. + /// Activity to populate baggage on. + public static void ReadActivityBaggage(this IHeaderDictionary headers, Activity activity) + { + Debug.Assert(headers != null, "Headers must not be null"); + Debug.Assert(activity != null, "Activity must not be null"); + Debug.Assert(!activity.Baggage.Any(), "Baggage must be empty"); + + int itemsCount = 0; + var correlationContexts = headers.GetValues(HeaderNames.CorrelationContext); + if (correlationContexts == null || correlationContexts.Count == 0) + { + return; + } + + int overallLength = 0; + foreach (var cc in correlationContexts) + { + var headerValue = cc.AsSpan(); + int currentLength = 0; + int initialLength = headerValue.Length; + while (itemsCount < CorrelationContextMaxPairs && currentLength < initialLength) + { + var nextSegment = headerValue.Slice(currentLength); + var nextComma = nextSegment.IndexOf(','); + if (nextComma < 0) + { + // last one + nextComma = nextSegment.Length; + } + + if (nextComma == 0) + { + currentLength += 1; + overallLength += 1; + continue; + } + + if (overallLength + nextComma >= CorrelationContextHeaderMaxLength) + { + return; + } + + ReadOnlySpan kvp = nextSegment.Slice(0, nextComma).Trim(); + + var separatorInd = kvp.IndexOf('='); + if (separatorInd > 0 && separatorInd < kvp.Length - 1) + { + var separatorIndNext = kvp.Slice(separatorInd + 1).IndexOf('='); + // check there is just one '=' in key-value-pair + if (separatorIndNext < 0) + { + var baggageKey = kvp.Slice(0, separatorInd).Trim().ToString(); + var baggageValue = kvp.Slice(separatorInd + 1).Trim().ToString(); + activity.AddBaggage(baggageKey, baggageValue); + itemsCount += 1; + } + } + + currentLength += nextComma + 1; + overallLength += nextComma + 1; + } + } + } + } +} diff --git a/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderNames.cs b/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderNames.cs new file mode 100644 index 00000000000..ec5499a8d00 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderNames.cs @@ -0,0 +1,27 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Implementation +{ + // // Microsoft.Net.Http.Headers headers (from https://github.com/dotnet/aspnetcore/blob/v5.0.0-rc.2.20475.17/src/Http/Headers/src/HeaderNames.cs) + internal static class HeaderNames + { + public static readonly string CorrelationContext = "Correlation-Context"; + public static readonly string RequestId = "Request-Id"; + public static readonly string TraceParent = "traceparent"; + public static readonly string TraceState = "tracestate"; + } +} diff --git a/src/OpenTelemetry.Extensions.Owin/Implementation/OwinExtensionsEventSource.cs b/src/OpenTelemetry.Extensions.Owin/Implementation/OwinExtensionsEventSource.cs new file mode 100644 index 00000000000..4fafeafe0e1 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/Implementation/OwinExtensionsEventSource.cs @@ -0,0 +1,49 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Tracing; +using System.Runtime.CompilerServices; + +namespace OpenTelemetry.Implementation +{ + /// + /// EventSource events emitted from the project. + /// + [EventSource(Name = "OpenTelemetry-Extensions-Owin")] + internal class OwinExtensionsEventSource : EventSource + { + public static OwinExtensionsEventSource Log = new OwinExtensionsEventSource(); + + [Event(1, Message = "Failed to extract activity, reason '{0}'", Level = EventLevel.Error)] + public void ActivityExtractionError(string reason) + { + this.WriteEvent(1, reason); + } + + [Event(2, Message = "Failed to parse header '{0}', value: '{1}'", Level = EventLevel.Informational)] + public void HeaderParsingError(string headerName, string headerValue) + { + this.WriteEvent(2, headerName, headerValue); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + [Event(3, Level = EventLevel.Error)] + public void UnhandledException() + { + this.WriteEvent(3); + } + } +} diff --git a/src/OpenTelemetry.Extensions.Owin/OpenTelemetry.Extensions.Owin.csproj b/src/OpenTelemetry.Extensions.Owin/OpenTelemetry.Extensions.Owin.csproj new file mode 100644 index 00000000000..87454ea2e6b --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/OpenTelemetry.Extensions.Owin.csproj @@ -0,0 +1,18 @@ + + + + net461;netstandard2.0 + A component to the OWIN pipeline for instrumenting incoming request with System.Diagnostics.Activity and notifying listeners with DiagnosticsSource. + OpenTelemetry + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Extensions.Owin/README.md b/src/OpenTelemetry.Extensions.Owin/README.md new file mode 100644 index 00000000000..22753806e02 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Owin/README.md @@ -0,0 +1,27 @@ +# Telemetry correlation library for OWIN/Katana + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.Owin.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Owin) +[![NuGet](https://img.shields.io/nuget/dt/OOpenTelemetry.Extensions.Owin.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Owin) + +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/glossary.md#instrumentation-library), +which instruments the [OWIN/Katana](https://github.com/aspnet/AspNetKatana/) +and notifies listeners about incoming web requests. + +## Steps to enable OpenTelemetry.Extensions.Owin + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Extensions.Owin`](https://www.nuget.org/packages/opentelemetry.extensions.owin) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Extensions.Owin +``` + +## References + +* [Open Web Interface for .NET](http://owin.org/) +* [Katana Project](https://github.com/aspnet/AspNetKatana/) +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs new file mode 100644 index 00000000000..bbe3b276364 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs @@ -0,0 +1,22 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Owin.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Owin.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md new file mode 100644 index 00000000000..134621e04d9 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/HttpInListener.cs new file mode 100644 index 00000000000..442e513556c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/HttpInListener.cs @@ -0,0 +1,34 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.Owin.Implementation +{ + internal class HttpInListener : ListenerHandler + { + private readonly OwinInstrumentationOptions options; + private readonly ActivitySourceAdapter activitySource; + + public HttpInListener(string name, OwinInstrumentationOptions options, ActivitySourceAdapter activitySource) + : base(name) + { + this.options = options ?? throw new ArgumentNullException(nameof(options)); + this.activitySource = activitySource; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs new file mode 100644 index 00000000000..0bf1b3609d7 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Instrumentation.Owin.Implementation +{ + /// + /// EventSource events emitted from the project. + /// + [EventSource(Name = "OpenTelemetry-Instrumentation-Owin")] + internal class OwinInstrumentationEventSource : EventSource + { + public static OwinInstrumentationEventSource Log = new OwinInstrumentationEventSource(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj new file mode 100644 index 00000000000..1bcc51c877f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -0,0 +1,21 @@ + + + net452;net46;netstandard2.0 + OWIN instrumentation for OpenTelemetry .NET + $(PackageTags);distributed-tracing;OWIN + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentation.cs new file mode 100644 index 00000000000..a18aef0d2e4 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentation.cs @@ -0,0 +1,47 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Instrumentation.Owin.Implementation; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.Owin +{ + /// + /// OWIN Requests instrumentation. + /// + internal class OwinInstrumentation : IDisposable + { + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + + /// + /// Initializes a new instance of the class. + /// + /// ActivitySource adapter instance. + /// Configuration options for OWIN instrumentation. + public OwinInstrumentation(ActivitySourceAdapter activitySource, OwinInstrumentationOptions options) + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new HttpInListener("OpenTelemetry.Extensions.Owin", options, activitySource), null); + this.diagnosticSourceSubscriber.Subscribe(); + } + + /// + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs new file mode 100644 index 00000000000..cdd0735e532 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -0,0 +1,25 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.Owin +{ + /// + /// Options for requests instrumentation. + /// + public class OwinInstrumentationOptions + { + } +} diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md new file mode 100644 index 00000000000..70ab5bb4940 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -0,0 +1,27 @@ +# OWIN Instrumentation for OpenTelemetry + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Owin.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Owin.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) + +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/glossary.md#instrumentation-library), +which instruments [OWIN/Katana](https://github.com/aspnet/AspNetKatana/) and +collect telemetry about incoming web requests. + +## Steps to enable OpenTelemetry.Instrumentation.Owin + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.Owin`](https://www.nuget.org/packages/opentelemetry.instrumentation.owin) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Instrumentation.Owin +``` + +## References + +* [Open Web Interface for .NET](http://owin.org/) +* [Katana Project](https://github.com/aspnet/AspNetKatana/) +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs new file mode 100644 index 00000000000..a1373dd878e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -0,0 +1,50 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Instrumentation.Owin; + +namespace OpenTelemetry.Trace +{ + /// + /// Extension methods to simplify registering of OWIN request instrumentation. + /// + public static class TracerProviderBuilderExtensions + { + /// + /// Enables the incoming requests automatic data collection for OWIN. + /// + /// being configured. + /// OWIN Request configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddOwinInstrumentation( + this TracerProviderBuilder builder, + Action configureOwinInstrumentationOptions = null) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + var owinOptions = new OwinInstrumentationOptions(); + configureOwinInstrumentationOptions?.Invoke(owinOptions); + + builder.AddInstrumentation(activitySource => new OwinInstrumentation(activitySource, owinOptions)); + + return builder; + } + } +} From fbe41cf311f01bad479e4c0f8d7374bf5666f1ec Mon Sep 17 00:00:00 2001 From: Denis Ivanov Date: Thu, 5 Nov 2020 18:22:29 +0100 Subject: [PATCH 2/3] Analyzers warnings fixed. --- src/OpenTelemetry.Extensions.Owin/AppBuilderExtensions.cs | 5 ++--- src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs | 3 ++- .../Implementation/ActivityExtensions.cs | 2 +- src/OpenTelemetry.Extensions.Owin/Implementation/Context.cs | 4 +++- .../Implementation/HeaderDictionaryExtensions.cs | 3 ++- .../OpenTelemetry.Instrumentation.Owin.csproj | 6 +----- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Owin/AppBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Owin/AppBuilderExtensions.cs index 1931119f8cd..67d93b5952c 100644 --- a/src/OpenTelemetry.Extensions.Owin/AppBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Owin/AppBuilderExtensions.cs @@ -25,9 +25,8 @@ public static class AppBuilderExtensions { /// Adds a component to the OWIN pipeline for instrumenting incoming request with System.Diagnostics.Activity and notifying listeners with DiagnosticsSource. /// The application builder. - /// The application builder. - public static void UseOpenTelemetry(this IAppBuilder appBuilder) + /// The application builder instance. + public static IAppBuilder UseOpenTelemetry(this IAppBuilder appBuilder) => appBuilder.Use(); - } } diff --git a/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs index 88e280cefab..3f031a50ba0 100644 --- a/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs @@ -38,7 +38,7 @@ public sealed class DiagnosticsMiddleware : OwinMiddleware /// /// Initializes a new instance of the class. /// - /// An optional pointer to the next component + /// An optional pointer to the next component. public DiagnosticsMiddleware(OwinMiddleware next) : base(next) { @@ -80,6 +80,7 @@ private void BeginRequest(IOwinContext owinContext) private void RequestEnd(IOwinContext owinContext, Exception exception) { var activity = this.context.Activity; + // Always stop activity if it was started if (activity != null) { diff --git a/src/OpenTelemetry.Extensions.Owin/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Extensions.Owin/Implementation/ActivityExtensions.cs index 069bbc81e92..bb2cc6af22b 100644 --- a/src/OpenTelemetry.Extensions.Owin/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Extensions.Owin/Implementation/ActivityExtensions.cs @@ -29,11 +29,11 @@ internal static class ActivityExtensions /// /// Reads Request-Id and Correlation-Context headers and sets ParentId and Baggage on Activity. - /// Based on the code from https://github.com/aspnet/Microsoft.AspNet.TelemetryCorrelation/blob/master/src/Microsoft.AspNet.TelemetryCorrelation/ActivityExtensions.cs#L48 /// /// Instance of activity that has not been started yet. /// Request headers collection. /// true if request was parsed successfully, false - otherwise. + // Based on the code from https://github.com/aspnet/Microsoft.AspNet.TelemetryCorrelation/blob/master/src/Microsoft.AspNet.TelemetryCorrelation/ActivityExtensions.cs#L48. public static bool Extract(this Activity activity, IHeaderDictionary requestHeaders) { if (activity == null) diff --git a/src/OpenTelemetry.Extensions.Owin/Implementation/Context.cs b/src/OpenTelemetry.Extensions.Owin/Implementation/Context.cs index 23502a4c667..3c21c83c663 100644 --- a/src/OpenTelemetry.Extensions.Owin/Implementation/Context.cs +++ b/src/OpenTelemetry.Extensions.Owin/Implementation/Context.cs @@ -21,7 +21,9 @@ namespace OpenTelemetry.Implementation internal class Context { public Activity Activity { get; set; } - internal bool HasDiagnosticListener { get; set; } + + public bool HasDiagnosticListener { get; set; } + public bool EventLogEnabled { get; set; } } } diff --git a/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderDictionaryExtensions.cs b/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderDictionaryExtensions.cs index 6fd280a9042..b8dccfe8015 100644 --- a/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderDictionaryExtensions.cs +++ b/src/OpenTelemetry.Extensions.Owin/Implementation/HeaderDictionaryExtensions.cs @@ -29,10 +29,10 @@ internal static class HeaderDictionaryExtensions /// /// Reads Correlation-Context and populates it on Activity.Baggage following https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/HttpCorrelationProtocol.md#correlation-context. /// Use this method when you want force parsing Correlation-Context is absence of Request-Id or traceparent. - /// Based on the code from https://github.com/microsoft/ApplicationInsights-dotnet/blob/2.15.0/WEB/Src/Common/WebHeaderCollectionExtensions.cs#L135 /// /// Header collection. /// Activity to populate baggage on. + // Based on the code from https://github.com/microsoft/ApplicationInsights-dotnet/blob/2.15.0/WEB/Src/Common/WebHeaderCollectionExtensions.cs#L135. public static void ReadActivityBaggage(this IHeaderDictionary headers, Activity activity) { Debug.Assert(headers != null, "Headers must not be null"); @@ -80,6 +80,7 @@ public static void ReadActivityBaggage(this IHeaderDictionary headers, Activity if (separatorInd > 0 && separatorInd < kvp.Length - 1) { var separatorIndNext = kvp.Slice(separatorInd + 1).IndexOf('='); + // check there is just one '=' in key-value-pair if (separatorIndNext < 0) { diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 1bcc51c877f..28d79344a49 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -1,6 +1,6 @@ - net452;net46;netstandard2.0 + net461;netstandard2.0 OWIN instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;OWIN @@ -10,10 +10,6 @@ - - - - From 2d09ea82b304330ae7fa5937d92a464a49405e03 Mon Sep 17 00:00:00 2001 From: Denis Ivanov Date: Thu, 5 Nov 2020 18:28:03 +0100 Subject: [PATCH 3/3] Formatting fixes. --- src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs | 2 +- .../OpenTelemetry.Extensions.Owin.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs index 3f031a50ba0..3c605234752 100644 --- a/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Extensions.Owin/DiagnosticsMiddleware.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.Owin/OpenTelemetry.Extensions.Owin.csproj b/src/OpenTelemetry.Extensions.Owin/OpenTelemetry.Extensions.Owin.csproj index 87454ea2e6b..fd6e0b24acb 100644 --- a/src/OpenTelemetry.Extensions.Owin/OpenTelemetry.Extensions.Owin.csproj +++ b/src/OpenTelemetry.Extensions.Owin/OpenTelemetry.Extensions.Owin.csproj @@ -5,7 +5,7 @@ A component to the OWIN pipeline for instrumenting incoming request with System.Diagnostics.Activity and notifying listeners with DiagnosticsSource. OpenTelemetry - +