Skip to content

Instantly share code, notes, and snippets.

@gertjvr
Last active October 14, 2022 14:28
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gertjvr/3ee7674f359942d964952dfd80753e00 to your computer and use it in GitHub Desktop.
Save gertjvr/3ee7674f359942d964952dfd80753e00 to your computer and use it in GitHub Desktop.
MT3 + Serilog CorrelationId Enricher.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Threading.Tasks;
using MassTransit;
using MassTransit.Configurators;
using MassTransit.PipeBuilders;
using MassTransit.PipeConfigurators;
using MassTransit.Pipeline;
using Serilog;
using Serilog.Configuration;
using Serilog.Core;
using Serilog.Events;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.Enrich.WithThreadId()
.Enrich.WithCorrelationId("CorrelationId")
.WriteTo.Seq("http://seq.localtest.me:5341/")
.WriteTo.ColoredConsole()
.CreateLogger();
var bus = Bus.Factory.CreateUsingInMemory(cfg =>
{
cfg.UseSerilog(Log.Logger);
cfg.ConfigurePublish(x => x.UseSendExecute(y => y.CorrelationId = Guid.NewGuid()));
cfg.ReceiveEndpoint("input", endpoint =>
{
endpoint.UseSeriLogEnricher();
endpoint.Consumer<CommandConsumer>();
});
});
bus.Start();
bus.Publish(new Command("Hello"));
Console.ReadLine();
bus.Stop();
}
}
public static class CorrelationContext
{
public const string IdKey = "CorrelationId";
public static string Id
{
get { return IdKey.Get(() => Guid.NewGuid().ToString()); }
set { IdKey.Set(value); }
}
static T Get<T>(this string key, Func<T> defaulter = null)
{
var value = (T)CallContext.LogicalGetData(key);
if (defaulter != null && EqualityComparer<T>.Default.Equals(value, default(T)))
{
value = defaulter();
key.Set(value);
}
return value;
}
static void Set<T>(this string key, T value)
{
CallContext.LogicalSetData(key, value);
}
}
public static class SerilogConfigurationExtensions
{
public static LoggerConfiguration WithCorrelationId(this LoggerEnrichmentConfiguration configuration, string propertyName)
{
return configuration.With((ILogEventEnricher)new CorrelationIdEnricher(propertyName));
}
}
public class CorrelationIdEnricher : ILogEventEnricher
{
private readonly string _propertyName;
public CorrelationIdEnricher(string propertyName)
{
_propertyName = propertyName;
}
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory factory)
{
logEvent.AddOrUpdateProperty(factory.CreateProperty(_propertyName, CorrelationContext.Id));
}
}
public static class ExampleMiddlewareConfiguratorExtensions
{
public static void UseSeriLogEnricher<T>(this IPipeConfigurator<T> configurator)
where T : class, PipeContext
{
configurator.AddPipeSpecification(new SerilogEnricherSpecification<T>());
}
}
public class SerilogEnricherSpecification<T> : IPipeSpecification<T> where T : class, PipeContext
{
public IEnumerable<ValidationResult> Validate()
{
return Enumerable.Empty<ValidationResult>();
}
public void Apply(IPipeBuilder<T> builder)
{
builder.AddFilter(new SerilogEnricherFilter<T>());
}
}
public class SerilogEnricherFilter<T> : IFilter<T>
where T : class, PipeContext
{
public void Probe(ProbeContext context)
{
var scope = context.CreateFilterScope("SerilogEnricher");
scope.Add("CorrelationId", CorrelationContext.Id);
}
public async Task Send(T context, IPipe<T> next)
{
var consumeContext = context.GetPayload<ConsumeContext>();
CorrelationContext.Id = consumeContext.CorrelationId.Value.ToString();
await next.Send(context);
}
}
public class Command
{
public Command(string say)
{
Say = say;
}
public string Say { get; }
}
class CommandConsumer : IConsumer<Command>
{
public string X { get; set; }
public Task Consume(ConsumeContext<Command> context)
{
Log.Logger.Debug("Say: {Say}", context.Message.Say);
return Task.CompletedTask;
}
}
}
@ffMathy
Copy link

ffMathy commented Oct 28, 2019

Where is CallContext from?

@gertjvr
Copy link
Author

gertjvr commented Oct 28, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment