/// <summary>
        /// Processes a request to synchronise TraceIdentifier and Correlation ID headers. Also creates a
        /// <see cref="CorrelationContext"/> for the current request and disposes of it when the request is completing.
        /// </summary>
        /// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
        /// <param name="correlationContextFactory">The <see cref="ICorrelationContextFactory"/> which can create a <see cref="CorrelationContext"/>.</param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context, ICorrelationContextFactory correlationContextFactory)
        {
            if (context.Request.Headers.TryGetValue(_options.Value.Header, out var correlationId))
            {
                context.TraceIdentifier = correlationId;
            }

            correlationContextFactory.Create(context.TraceIdentifier);

            if (_options.Value.IncludeInResponse)
            {
                // apply the correlation ID to the response header for client side tracking
                context.Response.OnStarting(() =>
                {
                    if (!context.Response.Headers.ContainsKey(_options.Value.Header))
                    {
                        context.Response.Headers.Add(_options.Value.Header, context.TraceIdentifier);
                    }

                    return(Task.CompletedTask);
                });
            }

            await _next(context);

            correlationContextFactory.Dispose();
        }
예제 #2
0
        public async Task Invoke(HttpContext context, ICorrelationContextFactory correlationContextFactory)
        {
            var correlationId = SetCorrelationId(context);

            if (_options.UpdateTraceIdentifier)
            {
                context.TraceIdentifier = correlationId.ToString();
            }

            correlationContextFactory.Create(correlationId, _options.Header);

            if (_options.IncludeInResponse)
            {
                // apply the correlation ID to the response header for client side tracking
                context.Response.OnStarting(() =>
                {
                    if (!context.Response.Headers.ContainsKey(_options.Header))
                    {
                        context.Response.Headers.Add(_options.Header, correlationId.ToString());
                    }

                    return(Task.CompletedTask);
                });
            }

            //using (LogContext.PushProperty(_options.Header, correlationId))
            //{
            //    await _next(context);
            //}

            await _next(context);

            correlationContextFactory.Dispose();
        }
예제 #3
0
 public ExceptionInterceptor(IOptions <CorrelationIdOptions> options,
                             ICorrelationContextFactory correlationContextFactory,
                             ILogger <ExceptionInterceptor> logger)
 {
     _options = options.Value ?? throw new ArgumentNullException(nameof(options));
     _correlationContextFactory = correlationContextFactory ?? throw new ArgumentNullException(nameof(correlationContextFactory));
     _logger = logger;
 }
예제 #4
0
 public RootActivity(
     ICorrelationContextFactory correlationContextFactory,
     ILogger logger,
     DiagnosticListener?diagnosticListener)
 {
     _correlationContextFactory = correlationContextFactory ?? throw new ArgumentNullException(nameof(correlationContextFactory));
     _logger             = logger ?? throw new ArgumentNullException(nameof(logger));
     _diagnosticListener = diagnosticListener;
 }
예제 #5
0
 public CorrelationManager(
     ICorrelationContextFactory correlationContextFactory,
     ICorrelationIdFactory correlationIdFactory,
     ILogger <CorrelationManager> logger,
     DiagnosticListener diagnosticListener
     ) : this(correlationContextFactory, correlationIdFactory, logger)
 {
     _diagnosticListener = diagnosticListener ?? throw new ArgumentNullException(nameof(diagnosticListener));
 }
        /// <summary>
        /// Processes a request to synchronise TraceIdentifier and Correlation ID headers. Also creates a
        /// <see cref="CorrelationContext"/> for the current request and disposes of it when the request is completing.
        /// </summary>
        /// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
        /// <param name="correlationContextFactory">The <see cref="ICorrelationContextFactory"/> which can create a <see cref="CorrelationContext"/>.</param>
        public async Task Invoke(HttpContext context, ICorrelationContextFactory correlationContextFactory)
        {
            Log.CorrelationIdProcessingBegin(_logger);

            var hasCorrelationIdHeader = context.Request.Headers.TryGetValue(CorrelationIdHeaderName, out var cid) &&
                                         !StringValues.IsNullOrEmpty(cid);

            var correlationId = hasCorrelationIdHeader ? cid.FirstOrDefault() : null;

            if (hasCorrelationIdHeader)
            {
                Log.FoundCorrelationIdHeader(_logger, correlationId);
            }
            else
            {
                Log.MissingCorrelationIdHeader(_logger);
            }

            if (RequiresGenerationOfCorrelationId(hasCorrelationIdHeader, cid))
            {
                correlationId = GenerateCorrelationId(context.TraceIdentifier);
            }

            if (!string.IsNullOrEmpty(correlationId))
            {
                Log.UpdatingTraceIdentifier(_logger);

                context.TraceIdentifier = correlationId;
            }

            Log.CreatingCorrelationContext(_logger);
            correlationContextFactory.Create(correlationId, CorrelationIdHeaderName);

            if (!string.IsNullOrEmpty(correlationId))
            {
                // apply the correlation ID to the response header for client side tracking
                context.Response.OnStarting(() =>
                {
                    if (!context.Response.Headers.ContainsKey(CorrelationIdHeaderName))
                    {
                        Log.WritingCorrelationIdResponseHeader(_logger, CorrelationIdHeaderName, correlationId);
                        context.Response.Headers.Add(CorrelationIdHeaderName, correlationId);
                    }

                    return(Task.CompletedTask);
                });
            }

            Log.CorrelationIdProcessingEnd(_logger, correlationId);
            await _next(context);

            Log.DisposingCorrelationContext(_logger);
            correlationContextFactory.Dispose();
        }
