This is an automated email from the ASF dual-hosted git repository. lizhanhui pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git
The following commit(s) were added to refs/heads/master by this push: new 17bd443b replace nlog with Microsoft.Extensions.Logging (#596) 17bd443b is described below commit 17bd443b438df9aa0e1d9d92d38973d8466e6f7c Author: EventHorizon <772552...@qq.com> AuthorDate: Sun Oct 8 14:07:34 2023 +0800 replace nlog with Microsoft.Extensions.Logging (#596) * replace nlog with Microsoft.Extensions.Logging * fix md format * use nlog as default LoggerFactory and remove useless nlog configuration file --------- Co-authored-by: Event Horizon <772552754@qq.com> --- csharp/README-CN.md | 16 +++++- csharp/README.md | 15 ++++-- csharp/examples/ProducerBenchmark.cs | 6 +-- csharp/examples/ProducerDelayMessageExample.cs | 6 +-- csharp/examples/ProducerFifoMessageExample.cs | 7 ++- csharp/examples/ProducerNormalMessageExample.cs | 6 +-- .../examples/ProducerTransactionMessageExample.cs | 8 +-- csharp/examples/QuickStart.cs | 9 ++++ csharp/examples/SimpleConsumerExample.cs | 10 ++-- csharp/examples/examples.csproj | 3 ++ csharp/rocketmq-client-csharp/Client.cs | 60 +++++++++++----------- .../ClientLoggerInterceptor.cs | 8 +-- csharp/rocketmq-client-csharp/ClientMeter.cs | 8 +-- .../rocketmq-client-csharp/ClientMeterManager.cs | 10 ++-- csharp/rocketmq-client-csharp/MessageView.cs | 9 ++-- csharp/rocketmq-client-csharp/MqLogManager.cs | 58 ++++++++++++--------- csharp/rocketmq-client-csharp/Producer.cs | 42 +++++++-------- .../rocketmq-client-csharp/PublishingSettings.cs | 6 +-- csharp/rocketmq-client-csharp/RpcClient.cs | 10 ++-- csharp/rocketmq-client-csharp/Session.cs | 14 ++--- csharp/rocketmq-client-csharp/SimpleConsumer.cs | 12 ++--- .../SimpleSubscriptionSettings.cs | 8 +-- csharp/rocketmq-client-csharp/StatusChecker.cs | 6 +-- .../rocketmq-client-csharp.csproj | 3 +- .../rocketmq-client-csharp.nlog | 45 ---------------- csharp/tests/MqLogManagerTest.cs | 45 ++++++++++++---- csharp/tests/tests.csproj | 1 + 27 files changed, 227 insertions(+), 204 deletions(-) diff --git a/csharp/README-CN.md b/csharp/README-CN.md index 69d9f198..dacf7a2a 100644 --- a/csharp/README-CN.md +++ b/csharp/README-CN.md @@ -51,14 +51,26 @@ dotnet test -l "console;verbosity=detailed" ## 日志系统 -我们使用 [NLog](https://nlog-project.org/) 作为日志实现,与 Java 客户端类似,我们允许使用环境变量来自定义日志相关的配置。 +我们使用 [Microsoft.Extensions.Logging](https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line#non-host-console-app) 作为日志实现。 + +默认的 `LoggerFactory` 是 [NLog](https://nlog-project.org/)。与 Java 客户端类似,我们允许使用环境变量来自定义日志相关的配置: * `rocketmq_log_level`:日志输出级别,默认为 INFO。 * `rocketmq_log_root` :日志输出的根目录。默认路径为 `$HOME/logs/rocketmq`,因此完整路径为 `$HOME/logs/rocketmq/rocketmq-client.log`。 * `rocketmq_log_file_maxIndex`:要保留的日志文件的最大数量。默认值为 10,单个日志文件的大小限制为 64 MB。暂不支持调整。 -除此之外,通过将 `mq_consoleAppender_enabled` 设置为 true,您可以同时将客户端日志输出到控制台进行调试。 +如果你想使用自定义的 `LoggerFactory`,可以使用 `MqLogManager.UseLoggerFactory` 方法来配置。 + +```csharp +var loggerFactory = LoggerFactory.Create(builder => +{ + builder + .AddFilter("Org.Apache.Rocketmq", LogLevel.Warning) + .AddConsole(); +}); +MqLogManager.UseLoggerFactory(loggerFactory); +``` ## NuGet 包发布步骤 diff --git a/csharp/README.md b/csharp/README.md index 1e648085..3b804a6d 100644 --- a/csharp/README.md +++ b/csharp/README.md @@ -54,7 +54,9 @@ dotnet test -l "console;verbosity=detailed" ## Logging System -We use [NLog](https://nlog-project.org/) as our logging implementation. Similar to the Java binding, we allow the use of +We use [Microsoft.Extensions.Logging](https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line#non-host-console-app) as our logging implementation. + +The default `LoggerFactory` is [NLog](https://nlog-project.org/). Similar to the Java binding, we allow the use of environment variables to customize the related configuration: * `rocketmq_log_level`: Log output level, default is INFO. @@ -63,8 +65,15 @@ environment variables to customize the related configuration: * `rocketmq_log_file_maxIndex`: The maximum number of log files to keep. The default is 10, and the size of a single log file is limited to 64 MB. Adjustment is not supported yet. -Specifically, by setting `mq_consoleAppender_enabled` to true, you can output client logs to the console simultaneously -if you need debugging. +If you want to use a custom `LoggerFactory`, you can use the `MqLogManager.UseLoggerFactory` method to configure. + +```csharp +var loggerFactory = LoggerFactory.Create( + builder => builder + .AddFilter("Org.Apache.Rocketmq", LogLevel.Warning) + .AddConsole()); +MqLogManager.UseLoggerFactory(loggerFactory); +``` ## Publishing Steps diff --git a/csharp/examples/ProducerBenchmark.cs b/csharp/examples/ProducerBenchmark.cs index 2b2ff427..6e57d7e3 100644 --- a/csharp/examples/ProducerBenchmark.cs +++ b/csharp/examples/ProducerBenchmark.cs @@ -20,14 +20,14 @@ using System.Collections.Concurrent; using System.Text; using System.Threading; using System.Threading.Tasks; -using NLog; +using Microsoft.Extensions.Logging; using Org.Apache.Rocketmq; namespace examples { public static class ProducerBenchmark { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(ProducerBenchmark).FullName); private static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(0); private const int TpsLimit = 1024; @@ -52,7 +52,7 @@ namespace examples { while (true) { - Logger.Info($"{Interlocked.Exchange(ref _successCounter, 0)} success, " + + Logger.LogInformation($"{Interlocked.Exchange(ref _successCounter, 0)} success, " + $"{Interlocked.Exchange(ref _failureCounter, 0)} failure."); await Task.Delay(TimeSpan.FromSeconds(1)); } diff --git a/csharp/examples/ProducerDelayMessageExample.cs b/csharp/examples/ProducerDelayMessageExample.cs index fa3d4bae..1da89186 100644 --- a/csharp/examples/ProducerDelayMessageExample.cs +++ b/csharp/examples/ProducerDelayMessageExample.cs @@ -18,14 +18,14 @@ using System; using System.Text; using System.Threading.Tasks; -using NLog; +using Microsoft.Extensions.Logging; using Org.Apache.Rocketmq; namespace examples { internal static class ProducerDelayMessageExample { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(ProducerDelayMessageExample).FullName); internal static async Task QuickStart() { @@ -65,7 +65,7 @@ namespace examples .Build(); var sendReceipt = await producer.Send(message); - Logger.Info($"Send message successfully, sendReceipt={sendReceipt}"); + Logger.LogInformation($"Send message successfully, sendReceipt={sendReceipt}"); // Close the producer if you don't need it anymore. await producer.DisposeAsync(); diff --git a/csharp/examples/ProducerFifoMessageExample.cs b/csharp/examples/ProducerFifoMessageExample.cs index bba5fc60..138cd02e 100644 --- a/csharp/examples/ProducerFifoMessageExample.cs +++ b/csharp/examples/ProducerFifoMessageExample.cs @@ -16,16 +16,15 @@ */ using System.Text; -using System.Threading; using System.Threading.Tasks; -using NLog; +using Microsoft.Extensions.Logging; using Org.Apache.Rocketmq; namespace examples { internal static class ProducerFifoMessageExample { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(ProducerFifoMessageExample).FullName); internal static async Task QuickStart() { @@ -67,7 +66,7 @@ namespace examples .Build(); var sendReceipt = await producer.Send(message); - Logger.Info($"Send message successfully, sendReceipt={sendReceipt}"); + Logger.LogInformation($"Send message successfully, sendReceipt={sendReceipt}"); // Close the producer if you don't need it anymore. await producer.DisposeAsync(); diff --git a/csharp/examples/ProducerNormalMessageExample.cs b/csharp/examples/ProducerNormalMessageExample.cs index c94662d0..6038eb6c 100644 --- a/csharp/examples/ProducerNormalMessageExample.cs +++ b/csharp/examples/ProducerNormalMessageExample.cs @@ -17,14 +17,14 @@ using System.Text; using System.Threading.Tasks; -using NLog; +using Microsoft.Extensions.Logging; using Org.Apache.Rocketmq; namespace examples { internal static class ProducerNormalMessageExample { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(ProducerNormalMessageExample).FullName); internal static async Task QuickStart() { @@ -63,7 +63,7 @@ namespace examples .Build(); var sendReceipt = await producer.Send(message); - Logger.Info($"Send message successfully, messageId={sendReceipt.MessageId}"); + Logger.LogInformation($"Send message successfully, messageId={sendReceipt.MessageId}"); // Close the producer if you don't need it anymore. await producer.DisposeAsync(); diff --git a/csharp/examples/ProducerTransactionMessageExample.cs b/csharp/examples/ProducerTransactionMessageExample.cs index ebaec134..d353f743 100644 --- a/csharp/examples/ProducerTransactionMessageExample.cs +++ b/csharp/examples/ProducerTransactionMessageExample.cs @@ -17,20 +17,20 @@ using System.Text; using System.Threading.Tasks; -using NLog; +using Microsoft.Extensions.Logging; using Org.Apache.Rocketmq; namespace examples { internal static class ProducerTransactionMessageExample { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(ProducerTransactionMessageExample).FullName); private class TransactionChecker : ITransactionChecker { public TransactionResolution Check(MessageView messageView) { - Logger.Info("Receive transaction check, messageId={}", messageView.MessageId); + Logger.LogInformation("Receive transaction check, messageId={}", messageView.MessageId); return TransactionResolution.Commit; } } @@ -74,7 +74,7 @@ namespace examples .Build(); var sendReceipt = await producer.Send(message, transaction); - Logger.Info("Send transaction message successfully, messageId={}", sendReceipt.MessageId); + Logger.LogInformation("Send transaction message successfully, messageId={}", sendReceipt.MessageId); // Commit the transaction. transaction.Commit(); // Or rollback the transaction. diff --git a/csharp/examples/QuickStart.cs b/csharp/examples/QuickStart.cs index 2d4a674d..63d57e85 100644 --- a/csharp/examples/QuickStart.cs +++ b/csharp/examples/QuickStart.cs @@ -15,12 +15,21 @@ * limitations under the License. */ +using Microsoft.Extensions.Logging; +using Org.Apache.Rocketmq; + namespace examples { internal static class QuickStart { public static void Main() { + var loggerFactory = LoggerFactory.Create( + builder => builder + .AddFilter("Org.Apache.Rocketmq", LogLevel.Warning) + .AddFilter("examples", LogLevel.Information) + .AddConsole()); + MqLogManager.UseLoggerFactory(loggerFactory); // ProducerNormalMessageExample.QuickStart().Wait(); // ProducerFifoMessageExample.QuickStart().Wait(); // ProducerDelayMessageExample.QuickStart().Wait(); diff --git a/csharp/examples/SimpleConsumerExample.cs b/csharp/examples/SimpleConsumerExample.cs index 221ce05a..3b2a4b7d 100644 --- a/csharp/examples/SimpleConsumerExample.cs +++ b/csharp/examples/SimpleConsumerExample.cs @@ -18,14 +18,14 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using NLog; +using Microsoft.Extensions.Logging; using Org.Apache.Rocketmq; namespace examples { internal static class SimpleConsumerExample { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(SimpleConsumerExample).FullName); internal static async Task QuickStart() { @@ -60,12 +60,12 @@ namespace examples var messageViews = await simpleConsumer.Receive(16, TimeSpan.FromSeconds(15)); foreach (var message in messageViews) { - Logger.Info( + Logger.LogInformation( $"Received a message, topic={message.Topic}, message-id={message.MessageId}, body-size={message.Body.Length}"); await simpleConsumer.Ack(message); - Logger.Info($"Message is acknowledged successfully, message-id={message.MessageId}"); + Logger.LogInformation($"Message is acknowledged successfully, message-id={message.MessageId}"); // await simpleConsumer.ChangeInvisibleDuration(message, TimeSpan.FromSeconds(15)); - // Logger.Info($"Changing message invisible duration successfully, message=id={message.MessageId}"); + // Logger.LogInformation($"Changing message invisible duration successfully, message=id={message.MessageId}"); } } // Close the simple consumer if you don't need it anymore. diff --git a/csharp/examples/examples.csproj b/csharp/examples/examples.csproj index c4836826..34e14655 100644 --- a/csharp/examples/examples.csproj +++ b/csharp/examples/examples.csproj @@ -2,6 +2,9 @@ <ItemGroup> <ProjectReference Include="..\rocketmq-client-csharp\rocketmq-client-csharp.csproj" /> </ItemGroup> + <ItemGroup> + <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.32" /> + </ItemGroup> <PropertyGroup> <OutputType>Exe</OutputType> diff --git a/csharp/rocketmq-client-csharp/Client.cs b/csharp/rocketmq-client-csharp/Client.cs index 2a2c9716..f3ea4a87 100644 --- a/csharp/rocketmq-client-csharp/Client.cs +++ b/csharp/rocketmq-client-csharp/Client.cs @@ -21,15 +21,15 @@ using System.Threading.Tasks; using System.Threading; using System; using System.Linq; +using Microsoft.Extensions.Logging; using Proto = Apache.Rocketmq.V2; using grpc = Grpc.Core; -using NLog; namespace Org.Apache.Rocketmq { public abstract class Client { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<Client>(); private static readonly TimeSpan HeartbeatScheduleDelay = TimeSpan.FromSeconds(1); private static readonly TimeSpan HeartbeatSchedulePeriod = TimeSpan.FromSeconds(10); @@ -85,7 +85,7 @@ namespace Org.Apache.Rocketmq protected virtual async Task Start() { - Logger.Debug($"Begin to start the rocketmq client, clientId={ClientId}"); + Logger.LogDebug($"Begin to start the rocketmq client, clientId={ClientId}"); foreach (var topic in GetTopics()) { await FetchTopicRoute(topic); @@ -97,12 +97,12 @@ namespace Org.Apache.Rocketmq ScheduleWithFixedDelay(SyncSettings, SettingsSyncScheduleDelay, SettingsSyncSchedulePeriod, _settingsSyncCts.Token); ScheduleWithFixedDelay(Stats, StatsScheduleDelay, StatsSchedulePeriod, _statsCts.Token); - Logger.Debug($"Start the rocketmq client successfully, clientId={ClientId}"); + Logger.LogDebug($"Start the rocketmq client successfully, clientId={ClientId}"); } protected virtual async Task Shutdown() { - Logger.Debug($"Begin to shutdown rocketmq client, clientId={ClientId}"); + Logger.LogDebug($"Begin to shutdown rocketmq client, clientId={ClientId}"); _heartbeatCts.Cancel(); _topicRouteUpdateCts.Cancel(); _settingsSyncCts.Cancel(); @@ -110,7 +110,7 @@ namespace Org.Apache.Rocketmq NotifyClientTermination(); await ClientManager.Shutdown(); ClientMeterManager.Shutdown(); - Logger.Debug($"Shutdown the rocketmq client successfully, clientId={ClientId}"); + Logger.LogDebug($"Shutdown the rocketmq client successfully, clientId={ClientId}"); } private (bool, Session) GetSession(Endpoints endpoints) @@ -174,9 +174,9 @@ namespace Org.Apache.Rocketmq continue; } - Logger.Info($"Begin to establish session for endpoints={endpoints}, clientId={ClientId}"); + Logger.LogInformation($"Begin to establish session for endpoints={endpoints}, clientId={ClientId}"); await session.SyncSettings(true); - Logger.Info($"Establish session for endpoints={endpoints} successfully, clientId={ClientId}"); + Logger.LogInformation($"Establish session for endpoints={endpoints} successfully, clientId={ClientId}"); } _topicRouteCache[topic] = topicRouteData; @@ -204,7 +204,7 @@ namespace Org.Apache.Rocketmq { try { - Logger.Info($"Start to update topic route cache for a new round, clientId={ClientId}"); + Logger.LogInformation($"Start to update topic route cache for a new round, clientId={ClientId}"); Dictionary<string, Task<TopicRouteData>> responses = new Dictionary<string, Task<TopicRouteData>>(); foreach (var topic in GetTopics()) @@ -221,13 +221,13 @@ namespace Org.Apache.Rocketmq } catch (Exception e) { - Logger.Error(e, $"Failed to update topic route cache, topic={item}"); + Logger.LogError(e, $"Failed to update topic route cache, topic={item}"); } } } catch (Exception e) { - Logger.Error(e, $"[Bug] unexpected exception raised during topic route cache update, " + + Logger.LogError(e, $"[Bug] unexpected exception raised during topic route cache update, " + $"clientId={ClientId}"); } } @@ -241,19 +241,19 @@ namespace Org.Apache.Rocketmq { var (_, session) = GetSession(endpoints); await session.SyncSettings(false); - Logger.Info($"Sync settings to remote, endpoints={endpoints}"); + Logger.LogInformation($"Sync settings to remote, endpoints={endpoints}"); } } catch (Exception e) { - Logger.Error(e, $"[Bug] unexpected exception raised during setting sync, clientId={ClientId}"); + Logger.LogError(e, $"[Bug] unexpected exception raised during setting sync, clientId={ClientId}"); } } private void Stats() { ThreadPool.GetAvailableThreads(out var availableWorker, out var availableIo); - Logger.Info( + Logger.LogInformation( $"ClientId={ClientId}, ClientVersion={MetadataConstants.Instance.ClientVersion}, " + $".NET Version={Environment.Version}, ThreadCount={ThreadPool.ThreadCount}, " + $"CompletedWorkItemCount={ThreadPool.CompletedWorkItemCount}, " + @@ -274,7 +274,7 @@ namespace Org.Apache.Rocketmq } catch (Exception e) { - Logger.Error(e, $"Failed to execute scheduled task, ClientId={ClientId}"); + Logger.LogError(e, $"Failed to execute scheduled task, ClientId={ClientId}"); } finally { @@ -299,7 +299,7 @@ namespace Org.Apache.Rocketmq { var topicRouteData = await FetchTopicRoute0(topic); await OnTopicRouteDataFetched(topic, topicRouteData); - Logger.Info( + Logger.LogInformation( $"Fetch topic route successfully, clientId={ClientId}, topic={topic}, topicRouteData={topicRouteData}"); return topicRouteData; } @@ -323,7 +323,7 @@ namespace Org.Apache.Rocketmq var code = invocation.Response.Status.Code; if (!Proto.Code.Ok.Equals(code)) { - Logger.Error($"Failed to fetch topic route, clientId={ClientId}, topic={topic}, code={code}, " + + Logger.LogError($"Failed to fetch topic route, clientId={ClientId}, topic={topic}, code={code}, " + $"statusMessage={invocation.Response.Status.Message}"); } @@ -334,7 +334,7 @@ namespace Org.Apache.Rocketmq } catch (Exception e) { - Logger.Error(e, $"Failed to fetch topic route, clientId={ClientId}, topic={topic}"); + Logger.LogError(e, $"Failed to fetch topic route, clientId={ClientId}, topic={topic}"); throw; } } @@ -364,10 +364,10 @@ namespace Org.Apache.Rocketmq if (code.Equals(Proto.Code.Ok)) { - Logger.Info($"Send heartbeat successfully, endpoints={item}, clientId={ClientId}"); + Logger.LogInformation($"Send heartbeat successfully, endpoints={item}, clientId={ClientId}"); if (Isolated.TryRemove(item, out _)) { - Logger.Info($"Rejoin endpoints which was isolated before, endpoints={item}, " + + Logger.LogInformation($"Rejoin endpoints which was isolated before, endpoints={item}, " + $"clientId={ClientId}"); } @@ -375,18 +375,18 @@ namespace Org.Apache.Rocketmq } var statusMessage = invocation.Response.Status.Message; - Logger.Info($"Failed to send heartbeat, endpoints={item}, code={code}, " + + Logger.LogInformation($"Failed to send heartbeat, endpoints={item}, code={code}, " + $"statusMessage={statusMessage}, clientId={ClientId}"); } catch (Exception e) { - Logger.Error(e, $"Failed to send heartbeat, endpoints={item}"); + Logger.LogError(e, $"Failed to send heartbeat, endpoints={item}"); } } } catch (Exception e) { - Logger.Error(e, $"[Bug] unexpected exception raised during heartbeat, clientId={ClientId}"); + Logger.LogError(e, $"[Bug] unexpected exception raised during heartbeat, clientId={ClientId}"); } } @@ -401,7 +401,7 @@ namespace Org.Apache.Rocketmq private async void NotifyClientTermination() { - Logger.Info($"Notify remote endpoints that current client is terminated, clientId={ClientId}"); + Logger.LogInformation($"Notify remote endpoints that current client is terminated, clientId={ClientId}"); var endpoints = GetTotalRouteEndpoints(); var request = WrapNotifyClientTerminationRequest(); foreach (var item in endpoints) @@ -414,7 +414,7 @@ namespace Org.Apache.Rocketmq } catch (Exception e) { - Logger.Error(e, $"Failed to notify client's termination, clientId=${ClientId}, " + + Logger.LogError(e, $"Failed to notify client's termination, clientId=${ClientId}, " + $"endpoints=${item}"); } } @@ -435,14 +435,14 @@ namespace Org.Apache.Rocketmq internal virtual void OnRecoverOrphanedTransactionCommand(Endpoints endpoints, Proto.RecoverOrphanedTransactionCommand command) { - Logger.Warn($"Ignore orphaned transaction recovery command from remote, which is not expected, " + - $"clientId={ClientId}, endpoints={endpoints}"); + Logger.LogWarning($"Ignore orphaned transaction recovery command from remote, which is not expected, " + + $"clientId={ClientId}, endpoints={endpoints}"); } internal async void OnVerifyMessageCommand(Endpoints endpoints, Proto.VerifyMessageCommand command) { // Only push consumer support message consumption verification. - Logger.Warn($"Ignore verify message command from remote, which is not expected, clientId={ClientId}, " + + Logger.LogWarning($"Ignore verify message command from remote, which is not expected, clientId={ClientId}, " + $"endpoints={endpoints}, command={command}"); var status = new Proto.Status { @@ -466,8 +466,8 @@ namespace Org.Apache.Rocketmq internal async void OnPrintThreadStackTraceCommand(Endpoints endpoints, Proto.PrintThreadStackTraceCommand command) { - Logger.Warn("Ignore thread stack trace printing command from remote because it is still not supported, " + - $"clientId={ClientId}, endpoints={endpoints}"); + Logger.LogWarning("Ignore thread stack trace printing command from remote because it is still not supported, " + + $"clientId={ClientId}, endpoints={endpoints}"); var status = new Proto.Status { Code = Proto.Code.Unsupported, diff --git a/csharp/rocketmq-client-csharp/ClientLoggerInterceptor.cs b/csharp/rocketmq-client-csharp/ClientLoggerInterceptor.cs index 6f990de7..7631bdfe 100644 --- a/csharp/rocketmq-client-csharp/ClientLoggerInterceptor.cs +++ b/csharp/rocketmq-client-csharp/ClientLoggerInterceptor.cs @@ -19,14 +19,14 @@ using System; using System.Threading.Tasks; using Grpc.Core; using Grpc.Core.Interceptors; -using NLog; +using Microsoft.Extensions.Logging; namespace Org.Apache.Rocketmq { public class ClientLoggerInterceptor : Interceptor { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<ClientLoggerInterceptor>(); public override TResponse BlockingUnaryCall<TRequest, TResponse>( TRequest request, @@ -55,7 +55,7 @@ namespace Org.Apache.Rocketmq private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> t) { var response = await t; - Logger.Trace($"Response received: {response}"); + Logger.LogTrace($"Response received: {response}"); return response; } @@ -94,7 +94,7 @@ namespace Org.Apache.Rocketmq where TRequest : class where TResponse : class { - Logger.Trace($"Starting call. Type: {method.Type}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}"); + Logger.LogTrace($"Starting call. Type: {method.Type}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}"); } private void AddCallerMetadata<TRequest, TResponse>(ref ClientInterceptorContext<TRequest, TResponse> context) diff --git a/csharp/rocketmq-client-csharp/ClientMeter.cs b/csharp/rocketmq-client-csharp/ClientMeter.cs index e4360cd1..2e215556 100644 --- a/csharp/rocketmq-client-csharp/ClientMeter.cs +++ b/csharp/rocketmq-client-csharp/ClientMeter.cs @@ -15,14 +15,14 @@ * limitations under the License. */ -using NLog; +using Microsoft.Extensions.Logging; using OpenTelemetry.Metrics; namespace Org.Apache.Rocketmq { public class ClientMeter { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<ClientMeter>(); public ClientMeter(Endpoints endpoints, MeterProvider meterProvider, string clientId) { @@ -58,9 +58,9 @@ namespace Org.Apache.Rocketmq return; } - Logger.Info($"Begin to shutdown the client meter, clientId={ClientId}, endpoints={Endpoints}"); + Logger.LogInformation($"Begin to shutdown the client meter, clientId={ClientId}, endpoints={Endpoints}"); MeterProvider.Shutdown(); - Logger.Info($"Shutdown the client meter successfully, clientId={ClientId}, endpoints={Endpoints}"); + Logger.LogInformation($"Shutdown the client meter successfully, clientId={ClientId}, endpoints={Endpoints}"); } public bool Satisfy(Metric metric) diff --git a/csharp/rocketmq-client-csharp/ClientMeterManager.cs b/csharp/rocketmq-client-csharp/ClientMeterManager.cs index dc856edd..5da0151b 100644 --- a/csharp/rocketmq-client-csharp/ClientMeterManager.cs +++ b/csharp/rocketmq-client-csharp/ClientMeterManager.cs @@ -18,7 +18,7 @@ using System; using System.Diagnostics.Metrics; using System.Net.Http; -using NLog; +using Microsoft.Extensions.Logging; using OpenTelemetry; using OpenTelemetry.Exporter; using OpenTelemetry.Metrics; @@ -28,7 +28,7 @@ namespace Org.Apache.Rocketmq { public class ClientMeterManager { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<ClientMeterManager>(); private const string MeterName = "Apache.RocketMQ.Client"; private const string Version = "1.0"; private const int MetricExportPeriodInMillis = 60 * 1000; @@ -59,14 +59,14 @@ namespace Org.Apache.Rocketmq var clientId = _client.GetClientId(); if (_clientMeter.Satisfy(metric)) { - Logger.Info( + Logger.LogInformation( $"Metric settings is satisfied by the current message meter, metric={metric}, clientId={clientId}"); return; } if (!metric.On) { - Logger.Info($"Metric is off, clientId={clientId}"); + Logger.LogInformation($"Metric is off, clientId={clientId}"); _clientMeter.Shutdown(); _clientMeter = ClientMeter.DisabledInstance(clientId); return; @@ -105,7 +105,7 @@ namespace Org.Apache.Rocketmq var exist = _clientMeter; _clientMeter = new ClientMeter(metric.Endpoints, meterProvider, clientId); exist.Shutdown(); - Logger.Info($"Metric is on, endpoints={metric.Endpoints}, clientId={clientId}"); + Logger.LogInformation($"Metric is on, endpoints={metric.Endpoints}, clientId={clientId}"); } } diff --git a/csharp/rocketmq-client-csharp/MessageView.cs b/csharp/rocketmq-client-csharp/MessageView.cs index 63906344..4d8824d4 100644 --- a/csharp/rocketmq-client-csharp/MessageView.cs +++ b/csharp/rocketmq-client-csharp/MessageView.cs @@ -19,8 +19,7 @@ using Proto = Apache.Rocketmq.V2; using System; using System.Collections.Generic; using System.Linq; -using System.Security.Cryptography; -using NLog; +using Microsoft.Extensions.Logging; namespace Org.Apache.Rocketmq { @@ -29,7 +28,7 @@ namespace Org.Apache.Rocketmq /// </summary> public class MessageView { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<MessageView>(); internal readonly MessageQueue MessageQueue; internal readonly string ReceiptHandle; @@ -125,7 +124,7 @@ namespace Org.Apache.Rocketmq case Proto.DigestType.Unspecified: default: { - Logger.Error( + Logger.LogError( $"Unsupported message body digest algorithm," + $"digestType={type}, topic={topic}, messageId={messageId}"); break; @@ -148,7 +147,7 @@ namespace Org.Apache.Rocketmq case Proto.Encoding.Unspecified: default: { - Logger.Error($"Unsupported message encoding algorithm," + + Logger.LogError($"Unsupported message encoding algorithm," + $" topic={topic}, messageId={messageId}, bodyEncoding={bodyEncoding}"); break; } diff --git a/csharp/rocketmq-client-csharp/MqLogManager.cs b/csharp/rocketmq-client-csharp/MqLogManager.cs index 1e68ea43..a6bde949 100644 --- a/csharp/rocketmq-client-csharp/MqLogManager.cs +++ b/csharp/rocketmq-client-csharp/MqLogManager.cs @@ -16,50 +16,63 @@ */ using System; -using NLog; +using Microsoft.Extensions.Logging; using NLog.Config; +using NLog.Extensions.Logging; using NLog.Layouts; using NLog.Targets; using NLog.Targets.Wrappers; +using LogLevel = NLog.LogLevel; namespace Org.Apache.Rocketmq { - /** - * RocketMQ Log Manager. - * - * Configure component logging, please refer to https://github.com/NLog/NLog/wiki/Configure-component-logging - */ + /// <summary> + /// RocketMQ Log Manager. + /// Use NLog as the default logger and support custom logger factory by using <see cref="UseLoggerFactory"/>. + /// To configure the logger factory, please refer to https://learn.microsoft.com/en-us/dotnet/core/extensions/logging. + /// </summary> public static class MqLogManager { - public static LogFactory Instance => LazyInstance.Value; - - private static readonly Lazy<LogFactory> LazyInstance = new Lazy<LogFactory>(BuildLogFactory); + private static ILoggerFactory _loggerFactory; private const string FileLogLevelKey = "rocketmq_log_level"; private const string FileLogLevel = "Info"; - private const string ConsoleAppenderEnabledKey = "mq_consoleAppender_enabled"; - private const string ConsoleAppenderEnabled = "false"; - private const string ConsoleAppenderLogLevel = "Off"; - - private const string FileLogRootKey = "rocketmq_log_root"; private const string FileMaxIndexKey = "rocketmq_log_file_maxIndex"; private const string FileMaxIndex = "10"; - private static LogFactory BuildLogFactory() + static MqLogManager() + { + _loggerFactory = BuildDefaultLoggerFactory(); + } + + public static ILogger<T> CreateLogger<T>() + { + return _loggerFactory.CreateLogger<T>(); + } + + public static ILogger CreateLogger(string categoryName) + { + return _loggerFactory.CreateLogger(categoryName); + } + + public static void UseLoggerFactory(ILoggerFactory loggerFactory) + { + _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); + } + + // Build default logger factory with NLog. + // Configure component logging, please refer to https://github.com/NLog/NLog/wiki/Configure-component-logging + private static ILoggerFactory BuildDefaultLoggerFactory() { var fileLogLevel = Environment.GetEnvironmentVariable(FileLogLevelKey) ?? FileLogLevel; - var consoleAppenderEnabled = - Environment.GetEnvironmentVariable(ConsoleAppenderEnabledKey) ?? ConsoleAppenderEnabled; - var consoleLogLevel = bool.Parse(consoleAppenderEnabled) ? fileLogLevel : ConsoleAppenderLogLevel; var fileLogRoot = Environment.GetEnvironmentVariable(FileLogRootKey) ?? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); var fileMaxIndexStr = Environment.GetEnvironmentVariable(FileMaxIndexKey) ?? FileMaxIndex; var fileMaxIndex = int.Parse(fileMaxIndexStr); - var config = new LoggingConfiguration(); var fileTarget = new FileTarget(); fileTarget.Name = "log_file"; @@ -92,12 +105,9 @@ namespace Org.Apache.Rocketmq var asyncFileRule = new LoggingRule("*", LogLevel.FromString(fileLogLevel), asyncTargetWrapper); config.LoggingRules.Add(asyncFileRule); - var consoleRule = new LoggingRule("*", LogLevel.FromString(consoleLogLevel), consoleTarget); - config.LoggingRules.Add(consoleRule); + var loggerFactory = LoggerFactory.Create(builder => builder.AddNLog(config)); - var logFactory = new LogFactory(); - logFactory.Configuration = config; - return logFactory; + return loggerFactory; } } } \ No newline at end of file diff --git a/csharp/rocketmq-client-csharp/Producer.cs b/csharp/rocketmq-client-csharp/Producer.cs index 78ee4e34..136bdada 100644 --- a/csharp/rocketmq-client-csharp/Producer.cs +++ b/csharp/rocketmq-client-csharp/Producer.cs @@ -22,15 +22,15 @@ using System.Diagnostics; using System.Diagnostics.Metrics; using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Proto = Apache.Rocketmq.V2; -using NLog; using Org.Apache.Rocketmq.Error; namespace Org.Apache.Rocketmq { public class Producer : Client, IAsyncDisposable, IDisposable { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<Producer>(); private readonly ConcurrentDictionary<string /* topic */, PublishingLoadBalancer> _publishingRouteDataCache; internal readonly PublishingSettings PublishingSettings; private readonly ConcurrentDictionary<string, bool> _publishingTopics; @@ -61,9 +61,9 @@ namespace Org.Apache.Rocketmq try { State = State.Starting; - Logger.Info($"Begin to start the rocketmq producer, clientId={ClientId}"); + Logger.LogInformation($"Begin to start the rocketmq producer, clientId={ClientId}"); await base.Start(); - Logger.Info($"The rocketmq producer starts successfully, clientId={ClientId}"); + Logger.LogInformation($"The rocketmq producer starts successfully, clientId={ClientId}"); State = State.Running; } catch (Exception) @@ -90,9 +90,9 @@ namespace Org.Apache.Rocketmq try { State = State.Stopping; - Logger.Info($"Begin to shutdown the rocketmq producer, clientId={ClientId}"); + Logger.LogInformation($"Begin to shutdown the rocketmq producer, clientId={ClientId}"); await base.Shutdown(); - Logger.Info($"Shutdown the rocketmq producer successfully, clientId={ClientId}"); + Logger.LogInformation($"Shutdown the rocketmq producer successfully, clientId={ClientId}"); State = State.Terminated; } catch (Exception) @@ -230,7 +230,7 @@ namespace Org.Apache.Rocketmq var sendReceipt = sendReceipts.First(); if (attempt > 1) { - Logger.Info( + Logger.LogInformation( $"Re-send message successfully, topic={message.Topic}, messageId={sendReceipt.MessageId}," + $" maxAttempts={maxAttempts}, endpoints={endpoints}, clientId={ClientId}"); } @@ -245,35 +245,35 @@ namespace Org.Apache.Rocketmq Isolated[endpoints] = true; if (attempt >= maxAttempts) { - Logger.Error(e, "Failed to send message finally, run out of attempt times, " + - $"topic={message.Topic}, maxAttempt={maxAttempts}, attempt={attempt}, " + - $"endpoints={endpoints}, messageId={message.MessageId}, clientId={ClientId}"); + Logger.LogError(e, "Failed to send message finally, run out of attempt times, " + + $"topic={message.Topic}, maxAttempt={maxAttempts}, attempt={attempt}, " + + $"endpoints={endpoints}, messageId={message.MessageId}, clientId={ClientId}"); throw; } if (MessageType.Transaction == message.MessageType) { - Logger.Error(e, "Failed to send transaction message, run out of attempt times, " + - $"topic={message.Topic}, maxAttempt=1, attempt={attempt}, " + - $"endpoints={endpoints}, messageId={message.MessageId}, clientId={ClientId}"); + Logger.LogError(e, "Failed to send transaction message, run out of attempt times, " + + $"topic={message.Topic}, maxAttempt=1, attempt={attempt}, " + + $"endpoints={endpoints}, messageId={message.MessageId}, clientId={ClientId}"); throw; } if (!(exception is TooManyRequestsException)) { // Retry immediately if the request is not throttled. - Logger.Warn(e, $"Failed to send message, topic={message.Topic}, maxAttempts={maxAttempts}, " + - $"attempt={attempt}, endpoints={endpoints}, messageId={message.MessageId}," + - $" clientId={ClientId}"); + Logger.LogWarning(e, $"Failed to send message, topic={message.Topic}, maxAttempts={maxAttempts}, " + + $"attempt={attempt}, endpoints={endpoints}, messageId={message.MessageId}," + + $" clientId={ClientId}"); continue; } var nextAttempt = 1 + attempt; var delay = retryPolicy.GetNextAttemptDelay(nextAttempt); await Task.Delay(delay); - Logger.Warn(e, "Failed to send message due to too many request, would attempt to resend " + - $"after {delay}, topic={message.Topic}, maxAttempts={maxAttempts}, attempt={attempt}, " + - $"endpoints={endpoints}, messageId={message.MessageId}, clientId={ClientId}"); + Logger.LogWarning(e, "Failed to send message due to too many request, would attempt to resend " + + $"after {delay}, topic={message.Topic}, maxAttempts={maxAttempts}, attempt={attempt}, " + + $"endpoints={endpoints}, messageId={message.MessageId}, clientId={ClientId}"); } finally { @@ -301,8 +301,8 @@ namespace Org.Apache.Rocketmq var messageId = command.Message.SystemProperties.MessageId; if (null == _checker) { - Logger.Error($"No transaction checker registered, ignore it, messageId={messageId}, " + - $"transactionId={command.TransactionId}, endpoints={endpoints}, clientId={ClientId}"); + Logger.LogError($"No transaction checker registered, ignore it, messageId={messageId}, " + + $"transactionId={command.TransactionId}, endpoints={endpoints}, clientId={ClientId}"); return; } diff --git a/csharp/rocketmq-client-csharp/PublishingSettings.cs b/csharp/rocketmq-client-csharp/PublishingSettings.cs index 22423b56..a5ab74d4 100644 --- a/csharp/rocketmq-client-csharp/PublishingSettings.cs +++ b/csharp/rocketmq-client-csharp/PublishingSettings.cs @@ -19,14 +19,14 @@ using System; using System.Collections.Concurrent; using System.Linq; using Google.Protobuf.WellKnownTypes; -using NLog; +using Microsoft.Extensions.Logging; using Proto = Apache.Rocketmq.V2; namespace Org.Apache.Rocketmq { public class PublishingSettings : Settings { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<PublishingSettings>(); private volatile int _maxBodySizeBytes = 4 * 1024 * 1024; private volatile bool _validateMessageType = true; @@ -54,7 +54,7 @@ namespace Org.Apache.Rocketmq { if (Proto.Settings.PubSubOneofCase.Publishing != settings.PubSubCase) { - Logger.Error($"[Bug] Issued settings does not match with the client type, clientId={ClientId}, " + + Logger.LogError($"[Bug] Issued settings does not match with the client type, clientId={ClientId}, " + $"pubSubCase={settings.PubSubCase}, clientType={ClientType}"); return; } diff --git a/csharp/rocketmq-client-csharp/RpcClient.cs b/csharp/rocketmq-client-csharp/RpcClient.cs index d5c24d7f..eeff96e5 100644 --- a/csharp/rocketmq-client-csharp/RpcClient.cs +++ b/csharp/rocketmq-client-csharp/RpcClient.cs @@ -25,13 +25,13 @@ using Proto = Apache.Rocketmq.V2; using Grpc.Core; using Grpc.Core.Interceptors; using Grpc.Net.Client; -using NLog; +using Microsoft.Extensions.Logging; namespace Org.Apache.Rocketmq { public class RpcClient : IRpcClient { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<RpcClient>(); private readonly Proto::MessagingService.MessagingServiceClient _stub; private readonly GrpcChannel _channel; private readonly string _target; @@ -126,17 +126,17 @@ namespace Org.Apache.Rocketmq var deadline = DateTime.UtcNow.Add(timeout); var callOptions = new CallOptions(metadata, deadline); var call = _stub.ReceiveMessage(request, callOptions); - Logger.Debug($"ReceiveMessageRequest has been written to {_target}"); + Logger.LogDebug($"ReceiveMessageRequest has been written to {_target}"); var result = new List<Proto::ReceiveMessageResponse>(); var stream = call.ResponseStream; while (await stream.MoveNext()) { var entry = stream.Current; - Logger.Debug($"Got ReceiveMessageResponse {entry} from {_target}"); + Logger.LogDebug($"Got ReceiveMessageResponse {entry} from {_target}"); result.Add(entry); } - Logger.Debug($"Receiving messages from {_target} completed"); + Logger.LogDebug($"Receiving messages from {_target} completed"); return result; } diff --git a/csharp/rocketmq-client-csharp/Session.cs b/csharp/rocketmq-client-csharp/Session.cs index f41694ec..ac66d5b7 100644 --- a/csharp/rocketmq-client-csharp/Session.cs +++ b/csharp/rocketmq-client-csharp/Session.cs @@ -19,8 +19,8 @@ using System; using System.Threading; using System.Threading.Tasks; using Grpc.Core; +using Microsoft.Extensions.Logging; using grpc = Grpc.Core; -using NLog; using Proto = Apache.Rocketmq.V2; namespace Org.Apache.Rocketmq @@ -28,7 +28,7 @@ namespace Org.Apache.Rocketmq // refer to https://learn.microsoft.com/en-us/aspnet/core/grpc/client?view=aspnetcore-7.0#bi-directional-streaming-call. public class Session { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<Session>(); private static readonly TimeSpan SettingsInitializationTimeout = TimeSpan.FromSeconds(3); private readonly ManualResetEventSlim _event = new ManualResetEventSlim(false); @@ -92,7 +92,7 @@ namespace Org.Apache.Rocketmq { case Proto.TelemetryCommand.CommandOneofCase.Settings: { - Logger.Info( + Logger.LogInformation( $"Receive setting from remote, endpoints={_endpoints}, clientId={_client.GetClientId()}"); _client.OnSettingsCommand(_endpoints, response.Settings); _event.Set(); @@ -100,7 +100,7 @@ namespace Org.Apache.Rocketmq } case Proto.TelemetryCommand.CommandOneofCase.RecoverOrphanedTransactionCommand: { - Logger.Info( + Logger.LogInformation( $"Receive orphaned transaction recovery command from remote, endpoints={_endpoints}, clientId={_client.GetClientId()}"); _client.OnRecoverOrphanedTransactionCommand(_endpoints, response.RecoverOrphanedTransactionCommand); @@ -108,21 +108,21 @@ namespace Org.Apache.Rocketmq } case Proto.TelemetryCommand.CommandOneofCase.VerifyMessageCommand: { - Logger.Info( + Logger.LogInformation( $"Receive message verification command from remote, endpoints={_endpoints}, clientId={_client.GetClientId()}"); _client.OnVerifyMessageCommand(_endpoints, response.VerifyMessageCommand); break; } case Proto.TelemetryCommand.CommandOneofCase.PrintThreadStackTraceCommand: { - Logger.Info( + Logger.LogInformation( $"Receive thread stack print command from remote, endpoints={_endpoints}, clientId={_client.GetClientId()}"); _client.OnPrintThreadStackTraceCommand(_endpoints, response.PrintThreadStackTraceCommand); break; } default: { - Logger.Warn( + Logger.LogWarning( $"Receive unrecognized command from remote, endpoints={_endpoints}, command={response}, clientId={_client.GetClientId()}"); break; } diff --git a/csharp/rocketmq-client-csharp/SimpleConsumer.cs b/csharp/rocketmq-client-csharp/SimpleConsumer.cs index da372177..d16a8c5f 100644 --- a/csharp/rocketmq-client-csharp/SimpleConsumer.cs +++ b/csharp/rocketmq-client-csharp/SimpleConsumer.cs @@ -21,15 +21,15 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Google.Protobuf.WellKnownTypes; +using Microsoft.Extensions.Logging; using Proto = Apache.Rocketmq.V2; -using NLog; using Org.Apache.Rocketmq.Error; namespace Org.Apache.Rocketmq { public class SimpleConsumer : Consumer, IAsyncDisposable, IDisposable { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<SimpleConsumer>(); private readonly ConcurrentDictionary<string /* topic */, SubscriptionLoadBalancer> _subscriptionRouteDataCache; private readonly ConcurrentDictionary<string /* topic */, FilterExpression> _subscriptionExpressions; private readonly TimeSpan _awaitDuration; @@ -79,9 +79,9 @@ namespace Org.Apache.Rocketmq try { State = State.Starting; - Logger.Info($"Begin to start the rocketmq simple consumer, clientId={ClientId}"); + Logger.LogInformation($"Begin to start the rocketmq simple consumer, clientId={ClientId}"); await base.Start(); - Logger.Info($"The rocketmq simple consumer starts successfully, clientId={ClientId}"); + Logger.LogInformation($"The rocketmq simple consumer starts successfully, clientId={ClientId}"); State = State.Running; } catch (Exception) @@ -108,9 +108,9 @@ namespace Org.Apache.Rocketmq try { State = State.Stopping; - Logger.Info($"Begin to shutdown the rocketmq simple consumer, clientId={ClientId}"); + Logger.LogInformation($"Begin to shutdown the rocketmq simple consumer, clientId={ClientId}"); await base.Shutdown(); - Logger.Info($"Shutdown the rocketmq simple consumer successfully, clientId={ClientId}"); + Logger.LogInformation($"Shutdown the rocketmq simple consumer successfully, clientId={ClientId}"); State = State.Terminated; } catch (Exception) diff --git a/csharp/rocketmq-client-csharp/SimpleSubscriptionSettings.cs b/csharp/rocketmq-client-csharp/SimpleSubscriptionSettings.cs index c83cca7d..2b214fa1 100644 --- a/csharp/rocketmq-client-csharp/SimpleSubscriptionSettings.cs +++ b/csharp/rocketmq-client-csharp/SimpleSubscriptionSettings.cs @@ -19,14 +19,14 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using Google.Protobuf.WellKnownTypes; -using NLog; +using Microsoft.Extensions.Logging; using Proto = Apache.Rocketmq.V2; namespace Org.Apache.Rocketmq { public class SimpleSubscriptionSettings : Settings { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger<SimpleSubscriptionSettings>(); private readonly Resource _group; private readonly TimeSpan _longPollingTimeout; @@ -46,7 +46,7 @@ namespace Org.Apache.Rocketmq { if (Proto.Settings.PubSubOneofCase.Subscription != settings.PubSubCase) { - Logger.Error($"[Bug] Issued settings doesn't match with the client type, clientId={ClientId}, " + + Logger.LogError($"[Bug] Issued settings doesn't match with the client type, clientId={ClientId}, " + $"pubSubCase={settings.PubSubCase}, clientType={ClientType}"); } } @@ -71,7 +71,7 @@ namespace Org.Apache.Rocketmq filterExpression.Type = Proto.FilterType.Sql; break; default: - Logger.Warn($"[Bug] Unrecognized filter type={value.Type} for simple consumer"); + Logger.LogWarning($"[Bug] Unrecognized filter type={value.Type} for simple consumer"); break; } diff --git a/csharp/rocketmq-client-csharp/StatusChecker.cs b/csharp/rocketmq-client-csharp/StatusChecker.cs index 3fecfd95..12d12fe6 100644 --- a/csharp/rocketmq-client-csharp/StatusChecker.cs +++ b/csharp/rocketmq-client-csharp/StatusChecker.cs @@ -16,7 +16,7 @@ */ using Google.Protobuf; -using NLog; +using Microsoft.Extensions.Logging; using Org.Apache.Rocketmq.Error; using Proto = Apache.Rocketmq.V2; @@ -24,7 +24,7 @@ namespace Org.Apache.Rocketmq { public static class StatusChecker { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger Logger = MqLogManager.CreateLogger(typeof(StatusChecker).FullName); public static void Check(Proto.Status status, IMessage request, string requestId) { @@ -101,7 +101,7 @@ namespace Org.Apache.Rocketmq case Proto.Code.FailedToConsumeMessage: case Proto.Code.Unspecified: default: - Logger.Warn($"Unrecognized status code={statusCode}, requestId={requestId}, statusMessage={statusMessage}"); + Logger.LogWarning($"Unrecognized status code={statusCode}, requestId={requestId}, statusMessage={statusMessage}"); throw new UnsupportedException((int)statusCode, requestId, statusMessage); } } diff --git a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj b/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj index 46a1ad40..b13ea1d1 100644 --- a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj +++ b/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj @@ -29,7 +29,8 @@ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> - <PackageReference Include="NLog" Version="4.7.13" /> + <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.32" /> + <PackageReference Include="NLog.Extensions.Logging" Version="5.3.4" /> <PackageReference Include="OpenTelemetry" Version="1.3.1" /> <PackageReference Include="OpenTelemetry.Api" Version="1.3.1" /> <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.3.1" /> diff --git a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.nlog b/csharp/rocketmq-client-csharp/rocketmq-client-csharp.nlog deleted file mode 100644 index 4a5319e7..00000000 --- a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.nlog +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - throwconfigexceptions="true"> - <variables> - <variable name="logLevel" value="${environment:rocketmq.log.level:whenEmpty=Info}" /> - <variable name="ConsoleLogLevel" value="${environment:rocketmq.console.log.level:whenEmpty=Off}" /> - </variables> - <targets> - <target name="asyncFile" xsi:type="AsyncWrapper"> - <target name="log_file" xsi:type="File" - fileName="${specialfolder:folder=UserProfile}/logs/rocketmq/rocketmq-client.log" - layout="${longdate} ${level:uppercase=true:padding=-5} [${processid}] [${threadid}] [${callsite}:${callsite-linenumber}] ${message} ${onexception:${exception:format=ToString,Data}}" - archiveFileName="${specialfolder:folder=UserProfile}/logs/rocketmq/rocketmq-client.{######}.log" - archiveAboveSize="67108864" - archiveNumbering="DateAndSequence" - maxArchiveFiles="10" - concurrentWrites="true" - keepFileOpen="false" /> - </target> - <target name="colorConsole" xsi:type="ColoredConsole" - useDefaultRowHighlightingRules="true" - layout="${longdate} ${level:uppercase=true:padding=-5} [${processid}] [${threadid}] [${callsite}:${callsite-linenumber}] ${message} ${onexception:${exception:format=ToString,Data}}" > - </target> - </targets> - <rules> - <logger name="*" minLevel="${logLevel}" writeTo="asyncFile" /> - <logger name="*" minLevel="${ConsoleLogLevel}" writeTo="colorConsole" /> - </rules> -</nlog> \ No newline at end of file diff --git a/csharp/tests/MqLogManagerTest.cs b/csharp/tests/MqLogManagerTest.cs index 076c9331..cd7b88eb 100644 --- a/csharp/tests/MqLogManagerTest.cs +++ b/csharp/tests/MqLogManagerTest.cs @@ -16,8 +16,8 @@ */ using System; +using Microsoft.Extensions.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; -using NLog; using Org.Apache.Rocketmq; namespace tests @@ -25,20 +25,45 @@ namespace tests [TestClass] public class MqLogManagerTest { - private static readonly Logger Logger = MqLogManager.Instance.GetCurrentClassLogger(); + private static readonly ILogger DefaultLogger1; + private static readonly ILogger DefaultLogger2; + private static readonly ILogger ConsoleLogger1; + private static readonly ILogger ConsoleLogger2; + + static MqLogManagerTest() + { + DefaultLogger1 = MqLogManager.CreateLogger<MqLogManagerTest>(); + DefaultLogger2 = MqLogManager.CreateLogger("MqLogManagerTest2"); + + var loggerFactory = LoggerFactory.Create( + builder => builder + .AddFilter("tests", LogLevel.Information) + .AddConsole()); + MqLogManager.UseLoggerFactory(loggerFactory); + ConsoleLogger1 = MqLogManager.CreateLogger<MqLogManagerTest>(); + ConsoleLogger2 = MqLogManager.CreateLogger("MqLogManagerTest2"); + } [TestMethod] public void TestLog() { - Logger.Trace("This is a trace message."); - Logger.Debug("This is a debug message."); - Logger.Info("This is an info message."); - Logger.Warn("This is a warn message."); - Logger.Error("This is an error message."); - Logger.Fatal("This is a fatal message."); + TestLog(DefaultLogger1); + TestLog(DefaultLogger2); + TestLog(ConsoleLogger1); + TestLog(ConsoleLogger2); + } + + private void TestLog(ILogger logger) + { + logger.LogTrace("This is a trace message."); + logger.LogDebug("This is a debug message."); + logger.LogInformation("This is an info message."); + logger.LogWarning("This is a warn message."); + logger.LogError("This is an error message."); + logger.LogCritical("This is a critical message."); - Logger.Error(new Exception("foobar"), "this is an error message with exception."); - Logger.Fatal(new Exception("foobar"), "this is a fatal message with exception."); + logger.LogError(new Exception("foobar"), "this is an error message with exception."); + logger.LogCritical(new Exception("foobar"), "this is a critical message with exception."); } } } \ No newline at end of file diff --git a/csharp/tests/tests.csproj b/csharp/tests/tests.csproj index ab8aad59..1e3b9fee 100644 --- a/csharp/tests/tests.csproj +++ b/csharp/tests/tests.csproj @@ -7,6 +7,7 @@ </PropertyGroup> <ItemGroup> + <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.32" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Moq" Version="4.16.1" /> <PackageReference Include="MSTest.TestAdapter" Version="2.2.3" />