Skip to content

Commit 24b9e70

Browse files
authored
Drop messages in azure loggers if queue is full (#494)
1 parent 53fa5cb commit 24b9e70

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

src/Logging/Logging.AzureAppServices/src/Internal/BatchingLoggerProvider.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ public abstract class BatchingLoggerProvider: ILoggerProvider, ISupportExternalS
1818
private readonly int? _batchSize;
1919
private readonly IDisposable _optionsChangeToken;
2020

21+
private int _messagesDropped;
22+
2123
private BlockingCollection<LogMessage> _messageQueue;
2224
private Task _outputTask;
2325
private CancellationTokenSource _cancellationTokenSource;
@@ -85,6 +87,16 @@ private async Task ProcessLogQueue(object state)
8587
limit--;
8688
}
8789

90+
var messagesDropped = Interlocked.Exchange(ref _messagesDropped, 0);
91+
if (messagesDropped != 0)
92+
{
93+
_currentBatch.Add(new LogMessage()
94+
{
95+
Message = $"{messagesDropped} message(s) dropped because of queue size limit. Increase the queue size or decrease logging verbosity to avoid this.{Environment.NewLine}",
96+
Timestamp = DateTimeOffset.Now
97+
});
98+
}
99+
88100
if (_currentBatch.Count > 0)
89101
{
90102
try
@@ -98,8 +110,10 @@ private async Task ProcessLogQueue(object state)
98110

99111
_currentBatch.Clear();
100112
}
101-
102-
await IntervalAsync(_interval, _cancellationTokenSource.Token);
113+
else
114+
{
115+
await IntervalAsync(_interval, _cancellationTokenSource.Token);
116+
}
103117
}
104118
}
105119

@@ -114,7 +128,10 @@ internal void AddMessage(DateTimeOffset timestamp, string message)
114128
{
115129
try
116130
{
117-
_messageQueue.Add(new LogMessage { Message = message, Timestamp = timestamp }, _cancellationTokenSource.Token);
131+
if (!_messageQueue.TryAdd(new LogMessage { Message = message, Timestamp = timestamp }, millisecondsTimeout: 0, cancellationToken: _cancellationTokenSource.Token))
132+
{
133+
Interlocked.Increment(ref _messagesDropped);
134+
}
118135
}
119136
catch
120137
{
@@ -172,4 +189,4 @@ void ISupportExternalScope.SetScopeProvider(IExternalScopeProvider scopeProvider
172189
_scopeProvider = scopeProvider;
173190
}
174191
}
175-
}
192+
}

src/Logging/Logging.AzureAppServices/test/BatchingLoggerProviderTests.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -77,36 +77,31 @@ public async Task RespectsBatchSize()
7777
provider.IntervalControl.Resume();
7878
await provider.IntervalControl.Pause;
7979

80-
Assert.Single(provider.Batches);
80+
Assert.Equal(2, provider.Batches.Count);
8181
Assert.Single(provider.Batches[0]);
8282
Assert.Equal("2016-05-04 03:02:01.000 +00:00 [Information] Cat: Info message" + _nl, provider.Batches[0][0].Message);
8383

84-
provider.IntervalControl.Resume();
85-
await provider.IntervalControl.Pause;
86-
87-
Assert.Equal(2, provider.Batches.Count);
8884
Assert.Single(provider.Batches[1]);
89-
9085
Assert.Equal("2016-05-04 04:02:01.000 +00:00 [Error] Cat: Error message" + _nl, provider.Batches[1][0].Message);
9186
}
9287

9388
[Fact]
94-
public async Task BlocksWhenReachingMaxQueue()
89+
public async Task DropsMessagesWhenReachingMaxQueue()
9590
{
9691
var provider = new TestBatchingLoggingProvider(maxQueueSize: 1);
9792
var logger = (BatchingLogger)provider.CreateLogger("Cat");
9893

9994
await provider.IntervalControl.Pause;
10095

10196
logger.Log(_timestampOne, LogLevel.Information, 0, "Info message", null, (state, ex) => state);
102-
var task = Task.Run(() => logger.Log(_timestampOne.AddHours(1), LogLevel.Error, 0, "Error message", null, (state, ex) => state));
103-
104-
Assert.False(task.Wait(1000));
97+
logger.Log(_timestampOne.AddHours(1), LogLevel.Error, 0, "Error message", null, (state, ex) => state);
10598

10699
provider.IntervalControl.Resume();
107100
await provider.IntervalControl.Pause;
108101

109-
Assert.True(task.Wait(1000));
102+
Assert.Equal(2, provider.Batches[0].Length);
103+
Assert.Equal("2016-05-04 03:02:01.000 +00:00 [Information] Cat: Info message" + _nl, provider.Batches[0][0].Message);
104+
Assert.Equal("1 message(s) dropped because of queue size limit. Increase the queue size or decrease logging verbosity to avoid this." + _nl, provider.Batches[0][1].Message);
110105
}
111106

112107
private class TestBatchingLoggingProvider: BatchingLoggerProvider

0 commit comments

Comments
 (0)