From 21b2de5ad46fb026fcb340ad1476308759938e88 Mon Sep 17 00:00:00 2001 From: Rolf Kristensen Date: Thu, 21 Sep 2023 20:28:03 +0200 Subject: [PATCH] MessageQueueTarget - Support SingleTransaction for sending message to transactional-queue (#5) --- appveyor.yml | 2 +- src/NLog.MSMQ/NLog.MSMQ.csproj | 2 +- src/NLog.MSMQ/Targets/MessageQueueTarget.cs | 81 ++++++++++--------- .../MessageQueueTargetTests.cs | 4 +- 4 files changed, 49 insertions(+), 40 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c504437..f3617cc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,6 @@ artifacts: deploy: - provider: NuGet api_key: - secure: e+0IpLU3V1eXUsWCRjKGuyyeuLQYfFpv6BAoIihFQryuYZsOWVvxUBvQOC0dOL2n + secure: ACKSV1ixxNpO+2k8KvNDy6hd9QmR8lkQmKn773ZIIeVpG0ywYUhY4j8LcyykVR1a on: branch: master diff --git a/src/NLog.MSMQ/NLog.MSMQ.csproj b/src/NLog.MSMQ/NLog.MSMQ.csproj index 51f3fff..cc622c7 100644 --- a/src/NLog.MSMQ/NLog.MSMQ.csproj +++ b/src/NLog.MSMQ/NLog.MSMQ.csproj @@ -4,7 +4,7 @@ net46;net45;net35;netstandard2.0 NLog - 5.2.0 + 5.3.0 5.0.0.0 diff --git a/src/NLog.MSMQ/Targets/MessageQueueTarget.cs b/src/NLog.MSMQ/Targets/MessageQueueTarget.cs index 222bc87..7ca852a 100644 --- a/src/NLog.MSMQ/Targets/MessageQueueTarget.cs +++ b/src/NLog.MSMQ/Targets/MessageQueueTarget.cs @@ -101,19 +101,19 @@ public MessageQueueTarget(string name) : this() public Layout Queue { get; set; } /// - /// Gets or sets the label to associate with each message. + /// Gets or sets a value indicating whether sending to a transactional queue using single-transaction-style. /// - /// - /// By default no label is associated. - /// /// - public Layout Label { get; set; } = "NLog"; + public bool SingleTransaction { get; set; } /// - /// Gets or sets a value indicating whether to create the queue if it doesn't exists. + /// Gets or sets the label to associate with each message. /// + /// + /// By default no label is associated. + /// /// - public bool CreateQueueIfNotExists { get; set; } + public Layout Label { get; set; } /// /// Gets or sets a value indicating whether to use recoverable messages (with guaranteed delivery). @@ -129,7 +129,6 @@ public MessageQueueTarget(string name) : this() /// /// Gets or sets a value indicating whether to use the XML format when serializing message. - /// This will also disable creating queues. /// /// public bool UseXmlEncoding { get; set; } @@ -138,8 +137,14 @@ public MessageQueueTarget(string name) : this() /// Gets or sets a value indicating whether to check if a queue exists before writing to it. /// /// - public bool CheckIfQueueExists { get; set; } = true; - + public bool CheckIfQueueExists { get; set; } + + /// + /// Gets or sets a value indicating whether to create the queue if it doesn't exists. + /// + /// + public bool CreateQueueIfNotExists { get; set; } + internal MessageQueueProxy MessageQueueProxy { get; set; } /// @@ -149,27 +154,32 @@ public MessageQueueTarget(string name) : this() /// The logging event. protected override void Write(LogEventInfo logEvent) { - if (Queue is null) + var queue = RenderLogEvent(Queue, logEvent); + if (string.IsNullOrEmpty(queue)) { + Common.InternalLogger.Debug("MessageQueueTarget: Failed sending message, because queue name is empty."); return; } - var queue = Queue.Render(logEvent); - - if (CheckIfQueueExists && !IsFormatNameSyntax(queue) && !MessageQueueProxy.Exists(queue)) + if (CheckIfQueueExists || CreateQueueIfNotExists) { - if (CreateQueueIfNotExists) - { - MessageQueueProxy.Create(queue); - } - else + if (!IsFormatNameSyntax(queue) && !MessageQueueProxy.Exists(queue)) { - return; + if (CreateQueueIfNotExists) + { + Common.InternalLogger.Debug("MessageQueueTarget: Creating queue: {0}", queue); + MessageQueueProxy.Create(queue, SingleTransaction); + } + else + { + Common.InternalLogger.Debug("MessageQueueTarget: Skip sending message, because non-existing queue: {0}", queue); + return; + } } } var msg = PrepareMessage(logEvent); - MessageQueueProxy.Send(queue, msg); + MessageQueueProxy.Send(queue, msg, SingleTransaction); } /// @@ -185,22 +195,23 @@ protected override void Write(LogEventInfo logEvent) protected virtual Message PrepareMessage(LogEventInfo logEvent) { var msg = new Message(); - if (Label != null) + var label = RenderLogEvent(Label, logEvent); + if (!string.IsNullOrEmpty(label)) { - msg.Label = Label.Render(logEvent); + msg.Label = label; } msg.Recoverable = Recoverable; msg.Priority = DefaultMessagePriority; + var body = RenderLogEvent(Layout, logEvent); if (UseXmlEncoding) { - msg.Body = Layout.Render(logEvent); + msg.Body = body; } else { - var dataBytes = Encoding.GetBytes(Layout.Render(logEvent)); - + var dataBytes = Encoding.GetBytes(body); msg.BodyStream.Write(dataBytes, 0, dataBytes.Length); } @@ -220,21 +231,19 @@ public virtual bool Exists(string queue) return MessageQueue.Exists(queue); } - public virtual void Create(string queue) + public virtual void Create(string queue, bool singleTransaction) { - MessageQueue.Create(queue); + MessageQueue.Create(queue, singleTransaction); } - public virtual void Send(string queue, Message message) + public virtual void Send(string queue, Message message, bool singleTransaction) { - if (message is null) - { - return; - } - - using (var mq = new MessageQueue(queue)) + using (var mq = new MessageQueue(queue, QueueAccessMode.Send)) { - mq.Send(message); + if (singleTransaction) + mq.Send(message, MessageQueueTransactionType.Single); + else + mq.Send(message); } } } diff --git a/tests/NLog.MSMQ.Tests/MessageQueueTargetTests.cs b/tests/NLog.MSMQ.Tests/MessageQueueTargetTests.cs index fd574eb..726f763 100644 --- a/tests/NLog.MSMQ.Tests/MessageQueueTargetTests.cs +++ b/tests/NLog.MSMQ.Tests/MessageQueueTargetTests.cs @@ -193,12 +193,12 @@ public override bool Exists(string queue) return QueueExists; } - public override void Create(string queue) + public override void Create(string queue, bool singleTransaction) { QueueCreated = true; } - public override void Send(string queue, Message message) + public override void Send(string queue, Message message, bool singleTransaction) { SentMessages.Add(message); }