Skip to content

Commit 963916b

Browse files
snakefootartdolya
authored andcommitted
Fix NullReferenceException when RabbitMQ instance is offline
1 parent 01fe47e commit 963916b

File tree

1 file changed

+18
-15
lines changed

1 file changed

+18
-15
lines changed

src/Nlog.RabbitMQ.Target/RabbitMQTarget.cs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.IO;
44
using System.IO.Compression;
@@ -15,7 +15,7 @@
1515
namespace Nlog.RabbitMQ.Target
1616
{
1717
/// <summary>
18-
/// TODO
18+
/// NLog target for writing to RabbitMQ Topic
1919
/// </summary>
2020
[Target("RabbitMQ")]
2121
public class RabbitMQTarget : TargetWithContext
@@ -31,8 +31,8 @@ public enum CompressionTypes
3131
private string _ModelExchange;
3232
private readonly Encoding _Encoding = Encoding.UTF8;
3333

34-
private readonly Queue<Tuple<byte[], IBasicProperties, string>> _UnsentMessages
35-
= new Queue<Tuple<byte[], IBasicProperties, string>>(512);
34+
private readonly Queue<Tuple<byte[], IBasicProperties, Func<IBasicProperties, IBasicProperties>, string>> _UnsentMessages
35+
= new Queue<Tuple<byte[], IBasicProperties, Func<IBasicProperties, IBasicProperties>, string>>(512);
3636

3737
private readonly object _sync = new object();
3838

@@ -259,11 +259,10 @@ protected override void Write(LogEventInfo logEvent)
259259
modelExchange = _ModelExchange;
260260
}
261261

262-
var basicProperties = GetBasicProperties(logEvent, model);
263-
262+
var basicProperties = model != null ? GetBasicProperties(logEvent, model) : null;
264263
if (model == null || !model.IsOpen)
265264
{
266-
if (!AddUnsent(routingKey, basicProperties, message))
265+
if (!AddUnsent(logEvent, routingKey, basicProperties, message))
267266
{
268267
throw new InvalidOperationException("LogEvent discarded because RabbitMQ instance is offline and reached MaxBuffer");
269268
}
@@ -281,13 +280,13 @@ protected override void Write(LogEventInfo logEvent)
281280
catch (IOException e)
282281
{
283282
InternalLogger.Error(e, "RabbitMQTarget(Name={0}): Could not send to RabbitMQ instance: {1}", Name, e.Message);
284-
if (!AddUnsent(routingKey, basicProperties, message))
283+
if (!AddUnsent(logEvent, routingKey, basicProperties, message))
285284
throw;
286285
}
287286
catch (ObjectDisposedException e)
288287
{
289288
InternalLogger.Error(e, "RabbitMQTarget(Name={0}): Could not send to RabbitMQ instance: {1}", Name, e.Message);
290-
if (!AddUnsent(routingKey, basicProperties, message))
289+
if (!AddUnsent(logEvent, routingKey, basicProperties, message))
291290
throw;
292291
}
293292
catch (Exception e)
@@ -305,11 +304,14 @@ protected override void Write(LogEventInfo logEvent)
305304
}
306305
}
307306

308-
private bool AddUnsent(string routingKey, IBasicProperties basicProperties, byte[] message)
307+
private bool AddUnsent(LogEventInfo logEvent, string routingKey, IBasicProperties basicProperties, byte[] message)
309308
{
310309
if (_UnsentMessages.Count < MaxBuffer)
311310
{
312-
_UnsentMessages.Enqueue(Tuple.Create(message, basicProperties, routingKey));
311+
Func<IBasicProperties, IBasicProperties> propertyResolver = (props) => props;
312+
if (basicProperties == null)
313+
propertyResolver = (props) => _Model != null ? GetBasicProperties(logEvent, _Model) : null;
314+
_UnsentMessages.Enqueue(Tuple.Create(message, basicProperties, propertyResolver, routingKey));
313315
return true;
314316
}
315317
else
@@ -326,7 +328,8 @@ private void CheckUnsent(IModel model, string exchange)
326328
{
327329
var tuple = _UnsentMessages.Dequeue();
328330
InternalLogger.Info("RabbitMQTarget(Name={0}): Publishing unsent message: {1}.", Name, tuple);
329-
Publish(model, tuple.Item1, tuple.Item2, tuple.Item3, exchange);
331+
var basicProperties = tuple.Item3.Invoke(tuple.Item2);
332+
Publish(model, tuple.Item1, basicProperties, tuple.Item4, exchange);
330333
}
331334
}
332335

@@ -497,7 +500,7 @@ private void StartConnection(IConnection oldConnection, int timeoutMilliseconds,
497500

498501
if (shutdownConnection == null)
499502
{
500-
InternalLogger.Error(e, string.Format("RabbitMQTarget(Name={0}): Could not connect to Rabbit instance: {1}", Name, e.Message));
503+
InternalLogger.Error(e, string.Format("RabbitMQTarget(Name={0}): Could not connect to RabbitMQ instance: {1}", Name, e.Message));
501504
}
502505
else
503506
{
@@ -530,11 +533,11 @@ private void StartConnection(IConnection oldConnection, int timeoutMilliseconds,
530533
var completedTask = Task.WhenAny(t, Task.Delay(TimeSpan.FromMilliseconds(timeoutMilliseconds))).ConfigureAwait(false).GetAwaiter().GetResult();
531534
if (!ReferenceEquals(completedTask, t))
532535
{
533-
InternalLogger.Warn("RabbitMQTarget(Name={0}): Starting connection-task timed out, continuing", Name);
536+
InternalLogger.Warn("RabbitMQTarget(Name={0}): Connection timeout to RabbitMQ instance after {1}ms", Name, timeoutMilliseconds);
534537
}
535538
else if (completedTask.Exception != null)
536539
{
537-
InternalLogger.Error(completedTask.Exception, "RabbitMQTarget(Name={0}): Starting connection-task failed: {0}", Name, completedTask.Exception.Message);
540+
InternalLogger.Error(completedTask.Exception, "RabbitMQTarget(Name={0}): Connection attempt to RabbitMQ instance failed: {1}", Name, completedTask.Exception.Message);
538541
}
539542
}
540543

0 commit comments

Comments
 (0)