diff --git a/src/MagicOnion.Server.Redis/RedisGroup.cs b/src/MagicOnion.Server.Redis/RedisGroup.cs index 585e58165..a35d4f03a 100644 --- a/src/MagicOnion.Server.Redis/RedisGroup.cs +++ b/src/MagicOnion.Server.Redis/RedisGroup.cs @@ -5,20 +5,22 @@ using MessagePack; using StackExchange.Redis; using System.Collections.Concurrent; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server.Redis; public class RedisGroupRepository : IGroupRepository { - IMagicOnionSerializer messageSerializer; - IMagicOnionLogger logger; + readonly IMagicOnionSerializer messageSerializer; + readonly ILogger logger; + ConnectionMultiplexer connection; int db; readonly Func factory; ConcurrentDictionary dictionary = new ConcurrentDictionary(); - public RedisGroupRepository(IMagicOnionSerializer messageSerializer, RedisGroupOptions redisGroupOptions, IMagicOnionLogger logger) + public RedisGroupRepository(IMagicOnionSerializer messageSerializer, RedisGroupOptions redisGroupOptions, ILogger logger) { this.messageSerializer = messageSerializer; this.logger = logger; diff --git a/src/MagicOnion.Server.Redis/RedisGroupRepositoryFactory.cs b/src/MagicOnion.Server.Redis/RedisGroupRepositoryFactory.cs index d64f36470..a73b4a1b6 100644 --- a/src/MagicOnion.Server.Redis/RedisGroupRepositoryFactory.cs +++ b/src/MagicOnion.Server.Redis/RedisGroupRepositoryFactory.cs @@ -2,20 +2,23 @@ using MagicOnion.Server.Diagnostics; using MagicOnion.Server.Hubs; using MessagePack; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace MagicOnion.Server.Redis; public class RedisGroupRepositoryFactory : IGroupRepositoryFactory { - private readonly RedisGroupOptions options; + readonly RedisGroupOptions options; + readonly ILogger logger; - public RedisGroupRepositoryFactory(IOptionsMonitor options) + public RedisGroupRepositoryFactory(IOptionsMonitor options, ILogger logger) { this.options = options.CurrentValue; + this.logger = logger; } - public IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer, IMagicOnionLogger logger) + public IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer) { return new RedisGroupRepository(messageSerializer, options, logger); } diff --git a/src/MagicOnion.Server/Diagnostics/IMagicOnionLogger.cs b/src/MagicOnion.Server/Diagnostics/IMagicOnionLogger.cs deleted file mode 100644 index 62034844c..000000000 --- a/src/MagicOnion.Server/Diagnostics/IMagicOnionLogger.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Grpc.Core; -using MagicOnion.Server.Hubs; - -namespace MagicOnion.Server.Diagnostics; - -public interface IMagicOnionLogger -{ - void BeginBuildServiceDefinition(); - void EndBuildServiceDefinition(double elapsed); - - void BeginInvokeMethod(ServiceContext context, Type type); - void EndInvokeMethod(ServiceContext context, Type type, double elapsed, bool isErrorOrInterrupted); - - void BeginInvokeHubMethod(StreamingHubContext context, ReadOnlyMemory request, Type type); - void EndInvokeHubMethod(StreamingHubContext context, int responseSize, Type? type, double elapsed, bool isErrorOrInterrupted); - void InvokeHubBroadcast(string groupName, int responseSize, int broadcastGroupCount); - - void WriteToStream(ServiceContext context, Type type); - void ReadFromStream(ServiceContext context, Type type, bool complete); - - void Error(Exception ex, ServerCallContext context); - void Error(Exception ex, StreamingHubContext context); -} diff --git a/src/MagicOnion.Server/Diagnostics/MagicOnionLogToLogger.cs b/src/MagicOnion.Server/Diagnostics/MagicOnionLogToLogger.cs deleted file mode 100644 index df6c43b1b..000000000 --- a/src/MagicOnion.Server/Diagnostics/MagicOnionLogToLogger.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Grpc.Core; -using MagicOnion.Server.Hubs; -using Microsoft.Extensions.Logging; - -namespace MagicOnion.Server.Diagnostics; - -public class MagicOnionLogToLogger : IMagicOnionLogger -{ - readonly ILogger logger; - - public MagicOnionLogToLogger(ILogger logger) - { - this.logger = logger; - } - - public void BeginBuildServiceDefinition() - { - logger.LogDebug(nameof(BeginBuildServiceDefinition)); - } - - public void EndBuildServiceDefinition(double elapsed) - { - logger.LogDebug($"{nameof(EndBuildServiceDefinition)} elapsed:{elapsed}"); - } - - public void BeginInvokeMethod(ServiceContext context, Type type) - { - logger.LogDebug($"{nameof(BeginInvokeMethod)} type:{MethodTypeToString(context.MethodType)} method:{context.CallContext.Method}"); - } - - public void EndInvokeMethod(ServiceContext context, Type type, double elapsed, bool isErrorOrInterrupted) - { - var msg = isErrorOrInterrupted ? "error" : ""; - logger.LogDebug($"{nameof(EndInvokeMethod)} type:{MethodTypeToString(context.MethodType)} method:{context.CallContext.Method} elapsed:{elapsed} {msg}"); - } - - public void WriteToStream(ServiceContext context, Type type) - { - logger.LogDebug($"{nameof(WriteToStream)} type:{MethodTypeToString(context.MethodType)} method:{context.CallContext.Method}"); - } - - public void ReadFromStream(ServiceContext context, Type type, bool complete) - { - logger.LogDebug($"{nameof(ReadFromStream)} type:{MethodTypeToString(context.MethodType)} method:{context.CallContext.Method} complete:{complete}"); - } - - // enum.ToString is slow. - string MethodTypeToString(MethodType type) - { - switch (type) - { - case MethodType.Unary: - return "Unary"; - case MethodType.ClientStreaming: - return "ClientStreaming"; - case MethodType.ServerStreaming: - return "ServerStreaming"; - case MethodType.DuplexStreaming: - return "DuplexStreaming"; - default: - return ((int)type).ToString(); - } - } - - public void BeginInvokeHubMethod(StreamingHubContext context, ReadOnlyMemory request, Type type) - { - logger.LogDebug($"{nameof(BeginInvokeHubMethod)} method:{context.Path} size:{request.Length}"); - - } - - public void EndInvokeHubMethod(StreamingHubContext context, int responseSize, Type? type, double elapsed, bool isErrorOrInterrupted) - { - var msg = isErrorOrInterrupted ? "error" : ""; - logger.LogDebug($"{nameof(EndInvokeHubMethod)} method:{context.Path} size:{responseSize} elapsed:{elapsed} {msg}"); - } - - public void InvokeHubBroadcast(string groupName, int responseSize, int broadcastGroupCount) - { - logger.LogDebug($"{nameof(InvokeHubBroadcast)} size:{responseSize} broadcastGroupCount:{broadcastGroupCount}"); - } - - public void Error(Exception ex, ServerCallContext context) - { - logger.LogError(ex, "MagicOnionHandler throws exception occurred in " + context.Method); - } - public void Error(Exception ex, StreamingHubContext context) - { - logger.LogError(ex, "Hub Method Handler throws exception occurred in " + context.Path); - } -} diff --git a/src/MagicOnion.Server/Diagnostics/MagicOnionServerLog.cs b/src/MagicOnion.Server/Diagnostics/MagicOnionServerLog.cs new file mode 100644 index 000000000..3d4c627a2 --- /dev/null +++ b/src/MagicOnion.Server/Diagnostics/MagicOnionServerLog.cs @@ -0,0 +1,75 @@ +using Grpc.Core; +using MagicOnion.Server.Hubs; +using Microsoft.Extensions.Logging; + +namespace MagicOnion.Server.Diagnostics; + +public static partial class MagicOnionServerLog +{ + public static void BeginInvokeMethod(ILogger logger, ServiceContext context, Type type) + => BeginInvokeMethod(logger, MethodTypeToString(context.MethodType), context.CallContext.Method); + + public static void EndInvokeMethod(ILogger logger, ServiceContext context, Type type, double elapsed, bool isErrorOrInterrupted) + => EndInvokeMethod(logger, MethodTypeToString(context.MethodType), context.CallContext.Method, elapsed, (isErrorOrInterrupted ? "error" : "")); + + public static void WriteToStream(ILogger logger, ServiceContext context, Type type) + => WriteToStream(logger, MethodTypeToString(context.MethodType), context.CallContext.Method); + + public static void ReadFromStream(ILogger logger, ServiceContext context, Type type, bool complete) + => ReadFromStream(logger, MethodTypeToString(context.MethodType), context.CallContext.Method, complete); + + public static void BeginInvokeHubMethod(ILogger logger, StreamingHubContext context, ReadOnlyMemory request, Type type) + => BeginInvokeHubMethod(logger, context.Path, request.Length); + + public static void EndInvokeHubMethod(ILogger logger, StreamingHubContext context, int responseSize, Type? type, double elapsed, bool isErrorOrInterrupted) + => EndInvokeHubMethod(logger, context.Path, responseSize, elapsed, isErrorOrInterrupted ? "error" : ""); + + public static void Error(ILogger logger, Exception ex, ServerCallContext context) + => ErrorOnServiceMethod(logger, ex, context.Method); + public static void Error(ILogger logger, Exception ex, StreamingHubContext context) + => ErrorOnHubMethod(logger, ex, context.Path); + + // enum.ToString is slow. + static string MethodTypeToString(MethodType type) => + type switch + { + MethodType.Unary => "Unary", + MethodType.ClientStreaming => "ClientStreaming", + MethodType.ServerStreaming => "ServerStreaming", + MethodType.DuplexStreaming => "DuplexStreaming", + _ => ((int)type).ToString(), + }; + + [LoggerMessage(EventId = 1, Level = LogLevel.Debug, EventName = nameof(BeginBuildServiceDefinition), Message = nameof(BeginBuildServiceDefinition))] + public static partial void BeginBuildServiceDefinition(ILogger logger); + + [LoggerMessage(EventId = 2, Level = LogLevel.Debug, EventName = nameof(EndBuildServiceDefinition), Message = nameof(EndBuildServiceDefinition) +" elapsed:{elapsed}")] + public static partial void EndBuildServiceDefinition(ILogger logger, double elapsed); + + [LoggerMessage(EventId = 3, Level = LogLevel.Debug, EventName = nameof(BeginInvokeMethod), Message = nameof(BeginInvokeMethod) + " type:{methodType} method:{method}")] + public static partial void BeginInvokeMethod(ILogger logger, string methodType, string method); + + [LoggerMessage(EventId = 4, Level = LogLevel.Debug, EventName = nameof(EndInvokeMethod), Message = nameof(EndInvokeMethod) + " type:{methodType} method:{method} elapsed:{elapsed} {message}")] + public static partial void EndInvokeMethod(ILogger logger, string methodType, string method, double elapsed, string message); + + [LoggerMessage(EventId = 5, Level = LogLevel.Debug, EventName = nameof(WriteToStream), Message = nameof(WriteToStream) + " type:{methodType} method:{method}")] + public static partial void WriteToStream(ILogger logger, string methodType, string method); + + [LoggerMessage(EventId = 6, Level = LogLevel.Debug, EventName = nameof(ReadFromStream), Message = nameof(ReadFromStream) + " type:{methodType} method:{method} complete:{complete}")] + public static partial void ReadFromStream(ILogger logger, string methodType, string method, bool complete); + + [LoggerMessage(EventId = 7, Level = LogLevel.Debug, EventName = nameof(BeginInvokeHubMethod), Message = nameof(BeginInvokeHubMethod) + " method:{method} size:{size}")] + public static partial void BeginInvokeHubMethod(ILogger logger, string method, int size); + + [LoggerMessage(EventId = 8, Level = LogLevel.Debug, EventName = nameof(EndInvokeHubMethod), Message = nameof(EndInvokeHubMethod) + " method:{method} size:{size} elapsed:{elapsed} {message}")] + public static partial void EndInvokeHubMethod(ILogger logger, string method, int size, double elapsed, string message); + + [LoggerMessage(EventId = 9, Level = LogLevel.Debug, EventName = nameof(InvokeHubBroadcast), Message = nameof(InvokeHubBroadcast) + " groupName:{groupName} size:{size} broadcastGroupCount:{broadcastGroupCount}")] + public static partial void InvokeHubBroadcast(ILogger logger, string groupName, int size, int broadcastGroupCount); + + [LoggerMessage(EventId = 90, Level = LogLevel.Error, EventName = nameof(ErrorOnServiceMethod), Message = "A service handler throws an exception occurred in {method}")] + public static partial void ErrorOnServiceMethod(ILogger logger, Exception ex, string method); + + [LoggerMessage(EventId = 91, Level = LogLevel.Error, EventName = nameof(ErrorOnHubMethod), Message = "A hub method handler throws an exception occurred in {path}")] + public static partial void ErrorOnHubMethod(ILogger logger, Exception ex, string path); +} diff --git a/src/MagicOnion.Server/Diagnostics/NullMagicOnionLogger.cs b/src/MagicOnion.Server/Diagnostics/NullMagicOnionLogger.cs deleted file mode 100644 index 2c2427c57..000000000 --- a/src/MagicOnion.Server/Diagnostics/NullMagicOnionLogger.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Grpc.Core; -using MagicOnion.Server.Hubs; - -namespace MagicOnion.Server.Diagnostics; - -public class NullMagicOnionLogger : IMagicOnionLogger -{ - public void BeginBuildServiceDefinition() - { - } - - public void BeginInvokeMethod(ServiceContext context, Type type) - { - } - - public void ReadFromStream(ServiceContext context, Type type, bool complete) - { - } - - public void WriteToStream(ServiceContext context, Type type) - { - } - - public void EndBuildServiceDefinition(double elapsed) - { - } - - public void EndInvokeMethod(ServiceContext context, Type type, double elapsed, bool isErrorOrInterrupted) - { - } - - public void BeginInvokeHubMethod(StreamingHubContext context, ReadOnlyMemory request, Type type) - { - } - - public void EndInvokeHubMethod(StreamingHubContext context, int responseSize, Type? type, double elapsed, bool isErrorOrInterrupted) - { - } - - public void InvokeHubBroadcast(string groupName, int responseSize, int broadcastGroupCount) - { - } - - public void Error(Exception ex, ServerCallContext context) - { - } - public void Error(Exception ex, StreamingHubContext context) - { - } -} diff --git a/src/MagicOnion.Server/Extensions/MagicOnionServicesExtensions.cs b/src/MagicOnion.Server/Extensions/MagicOnionServicesExtensions.cs index 029f64574..224a77807 100644 --- a/src/MagicOnion.Server/Extensions/MagicOnionServicesExtensions.cs +++ b/src/MagicOnion.Server/Extensions/MagicOnionServicesExtensions.cs @@ -1,14 +1,13 @@ -using System; using System.Reflection; using Grpc.AspNetCore.Server.Model; using MagicOnion.Server; -using MagicOnion.Server.Diagnostics; using MagicOnion.Server.Glue; using MagicOnion.Server.Hubs; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; +// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection; public static class MagicOnionServicesExtensions @@ -16,21 +15,21 @@ public static class MagicOnionServicesExtensions public static IMagicOnionServerBuilder AddMagicOnion(this IServiceCollection services, Action? configureOptions = null) { var configName = Options.Options.DefaultName; - services.AddSingleton(sp => MagicOnionEngine.BuildServerServiceDefinition(sp, sp.GetRequiredService>().Get(configName), sp.GetRequiredService())); + services.AddSingleton(sp => MagicOnionEngine.BuildServerServiceDefinition(sp, sp.GetRequiredService>().Get(configName))); return services.AddMagicOnionCore(configureOptions); } public static IMagicOnionServerBuilder AddMagicOnion(this IServiceCollection services, Assembly[] searchAssemblies, Action? configureOptions = null) { var configName = Options.Options.DefaultName; - services.AddSingleton(sp => MagicOnionEngine.BuildServerServiceDefinition(sp, searchAssemblies, sp.GetRequiredService>().Get(configName), sp.GetRequiredService())); + services.AddSingleton(sp => MagicOnionEngine.BuildServerServiceDefinition(sp, searchAssemblies, sp.GetRequiredService>().Get(configName))); return services.AddMagicOnionCore(configureOptions); } public static IMagicOnionServerBuilder AddMagicOnion(this IServiceCollection services, IEnumerable searchTypes, Action? configureOptions = null) { var configName = Options.Options.DefaultName; - services.AddSingleton(sp => MagicOnionEngine.BuildServerServiceDefinition(sp, searchTypes, sp.GetRequiredService>().Get(configName), sp.GetRequiredService())); + services.AddSingleton(sp => MagicOnionEngine.BuildServerServiceDefinition(sp, searchTypes, sp.GetRequiredService>().Get(configName))); return services.AddMagicOnionCore(configureOptions); } @@ -39,7 +38,6 @@ static IMagicOnionServerBuilder AddMagicOnionCore(this IServiceCollection servic var configName = Options.Options.DefaultName; var glueServiceType = MagicOnionGlueService.CreateType(); - services.TryAddSingleton(); services.TryAddSingleton(); services.AddSingleton(sp => new MagicOnionServiceDefinitionGlueDescriptor(glueServiceType, sp.GetRequiredService())); diff --git a/src/MagicOnion.Server/Hubs/Group.ConcurrentDictionary.cs b/src/MagicOnion.Server/Hubs/Group.ConcurrentDictionary.cs index 51d0f657c..0f696b4e0 100644 --- a/src/MagicOnion.Server/Hubs/Group.ConcurrentDictionary.cs +++ b/src/MagicOnion.Server/Hubs/Group.ConcurrentDictionary.cs @@ -4,12 +4,20 @@ using MessagePack; using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server.Hubs; public class ConcurrentDictionaryGroupRepositoryFactory : IGroupRepositoryFactory { - public IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer, IMagicOnionLogger logger) + readonly ILogger logger; + + public ConcurrentDictionaryGroupRepositoryFactory(ILogger logger) + { + this.logger = logger; + } + + public IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer) { return new ConcurrentDictionaryGroupRepository(messageSerializer, logger); } @@ -17,13 +25,13 @@ public IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer public class ConcurrentDictionaryGroupRepository : IGroupRepository { - IMagicOnionSerializer messageSerializer; - IMagicOnionLogger logger; + readonly IMagicOnionSerializer messageSerializer; + readonly ILogger logger; readonly Func factory; ConcurrentDictionary dictionary = new ConcurrentDictionary(); - public ConcurrentDictionaryGroupRepository(IMagicOnionSerializer messageSerializer, IMagicOnionLogger logger) + public ConcurrentDictionaryGroupRepository(IMagicOnionSerializer messageSerializer, ILogger logger) { this.messageSerializer = messageSerializer; this.factory = CreateGroup; @@ -61,14 +69,14 @@ public class ConcurrentDictionaryGroup : IGroup readonly IGroupRepository parent; readonly IMagicOnionSerializer messageSerializer; - readonly IMagicOnionLogger logger; + readonly ILogger logger; ConcurrentDictionary> members; IInMemoryStorage? inmemoryStorage; public string GroupName { get; } - public ConcurrentDictionaryGroup(string groupName, IGroupRepository parent, IMagicOnionSerializer messageSerializer, IMagicOnionLogger logger) + public ConcurrentDictionaryGroup(string groupName, IGroupRepository parent, IMagicOnionSerializer messageSerializer, ILogger logger) { this.GroupName = groupName; this.parent = parent; @@ -144,7 +152,7 @@ public Task WriteAllAsync(int methodId, T value, bool fireAndForget) item.Value.QueueResponseStreamWrite(message); writeCount++; } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -167,7 +175,7 @@ public Task WriteExceptAsync(int methodId, T value, Guid connectionId, bool f writeCount++; } } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -196,7 +204,7 @@ public Task WriteExceptAsync(int methodId, T value, Guid[] connectionIds, boo NEXT: continue; } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -213,7 +221,7 @@ public Task WriteToAsync(int methodId, T value, Guid connectionId, bool fireA if (members.TryGetValue(connectionId, out var context)) { context.QueueResponseStreamWrite(message); - logger.InvokeHubBroadcast(GroupName, message.Length, 1); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, 1); } return TaskEx.CompletedTask; } @@ -237,7 +245,7 @@ public Task WriteToAsync(int methodId, T value, Guid[] connectionIds, bool fi writeCount++; } } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -261,7 +269,7 @@ public Task WriteExceptRawAsync(ArraySegment msg, Guid[] exceptConnectionI item.Value.QueueResponseStreamWrite(message); writeCount++; } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -281,7 +289,7 @@ public Task WriteExceptRawAsync(ArraySegment msg, Guid[] exceptConnectionI NEXT: continue; } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } } @@ -312,7 +320,7 @@ public Task WriteToRawAsync(ArraySegment msg, Guid[] connectionIds, bool f } } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); } return TaskEx.CompletedTask; diff --git a/src/MagicOnion.Server/Hubs/Group.ImmutableArray.cs b/src/MagicOnion.Server/Hubs/Group.ImmutableArray.cs index 7ddf8afab..95bfd36f9 100644 --- a/src/MagicOnion.Server/Hubs/Group.ImmutableArray.cs +++ b/src/MagicOnion.Server/Hubs/Group.ImmutableArray.cs @@ -5,12 +5,20 @@ using System.Collections.Concurrent; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server.Hubs; public class ImmutableArrayGroupRepositoryFactory : IGroupRepositoryFactory { - public IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer, IMagicOnionLogger logger) + readonly ILogger logger; + + public ImmutableArrayGroupRepositoryFactory(ILogger logger) + { + this.logger = logger; + } + + public IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer) { return new ImmutableArrayGroupRepository(messageSerializer, logger); } @@ -18,13 +26,13 @@ public IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer public class ImmutableArrayGroupRepository : IGroupRepository { - IMagicOnionSerializer messageSerializer; - IMagicOnionLogger logger; + readonly IMagicOnionSerializer messageSerializer; + readonly ILogger logger; readonly Func factory; ConcurrentDictionary dictionary = new ConcurrentDictionary(); - public ImmutableArrayGroupRepository(IMagicOnionSerializer messageSerializer, IMagicOnionLogger logger) + public ImmutableArrayGroupRepository(IMagicOnionSerializer messageSerializer, ILogger logger) { this.messageSerializer = messageSerializer; this.factory = CreateGroup; @@ -57,14 +65,14 @@ public class ImmutableArrayGroup : IGroup readonly object gate = new object(); readonly IGroupRepository parent; readonly IMagicOnionSerializer messageSerializer; - readonly IMagicOnionLogger logger; + readonly ILogger logger; ImmutableArray> members; IInMemoryStorage? inmemoryStorage; public string GroupName { get; } - public ImmutableArrayGroup(string groupName, IGroupRepository parent, IMagicOnionSerializer messageSerializer, IMagicOnionLogger logger) + public ImmutableArrayGroup(string groupName, IGroupRepository parent, IMagicOnionSerializer messageSerializer, ILogger logger) { this.GroupName = groupName; this.parent = parent; @@ -144,7 +152,7 @@ public Task WriteAllAsync(int methodId, T value, bool fireAndForget) { source[i].QueueResponseStreamWrite(message); } - logger.InvokeHubBroadcast(GroupName, message.Length, source.Length); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, source.Length); return TaskEx.CompletedTask; } else @@ -169,7 +177,7 @@ public Task WriteExceptAsync(int methodId, T value, Guid connectionId, bool f writeCount++; } } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -201,7 +209,7 @@ public Task WriteExceptAsync(int methodId, T value, Guid[] connectionIds, boo NEXT: continue; } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -228,7 +236,7 @@ public Task WriteToAsync(int methodId, T value, Guid connectionId, bool fireA break; } } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -260,7 +268,7 @@ public Task WriteToAsync(int methodId, T value, Guid[] connectionIds, bool fi NEXT: continue; } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -304,7 +312,7 @@ public Task WriteExceptRawAsync(ArraySegment msg, Guid[] exceptConnectionI continue; } } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); return TaskEx.CompletedTask; } else @@ -340,7 +348,7 @@ public Task WriteToRawAsync(ArraySegment msg, Guid[] connectionIds, bool f continue; } - logger.InvokeHubBroadcast(GroupName, message.Length, writeCount); + MagicOnionServerLog.InvokeHubBroadcast(logger, GroupName, message.Length, writeCount); } return TaskEx.CompletedTask; } diff --git a/src/MagicOnion.Server/Hubs/Group.cs b/src/MagicOnion.Server/Hubs/Group.cs index 792620708..aa1434c30 100644 --- a/src/MagicOnion.Server/Hubs/Group.cs +++ b/src/MagicOnion.Server/Hubs/Group.cs @@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis; using MagicOnion.Serialization; using MagicOnion.Server.Diagnostics; -using MessagePack; namespace MagicOnion.Server.Hubs; @@ -24,7 +23,7 @@ public GroupConfigurationAttribute(Type groupRepositoryFactoryType) public interface IGroupRepositoryFactory { - IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer, IMagicOnionLogger logger); + IGroupRepository CreateRepository(IMagicOnionSerializer messageSerializer); } public interface IGroupRepository diff --git a/src/MagicOnion.Server/Hubs/StreamingHub.cs b/src/MagicOnion.Server/Hubs/StreamingHub.cs index eae10908c..ff457886d 100644 --- a/src/MagicOnion.Server/Hubs/StreamingHub.cs +++ b/src/MagicOnion.Server/Hubs/StreamingHub.cs @@ -1,4 +1,5 @@ using Grpc.Core; +using MagicOnion.Server.Diagnostics; using MessagePack; using MagicOnion.Utils; using Microsoft.AspNetCore.Connections; @@ -177,7 +178,7 @@ async Task HandleMessageAsync() }; var isErrorOrInterrupted = false; - Context.MethodHandler.Logger.BeginInvokeHubMethod(context, context.Request, handler.RequestType); + MagicOnionServerLog.BeginInvokeHubMethod(Context.MethodHandler.Logger, context, context.Request, handler.RequestType); try { await handler.MethodBody.Invoke(context); @@ -192,7 +193,7 @@ async Task HandleMessageAsync() catch (Exception ex) { isErrorOrInterrupted = true; - Context.MethodHandler.Logger.Error(ex, context); + MagicOnionServerLog.Error(Context.MethodHandler.Logger, ex, context); if (hasResponse) { @@ -201,7 +202,7 @@ async Task HandleMessageAsync() } finally { - Context.MethodHandler.Logger.EndInvokeHubMethod(context, context.responseSize, context.responseType, (DateTime.UtcNow - context.Timestamp).TotalMilliseconds, isErrorOrInterrupted); + MagicOnionServerLog.EndInvokeHubMethod(Context.MethodHandler.Logger, context, context.responseSize, context.responseType, (DateTime.UtcNow - context.Timestamp).TotalMilliseconds, isErrorOrInterrupted); } } else diff --git a/src/MagicOnion.Server/MagicOnionEngine.cs b/src/MagicOnion.Server/MagicOnionEngine.cs index 68c449b9c..f853efca6 100644 --- a/src/MagicOnion.Server/MagicOnionEngine.cs +++ b/src/MagicOnion.Server/MagicOnionEngine.cs @@ -5,21 +5,24 @@ using Grpc.Core; using Microsoft.Extensions.DependencyInjection; using MagicOnion.Server.Diagnostics; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server; public static class MagicOnionEngine { + const string LoggerNameMagicOnionEngine = "MagicOnion.Server.MagicOnionEngine"; + const string LoggerNameMethodHandler = "MagicOnion.Server.MethodHandler"; + /// /// Search MagicOnion service from all assemblies. /// /// The service provider is used to resolve dependencies /// If true, when method body throws exception send to client exception.ToString message. It is useful for debugging. /// - /// The logger for MagicOnion server - public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceProvider serviceProvider, IMagicOnionLogger logger, bool isReturnExceptionStackTraceInErrorDetail = false) + public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceProvider serviceProvider, bool isReturnExceptionStackTraceInErrorDetail = false) { - return BuildServerServiceDefinition(serviceProvider, new MagicOnionOptions() { IsReturnExceptionStackTraceInErrorDetail = isReturnExceptionStackTraceInErrorDetail }, logger); + return BuildServerServiceDefinition(serviceProvider, new MagicOnionOptions() { IsReturnExceptionStackTraceInErrorDetail = isReturnExceptionStackTraceInErrorDetail }); } /// @@ -27,8 +30,7 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP /// /// The service provider is used to resolve dependencies /// The options for MagicOnion server - /// The logger for MagicOnion server - public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceProvider serviceProvider, MagicOnionOptions options, IMagicOnionLogger logger) + public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceProvider serviceProvider, MagicOnionOptions options) { // NOTE: Exclude well-known system assemblies from automatic discovery of services. var wellKnownIgnoreAssemblies = new[] @@ -80,7 +82,7 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP }) .ToArray(); - return BuildServerServiceDefinition(serviceProvider, assemblies, options, logger); + return BuildServerServiceDefinition(serviceProvider, assemblies, options); } /// @@ -89,8 +91,7 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP /// The service provider is used to resolve dependencies /// The assemblies to be search for services /// The options for MagicOnion server - /// The logger for MagicOnion server - public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceProvider serviceProvider, Assembly[] searchAssemblies, MagicOnionOptions options, IMagicOnionLogger logger) + public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceProvider serviceProvider, Assembly[] searchAssemblies, MagicOnionOptions options) { var types = searchAssemblies .SelectMany(x => @@ -109,7 +110,7 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP }); #pragma warning disable CS8620 // Argument of type cannot be used for parameter of type in due to differences in the nullability of reference types. - return BuildServerServiceDefinition(serviceProvider, types, options, logger); + return BuildServerServiceDefinition(serviceProvider, types, options); #pragma warning restore CS8620 // Argument of type cannot be used for parameter of type in due to differences in the nullability of reference types. } @@ -119,8 +120,7 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP /// The service provider is used to resolve dependencies /// The types to be search for services /// The options for MagicOnion server - /// The logger for MagicOnion server - public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceProvider serviceProvider, IEnumerable targetTypes, MagicOnionOptions options, IMagicOnionLogger logger) + public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceProvider serviceProvider, IEnumerable targetTypes, MagicOnionOptions options) { var handlers = new HashSet(); var streamingHubHandlers = new List(); @@ -128,7 +128,11 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP var methodHandlerOptions = new MethodHandlerOptions(options); var streamingHubHandlerOptions = new StreamingHubHandlerOptions(options); - logger.BeginBuildServiceDefinition(); + var loggerFactory = serviceProvider.GetRequiredService(); + var loggerMagicOnionEngine = loggerFactory.CreateLogger(LoggerNameMagicOnionEngine); + var loggerMethodHandler = loggerFactory.CreateLogger(LoggerNameMethodHandler); + MagicOnionServerLog.BeginBuildServiceDefinition(loggerMagicOnionEngine); + var sw = Stopwatch.StartNew(); try @@ -192,7 +196,7 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP else { // create handler - var handler = new MethodHandler(classType, methodInfo, methodName, methodHandlerOptions, serviceProvider, logger, isStreamingHub: false); + var handler = new MethodHandler(classType, methodInfo, methodName, methodHandlerOptions, serviceProvider, loggerMethodHandler, isStreamingHub: false); if (!handlers.Add(handler)) { throw new InvalidOperationException($"Method does not allow overload, {className}.{methodName}"); @@ -202,7 +206,7 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP if (isStreamingHub) { - var connectHandler = new MethodHandler(classType, classType.GetMethod("Connect")!, "Connect", methodHandlerOptions, serviceProvider, logger, isStreamingHub: true); + var connectHandler = new MethodHandler(classType, classType.GetMethod("Connect")!, "Connect", methodHandlerOptions, serviceProvider, loggerMethodHandler, isStreamingHub: true); if (!handlers.Add(connectHandler)) { throw new InvalidOperationException($"Method does not allow overload, {className}.Connect"); @@ -220,7 +224,7 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP { factory = serviceProvider.GetRequiredService(); } - StreamingHubHandlerRepository.AddGroupRepository(connectHandler, factory.CreateRepository(options.MessageSerializer.Create(MethodType.DuplexStreaming, null), logger)); + StreamingHubHandlerRepository.AddGroupRepository(connectHandler, factory.CreateRepository(options.MessageSerializer.Create(MethodType.DuplexStreaming, null))); } } } @@ -232,7 +236,7 @@ public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceP var result = new MagicOnionServiceDefinition(handlers.ToArray(), streamingHubHandlers.ToArray()); sw.Stop(); - logger.EndBuildServiceDefinition(sw.Elapsed.TotalMilliseconds); + MagicOnionServerLog.EndBuildServiceDefinition(loggerMagicOnionEngine, sw.Elapsed.TotalMilliseconds); return result; } diff --git a/src/MagicOnion.Server/MethodHandler.cs b/src/MagicOnion.Server/MethodHandler.cs index d45cfb664..4ec2a702e 100644 --- a/src/MagicOnion.Server/MethodHandler.cs +++ b/src/MagicOnion.Server/MethodHandler.cs @@ -9,6 +9,7 @@ using MagicOnion.Server.Diagnostics; using MagicOnion.Server.Internal; using MagicOnion.Serialization; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server; @@ -36,7 +37,7 @@ public class MethodHandler : IEquatable // options readonly bool enableCurrentContext; - internal IMagicOnionLogger Logger { get; } + internal ILogger Logger { get; } internal bool IsReturnExceptionStackTraceInErrorDetail { get; } public IMagicOnionSerializer MessageSerializer => messageSerializer; @@ -52,7 +53,7 @@ public class MethodHandler : IEquatable public Type RequestType => metadata.RequestType; public Type UnwrappedResponseType => metadata.ResponseType; - public MethodHandler(Type classType, MethodInfo methodInfo, string methodName, MethodHandlerOptions handlerOptions, IServiceProvider serviceProvider, IMagicOnionLogger logger, bool isStreamingHub) + public MethodHandler(Type classType, MethodInfo methodInfo, string methodName, MethodHandlerOptions handlerOptions, IServiceProvider serviceProvider, ILogger logger, bool isStreamingHub) { this.metadata = MethodHandlerMetadataFactory.CreateServiceMethodHandlerMetadata(classType, methodInfo); this.methodHandlerId = Interlocked.Increment(ref methodHandlerIdBuild); @@ -233,7 +234,7 @@ internal void BindHandler(ServiceBinderBase binder) object? response = default(TResponse?); try { - Logger.BeginInvokeMethod(serviceContext, typeof(TRequest)); + MagicOnionServerLog.BeginInvokeMethod(Logger, serviceContext, typeof(TRequest)); if (enableCurrentContext) { ServiceContext.currentServiceContext.Value = serviceContext; @@ -289,7 +290,7 @@ internal void BindHandler(ServiceBinderBase binder) var str = sb.ToString(); context.Status = new Status(StatusCode.Unknown, str); - Logger.Error(ex, context); + MagicOnionServerLog.Error(Logger, ex, context); response = default; } else @@ -299,7 +300,7 @@ internal void BindHandler(ServiceBinderBase binder) } finally { - Logger.EndInvokeMethod(serviceContext, typeof(TResponse), (DateTime.UtcNow - serviceContext.Timestamp).TotalMilliseconds, isErrorOrInterrupted); + MagicOnionServerLog.EndInvokeMethod(Logger, serviceContext, typeof(TResponse), (DateTime.UtcNow - serviceContext.Timestamp).TotalMilliseconds, isErrorOrInterrupted); } return response; @@ -327,7 +328,7 @@ internal void BindHandler(ServiceBinderBase binder) { using (requestStream as IDisposable) { - Logger.BeginInvokeMethod(serviceContext, typeof(Nil)); + MagicOnionServerLog.BeginInvokeMethod(Logger, serviceContext, typeof(Nil)); if (enableCurrentContext) { ServiceContext.currentServiceContext.Value = serviceContext; @@ -348,7 +349,7 @@ internal void BindHandler(ServiceBinderBase binder) if (IsReturnExceptionStackTraceInErrorDetail) { context.Status = new Status(StatusCode.Unknown, ex.ToString()); - Logger.Error(ex, context); + MagicOnionServerLog.Error(Logger, ex, context); response = default; } else @@ -358,7 +359,7 @@ internal void BindHandler(ServiceBinderBase binder) } finally { - Logger.EndInvokeMethod(serviceContext, typeof(TResponse), (DateTime.UtcNow - serviceContext.Timestamp).TotalMilliseconds, isErrorOrInterrupted); + MagicOnionServerLog.EndInvokeMethod(Logger, serviceContext, typeof(TResponse), (DateTime.UtcNow - serviceContext.Timestamp).TotalMilliseconds, isErrorOrInterrupted); } return response; @@ -383,7 +384,7 @@ internal void BindHandler(ServiceBinderBase binder) serviceContext.SetRawRequest(request); try { - Logger.BeginInvokeMethod(serviceContext, typeof(TRequest)); + MagicOnionServerLog.BeginInvokeMethod(Logger, serviceContext, typeof(TRequest)); if (enableCurrentContext) { ServiceContext.currentServiceContext.Value = serviceContext; @@ -403,7 +404,7 @@ internal void BindHandler(ServiceBinderBase binder) if (IsReturnExceptionStackTraceInErrorDetail) { context.Status = new Status(StatusCode.Unknown, ex.ToString()); - Logger.Error(ex, context); + MagicOnionServerLog.Error(Logger, ex, context); return; } else @@ -413,7 +414,7 @@ internal void BindHandler(ServiceBinderBase binder) } finally { - Logger.EndInvokeMethod(serviceContext, typeof(Nil), (DateTime.UtcNow - serviceContext.Timestamp).TotalMilliseconds, isErrorOrInterrupted); + MagicOnionServerLog.EndInvokeMethod(Logger, serviceContext, typeof(Nil), (DateTime.UtcNow - serviceContext.Timestamp).TotalMilliseconds, isErrorOrInterrupted); } } @@ -435,7 +436,7 @@ internal void BindHandler(ServiceBinderBase binder) ); try { - Logger.BeginInvokeMethod(serviceContext, typeof(Nil)); + MagicOnionServerLog.BeginInvokeMethod(Logger, serviceContext, typeof(Nil)); using (requestStream as IDisposable) { if (enableCurrentContext) @@ -459,7 +460,7 @@ internal void BindHandler(ServiceBinderBase binder) if (IsReturnExceptionStackTraceInErrorDetail) { context.Status = new Status(StatusCode.Unknown, ex.ToString()); - Logger.Error(ex, context); + MagicOnionServerLog.Error(Logger, ex, context); return; } else @@ -469,7 +470,7 @@ internal void BindHandler(ServiceBinderBase binder) } finally { - Logger.EndInvokeMethod(serviceContext, typeof(Nil), (DateTime.UtcNow - serviceContext.Timestamp).TotalMilliseconds, isErrorOrInterrupted); + MagicOnionServerLog.EndInvokeMethod(Logger, serviceContext, typeof(Nil), (DateTime.UtcNow - serviceContext.Timestamp).TotalMilliseconds, isErrorOrInterrupted); } } diff --git a/src/MagicOnion.Server/ServiceContext.Streaming.cs b/src/MagicOnion.Server/ServiceContext.Streaming.cs index 29e8c50e1..facce8626 100644 --- a/src/MagicOnion.Server/ServiceContext.Streaming.cs +++ b/src/MagicOnion.Server/ServiceContext.Streaming.cs @@ -4,6 +4,7 @@ using MagicOnion.Server.Diagnostics; using MagicOnion.Server.Internal; using MessagePack; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server; @@ -44,7 +45,7 @@ internal class StreamingServiceContext : ServiceContext, IS MethodType methodType, ServerCallContext context, IMagicOnionSerializer messageSerializer, - IMagicOnionLogger logger, + ILogger logger, MethodHandler methodHandler, IServiceProvider serviceProvider, IAsyncStreamReader? requestStream, diff --git a/src/MagicOnion.Server/ServiceContext.cs b/src/MagicOnion.Server/ServiceContext.cs index a67c3cc12..f4463d611 100644 --- a/src/MagicOnion.Server/ServiceContext.cs +++ b/src/MagicOnion.Server/ServiceContext.cs @@ -1,10 +1,10 @@ using Grpc.Core; using MagicOnion.Serialization; using MagicOnion.Server.Diagnostics; -using MessagePack; using System.Collections.Concurrent; using System.Reflection; using MagicOnion.Internal; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server; @@ -80,7 +80,7 @@ public class ServiceContext : IServiceContext internal object? Request => request; internal object? Result { get; set; } - internal IMagicOnionLogger MagicOnionLogger { get; } + internal ILogger Logger { get; } internal MethodHandler MethodHandler { get; } public ServiceContext( @@ -90,7 +90,7 @@ public class ServiceContext : IServiceContext MethodType methodType, ServerCallContext context, IMagicOnionSerializer messageSerializer, - IMagicOnionLogger logger, + ILogger logger, MethodHandler methodHandler, IServiceProvider serviceProvider ) @@ -103,7 +103,7 @@ IServiceProvider serviceProvider this.CallContext = context; this.Timestamp = DateTime.UtcNow; this.MessageSerializer = messageSerializer; - this.MagicOnionLogger = logger; + this.Logger = logger; this.MethodHandler = methodHandler; this.ServiceProvider = serviceProvider; } diff --git a/src/MagicOnion.Server/StreamingContext.Client.cs b/src/MagicOnion.Server/StreamingContext.Client.cs index 79baceb47..8de11ccd3 100644 --- a/src/MagicOnion.Server/StreamingContext.Client.cs +++ b/src/MagicOnion.Server/StreamingContext.Client.cs @@ -1,6 +1,7 @@ using Grpc.Core; using MagicOnion.Server.Diagnostics; using MessagePack; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server; @@ -8,13 +9,13 @@ public class ClientStreamingContext : IAsyncStreamReader context; readonly IAsyncStreamReader inner; - readonly IMagicOnionLogger logger; + readonly ILogger logger; internal ClientStreamingContext(StreamingServiceContext context) { this.context = context; this.inner = context.RequestStream!; - this.logger = context.MagicOnionLogger; + this.logger = context.Logger; } public ServiceContext ServiceContext => context; @@ -30,7 +31,7 @@ public async Task MoveNext(CancellationToken cancellationToken = default(C } else { - logger.ReadFromStream(context, typeof(TRequest), true); + MagicOnionServerLog.ReadFromStream(logger, context, typeof(TRequest), true); return false; } } diff --git a/src/MagicOnion.Server/StreamingContext.Duplex.cs b/src/MagicOnion.Server/StreamingContext.Duplex.cs index de4f1c32e..501735ca7 100644 --- a/src/MagicOnion.Server/StreamingContext.Duplex.cs +++ b/src/MagicOnion.Server/StreamingContext.Duplex.cs @@ -1,6 +1,6 @@ using Grpc.Core; using MagicOnion.Server.Diagnostics; -using MessagePack; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server; @@ -9,14 +9,14 @@ public class DuplexStreamingContext : IAsyncStreamReader context; readonly IAsyncStreamReader innerReader; readonly IAsyncStreamWriter innerWriter; - readonly IMagicOnionLogger logger; + readonly ILogger logger; internal DuplexStreamingContext(StreamingServiceContext context) { this.context = context; this.innerReader = context.RequestStream!; this.innerWriter = context.ResponseStream!; - this.logger = context.MagicOnionLogger; + this.logger = context.Logger; } public ServiceContext ServiceContext => context; @@ -38,13 +38,13 @@ public async Task MoveNext(CancellationToken cancellationToken = default(C { if (await innerReader.MoveNext(cancellationToken)) { - logger.ReadFromStream(context, typeof(TRequest), false); + MagicOnionServerLog.ReadFromStream(logger, context, typeof(TRequest), false); this.Current = innerReader.Current; return true; } else { - logger.ReadFromStream(context, typeof(TRequest), true); + MagicOnionServerLog.ReadFromStream(logger, context, typeof(TRequest), true); return false; } } @@ -60,7 +60,7 @@ public void Dispose() /// public Task WriteAsync(TResponse message) { - logger.WriteToStream(context, typeof(TResponse)); + MagicOnionServerLog.WriteToStream(logger, context, typeof(TResponse)); return innerWriter.WriteAsync(message); } diff --git a/src/MagicOnion.Server/StreamingContext.Server.cs b/src/MagicOnion.Server/StreamingContext.Server.cs index 0ff137a90..1b5c181df 100644 --- a/src/MagicOnion.Server/StreamingContext.Server.cs +++ b/src/MagicOnion.Server/StreamingContext.Server.cs @@ -1,21 +1,21 @@ using Grpc.Core; using MagicOnion.Server.Diagnostics; using MessagePack; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server; - public class ServerStreamingContext : IAsyncStreamWriter { readonly StreamingServiceContext context; readonly IAsyncStreamWriter inner; - readonly IMagicOnionLogger logger; + readonly ILogger logger; internal ServerStreamingContext(StreamingServiceContext context) { this.context = context; this.inner = context.ResponseStream!; - this.logger = context.MagicOnionLogger; + this.logger = context.Logger; } public ServiceContext ServiceContext => context; @@ -28,7 +28,7 @@ public WriteOptions WriteOptions public Task WriteAsync(TResponse message) { - logger.WriteToStream(context, typeof(TResponse)); + MagicOnionServerLog.WriteToStream(logger, context, typeof(TResponse)); return inner.WriteAsync(message); } diff --git a/tests/MagicOnion.Server.Tests/MagicOnionEngineTest.cs b/tests/MagicOnion.Server.Tests/MagicOnionEngineTest.cs index 98a331a65..5d57352fa 100644 --- a/tests/MagicOnion.Server.Tests/MagicOnionEngineTest.cs +++ b/tests/MagicOnion.Server.Tests/MagicOnionEngineTest.cs @@ -14,12 +14,13 @@ public void CollectFromTypes_Empty() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); var serviceProvider = services.BuildServiceProvider(); var types = new Type[]{}; var options = new MagicOnionOptions(); // Act - var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options, new NullMagicOnionLogger()); + var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options); // Assert def.MethodHandlers.Should().BeEmpty(); @@ -31,12 +32,13 @@ public void CollectFromTypes_NonService() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); var serviceProvider = services.BuildServiceProvider(); var types = new Type[]{ typeof(NonService) }; var options = new MagicOnionOptions(); // Act - var ex = Record.Exception(() => MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options, new NullMagicOnionLogger())); + var ex = Record.Exception(() => MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options)); // Assert ex.Should().NotBeNull(); @@ -48,12 +50,13 @@ public void CollectFromTypes_Service() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); var serviceProvider = services.BuildServiceProvider(); var types = new Type[]{ typeof(MyService) }; var options = new MagicOnionOptions(); // Act - var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options, new NullMagicOnionLogger()); + var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options); // Assert def.MethodHandlers.Should().HaveCount(2); @@ -65,13 +68,14 @@ public void CollectFromTypes_StreamingHub() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); var types = new Type[]{ typeof(MyHub) }; var options = new MagicOnionOptions(); // Act - var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options, new NullMagicOnionLogger()); + var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options); // Assert def.MethodHandlers.Should().HaveCount(1); // Connect @@ -83,13 +87,14 @@ public void CollectFromAssembly() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); var assemblies = new Assembly[]{ typeof(IMyService).Assembly }; var options = new MagicOnionOptions(); // Act - var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options, new NullMagicOnionLogger()); + var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options); // Assert def.MethodHandlers.Should().HaveCount(6); // IMyHub.Connect, IMyService.MethodA, IMyService.MethodB, IMyGenericsHub.Connect, IMyGenericsService.MethodA, IMyGenericsService.MethodB @@ -101,13 +106,14 @@ public void CollectFromAssembly_Ignore() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); var assemblies = new Assembly[]{ typeof(IMyIgnoredService).Assembly }; var options = new MagicOnionOptions(); // Act - var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options, new NullMagicOnionLogger()); + var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options); // Assert def.MethodHandlers.Should().NotContain(x => x.ServiceName.Contains("Ignored")); @@ -119,13 +125,14 @@ public void CollectFromAssembly_NonPublic() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); var assemblies = new Assembly[]{ typeof(IMyNonPublicService).Assembly }; var options = new MagicOnionOptions(); // Act - var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options, new NullMagicOnionLogger()); + var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options); // Assert def.MethodHandlers.Should().NotContain(x => x.ServiceName.Contains("NonPublic")); @@ -137,13 +144,14 @@ public void CollectFromAssembly_Abstract() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); var assemblies = new Assembly[]{ typeof(IMyAbstractService).Assembly }; var options = new MagicOnionOptions(); // Act - var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options, new NullMagicOnionLogger()); + var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options); // Assert def.MethodHandlers.Should().NotContain(x => x.ServiceName.Contains("Abstract")); @@ -155,13 +163,14 @@ public void CollectFromAssembly_Generic_Constructed() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); var assemblies = new Assembly[]{ typeof(IMyGenericsService).Assembly }; var options = new MagicOnionOptions(); // Act - var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options, new NullMagicOnionLogger()); + var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options); // Assert def.MethodHandlers.Should().Contain(x => x.ServiceType == typeof(MyConstructedGenericsService)); @@ -173,13 +182,14 @@ public void CollectFromAssembly_Generic_Definitions() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); var assemblies = new Assembly[]{ typeof(IMyGenericsService).Assembly }; var options = new MagicOnionOptions(); // Act - var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options, new NullMagicOnionLogger()); + var def = MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, assemblies, options); // Assert def.MethodHandlers.Should().NotContain(x => x.ServiceType.Name.Contains("GenericsDefinition")); @@ -193,13 +203,14 @@ public void CollectHandlers_Duplicated_Service() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); var types = new Type[]{ typeof(MyService), typeof(MyService) }; var options = new MagicOnionOptions(); // Act - var ex = Record.Exception(() => MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options, new NullMagicOnionLogger())); + var ex = Record.Exception(() => MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options)); // Assert ex.Should().NotBeNull(); @@ -211,13 +222,14 @@ public void CollectHandlers_Duplicated_Hub() { // Arrange var services = new ServiceCollection(); + services.AddLogging(); services.AddSingleton(); var serviceProvider = services.BuildServiceProvider(); var types = new Type[]{ typeof(MyHub), typeof(MyHub) }; var options = new MagicOnionOptions(); // Act - var ex = Record.Exception(() => MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options, new NullMagicOnionLogger())); + var ex = Record.Exception(() => MagicOnionEngine.BuildServerServiceDefinition(serviceProvider, types, options)); // Assert ex.Should().NotBeNull();