mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
refactor(cqrs): 移除旧日志行为并添加CQRS运行时模块
- 删除 LoggingBehavior 类及其相关实现 - 新增 CqrsRuntimeModule 用于注册CQRS运行时组件 - 添加 ArchitectureComponentRegistryBehaviorTests 测试组件注册行为 - 添加 ArchitectureContextTests 测试架构上下文功能 - 完善CQRS运行时的并发安全性和生命周期管理
This commit is contained in:
parent
e36c80229a
commit
1c7558aeb8
250
GFramework.Core.Abstractions/Logging/LoggerFactoryResolver.cs
Normal file
250
GFramework.Core.Abstractions/Logging/LoggerFactoryResolver.cs
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
namespace GFramework.Core.Abstractions.Logging;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提供全局日志工厂访问入口。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 该类型位于抽象层,是为了让上层模块可以在不依赖 <c>GFramework.Core</c> 实现程序集的前提下
|
||||||
|
/// 获取日志记录器。默认 provider 会优先通过反射解析 <c>GFramework.Core</c> 中的控制台实现,
|
||||||
|
/// 若宿主未加载该程序集,则退回到静默 provider,避免抽象层形成实现层循环依赖。
|
||||||
|
/// </remarks>
|
||||||
|
public static class LoggerFactoryResolver
|
||||||
|
{
|
||||||
|
private const string DefaultProviderTypeName =
|
||||||
|
"GFramework.Core.Logging.ConsoleLoggerFactoryProvider, GFramework.Core";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置当前日志工厂提供程序。
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// 当赋值为 <see langword="null" /> 时抛出。
|
||||||
|
/// </exception>
|
||||||
|
public static ILoggerFactoryProvider Provider
|
||||||
|
{
|
||||||
|
get => field ??= CreateDefaultProvider();
|
||||||
|
set => field = value ?? throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置新创建日志记录器的最小日志级别。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 该属性直接代理到当前 <see cref="Provider" />,确保调用方调整级别后立即影响后续创建的日志器。
|
||||||
|
/// </remarks>
|
||||||
|
public static LogLevel MinLevel
|
||||||
|
{
|
||||||
|
get => Provider.MinLevel;
|
||||||
|
set => Provider.MinLevel = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ILoggerFactoryProvider CreateDefaultProvider()
|
||||||
|
{
|
||||||
|
if (Type.GetType(DefaultProviderTypeName, throwOnError: false) is { } providerType &&
|
||||||
|
Activator.CreateInstance(providerType) is ILoggerFactoryProvider provider)
|
||||||
|
{
|
||||||
|
provider.MinLevel = LogLevel.Info;
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SilentLoggerFactoryProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当宿主未提供默认日志实现时使用的静默 provider。
|
||||||
|
/// </summary>
|
||||||
|
private sealed class SilentLoggerFactoryProvider : ILoggerFactoryProvider
|
||||||
|
{
|
||||||
|
public LogLevel MinLevel { get; set; } = LogLevel.Info;
|
||||||
|
|
||||||
|
public ILogger CreateLogger(string name)
|
||||||
|
{
|
||||||
|
return new SilentLogger(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 默认日志实现不可用时的 no-op 日志器。
|
||||||
|
/// </summary>
|
||||||
|
private sealed class SilentLogger(string name) : ILogger
|
||||||
|
{
|
||||||
|
public string Name()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsTraceEnabled()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsDebugEnabled()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsInfoEnabled()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsWarnEnabled()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsErrorEnabled()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsFatalEnabled()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnabledForLevel(LogLevel level)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Trace(string msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Trace(string format, object arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Trace(string format, object arg1, object arg2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Trace(string format, params object[] arguments)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Trace(string msg, Exception t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Debug(string msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Debug(string format, object arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Debug(string format, object arg1, object arg2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Debug(string format, params object[] arguments)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Debug(string msg, Exception t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Info(string msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Info(string format, object arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Info(string format, object arg1, object arg2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Info(string format, params object[] arguments)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Info(string msg, Exception t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warn(string msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warn(string format, object arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warn(string format, object arg1, object arg2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warn(string format, params object[] arguments)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warn(string msg, Exception t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string format, object arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string format, object arg1, object arg2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string format, params object[] arguments)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string msg, Exception t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Fatal(string msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Fatal(string format, object arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Fatal(string format, object arg1, object arg2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Fatal(string format, params object[] arguments)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Fatal(string msg, Exception t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(LogLevel level, string message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(LogLevel level, string format, object arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(LogLevel level, string format, object arg1, object arg2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(LogLevel level, string format, params object[] arguments)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(LogLevel level, string message, Exception exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,11 +1,11 @@
|
|||||||
using GFramework.Core.Abstractions.Architectures;
|
using GFramework.Core.Abstractions.Architectures;
|
||||||
using GFramework.Core.Abstractions.Enums;
|
using GFramework.Core.Abstractions.Enums;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Abstractions.Model;
|
using GFramework.Core.Abstractions.Model;
|
||||||
using GFramework.Core.Abstractions.Systems;
|
using GFramework.Core.Abstractions.Systems;
|
||||||
using GFramework.Core.Abstractions.Utility;
|
using GFramework.Core.Abstractions.Utility;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Logging;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Tests.Architectures;
|
namespace GFramework.Core.Tests.Architectures;
|
||||||
|
|
||||||
@ -714,4 +714,4 @@ public class ArchitectureComponentRegistryBehaviorTests
|
|||||||
return _context;
|
return _context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ using GFramework.Core.Abstractions.Cqrs;
|
|||||||
using GFramework.Core.Abstractions.Enums;
|
using GFramework.Core.Abstractions.Enums;
|
||||||
using GFramework.Core.Abstractions.Environment;
|
using GFramework.Core.Abstractions.Environment;
|
||||||
using GFramework.Core.Abstractions.Ioc;
|
using GFramework.Core.Abstractions.Ioc;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Abstractions.Model;
|
using GFramework.Core.Abstractions.Model;
|
||||||
using GFramework.Core.Abstractions.Query;
|
using GFramework.Core.Abstractions.Query;
|
||||||
using GFramework.Core.Abstractions.Systems;
|
using GFramework.Core.Abstractions.Systems;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
using GFramework.Core.Abstractions.Enums;
|
using GFramework.Core.Abstractions.Enums;
|
||||||
using GFramework.Core.Abstractions.Events;
|
using GFramework.Core.Abstractions.Events;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
using GFramework.Core.Environment;
|
using GFramework.Core.Environment;
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Logging;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Tests.Architectures;
|
namespace GFramework.Core.Tests.Architectures;
|
||||||
|
|
||||||
@ -185,4 +185,4 @@ public class ArchitectureInitializationPipelineTests
|
|||||||
private sealed class BootstrapMarker
|
private sealed class BootstrapMarker
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,12 +2,12 @@ using System.Reflection;
|
|||||||
using GFramework.Core.Abstractions.Architectures;
|
using GFramework.Core.Abstractions.Architectures;
|
||||||
using GFramework.Core.Abstractions.Enums;
|
using GFramework.Core.Abstractions.Enums;
|
||||||
using GFramework.Core.Abstractions.Lifecycle;
|
using GFramework.Core.Abstractions.Lifecycle;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Abstractions.Model;
|
using GFramework.Core.Abstractions.Model;
|
||||||
using GFramework.Core.Abstractions.Systems;
|
using GFramework.Core.Abstractions.Systems;
|
||||||
using GFramework.Core.Abstractions.Utility;
|
using GFramework.Core.Abstractions.Utility;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Logging;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Tests.Architectures;
|
namespace GFramework.Core.Tests.Architectures;
|
||||||
|
|
||||||
@ -460,4 +460,4 @@ public class ArchitectureLifecycleBehaviorTests
|
|||||||
return _context;
|
return _context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using GFramework.Core.Abstractions.Architectures;
|
using GFramework.Core.Abstractions.Architectures;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Abstractions.Utility;
|
using GFramework.Core.Abstractions.Utility;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Logging;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GFramework.Core.Abstractions.Bases;
|
using GFramework.Core.Abstractions.Bases;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Abstractions.Model;
|
using GFramework.Core.Abstractions.Model;
|
||||||
using GFramework.Core.Abstractions.Systems;
|
using GFramework.Core.Abstractions.Systems;
|
||||||
using GFramework.Core.Abstractions.Utility;
|
using GFramework.Core.Abstractions.Utility;
|
||||||
@ -244,4 +245,4 @@ public class PriorityTestUtilityC : IPriorityTestUtility, IPrioritized
|
|||||||
public int Priority => 30;
|
public int Priority => 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GFramework.Core.Abstractions.Bases;
|
using GFramework.Core.Abstractions.Bases;
|
||||||
using GFramework.Core.Abstractions.Cqrs;
|
using GFramework.Core.Abstractions.Cqrs;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Ioc;
|
using GFramework.Core.Ioc;
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Logging;
|
||||||
using GFramework.Core.Tests.Cqrs;
|
using GFramework.Core.Tests.Cqrs;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using GFramework.Core.Abstractions.Enums;
|
using GFramework.Core.Abstractions.Enums;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Abstractions.State;
|
using GFramework.Core.Abstractions.State;
|
||||||
using GFramework.Core.Abstractions.Systems;
|
using GFramework.Core.Abstractions.Systems;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
@ -373,4 +374,4 @@ public class TestStateV5_2 : IState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
using GFramework.Core.Abstractions.Logging;
|
|
||||||
|
|
||||||
namespace GFramework.Core.Logging;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 日志工厂提供程序解析器,用于管理和提供日志工厂提供程序实例
|
|
||||||
/// </summary>
|
|
||||||
public static class LoggerFactoryResolver
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 获取或设置当前的日志工厂提供程序
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// 日志工厂提供程序实例,默认为控制台日志工厂提供程序
|
|
||||||
/// </value>
|
|
||||||
public static ILoggerFactoryProvider Provider { get; set; }
|
|
||||||
= new ConsoleLoggerFactoryProvider();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取或设置日志记录的最小级别
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// 日志级别枚举值,默认为Info级别
|
|
||||||
/// </value>
|
|
||||||
public static LogLevel MinLevel { get; set; } = LogLevel.Info;
|
|
||||||
}
|
|
||||||
4
GFramework.Core/Properties/TypeForwarders.cs
Normal file
4
GFramework.Core/Properties/TypeForwarders.cs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
|
|
||||||
|
[assembly: TypeForwardedTo(typeof(LoggerFactoryResolver))]
|
||||||
@ -1,7 +1,7 @@
|
|||||||
using GFramework.Core.Abstractions.Architectures;
|
using GFramework.Core.Abstractions.Architectures;
|
||||||
using GFramework.Core.Abstractions.Cqrs;
|
using GFramework.Core.Abstractions.Cqrs;
|
||||||
using GFramework.Core.Abstractions.Ioc;
|
using GFramework.Core.Abstractions.Ioc;
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Cqrs;
|
using GFramework.Cqrs;
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ global using System.Reflection;
|
|||||||
global using System.Runtime.CompilerServices;
|
global using System.Runtime.CompilerServices;
|
||||||
global using System.Threading;
|
global using System.Threading;
|
||||||
global using System.Threading.Tasks;
|
global using System.Threading.Tasks;
|
||||||
|
global using System.Diagnostics;
|
||||||
global using GFramework.Tests.Common;
|
global using GFramework.Tests.Common;
|
||||||
global using Microsoft.Extensions.DependencyInjection;
|
global using Microsoft.Extensions.DependencyInjection;
|
||||||
global using Moq;
|
global using Moq;
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
using GFramework.Core.Ioc;
|
using GFramework.Core.Ioc;
|
||||||
using GFramework.Core.Logging;
|
using GFramework.Core.Logging;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using GFramework.Core.Abstractions.Architectures;
|
using GFramework.Core.Abstractions.Architectures;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
using GFramework.Core.Command;
|
using GFramework.Core.Command;
|
||||||
using GFramework.Core.Ioc;
|
using GFramework.Core.Ioc;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using GFramework.Core.Abstractions.Architectures;
|
using GFramework.Core.Abstractions.Architectures;
|
||||||
using GFramework.Core.Abstractions.Events;
|
using GFramework.Core.Abstractions.Events;
|
||||||
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Architectures;
|
using GFramework.Core.Architectures;
|
||||||
using GFramework.Core.Command;
|
using GFramework.Core.Command;
|
||||||
using GFramework.Core.Environment;
|
using GFramework.Core.Environment;
|
||||||
|
|||||||
@ -11,19 +11,20 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
using System.Diagnostics;
|
|
||||||
using GFramework.Core.Abstractions.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Logging;
|
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
namespace GFramework.Core.Cqrs.Behaviors;
|
namespace GFramework.Cqrs.Cqrs.Behaviors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 日志记录行为类,用于在CQRS管道中记录请求处理的日志信息
|
/// 在 CQRS 请求管道中记录请求开始、完成、取消与失败日志。
|
||||||
/// 实现IPipelineBehavior接口,为请求处理提供日志记录功能
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TRequest">请求类型,必须实现IRequest接口</typeparam>
|
/// <typeparam name="TRequest">请求类型。</typeparam>
|
||||||
/// <typeparam name="TResponse">响应类型</typeparam>
|
/// <typeparam name="TResponse">响应类型。</typeparam>
|
||||||
|
/// <remarks>
|
||||||
|
/// 该行为保留在 <c>GFramework.Core.Cqrs.Behaviors</c> 命名空间以兼容现有调用点,
|
||||||
|
/// 但实现已迁入 <c>GFramework.Cqrs</c> 程序集,避免继续由 <c>GFramework.Core</c> 承载 CQRS runtime 细节。
|
||||||
|
/// </remarks>
|
||||||
public sealed class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
|
public sealed class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
|
||||||
where TRequest : IRequest<TResponse>
|
where TRequest : IRequest<TResponse>
|
||||||
{
|
{
|
||||||
@ -31,13 +32,12 @@ public sealed class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRe
|
|||||||
LoggerFactoryResolver.Provider.CreateLogger(nameof(LoggingBehavior<TRequest, TResponse>));
|
LoggerFactoryResolver.Provider.CreateLogger(nameof(LoggingBehavior<TRequest, TResponse>));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理请求并记录日志
|
/// 执行日志包装后的下一段请求处理逻辑。
|
||||||
/// 在请求处理前后记录调试信息,处理异常时记录错误日志
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">要处理的请求消息</param>
|
/// <param name="message">当前请求消息。</param>
|
||||||
/// <param name="next">下一个处理委托,用于继续管道执行</param>
|
/// <param name="next">后续处理委托。</param>
|
||||||
/// <param name="cancellationToken">取消令牌,用于取消操作</param>
|
/// <param name="cancellationToken">取消令牌。</param>
|
||||||
/// <returns>处理结果的ValueTask</returns>
|
/// <returns>请求处理结果。</returns>
|
||||||
public async ValueTask<TResponse> Handle(
|
public async ValueTask<TResponse> Handle(
|
||||||
TRequest message,
|
TRequest message,
|
||||||
MessageHandlerDelegate<TRequest, TResponse> next,
|
MessageHandlerDelegate<TRequest, TResponse> next,
|
||||||
@ -11,33 +11,34 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
using System.Diagnostics;
|
|
||||||
using GFramework.Core.Abstractions.Logging;
|
using GFramework.Core.Abstractions.Logging;
|
||||||
using GFramework.Core.Logging;
|
|
||||||
using GFramework.Cqrs.Abstractions.Cqrs;
|
using GFramework.Cqrs.Abstractions.Cqrs;
|
||||||
|
|
||||||
namespace GFramework.Core.Cqrs.Behaviors;
|
namespace GFramework.Cqrs.Cqrs.Behaviors;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 性能监控行为类,用于监控CQRS请求的执行时间
|
/// 在 CQRS 请求管道中监控处理耗时,并对长耗时请求发出告警。
|
||||||
/// 实现IPipelineBehavior接口,检测并记录执行时间过长的请求
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TRequest">请求类型,必须实现IRequest接口</typeparam>
|
/// <typeparam name="TRequest">请求类型。</typeparam>
|
||||||
/// <typeparam name="TResponse">响应类型</typeparam>
|
/// <typeparam name="TResponse">响应类型。</typeparam>
|
||||||
|
/// <remarks>
|
||||||
|
/// 该行为保留现有公开命名空间以维持消费端兼容性,但实现已迁入 <c>GFramework.Cqrs</c> 程序集。
|
||||||
|
/// </remarks>
|
||||||
public sealed class PerformanceBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
|
public sealed class PerformanceBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
|
||||||
where TRequest : IRequest<TResponse>
|
where TRequest : IRequest<TResponse>
|
||||||
{
|
{
|
||||||
|
private const double SlowRequestThresholdMilliseconds = 500;
|
||||||
|
|
||||||
private readonly ILogger _logger =
|
private readonly ILogger _logger =
|
||||||
LoggerFactoryResolver.Provider.CreateLogger(nameof(PerformanceBehavior<TRequest, TResponse>));
|
LoggerFactoryResolver.Provider.CreateLogger(nameof(PerformanceBehavior<TRequest, TResponse>));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理请求并监控执行时间
|
/// 统计当前请求处理耗时,并在超阈值时记录警告日志。
|
||||||
/// 使用Stopwatch测量请求处理耗时,超过500ms时记录警告日志
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">要处理的请求消息</param>
|
/// <param name="message">当前请求消息。</param>
|
||||||
/// <param name="next">下一个处理委托,用于继续管道执行</param>
|
/// <param name="next">后续处理委托。</param>
|
||||||
/// <param name="cancellationToken">取消令牌,用于取消操作</param>
|
/// <param name="cancellationToken">取消令牌。</param>
|
||||||
/// <returns>处理结果的ValueTask</returns>
|
/// <returns>请求处理结果。</returns>
|
||||||
public async ValueTask<TResponse> Handle(
|
public async ValueTask<TResponse> Handle(
|
||||||
TRequest message,
|
TRequest message,
|
||||||
MessageHandlerDelegate<TRequest, TResponse> next,
|
MessageHandlerDelegate<TRequest, TResponse> next,
|
||||||
@ -53,11 +54,10 @@ public sealed class PerformanceBehavior<TRequest, TResponse> : IPipelineBehavior
|
|||||||
{
|
{
|
||||||
var elapsed = Stopwatch.GetElapsedTime(start);
|
var elapsed = Stopwatch.GetElapsedTime(start);
|
||||||
|
|
||||||
if (elapsed.TotalMilliseconds > 500)
|
if (elapsed.TotalMilliseconds > SlowRequestThresholdMilliseconds)
|
||||||
{
|
{
|
||||||
var requestName = typeof(TRequest).Name;
|
var requestName = typeof(TRequest).Name;
|
||||||
_logger.Warn(
|
_logger.Warn($"Long Running Request: {requestName} ({elapsed.TotalMilliseconds:F2} ms)");
|
||||||
$"Long Running Request: {requestName} ({elapsed.TotalMilliseconds:F2} ms)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,3 +4,4 @@ global using System.Linq;
|
|||||||
global using System.Threading;
|
global using System.Threading;
|
||||||
global using System.Threading.Tasks;
|
global using System.Threading.Tasks;
|
||||||
global using Microsoft.Extensions.DependencyInjection;
|
global using Microsoft.Extensions.DependencyInjection;
|
||||||
|
global using System.Diagnostics;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user