Skip to content

Commit 050d938

Browse files
Sergey KanzhelevJinhuafei
authored andcommitted
Few fixes (#16)
* add event register package * added the stylecop * add all misc files
1 parent 8b59db4 commit 050d938

16 files changed

Lines changed: 292 additions & 102 deletions

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Contributing
2+
======
3+
4+
Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo.

LICENSE.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Copyright (c) .NET Foundation. All rights reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4+
these files except in compliance with the License. You may obtain a copy of the
5+
License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software distributed
10+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
12+
specific language governing permissions and limitations under the License.

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Telemetry correlation http module
2+
3+
Telemetry correlation http module enables cross tier telemetry tracking.
4+
5+
- Reads http headers
6+
- Start/Stops Activity for the http request
7+
- Ensure the Activity ambient state is transferred thru the IIS callbacks
8+
9+
See http protocol [specifications](https://github.com/lmolkova/corefx/blob/80e8a8d767a71f413fd7b2f11b507cd395110e8d/src/System.Diagnostics.DiagnosticSource/src/FlatRequestId.md) for details.
10+
11+
12+
This http module is used by Application Insights. See [documentation](https://docs.microsoft.com/en-us/azure/application-insights/application-insights-correlation) and [code](https://github.com/Microsoft/ApplicationInsights-dotnet-server).
13+

src/Microsoft.AspNet.TelemetryCorrelation/ActivityExtensions.cs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System;
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
25
using System.Collections.Specialized;
36
using System.ComponentModel;
47
using System.Diagnostics;
@@ -12,31 +15,39 @@ namespace Microsoft.AspNet.TelemetryCorrelation
1215
[EditorBrowsable(EditorBrowsableState.Never)]
1316
public static class ActivityExtensions
1417
{
18+
/// <summary>
19+
/// Http header name to carry the Request ID.
20+
/// </summary>
1521
internal const string RequestIDHeaderName = "Request-Id";
22+
23+
/// <summary>
24+
/// Http header name to carry the correlation context.
25+
/// </summary>
1626
internal const string CorrelationContextHeaderName = "Correlation-Context";
1727

1828
/// <summary>
1929
/// Reads Request-Id and Correlation-Context headers and sets ParentId and Baggage on Activity.
2030
/// </summary>
2131
/// <param name="activity">Instance of activity that has not been started yet.</param>
2232
/// <param name="requestHeaders">Request headers collection.</param>
33+
/// <returns>true if request was parsed successfully, false - otherwise.</returns>
2334
public static bool Extract(this Activity activity, NameValueCollection requestHeaders)
2435
{
2536
if (activity == null)
2637
{
27-
AspNetTelemetryCorrelaitonEventSource.Log.ActvityExtractionError("activity is null");
38+
AspNetTelemetryCorrelationEventSource.Log.ActvityExtractionError("activity is null");
2839
return false;
2940
}
3041

3142
if (activity.ParentId != null)
3243
{
33-
AspNetTelemetryCorrelaitonEventSource.Log.ActvityExtractionError("ParentId is already set on activity");
44+
AspNetTelemetryCorrelationEventSource.Log.ActvityExtractionError("ParentId is already set on activity");
3445
return false;
3546
}
3647

3748
if (activity.Id != null)
3849
{
39-
AspNetTelemetryCorrelaitonEventSource.Log.ActvityExtractionError("Activity is already started");
50+
AspNetTelemetryCorrelationEventSource.Log.ActvityExtractionError("Activity is already started");
4051
return false;
4152
}
4253

@@ -46,23 +57,22 @@ public static bool Extract(this Activity activity, NameValueCollection requestHe
4657
// there may be several Request-Id header, but we only read the first one
4758
activity.SetParentId(requestIDs[0]);
4859

49-
// Header format - Correlation-Context: key1=value1, key2=value2
60+
// Header format - Correlation-Context: key1=value1, key2=value2
5061
var baggages = requestHeaders.GetValues(CorrelationContextHeaderName);
5162
if (baggages != null)
5263
{
53-
// there may be several Correlation-Context header
64+
// there may be several Correlation-Context header
5465
foreach (var item in baggages)
5566
{
5667
foreach (var pair in item.Split(','))
5768
{
58-
NameValueHeaderValue baggageItem;
59-
if (NameValueHeaderValue.TryParse(pair, out baggageItem))
69+
if (NameValueHeaderValue.TryParse(pair, out NameValueHeaderValue baggageItem))
6070
{
6171
activity.AddBaggage(baggageItem.Name, baggageItem.Value);
6272
}
6373
else
6474
{
65-
AspNetTelemetryCorrelaitonEventSource.Log.HeaderParsingError(CorrelationContextHeaderName, pair);
75+
AspNetTelemetryCorrelationEventSource.Log.HeaderParsingError(CorrelationContextHeaderName, pair);
6676
}
6777
}
6878
}
@@ -74,10 +84,12 @@ public static bool Extract(this Activity activity, NameValueCollection requestHe
7484
return false;
7585
}
7686

77-
7887
/// <summary>
79-
///
88+
/// Reads Request-Id and Correlation-Context headers and sets ParentId and Baggage on Activity.
8089
/// </summary>
90+
/// <param name="activity">Instance of activity that has not been started yet.</param>
91+
/// <param name="requestHeaders">Request headers collection.</param>
92+
/// <returns>true if request was parsed successfully, false - otherwise.</returns>
8193
[Obsolete("Method is obsolete, use Extract method instead", true)]
8294
[EditorBrowsable(EditorBrowsableState.Never)]
8395
public static bool TryParse(this Activity activity, NameValueCollection requestHeaders)

src/Microsoft.AspNet.TelemetryCorrelation/ActivityHelper.cs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System.Diagnostics;
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Diagnostics;
25
using System.Web;
36

47
namespace Microsoft.AspNet.TelemetryCorrelation
@@ -8,20 +11,40 @@ namespace Microsoft.AspNet.TelemetryCorrelation
811
/// </summary>
912
internal static class ActivityHelper
1013
{
14+
/// <summary>
15+
/// Listener name.
16+
/// </summary>
1117
public const string AspNetListenerName = "Microsoft.AspNet.TelemetryCorrelation";
18+
19+
/// <summary>
20+
/// Activity name for http request.
21+
/// </summary>
1222
public const string AspNetActivityName = "Microsoft.AspNet.HttpReqIn";
23+
24+
/// <summary>
25+
/// Event name for the activity start event.
26+
/// </summary>
1327
public const string AspNetActivityStartName = "Microsoft.AspNet.HttpReqIn.Start";
28+
29+
/// <summary>
30+
/// Event name for the activity stop event.
31+
/// </summary>
1432
public const string AspNetActivityLostStopName = "Microsoft.AspNet.HttpReqIn.ActivityLost.Stop";
1533

34+
/// <summary>
35+
/// Key to store the activity in HttpContext.
36+
/// </summary>
1637
public const string ActivityKey = "__AspnetActivity__";
17-
private static readonly DiagnosticListener s_aspNetListener = new DiagnosticListener(AspNetListenerName);
38+
39+
private static readonly DiagnosticListener AspNetListener = new DiagnosticListener(AspNetListenerName);
1840

1941
/// <summary>
2042
/// It's possible that a request is executed in both native threads and managed threads,
2143
/// in such case Activity.Current will be lost during native thread and managed thread switch.
2244
/// This method is intended to restore the current activity in order to correlate the child
2345
/// activities with the root activity of the request.
2446
/// </summary>
47+
/// <param name="root">Root activity id for the current request.</param>
2548
/// <returns>If it returns an activity, it will be silently stopped with the parent activity</returns>
2649
public static Activity RestoreCurrentActivity(Activity root)
2750
{
@@ -32,13 +55,14 @@ public static Activity RestoreCurrentActivity(Activity root)
3255
var childActivity = new Activity(root.OperationName);
3356
childActivity.SetParentId(root.Id);
3457
childActivity.SetStartTime(root.StartTimeUtc);
35-
foreach(var item in root.Baggage)
58+
foreach (var item in root.Baggage)
3659
{
3760
childActivity.AddBaggage(item.Key, item.Value);
3861
}
62+
3963
childActivity.Start();
4064

41-
AspNetTelemetryCorrelaitonEventSource.Log.ActivityStarted(childActivity.Id);
65+
AspNetTelemetryCorrelationEventSource.Log.ActivityStarted(childActivity.Id);
4266
return childActivity;
4367
}
4468

@@ -55,9 +79,9 @@ public static bool StopAspNetActivity(Activity activity, HttpContext context)
5579
// if activity is in the stack, stop it with Stop event
5680
if (Activity.Current != null)
5781
{
58-
s_aspNetListener.StopActivity(Activity.Current, new { });
82+
AspNetListener.StopActivity(Activity.Current, new { });
5983
RemoveCurrentActivity(context);
60-
AspNetTelemetryCorrelaitonEventSource.Log.ActivityStopped(activity.Id);
84+
AspNetTelemetryCorrelationEventSource.Log.ActivityStopped(activity.Id);
6185
return true;
6286
}
6387
}
@@ -69,51 +93,54 @@ public static void StopLostActivity(Activity activity, HttpContext context)
6993
{
7094
if (activity != null)
7195
{
72-
s_aspNetListener.Write(AspNetActivityLostStopName, new { activity });
96+
AspNetListener.Write(AspNetActivityLostStopName, new { activity });
7397
RemoveCurrentActivity(context);
74-
AspNetTelemetryCorrelaitonEventSource.Log.ActivityStopped(activity.Id, true);
98+
AspNetTelemetryCorrelationEventSource.Log.ActivityStopped(activity.Id, true);
7599
}
76100
}
77101

78102
public static Activity CreateRootActivity(HttpContext context)
79103
{
80-
if (s_aspNetListener.IsEnabled() && s_aspNetListener.IsEnabled(AspNetActivityName))
104+
if (AspNetListener.IsEnabled() && AspNetListener.IsEnabled(AspNetActivityName))
81105
{
82106
var rootActivity = new Activity(ActivityHelper.AspNetActivityName);
83107

84108
rootActivity.Extract(context.Request.Unvalidated.Headers);
85109
if (StartAspNetActivity(rootActivity))
86110
{
87111
SaveCurrentActivity(context, rootActivity);
88-
AspNetTelemetryCorrelaitonEventSource.Log.ActivityStarted(rootActivity.Id);
112+
AspNetTelemetryCorrelationEventSource.Log.ActivityStarted(rootActivity.Id);
89113
return rootActivity;
90114
}
91115
}
116+
92117
return null;
93118
}
94119

95120
private static bool StartAspNetActivity(Activity activity)
96121
{
97-
if (s_aspNetListener.IsEnabled(AspNetActivityName, activity, new { }))
122+
if (AspNetListener.IsEnabled(AspNetActivityName, activity, new { }))
98123
{
99-
if (s_aspNetListener.IsEnabled(AspNetActivityStartName))
124+
if (AspNetListener.IsEnabled(AspNetActivityStartName))
100125
{
101-
s_aspNetListener.StartActivity(activity, new { });
126+
AspNetListener.StartActivity(activity, new { });
102127
}
103128
else
104129
{
105130
activity.Start();
106131
}
132+
107133
return true;
108134
}
109135

110136
return false;
111137
}
112138

113139
/// <summary>
114-
/// This should be called after the Activity starts
115-
/// and only for root activity of a request
140+
/// This should be called after the Activity starts and only for root activity of a request.
116141
/// </summary>
142+
/// <param name="context">Context to save context to.</param>
143+
/// <param name="activity">Activity to save.</param>
117144
private static void SaveCurrentActivity(HttpContext context, Activity activity)
118145
{
119146
Debug.Assert(context != null);

src/Microsoft.AspNet.TelemetryCorrelation/AspNetDiagnosticsEventSource.cs renamed to src/Microsoft.AspNet.TelemetryCorrelation/AspNetTelemetryCorrelationEventSource.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
using System.Diagnostics.Tracing;
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Diagnostics.Tracing;
25

36
namespace Microsoft.AspNet.TelemetryCorrelation
47
{
58
/// <summary>
69
/// ETW EventSource tracing class.
710
/// </summary>
811
[EventSource(Name = "Microsoft-AspNet-Telemetry-Correlation", Guid = "ace2021e-e82c-5502-d81d-657f27612673")]
9-
internal sealed class AspNetTelemetryCorrelaitonEventSource : EventSource
12+
internal sealed class AspNetTelemetryCorrelationEventSource : EventSource
1013
{
1114
/// <summary>
1215
/// Instance of the PlatformEventSource class.
1316
/// </summary>
14-
public static readonly AspNetTelemetryCorrelaitonEventSource Log = new AspNetTelemetryCorrelaitonEventSource();
17+
public static readonly AspNetTelemetryCorrelationEventSource Log = new AspNetTelemetryCorrelationEventSource();
1518

1619
[Event(1, Message = "Callback='{0}'", Level = EventLevel.Verbose)]
1720
public void TraceCallback(string callback)

src/Microsoft.AspNet.TelemetryCorrelation/Microsoft.AspNet.TelemetryCorrelation.csproj

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
2424
<RestorePackages>true</RestorePackages>
2525
<TargetFrameworkProfile />
26+
<NuGetPackageImportStamp>
27+
</NuGetPackageImportStamp>
2628
</PropertyGroup>
2729
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
2830
<DebugSymbols>true</DebugSymbols>
@@ -31,13 +33,17 @@
3133
<DefineConstants>DEBUG;TRACE</DefineConstants>
3234
<ErrorReport>prompt</ErrorReport>
3335
<WarningLevel>4</WarningLevel>
36+
<CodeAnalysisRuleSet>Microsoft.AspNet.TelemetryCorrelation.ruleset</CodeAnalysisRuleSet>
37+
<RunCodeAnalysis>true</RunCodeAnalysis>
3438
</PropertyGroup>
3539
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
3640
<DebugType>pdbonly</DebugType>
3741
<Optimize>true</Optimize>
3842
<DefineConstants>TRACE</DefineConstants>
3943
<ErrorReport>prompt</ErrorReport>
4044
<WarningLevel>4</WarningLevel>
45+
<CodeAnalysisRuleSet>Microsoft.AspNet.TelemetryCorrelation.ruleset</CodeAnalysisRuleSet>
46+
<RunCodeAnalysis>true</RunCodeAnalysis>
4147
</PropertyGroup>
4248
<ItemGroup>
4349
<Reference Include="System" />
@@ -55,11 +61,24 @@
5561
<Compile Include="ActivityExtensions.cs" />
5662
<Compile Include="ActivityHelper.cs" />
5763
<Compile Include="TelemetryCorrelationHttpModule.cs" />
58-
<Compile Include="AspNetDiagnosticsEventSource.cs" />
64+
<Compile Include="AspNetTelemetryCorrelationEventSource.cs" />
5965
<Compile Include="Properties\AssemblyInfo.cs" />
6066
</ItemGroup>
6167
<ItemGroup>
68+
<None Include="Microsoft.AspNet.TelemetryCorrelation.ruleset" />
6269
<None Include="packages.config" />
6370
</ItemGroup>
71+
<ItemGroup>
72+
<Analyzer Include="..\..\packages\StyleCop.Analyzers.1.0.0\analyzers\dotnet\cs\Newtonsoft.Json.dll" />
73+
<Analyzer Include="..\..\packages\StyleCop.Analyzers.1.0.0\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll" />
74+
<Analyzer Include="..\..\packages\StyleCop.Analyzers.1.0.0\analyzers\dotnet\cs\StyleCop.Analyzers.dll" />
75+
</ItemGroup>
6476
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
77+
<Import Project="..\..\packages\Microsoft.Diagnostics.Tracing.EventRegister.1.1.28\build\Microsoft.Diagnostics.Tracing.EventRegister.targets" Condition="Exists('..\..\packages\Microsoft.Diagnostics.Tracing.EventRegister.1.1.28\build\Microsoft.Diagnostics.Tracing.EventRegister.targets')" />
78+
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
79+
<PropertyGroup>
80+
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
81+
</PropertyGroup>
82+
<Error Condition="!Exists('..\..\packages\Microsoft.Diagnostics.Tracing.EventRegister.1.1.28\build\Microsoft.Diagnostics.Tracing.EventRegister.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Diagnostics.Tracing.EventRegister.1.1.28\build\Microsoft.Diagnostics.Tracing.EventRegister.targets'))" />
83+
</Target>
6584
</Project>

0 commit comments

Comments
 (0)