public void ClonedLogContextCanSharedAcrossThreads() { LogEvent?lastEvent = null; var log = new LoggerConfiguration() .Enrich.FromLogContext() .WriteTo.Sink(new DelegatingSink(e => lastEvent = e)) .CreateLogger(); ILogEventEnricher clonedContext; using (LogContext.PushProperty("A", 1)) { clonedContext = LogContext.Clone(); } var t = new Thread(() => { using (LogContext.Push(clonedContext)) { log.Write(Some.InformationEvent()); } }); t.Start(); t.Join(); Assert.NotNull(lastEvent); Assert.Equal(1, lastEvent !.Properties["A"].LiteralValue()); }
public static LogContextDump Serialize() { var logContextEnricher = LogContext.Clone(); var captureFactory = new CaptureLogEventPropertyFactory(); logContextEnricher.Enrich(new LogEvent(DateTimeOffset.Now, LogEventLevel.Verbose, null, MessageTemplate.Empty, Enumerable.Empty <LogEventProperty>()), captureFactory); return(captureFactory.Dump()); }
/// <summary> /// Captures Exceptions at the context where they occur. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> static void CurrentDomain_FirstChanceException(object sender, FirstChanceExceptionEventArgs args) { if (args.Exception != null) { if (context.TryGetValue(args.Exception, out var enricher) == false) { context.Add(args.Exception, LogContext.Clone()); } } }
private void CurrentDomain_FirstChanceException(object sender, FirstChanceExceptionEventArgs exceptionEvent) { try { var context = LogContext.Clone(); // Call Add, not AddOrUpdate. If an exception is logged twice, the context from the original callsite will be preserved. // This is desireable as subsequent throws/logs of the exception will unwind the stack, removing the context we're trying to preserve // Note: this can throw, which absoutely necessitates the try/catch _exceptionToContextLookup.Add(exceptionEvent.Exception, context); } catch { // Any exceptions raised in here cannot be propagated, or the whole application will be taken down } }
public void LogContextCanBeCloned() { LogEvent lastEvent = null; var log = new LoggerConfiguration() .Enrich.FromLogContext() .WriteTo.Sink(new DelegatingSink(e => lastEvent = e)) .CreateLogger(); ILogEventEnricher clonedContext; using (LogContext.PushProperty("A", 1)) { clonedContext = LogContext.Clone(); } using (LogContext.Push(clonedContext)) { log.Write(Some.InformationEvent()); Assert.Equal(1, lastEvent.Properties["A"].LiteralValue()); } }
public async Task InvokeAsync(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } SetHeaders(context); var curCorrelationId = context.Request.Headers[Model.CORRELATION_CURRENT_ID].ToString(); var orgCorrelationId = context.Request.Headers[Model.CORRELATION_ORIGIN_ID].ToString(); var parCorrelationId = string.IsNullOrWhiteSpace(context.Request.Headers[Model.CORRELATION_PARENT_ID]) ? null : context.Request.Headers[Model.CORRELATION_PARENT_ID].ToString(); var user = context.Request.Headers[Model.USER].ToString(); var traceId = string.IsNullOrWhiteSpace(context.Request.Headers[Model.B3_TRACE_ID]) ? _tracer?.ActiveSpan?.Context.TraceId : context.Request.Headers[Model.B3_TRACE_ID].ToString(); try { //Add using for adding more properties using (LogContext.PushProperty(Model.CORRELATION_CURRENT_ID, curCorrelationId, true)) using (LogContext.PushProperty(Model.CORRELATION_ORIGIN_ID, orgCorrelationId, true)) using (LogContext.PushProperty(Model.CORRELATION_PARENT_ID, parCorrelationId, true)) using (LogContext.PushProperty(Model.METHOD, context.Request.Method, true)) using (LogContext.PushProperty(Model.USER, user, true)) using (traceId != null ? LogContext.PushProperty(Model.Trace_Id, traceId, true) : null) { //if trace is on then delegate will be invoked before //response headers will be sent to the client if (_traceConfiguration.Enabled) { //trace if there is no endpoint to exclude OR not matching request path if (string.IsNullOrWhiteSpace(_traceConfiguration.ExcludePattern) || !Regex.IsMatch(context.Request.Path, _traceConfiguration.ExcludePattern, RegexOptions.IgnoreCase)) { // Start the Timer using Stopwatch var watch = new Stopwatch(); var logEventEnricher = LogContext.Clone(); watch.Start(); context.Response.OnStarting(() => { // Stop the timer information and calculate the time watch.Stop(); var responseTimeNS = watch.ElapsedMilliseconds * 1000000; using (LogContext.Push(logEventEnricher)) using (LogContext.PushProperty(Model.DURATION_NS, responseTimeNS, true)) using (LogContext.PushProperty(Model.STATUS_CODE, context.Response.StatusCode, true)) { Log.Information("TRACING"); } return(Task.CompletedTask); }); } } await _next(context); } } //To make sure that we don't loose the scope in case of an unexpected error catch (Exception ex) when(LogOnUnexpectedError(ex)) { return; } }