Skip to content

Commit 608bac1

Browse files
committed
Upgrading example PostSharp.Samples.Logging.ElasticStack.
1 parent 74a9faa commit 608bac1

File tree

11 files changed

+184
-85
lines changed

11 files changed

+184
-85
lines changed

Diagnostics/PostSharp.Samples.Logging.ElasticStack/ClientExample/ClientExample.csproj

+3-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
<PropertyGroup>
55
<OutputType>Exe</OutputType>
66
<TargetFramework>netcoreapp2.1</TargetFramework>
7-
<LangVersion>7.2</LangVersion>
7+
<LangVersion>7.3</LangVersion>
88
<Platforms>AnyCPU</Platforms>
9-
<Configurations >Debug;Release;Development</Configurations>
9+
<Configurations>Debug;Release;Development</Configurations>
1010
<PostSharpBuild Condition="'$(Configuration)'=='Development'">Debug</PostSharpBuild>
1111
</PropertyGroup>
1212

@@ -22,7 +22,6 @@
2222
<ItemGroup Condition="'$(Configuration)'!='Development'">
2323
<PackageReference Include="PostSharp.Patterns.Diagnostics" Version="6.1.6-preview" />
2424
<PackageReference Include="PostSharp.Patterns.Diagnostics.Serilog" Version="6.1.6-preview" />
25-
<PackageReference Include="PostSharp.Patterns.Diagnostics.ApplicationInsights" Version="6.1.6-preview" />
2625
</ItemGroup>
2726

2827
<ItemGroup Condition="'$(Configuration)'=='Development'">
@@ -35,13 +34,10 @@
3534
<Reference Include="PostSharp.Patterns.Diagnostics">
3635
<HintPath>C:\src\postsharp\Patterns\Build\bin\Debug\netstandard2.0\PostSharp.Patterns.Diagnostics.dll</HintPath>
3736
</Reference>
38-
<Reference Include="PostSharp.Patterns.Diagnostics.Backends.ApplicationInsights">
39-
<HintPath>C:\src\postsharp\Patterns\Build\bin\Debug\netstandard2.0\PostSharp.Patterns.Diagnostics.Backends.ApplicationInsights.dll</HintPath>
40-
</Reference>
4137
<Reference Include="PostSharp.Patterns.Diagnostics.Backends.Serilog">
4238
<HintPath>C:\src\postsharp\Patterns\Build\bin\Debug\netstandard2.0\PostSharp.Patterns.Diagnostics.Backends.Serilog.dll</HintPath>
4339
</Reference>
44-
<PostSharpAddIn Include="C:\src\postsharp\Patterns\Build\bin\Debug\PostSharp.Patterns.Common.Weaver.dll"/>
40+
<PostSharpAddIn Include="C:\src\postsharp\Patterns\Build\bin\Debug\PostSharp.Patterns.Common.Weaver.dll" />
4541
</ItemGroup>
4642

4743
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />

Diagnostics/PostSharp.Samples.Logging.ElasticStack/ClientExample/InstrumentOutgoingRequestsAspect.cs

+65-15
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Net.Http;
4+
using System.Runtime.Serialization;
5+
using System.Text;
36
using System.Threading.Tasks;
47
using ClientExample;
58
using PostSharp.Aspects;
69
using PostSharp.Patterns.Diagnostics;
10+
using PostSharp.Patterns.Formatters;
711
using PostSharp.Serialization;
812
using static PostSharp.Patterns.Diagnostics.SemanticMessageBuilder;
913

10-
[assembly: InstrumentOutgoingRequestsAspect( AttributeTargetAssemblies = "System.Net.Http",
14+
// The following attribute intercepts all calls to the specified methods of HttpClient.
15+
[assembly: InstrumentOutgoingRequestsAspect(
16+
AttributeTargetAssemblies = "System.Net.Http",
1117
AttributeTargetTypes = "System.Net.Http.HttpClient",
1218
AttributeTargetMembers = "regex:(Get*|Delete|Post|Push|Patch)Async" )]
1319

@@ -16,7 +22,7 @@ namespace ClientExample
1622
[PSerializable]
1723
internal class InstrumentOutgoingRequestsAspect : MethodInterceptionAspect
1824
{
19-
private static readonly LogSource logger = LogSource.Get();
25+
private static readonly LogSource logSource = LogSource.Get();
2026

2127
public override async Task OnInvokeAsync( MethodInterceptionArgs args )
2228
{
@@ -25,13 +31,66 @@ public override async Task OnInvokeAsync( MethodInterceptionArgs args )
2531

2632
var verb = Trim( args.Method.Name, "Async" );
2733

28-
using ( var activity = logger.Default.OpenActivity( Semantic( verb, ("Url", args.Arguments[0] ) ) ) )
34+
using ( var activity = logSource.Default.OpenActivity( Semantic( verb, ("Url", args.Arguments[0] ) ) ) )
2935
{
3036
try
3137
{
38+
// TODO: this implementation conflicts with System.Diagnostics.Activity.
3239

40+
41+
// Remove headers.
3342
http.DefaultRequestHeaders.Remove( "Request-Id" );
34-
http.DefaultRequestHeaders.Add( "Request-Id", activity.ContextId );
43+
http.DefaultRequestHeaders.Remove( "Correlation-Context" );
44+
45+
46+
// Set Request-Id header.
47+
http.DefaultRequestHeaders.Add( "Request-Id", activity.Context.SyntheticId );
48+
49+
50+
// Generate the Correlation-Context header.
51+
UnsafeStringBuilder correlationContextBuilder = null;
52+
var propertyNames = new HashSet<string>();
53+
try
54+
{
55+
activity.Context.ForEachProperty((LoggingProperty property, object value, ref object state) =>
56+
{
57+
if (property.IsBaggage)
58+
{
59+
if (correlationContextBuilder == null)
60+
{
61+
propertyNames = new HashSet<string>();
62+
correlationContextBuilder = new UnsafeStringBuilder(1024);
63+
}
64+
65+
if (propertyNames.Add(property.Name))
66+
{
67+
68+
if (correlationContextBuilder.Length > 0)
69+
{
70+
correlationContextBuilder.Append(", ");
71+
}
72+
73+
correlationContextBuilder.Append(property.Name);
74+
correlationContextBuilder.Append('=');
75+
76+
var formatter =
77+
property.Formatter ?? LoggingServices.Formatters.Get(value.GetType());
78+
79+
formatter.Write(correlationContextBuilder, value);
80+
}
81+
}
82+
});
83+
84+
if (correlationContextBuilder != null)
85+
{
86+
http.DefaultRequestHeaders.Add("Correlation-Context", correlationContextBuilder.ToString());
87+
}
88+
}
89+
finally
90+
{
91+
correlationContextBuilder?.Dispose();
92+
}
93+
3594

3695
var t = base.OnInvokeAsync( args );
3796

@@ -78,16 +137,7 @@ public override async Task OnInvokeAsync( MethodInterceptionArgs args )
78137

79138
}
80139

81-
private static string Trim( string s, string suffix )
82-
{
83-
if ( s.EndsWith( suffix ) )
84-
{
85-
return s.Substring( 0, s.Length - suffix.Length );
86-
}
87-
else
88-
{
89-
return s;
90-
}
91-
}
140+
private static string Trim( string s, string suffix )
141+
=> s.EndsWith( suffix ) ? s.Substring( 0, s.Length - suffix.Length ) : s;
92142
}
93143
}
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,52 @@
11
using System;
22
using System.Threading.Tasks;
33
using PostSharp.Patterns.Diagnostics;
4+
using static PostSharp.Patterns.Diagnostics.FormattedMessageBuilder;
45
using PostSharp.Patterns.Diagnostics.Backends.Serilog;
56
using PostSharp.Patterns.Diagnostics.RecordBuilders;
67
using Serilog;
7-
using Serilog.Sinks.Http.BatchFormatters;
88

99
[assembly: Log]
1010

1111
namespace ClientExample
1212
{
1313
public static class Program
1414
{
15+
private static readonly LogSource logSource = LogSource.Get();
16+
1517
private static async Task Main()
1618
{
17-
var logger = new LoggerConfiguration()
18-
.Enrich.WithProperty( "Application", "ClientExample" )
19+
using (var logger = new LoggerConfiguration()
20+
.Enrich.WithProperty("Application", "ClientExample")
1921
.MinimumLevel.Debug()
20-
.WriteTo.Async( a => a.DurableHttp( requestUri: "http://localhost:31311", batchFormatter: new ArrayBatchFormatter(), batchPostingLimit: 5 ) )
21-
.WriteTo.Console( outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {Indent:l}{Message:l}{NewLine}{Exception}" )
22-
.CreateLogger();
23-
22+
.WriteTo.Async(a => a.DurableHttp(requestUri: "http://localhost:31311", batchPostingLimit: 5))
23+
.WriteTo.Console(
24+
outputTemplate:
25+
"{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {Indent:l}{Message:l}{NewLine}{Exception}")
26+
.CreateLogger())
27+
{
28+
var backend = new SerilogLoggingBackend(logger);
29+
backend.Options.IncludeActivityExecutionTime = true;
30+
backend.Options.IncludeExceptionDetails = true;
31+
backend.Options.SemanticParametersTreatedSemantically = SemanticParameterKind.All;
32+
backend.Options.IncludedSpecialProperties = SerilogSpecialProperties.None;
33+
backend.Options.ContextIdGenerationStrategy = ContextIdGenerationStrategy.Hierarchical;
34+
LoggingServices.DefaultBackend = backend;
2435

25-
var backend = new SerilogLoggingBackend( logger );
26-
LoggingServices.Roles["Custom"].CustomRecordLoggingOptions.IncludeExecutionTime = true;
27-
backend.Options.IncludeExceptionDetails = true;
28-
backend.Options.SemanticParametersTreatedSemantically |= SemanticParameterKind.MemberName;
29-
backend.Options.AddEventIdProperty = true;
30-
backend.Options.ContextIdGenerationStrategy = LoggingOperationIdGenerationStrategy.Hierarchical;
31-
LoggingServices.DefaultBackend = backend;
3236

33-
using ( logger )
34-
{
35-
await QueueProcessor.ProcessQueue( ".\\My\\Queue" );
37+
using (logSource.Debug.OpenActivity(Formatted("Running the client"), new OpenActivityOptions
38+
{
39+
Properties = new[]
40+
{
41+
new LoggingProperty("User", "Gaius Julius Caesar") {IsBaggage = true}
42+
}
43+
}))
44+
{
45+
await QueueProcessor.ProcessQueue(".\\My\\Queue");
46+
}
3647
}
3748

38-
Console.WriteLine( "Done!" );
49+
Console.WriteLine("Done!");
3950
}
40-
4151
}
42-
}
52+
}

Diagnostics/PostSharp.Samples.Logging.ElasticStack/ClientExample/QueueProcessor.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ namespace ClientExample
88
{
99
public class QueueProcessor
1010
{
11-
private static readonly Logger logger = Logger.GetLogger();
11+
private static readonly LogSource logger = LogSource.Get();
1212

13-
private static HttpClient http = new HttpClient();
13+
private static readonly HttpClient http = new HttpClient();
1414

1515
static QueueProcessor()
1616
{
@@ -65,7 +65,7 @@ private static async Task ProcessItem( QueueItem item )
6565
}
6666
catch ( Exception e )
6767
{
68-
logger.WriteException( LogLevel.Warning, e, "Ignoring exception and continuing." );
68+
logger.Warning.Write( FormattedMessageBuilder.Formatted( "Ignoring exception and continuing." ), e );
6969
}
7070

7171
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Debug",
5+
"System": "Information",
6+
"Microsoft": "Information"
7+
}
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Warning"
5+
}
6+
},
7+
"AllowedHosts": "*",
8+
"ApplicationInsights": {
9+
"InstrumentationKey": "4f9d01cc-aa54-4270-ad8f-04b89088b8a2"
10+
}
11+
}

Diagnostics/PostSharp.Samples.Logging.ElasticStack/MicroserviceExample/Connected Services/Application Insights/ConnectedService.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider",
3-
"Version": "8.13.10627.1",
3+
"Version": "8.14.11009.1",
44
"GettingStartedDocument": {
55
"Uri": "https://go.microsoft.com/fwlink/?LinkID=798432"
66
}

Diagnostics/PostSharp.Samples.Logging.ElasticStack/MicroserviceExample/LoggingActionFilter.cs

+25-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Net;
34
using System.Threading.Tasks;
45
using Microsoft.AspNetCore.Mvc.Filters;
@@ -17,29 +18,48 @@ public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionE
1718

1819
// Read the Request-Id header so we can assign it to the activity.
1920
string parentOperationId = context.HttpContext.Request.Headers["Request-Id"];
21+
string correlationContext = context.HttpContext.Request.Headers["Correlation-Context"];
2022

2123
OpenActivityOptions options = default;
2224

25+
// Set the parent id.
2326
if (!string.IsNullOrEmpty(parentOperationId))
2427
{
25-
options.ParentId = parentOperationId;
28+
options.SyntheticParentId = parentOperationId;
2629
}
2730
else
2831
{
29-
options.IsRoot = true;
32+
options.IsSyntheticRootId = true;
33+
}
34+
35+
// Define the baggage.
36+
if (!string.IsNullOrEmpty(correlationContext))
37+
{
38+
var properties = new List<LoggingProperty>();
39+
foreach (var pair in correlationContext.Split(',', StringSplitOptions.RemoveEmptyEntries))
40+
{
41+
var posOfEqual = pair.IndexOf('=');
42+
if (posOfEqual <= 0) continue;
43+
var propertyName = pair.Substring(0, posOfEqual);
44+
var propertyValue = pair.Substring(posOfEqual + 1);
45+
properties.Add(new LoggingProperty(propertyName, propertyValue) { IsBaggage = true});
46+
47+
}
48+
49+
options.Properties = properties.ToArray();
3050
}
3151

3252
var request = context.HttpContext.Request;
33-
using (var activity = logger.Default.OpenActivity(Semantic("Request", ("Path", request.Path),
34-
("Query", request.QueryString), ("Method", request.Method)), options))
53+
using (var activity = logger.Default.OpenActivity( Semantic("Request", ("Path", request.Path),
54+
("Query", request.QueryString), ("Method", request.Method)), options))
3555
{
3656
try
3757
{
3858
await next();
3959

4060
var response = context.HttpContext.Response;
4161

42-
if (response.StatusCode >= (int) HttpStatusCode.OK && response.StatusCode <= (int) 299)
62+
if (response.StatusCode >= (int) HttpStatusCode.OK && response.StatusCode <= 299)
4363
{
4464
// Success.
4565
activity.SetOutcome( LogLevel.Info, Semantic("Success", ("StatusCode", response.StatusCode)));

Diagnostics/PostSharp.Samples.Logging.ElasticStack/MicroserviceExample/MicroserviceExample.csproj

+5-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<PropertyGroup>
66
<TargetFramework>netcoreapp2.1</TargetFramework>
7-
<LangVersion>7.2</LangVersion>
7+
<LangVersion>7.3</LangVersion>
88
<OutputType>Exe</OutputType>
99
<Configurations>Debug;Release;Development</Configurations>
1010
<Platforms>AnyCPU</Platforms>
@@ -27,7 +27,6 @@
2727
<ItemGroup Condition="'$(Configuration)'!='Development'">
2828
<PackageReference Include="PostSharp.Patterns.Diagnostics" Version="6.1.6-preview" />
2929
<PackageReference Include="PostSharp.Patterns.Diagnostics.Serilog" Version="6.1.6-preview" />
30-
<PackageReference Include="PostSharp.Patterns.Diagnostics.ApplicationInsights" Version="6.1.6-preview" />
3130
</ItemGroup>
3231

3332
<ItemGroup Condition="'$(Configuration)'=='Development'">
@@ -43,13 +42,13 @@
4342
<Reference Include="PostSharp.Patterns.Diagnostics.Backends.Serilog">
4443
<HintPath>C:\src\postsharp\Patterns\Build\bin\Debug\netstandard2.0\PostSharp.Patterns.Diagnostics.Backends.Serilog.dll</HintPath>
4544
</Reference>
46-
<Reference Include="PostSharp.Patterns.Diagnostics.Backends.ApplicationInsights">
47-
<HintPath>C:\src\postsharp\Patterns\Build\bin\Debug\netstandard2.0\PostSharp.Patterns.Diagnostics.Backends.ApplicationInsights.dll</HintPath>
48-
</Reference>
49-
5045
<PostSharpAddIn Include="C:\src\postsharp\Patterns\Build\bin\Debug\PostSharp.Patterns.Common.Weaver.dll" />
5146
</ItemGroup>
5247

48+
<ItemGroup>
49+
<WCFMetadata Include="Connected Services" />
50+
</ItemGroup>
51+
5352
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk.Web" />
5453

5554
<Import Project="C:\src\postsharp\Build\bin\PostSharp.targets" Condition="'$(Configuration)'=='Development'" />

0 commit comments

Comments
 (0)