예제 #7
0
 public CorrelationManager
 (
     ICorrelationContextFactory correlationContextFactory,
     ICorrelationIdFactory correlationIdFactory,
     ILogger <CorrelationManager> logger
 )
 {
     _correlationContextFactory = correlationContextFactory ?? throw new ArgumentNullException(nameof(correlationContextFactory));
     _correlationIdFactory      = correlationIdFactory ?? throw new ArgumentNullException(nameof(correlationIdFactory));
     _logger = logger ?? throw new ArgumentNullException(nameof(logger));
 }
        /// <summary />
        public async Task InvokeAsync(HttpContext httpContext, ICorrelationContextFactory correlationContextFactory, ILogger <CorrelationMiddleware> logger)
        {
            var correlationContext = correlationContextFactory.Create(httpContext);

            // Put correlation identifier into a header.
            httpContext.Items[HeaderNames.CorrelationId] = correlationContext.Id;
            httpContext.Response.Headers.Add(HeaderNames.CorrelationId, correlationContext.Id);

            // Put correlation identifier into a log context.
            using (logger.BeginScope("{CorrelationId}", correlationContext.Id))
            {
                await _next(httpContext);
            }
        }
예제 #9
0
        /// <summary>
        /// Processes a request to synchronise TraceIdentifier and Correlation ID headers. Also creates a
        /// <see cref="CorrelationContext"/> for the current request and disposes of it when the request is completing.
        /// </summary>
        /// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
        /// <param name="contextFactory">The <see cref="ICorrelationContextFactory"/> which can create a <see cref="CorrelationContext"/>.</param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context, ICorrelationContextFactory contextFactory)
        {
            var correlationId = this.EnsureCorrelationId(context);
            var requestId     = this.EnsureRequestId(context);

            var loggerState = new Dictionary <string, object>
            {
                [LogEventPropertyKeys.CorrelationId] = correlationId,
                [LogEventPropertyKeys.RequestId]     = requestId
            };

            using (this.logger.BeginScope(loggerState))
            {
                // needed by other request middlewares (requestresponselogging, filtering)
                context.SetCorrelationId(correlationId);
                context.SetRequestId(requestId);

                if (this.options.UpdateTraceIdentifier)
                {
                    this.logger.LogDebug($"{{LogKey:l}} [{requestId}] http now has traceIdentifier {correlationId}, was {context.TraceIdentifier}", LogKeys.InboundRequest); // TODO: move to request logging middleware (operations)
                    context.TraceIdentifier = correlationId;
                }

                contextFactory.Create(correlationId, this.options.CorrelationHeader, requestId, this.options.RequestHeader);

                if (this.options.IncludeInResponse)
                {
                    context.Response.OnStarting(() =>
                    {
                        // add the response headers
                        if (!context.Response.Headers.ContainsKey(this.options.CorrelationHeader))
                        {
                            context.Response.Headers.Add(this.options.CorrelationHeader, correlationId);
                        }

                        if (!context.Response.Headers.ContainsKey(this.options.RequestHeader))
                        {
                            context.Response.Headers.Add(this.options.RequestHeader, requestId);
                        }

                        return(Task.CompletedTask);
                    });
                }

                await this.next(context);
            }

            contextFactory.Dispose();
        }
예제 #10
0
        public ConveyHttpClient(HttpClient client, HttpClientOptions options,
                                ICorrelationContextFactory correlationContextFactory)
        {
            _client  = client;
            _options = options;
            if (string.IsNullOrWhiteSpace(_options.CorrelationContextHeader))
            {
                return;
            }

            var correlationContext = correlationContextFactory.Create();

            _client.DefaultRequestHeaders.TryAddWithoutValidation(_options.CorrelationContextHeader,
                                                                  correlationContext);
        }
예제 #11
0
        public BioworldHttpClient(HttpClient client, HttpClientOptions options,
                                  ICorrelationContextFactory correlationContextFactory, ICorrelationIdFactory correlationIdFactory)
        {
            _client  = client;
            _options = options;
            if (!string.IsNullOrWhiteSpace(_options.CorrelationContextHeader))
            {
                var correlationContext = correlationContextFactory.Create();
                _client.DefaultRequestHeaders.TryAddWithoutValidation(_options.CorrelationContextHeader,
                                                                      correlationContext);
            }

            if (!string.IsNullOrWhiteSpace(_options.CorrelationIdHeader))
            {
                var correlationId = correlationIdFactory.Create();
                _client.DefaultRequestHeaders.TryAddWithoutValidation(_options.CorrelationContextHeader, correlationId);
            }
        }
