Skip to content

Commit 00d2285

Browse files
re #18483 - Making the EMG.Extensions.Logging.Loggly awaitable (#5)
* re #18483 - Making the EMG.Extensions.Logging.Loggly awaitable Added possibility to flush the messages in the logglyprocessor instead of having to wait for the buffer * Update README.md Trigger build * re #18483 - Making the EMG.Extensions.Logging.Loggly awaitable Moved buffer to loggly options to allow for customization and fix broken tests * re #18483 - Making the EMG.Extensions.Logging.Loggly awaitable Fix for tests Co-authored-by: Erik Karlsson <[email protected]>
1 parent 2bf400c commit 00d2285

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

src/Logging/Loggly/Loggly/LogglyMessage.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public class LogglyMessage
2323
public LogLevel Level { get; set; }
2424

2525
public Error Error { get; set; }
26+
27+
public static LogglyMessage Default => new LogglyMessage {Level = LogLevel.Trace};
2628
}
2729

2830
public class Error

src/Logging/Loggly/Loggly/LogglyOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public class LogglyOptions
2626
public Action<LogglyMessage> PreProcessMessage { get; set; }
2727

2828
public Encoding ContentEncoding { get; set; } = Encoding.UTF8;
29+
30+
public TimeSpan Buffer { get; set; } = TimeSpan.FromMilliseconds(50);
2931
}
3032

3133
public delegate bool FilterDelegate(string categoryName, EventId eventId, LogLevel logLevel);

src/Logging/Loggly/Loggly/LogglyProcessor.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,36 @@ namespace EMG.Extensions.Logging.Loggly
88
public interface ILogglyProcessor : IDisposable
99
{
1010
void EnqueueMessage(LogglyMessage message);
11+
12+
void FlushMessages();
1113
}
1214

1315
public class LogglyProcessor : ILogglyProcessor
1416
{
1517
private readonly ILogglyClient _client;
1618
private readonly ISubject<LogglyMessage> _messageSubject = new Subject<LogglyMessage>();
19+
private readonly ISubject<LogglyMessage> _flush = new Subject<LogglyMessage>();
1720
private readonly IDisposable _subscription;
1821

19-
public LogglyProcessor(ILogglyClient client)
22+
public LogglyProcessor(ILogglyClient client, LogglyOptions options)
2023
{
2124
_client = client ?? throw new ArgumentNullException(nameof(client));
25+
_ = options ?? throw new ArgumentNullException(nameof(options));
2226

23-
_subscription = _messageSubject.Buffer(TimeSpan.FromMilliseconds(50)).Subscribe(ProcessLogQueue);
27+
var closing = _messageSubject.Buffer(options.Buffer).Select(i => LogglyMessage.Default).Merge(_flush);
28+
_subscription = _messageSubject.Buffer(() => closing).Subscribe(ProcessLogQueue);
2429
}
2530

2631
public void EnqueueMessage(LogglyMessage message)
2732
{
2833
_messageSubject.OnNext(message);
2934
}
3035

36+
public void FlushMessages()
37+
{
38+
_flush.OnNext(LogglyMessage.Default);
39+
}
40+
3141
public void Dispose()
3242
{
3343
_subscription.Dispose();

tests/Logging/Tests.Loggly/Loggly/LogglyProcessorTests.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.Linq;
55
using System.Threading.Tasks;
6+
using AutoFixture;
67
using AutoFixture.Idioms;
78
using AutoFixture.NUnit3;
89
using EMG.Extensions.Logging.Loggly;
@@ -21,8 +22,10 @@ public void Constructor_is_guarded(GuardClauseAssertion assertion)
2122
}
2223

2324
[Test, AutoMoqData]
24-
public async Task Message_is_published_after_adding_to_queue([Frozen] ILogglyClient client, LogglyProcessor sut, LogglyMessage message)
25+
public async Task Message_is_published_after_adding_to_queue_with_delay([Frozen] ILogglyClient client, LogglyMessage message, IFixture fixture)
2526
{
27+
var sut = CreateSut(fixture, client, 50);
28+
2629
sut.EnqueueMessage(message);
2730

2831
await Task.Delay(TimeSpan.FromMilliseconds(100));
@@ -37,7 +40,36 @@ public void Message_is_not_published_after_adding_to_queue_when_disposed([Frozen
3740

3841
sut.EnqueueMessage(message);
3942

40-
Mock.Get(client).Verify(p => p.PublishAsync(message), Times.Never);
43+
Mock.Get(client).Verify(p => p.PublishManyAsync(It.Is<IEnumerable<LogglyMessage>>(m => m.Contains(message))), Times.Never);
44+
}
45+
46+
[Test, AutoMoqData]
47+
public async Task Message_is_not_published_after_adding_to_queue_without_delay([Frozen] ILogglyClient client, LogglyMessage message, IFixture fixture)
48+
{
49+
var sut = CreateSut(fixture, client, 1000);
50+
51+
sut.EnqueueMessage(message);
52+
53+
Mock.Get(client).Verify(p => p.PublishManyAsync(It.Is<IEnumerable<LogglyMessage>>(m => m.Contains(message))), Times.Never);
54+
}
55+
56+
[Test, AutoMoqData]
57+
public async Task Message_is_published_after_adding_to_queue_without_delay_after_flush([Frozen] ILogglyClient client, LogglyMessage message, IFixture fixture)
58+
{
59+
var sut = CreateSut(fixture, client, 1000);
60+
61+
sut.EnqueueMessage(message);
62+
63+
sut.FlushMessages();
64+
65+
Mock.Get(client).Verify(p => p.PublishManyAsync(It.Is<IEnumerable<LogglyMessage>>(m => m.Contains(message))), Times.Once);
66+
}
67+
68+
private LogglyProcessor CreateSut(IFixture fixture, ILogglyClient client, int buffer)
69+
{
70+
var options = fixture.Build<LogglyOptions>().With(i => i.Buffer, TimeSpan.FromMilliseconds(buffer))
71+
.Create();
72+
return new LogglyProcessor(client, options);
4173
}
4274
}
4375
}

0 commit comments

Comments
 (0)