Example #1
0
        /// <summary>
        /// Crée un contexte pour ajouter des informations de la requête dans les traces
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private TraceContext CreateContextForApiRequest(HttpRequest request)
        {
            string       origin       = request?.Headers?[Constants.TraceParameter.Origin].FirstOrDefault();
            TraceContext traceContext = TraceContext
                                        .Create(Constants.TraceParameter.Method, request.Method)
                                        .Add(Constants.TraceParameter.Uri, request.GetEncodedPathAndQuery())
                                        .Add(Constants.TraceParameter.Origin, origin);

            return(traceContext);
        }
        /// <summary>
        /// Обрабатывает запрос для установки/чтения TraceId в заголовках и устанавливает в <see cref="TraceContext"/>
        /// </summary>
        /// <param name="context"><see cref="HttpContext"/> для текущего запроса.</param>
        /// <param name="logger">Логгер.</param>
        #pragma warning disable IDE1006
        public async Task Invoke(HttpContext context, ILogger <TraceIdMiddleware> logger)
        #pragma warning restore IDE1006
        {
            var(traceId, traceIdSource) = GetTraceIdFromHeaders(context, logger);

            if (!traceId.HasValue)
            {
                if (_settings.ThrowBadRequestIfNotPresent)
                {
                    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    await context.Response.WriteAsync($"{_settings.Header} должен быть установлен.");

                    return;
                }

                TraceContext.Create(null, traceIdSource);
                await _next(context);

                return;
            }

            context.Response.OnStarting(() =>
            {
                UpdateHeaders(context.Response.Headers, _settings.Header, traceId?.ToString());
                UpdateHeaders(context.Response.Headers, _settings.TraceIdSourceHeader, traceIdSource);

                return(Task.CompletedTask);
            });

            if (_settings.UseLoggerScope)
            {
                TraceContext.Create(traceId, traceIdSource);
                using (logger.WithTraceContext())
                {
                    await _next(context);
                }
            }
            else
            {
                TraceContext.Create(traceId, traceIdSource);
                await _next(context);
            }
        }
Example #3
0
        /// <summary>
        /// Получить или сгенерировать TraceId и установить контекст трейсинга.
        /// </summary>
        /// <param name="properties">Метаданные сообщения.</param>
        /// <param name="settings">Настройки трейсинга.</param>
        /// <param name="logger">Логгер.</param>
        /// <param name="stubMessage">TraceId из тела сообщения.</param>
        /// <param name="loggingScope">Скоуп.</param>
        /// <returns>Идентификатор отслеживания.</returns>
        public static void EnsureTraceId(
            this IBasicProperties properties,
            TracingSettings settings,
            ILogger logger,
            ref StubMessage stubMessage,
            Dictionary <string, object?> loggingScope
            )
        {
            if (!TryGetTraceInfo(properties, stubMessage.TraceId, out var traceId, out var traceIdSource))
            {
                if (settings.GenerateIfNotPresent)
                {
                    traceId = Guid.NewGuid();

                    if (settings.LogWhenGenerated)
                    {
                        using (logger.BeginScope(loggingScope))
                        {
                            logger.LogInformation("TraceId не указан. Сгенерирован новый {TraceId}.", traceId);
                        }
                    }
                }
            }

            TraceContext.Create(traceId, traceIdSource);

            loggingScope["TraceId"]       = traceId;
            loggingScope["TraceIdSource"] = traceIdSource;

            properties.AddTraceId();

            if (traceId.HasValue)
            {
                stubMessage.TraceId = traceId.Value;
            }
        }
Example #4
0
 public void OnTearDown()
 {
     TraceContext.Create(null);
 }
Example #5
0
        public async Task CorrectHandleSettingsAsync(
            int caseNumber,
            HttpStatusCode expectedStatusCode,
            string initialTraceString,
            bool generateIfNotPresent,
            bool throwBadRequestIfNotPresent,
            bool initialAndFinalTraceIdMustBeEqual
            )
        {
            #region Arrange

            var initialTraceId  = Guid.Parse(initialTraceString);
            var traceIdSettings = new TraceIdSettings
            {
                GenerateIfNotPresent        = generateIfNotPresent,
                ThrowBadRequestIfNotPresent = throwBadRequestIfNotPresent
            };
            var traceContext1 = TraceContext.Create(initialTraceId);

            var context           = GetMockedContextFor(traceIdSettings, out var feature);
            var traceIdMiddleware =
                new TraceIdMiddleware(_ => feature.CompleteAsync(), Options.Create(traceIdSettings));

            #endregion Arrange

            #region Act

            await traceIdMiddleware.Invoke(context, NullLogger <TraceIdMiddleware> .Instance);

            #endregion Act

            #region Assert

            var traceContext2 = TraceContext.Current;

            var actualTraceId = GetActualTraceId(context, traceIdSettings);

            Assert.Multiple(() =>
            {
                Assert.AreEqual((int)expectedStatusCode, context.Response.StatusCode,
                                "status code должен быть ожидаемым.");

                if (initialAndFinalTraceIdMustBeEqual)
                {
                    Assert.AreEqual(initialTraceId, actualTraceId ?? Guid.Empty, "traceId до и после выполнения должны быть одинаковыми.");
                }

                if (traceIdSettings.GenerateIfNotPresent)
                {
                    Assert.IsTrue(ReferenceEquals(traceContext1, traceContext2), "Инстансы должны быть одним и тем же.");
                    Assert.AreNotEqual(Guid.Empty, TraceContext.Current.TraceId,
                                       "Если требуется генерировать при отсутствии TraceId, то TraceId не должен быть пустым.");

                    if (actualTraceId.HasValue)
                    {
                        Assert.IsTrue(actualTraceId != Guid.Empty);
                    }
                }
                else
                {
                    if (initialTraceId == Guid.Empty)
                    {
                        Assert.IsNull(actualTraceId);
                    }
                    else
                    {
                        Assert.AreEqual(initialTraceId, actualTraceId);
                    }
                }
            });

            #endregion Assert
        }