| File: Logging\Internal\LoggerMessageStateExtensions.cs | Web Access |
| Project: src\src\Libraries\Microsoft.Extensions.Http.Diagnostics\Microsoft.Extensions.Http.Diagnostics.csproj (Microsoft.Extensions.Http.Diagnostics) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Http.Diagnostics; using Microsoft.Extensions.Logging; namespace Microsoft.Extensions.Http.Logging.Internal; internal static class LoggerMessageStateExtensions { private static readonly ConcurrentDictionary<string, string> _requestPrefixedNamesCache = new(); private static readonly ConcurrentDictionary<string, string> _responsePrefixedNamesCache = new(); /// <summary> /// Adds request headers to <see cref="LoggerMessageState"/>. /// </summary> /// <param name="state">A <see cref="LoggerMessageState"/> to be filled.</param> /// <param name="items">A list with request headers.</param> /// <param name="index">Represents an index to be used when writing tags into <paramref name="state"/>.</param> /// <remarks><paramref name="index"/> will be mutated to point to the next <paramref name="state"/> item.</remarks> public static void AddRequestHeaders(this LoggerMessageState state, List<KeyValuePair<string, string>> items, ref int index) { for (var i = 0; i < items.Count; i++) { var key = _requestPrefixedNamesCache.GetOrAdd( items[i].Key, static x => HttpClientLoggingTagNames.RequestHeaderPrefix + Normalize(x)); state.TagArray[index++] = new(key, items[i].Value); } } /// <summary> /// Adds response headers to <see cref="LoggerMessageState"/>. /// </summary> /// <param name="state">A <see cref="LoggerMessageState"/> to be filled.</param> /// <param name="items">A list with response headers.</param> /// <param name="index">Represents an index to be used when writing tags into <paramref name="state"/>.</param> /// <remarks><paramref name="index"/> will be mutated to point to the next <paramref name="state"/> item.</remarks> public static void AddResponseHeaders(this LoggerMessageState state, List<KeyValuePair<string, string>> items, ref int index) { for (var i = 0; i < items.Count; i++) { var key = _responsePrefixedNamesCache.GetOrAdd( items[i].Key, static x => HttpClientLoggingTagNames.ResponseHeaderPrefix + Normalize(x)); state.TagArray[index++] = new(key, items[i].Value); } } /// <summary> /// Adds path parameters to <see cref="LoggerMessageState"/>. /// </summary> /// <param name="state">A <see cref="LoggerMessageState"/> to be filled.</param> /// <param name="parameters">An array with path parameters.</param> /// <param name="paramsCount">A number of path parameters.</param> /// <param name="index">Represents an index to be used when writing tags into <paramref name="state"/>.</param> /// <remarks><paramref name="index"/> will be mutated to point to the next <paramref name="state"/> item.</remarks> public static void AddPathParameters(this LoggerMessageState state, HttpRouteParameter[] parameters, int paramsCount, ref int index) { for (var i = 0; i < paramsCount; i++) { state.TagArray[index++] = new(parameters[i].Name, parameters[i].Value); } } [SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Normalization to lower case is required by OTel's semantic conventions")] private static string Normalize(string header) => header.ToLowerInvariant(); }