|
9 | 9 | using System.Threading;
|
10 | 10 | using Microsoft.Extensions.Diagnostics.Buffering;
|
11 | 11 | using Microsoft.Extensions.Logging.Abstractions;
|
| 12 | +using Microsoft.Extensions.ObjectPool; |
12 | 13 | using Microsoft.Extensions.Options;
|
13 | 14 | using Microsoft.Shared.Diagnostics;
|
| 15 | +using Microsoft.Shared.Pools; |
14 | 16 |
|
15 | 17 | namespace Microsoft.AspNetCore.Diagnostics.Buffering;
|
16 | 18 |
|
17 | 19 | internal sealed class IncomingRequestLogBuffer
|
18 | 20 | {
|
| 21 | + private const int MaxBatchSize = 256; |
| 22 | + private static readonly ObjectPool<List<DeserializedLogRecord>> _recordsToEmitListPool = |
| 23 | + PoolFactory.CreateListPoolWithCapacity<DeserializedLogRecord>(MaxBatchSize); |
| 24 | + |
19 | 25 | private readonly IBufferedLogger _bufferedLogger;
|
20 | 26 | private readonly LogBufferingFilterRuleSelector _ruleSelector;
|
21 | 27 | private readonly IOptionsMonitor<PerRequestLogBufferingOptions> _options;
|
@@ -105,23 +111,41 @@ public void Flush()
|
105 | 111 | // Prepare the new standby buffer for future Flush() calls
|
106 | 112 | _standbyBuffer = new ConcurrentQueue<SerializedLogRecord>();
|
107 | 113 | }
|
108 |
| - SerializedLogRecord[] bufferedRecords = bufferToFlush.ToArray(); |
109 | 114 |
|
| 115 | + SerializedLogRecord[] bufferedRecords = bufferToFlush.ToArray(); |
110 | 116 |
|
111 |
| - var recordsToEmit = new List<DeserializedLogRecord>(bufferedRecords.Length); |
112 |
| - foreach (SerializedLogRecord bufferedRecord in bufferedRecords) |
| 117 | + // Process records in batches |
| 118 | + for (int offset = 0; offset < bufferedRecords.Length; offset += MaxBatchSize) |
113 | 119 | {
|
114 |
| - recordsToEmit.Add(new DeserializedLogRecord( |
115 |
| - bufferedRecord.Timestamp, |
116 |
| - bufferedRecord.LogLevel, |
117 |
| - bufferedRecord.EventId, |
118 |
| - bufferedRecord.Exception, |
119 |
| - bufferedRecord.FormattedMessage, |
120 |
| - bufferedRecord.Attributes)); |
| 120 | + int currentBatchSize = Math.Min(MaxBatchSize, bufferedRecords.Length - offset); |
| 121 | + List<DeserializedLogRecord>? recordsToEmit = null; |
| 122 | + try |
| 123 | + { |
| 124 | + recordsToEmit = _recordsToEmitListPool.Get(); |
| 125 | + |
| 126 | + for (int i = 0; i < currentBatchSize; i++) |
| 127 | + { |
| 128 | + SerializedLogRecord bufferedRecord = bufferedRecords[offset + i]; |
| 129 | + recordsToEmit.Add(new DeserializedLogRecord( |
| 130 | + bufferedRecord.Timestamp, |
| 131 | + bufferedRecord.LogLevel, |
| 132 | + bufferedRecord.EventId, |
| 133 | + bufferedRecord.Exception, |
| 134 | + bufferedRecord.FormattedMessage, |
| 135 | + bufferedRecord.Attributes)); |
| 136 | + } |
| 137 | + |
| 138 | + _bufferedLogger.LogRecords(recordsToEmit); |
| 139 | + } |
| 140 | + finally |
| 141 | + { |
| 142 | + if (recordsToEmit is not null) |
| 143 | + { |
| 144 | + _recordsToEmitListPool.Return(recordsToEmit); |
| 145 | + } |
| 146 | + } |
121 | 147 | }
|
122 | 148 |
|
123 |
| - _bufferedLogger.LogRecords(recordsToEmit); |
124 |
| - |
125 | 149 | SerializedLogRecordFactory.Return(bufferedRecords);
|
126 | 150 | }
|
127 | 151 |
|
|
0 commit comments