| File: LogBuffering\SerializedLogRecordFactory.cs | Web Access |
| Project: src\src\Shared\Shared.csproj (Shared) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using Microsoft.Extensions.Logging; using Microsoft.Extensions.ObjectPool; using Microsoft.Shared.Pools; namespace Microsoft.Extensions.Diagnostics.Buffering; internal static class SerializedLogRecordFactory { private static readonly ObjectPool<List<KeyValuePair<string, object?>>> _attributesPool = PoolFactory.CreateListPool<KeyValuePair<string, object?>>(); private static readonly int _serializedLogRecordSize = Unsafe.SizeOf<SerializedLogRecord>(); public static SerializedLogRecord Create( LogLevel logLevel, EventId eventId, DateTimeOffset timestamp, IReadOnlyList<KeyValuePair<string, object?>> attributes, Exception? exception, string formattedMessage) { int sizeInBytes = _serializedLogRecordSize; List<KeyValuePair<string, object?>> serializedAttributes = _attributesPool.Get(); for (int i = 0; i < attributes.Count; i++) { string key = attributes[i].Key; string value = attributes[i].Value?.ToString() ?? string.Empty; // deliberately not counting the size of the key, // as it is constant strings in the vast majority of cases sizeInBytes += CalculateStringSize(value); serializedAttributes.Add(new KeyValuePair<string, object?>(key, value)); } string exceptionMessage = string.Empty; if (exception is not null) { exceptionMessage = exception.Message; sizeInBytes += CalculateStringSize(exceptionMessage); } sizeInBytes += CalculateStringSize(formattedMessage); return new SerializedLogRecord( logLevel, eventId, timestamp, serializedAttributes, exceptionMessage, formattedMessage, sizeInBytes); } public static void Return(SerializedLogRecord bufferedRecord) { _attributesPool.Return(bufferedRecord.Attributes); } private static int CalculateStringSize(string str) { if (string.IsNullOrEmpty(str)) { return 0; } // Base size: object overhead (16 bytes) + other stuff. const int BaseSize = 26; // Strings are aligned to 8-byte boundaries const int Alignment = 7; int charSize = str.Length * sizeof(char); return (BaseSize + charSize + Alignment) & ~Alignment; } }