/// <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); } }
/// <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; } }
public void OnTearDown() { TraceContext.Create(null); }
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 }