예제 #12
0
        public LoggerHelper(ICorrelationContextFactory correlationContextFactory)
        {
            Ensure.That(correlationContextFactory).IsNotNull();

            _correlationContextFactory = correlationContextFactory;
        }
예제 #13
0
        /// <summary>
        /// Processes a request to synchronise TraceIdentifier and Correlation ID headers. Also creates a
        /// <see cref="CorrelationContext"/> for the current request and disposes of it when the request is completing.
        /// </summary>
        /// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
        /// <param name="correlationContextFactory">The <see cref="ICorrelationContextFactory"/> which can create a <see cref="CorrelationContext"/>.</param>
        public async Task Invoke(HttpContext context, ICorrelationContextFactory correlationContextFactory)
        {
            Log.CorrelationIdProcessingBegin(_logger);

            if (_correlationIdProvider is null)
            {
                Log.MissingCorrelationIdProvider(_logger);

                throw new InvalidOperationException("No 'ICorrelationIdProvider' has been registered. You must either add the correlation ID services" +
                                                    " using the 'AddDefaultCorrelationId' extension method or you must register a suitable provider using the" +
                                                    " 'ICorrelationIdBuilder'.");
            }

            var hasCorrelationIdHeader = context.Request.Headers.TryGetValue(_options.RequestHeader, out var cid) &&
                                         !StringValues.IsNullOrEmpty(cid);

            if (!hasCorrelationIdHeader && _options.EnforceHeader)
            {
                Log.EnforcedCorrelationIdHeaderMissing(_logger);

                context.Response.StatusCode = StatusCodes.Status400BadRequest;
                await context.Response.WriteAsync($"The '{_options.RequestHeader}' request header is required, but was not found.");

                return;
            }

            var correlationId = hasCorrelationIdHeader ? cid.FirstOrDefault() : null;

            if (hasCorrelationIdHeader)
            {
                Log.FoundCorrelationIdHeader(_logger, correlationId);
            }
            else
            {
                Log.MissingCorrelationIdHeader(_logger);
            }

            if (_options.IgnoreRequestHeader || RequiresGenerationOfCorrelationId(hasCorrelationIdHeader, cid))
            {
                correlationId = GenerateCorrelationId(context);
            }

            if (!string.IsNullOrEmpty(correlationId) && _options.UpdateTraceIdentifier)
            {
                Log.UpdatingTraceIdentifier(_logger);

                context.TraceIdentifier = correlationId;
            }

            Log.CreatingCorrelationContext(_logger);
            correlationContextFactory.Create(correlationId, _options.RequestHeader);

            if (_options.IncludeInResponse && !string.IsNullOrEmpty(correlationId))
            {
                // apply the correlation ID to the response header for client side tracking
                context.Response.OnStarting(() =>
                {
                    if (!context.Response.Headers.ContainsKey(_options.ResponseHeader))
                    {
                        Log.WritingCorrelationIdResponseHeader(_logger, _options.ResponseHeader, correlationId);
                        context.Response.Headers.Add(_options.ResponseHeader, correlationId);
                    }

                    return(Task.CompletedTask);
                });
            }

            if (_options.AddToLoggingScope && !string.IsNullOrEmpty(_options.LoggingScopeKey) && !string.IsNullOrEmpty(correlationId))
            {
                using (_logger.BeginScope(new FormattedDictionary <string, object>
                {
                    [_options.LoggingScopeKey] = correlationId
                }))
                {
                    Log.CorrelationIdProcessingEnd(_logger, correlationId);
                    await _next(context);
                }
            }
            else
            {
                Log.CorrelationIdProcessingEnd(_logger, correlationId);
                await _next(context);
            }

            Log.DisposingCorrelationContext(_logger);
            correlationContextFactory.Dispose();
        }
예제 #14
0
 public CorrelationContextManager(ICorrelationContextAccessor accessor, ICorrelationContextFactory factory)
 {
     _accessor = accessor;
     _factory  = factory;
 }
예제 #15
0
 public FabioHttpClient(HttpClient client, HttpClientOptions options, IHttpClientSerializer serializer,
                        ICorrelationContextFactory correlationContextFactory, ICorrelationIdFactory correlationIdFactory)
     : base(client, options, serializer, correlationContextFactory, correlationIdFactory)
 {
 }
예제 #16
0
 public ConsulHttpClient(HttpClient client, HttpClientOptions options,
                         ICorrelationContextFactory correlationContextFactory)
     : base(client, options, correlationContextFactory)
 {
 }
 public CorrelationContextContainer(ICorrelationContextFactory correlationContextFactory)
 {
     _correlationContextFactory = correlationContextFactory;
 }