mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-24 20:34:29 +08:00
feat(logging): 添加日志系统并集成到框架核心组件
- 实现了完整的日志系统,包括ILog接口和ConsoleLogger实现 - 添加了LogConfig配置类和LoggerFactory工厂类 - 在架构、系统、事件、IOC容器等核心组件中集成了日志记录功能 - 添加了NullLogger和CompositeLogger支持 - 创建了详细的日志使用示例和文档 - 实现了日志级别的分类配置和彩色输出功能
This commit is contained in:
parent
fdaac135f9
commit
32a1734659
@ -1,6 +1,7 @@
|
|||||||
using GFramework.Core.command;
|
using GFramework.Core.command;
|
||||||
using GFramework.Core.events;
|
using GFramework.Core.events;
|
||||||
using GFramework.Core.ioc;
|
using GFramework.Core.ioc;
|
||||||
|
using GFramework.Core.logging;
|
||||||
using GFramework.Core.model;
|
using GFramework.Core.model;
|
||||||
using GFramework.Core.query;
|
using GFramework.Core.query;
|
||||||
using GFramework.Core.system;
|
using GFramework.Core.system;
|
||||||
@ -93,28 +94,49 @@ public abstract class Architecture<T> : IArchitecture
|
|||||||
private static readonly Lazy<T> MArchitectureLazy = new(() =>
|
private static readonly Lazy<T> MArchitectureLazy = new(() =>
|
||||||
{
|
{
|
||||||
var arch = new T();
|
var arch = new T();
|
||||||
|
var logger = Log.CreateLogger("Architecture");
|
||||||
|
|
||||||
// == Architecture Init ==
|
// == Architecture Init ==
|
||||||
arch.EnterPhase(ArchitecturePhase.Created);
|
arch.EnterPhase(ArchitecturePhase.Created);
|
||||||
|
logger.Info($"Architecture {typeof(T).Name} created");
|
||||||
|
|
||||||
arch.EnterPhase(ArchitecturePhase.BeforeInit);
|
arch.EnterPhase(ArchitecturePhase.BeforeInit);
|
||||||
|
logger.Info("Starting architecture initialization");
|
||||||
|
|
||||||
// 调用用户实现的初始化
|
// 调用用户实现的初始化
|
||||||
arch.Init();
|
arch.Init();
|
||||||
arch.EnterPhase(ArchitecturePhase.AfterInit);
|
arch.EnterPhase(ArchitecturePhase.AfterInit);
|
||||||
|
logger.Info("Architecture initialization completed");
|
||||||
|
|
||||||
|
|
||||||
// == Model Init ==
|
// == Model Init ==
|
||||||
arch.EnterPhase(ArchitecturePhase.BeforeModelInit);
|
arch.EnterPhase(ArchitecturePhase.BeforeModelInit);
|
||||||
|
logger.Info($"Initializing {arch._mModels.Count} models");
|
||||||
|
|
||||||
// 初始化所有已注册但尚未初始化的模型
|
// 初始化所有已注册但尚未初始化的模型
|
||||||
foreach (var model in arch._mModels) model.Init();
|
foreach (var model in arch._mModels)
|
||||||
|
{
|
||||||
|
logger.Debug($"Initializing model: {model.GetType().Name}");
|
||||||
|
model.Init();
|
||||||
|
}
|
||||||
arch._mModels.Clear();
|
arch._mModels.Clear();
|
||||||
arch.EnterPhase(ArchitecturePhase.AfterModelInit);
|
arch.EnterPhase(ArchitecturePhase.AfterModelInit);
|
||||||
|
logger.Info("All models initialized");
|
||||||
|
|
||||||
|
|
||||||
// == System Init ==
|
// == System Init ==
|
||||||
arch.EnterPhase(ArchitecturePhase.BeforeSystemInit);
|
arch.EnterPhase(ArchitecturePhase.BeforeSystemInit);
|
||||||
|
logger.Info($"Initializing {arch._mSystems.Count} systems");
|
||||||
|
|
||||||
// 初始化所有已注册但尚未初始化的系统
|
// 初始化所有已注册但尚未初始化的系统
|
||||||
foreach (var system in arch._mSystems) system.Init();
|
foreach (var system in arch._mSystems)
|
||||||
|
{
|
||||||
|
logger.Debug($"Initializing system: {system.GetType().Name}");
|
||||||
|
system.Init();
|
||||||
|
}
|
||||||
arch._mSystems.Clear();
|
arch._mSystems.Clear();
|
||||||
arch.EnterPhase(ArchitecturePhase.AfterSystemInit);
|
arch.EnterPhase(ArchitecturePhase.AfterSystemInit);
|
||||||
|
logger.Info("All systems initialized");
|
||||||
|
|
||||||
|
|
||||||
// == Finalize ==
|
// == Finalize ==
|
||||||
@ -124,6 +146,7 @@ public abstract class Architecture<T> : IArchitecture
|
|||||||
arch.EnterPhase(ArchitecturePhase.Ready);
|
arch.EnterPhase(ArchitecturePhase.Ready);
|
||||||
// 发送架构生命周期就绪事件
|
// 发送架构生命周期就绪事件
|
||||||
arch.SendEvent(new ArchitectureEvents.ArchitectureLifecycleReadyEvent());
|
arch.SendEvent(new ArchitectureEvents.ArchitectureLifecycleReadyEvent());
|
||||||
|
logger.Info($"Architecture {typeof(T).Name} is ready - all components initialized");
|
||||||
return arch;
|
return arch;
|
||||||
}, LazyThreadSafetyMode.ExecutionAndPublication);
|
}, LazyThreadSafetyMode.ExecutionAndPublication);
|
||||||
|
|
||||||
@ -138,21 +161,32 @@ public abstract class Architecture<T> : IArchitecture
|
|||||||
/// <exception cref="InvalidOperationException">当阶段转换不被允许时抛出异常</exception>
|
/// <exception cref="InvalidOperationException">当阶段转换不被允许时抛出异常</exception>
|
||||||
private void EnterPhase(ArchitecturePhase next)
|
private void EnterPhase(ArchitecturePhase next)
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("Architecture");
|
||||||
|
|
||||||
if (Options.StrictPhaseValidation &&
|
if (Options.StrictPhaseValidation &&
|
||||||
(!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) ||
|
(!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) ||
|
||||||
!allowed.Contains(next)))
|
!allowed.Contains(next)))
|
||||||
{
|
{
|
||||||
// 验证阶段转换是否合法
|
// 验证阶段转换是否合法
|
||||||
throw new InvalidOperationException(
|
var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}";
|
||||||
$"Invalid phase transition: {CurrentPhase} -> {next}");
|
logger.Fatal(errorMsg);
|
||||||
|
throw new InvalidOperationException(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var previousPhase = CurrentPhase;
|
||||||
CurrentPhase = next;
|
CurrentPhase = next;
|
||||||
|
|
||||||
|
if (previousPhase != next)
|
||||||
|
{
|
||||||
|
logger.Info($"Architecture phase changed: {previousPhase} -> {next}");
|
||||||
|
}
|
||||||
|
|
||||||
NotifyPhase(next);
|
NotifyPhase(next);
|
||||||
|
|
||||||
// 通知所有架构阶段感知对象阶段变更
|
// 通知所有架构阶段感知对象阶段变更
|
||||||
foreach (var obj in _mContainer.GetAll<IArchitecturePhaseAware>())
|
foreach (var obj in _mContainer.GetAll<IArchitecturePhaseAware>())
|
||||||
{
|
{
|
||||||
|
logger.Debug($"Notifying phase-aware object {obj.GetType().Name} of phase change to {next}");
|
||||||
obj.OnArchitecturePhase(next);
|
obj.OnArchitecturePhase(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,23 +228,34 @@ public abstract class Architecture<T> : IArchitecture
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public virtual void Destroy()
|
public virtual void Destroy()
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("Architecture");
|
||||||
|
|
||||||
// 检查当前阶段,如果已经处于销毁或已销毁状态则直接返回
|
// 检查当前阶段,如果已经处于销毁或已销毁状态则直接返回
|
||||||
if (CurrentPhase >= ArchitecturePhase.Destroying)
|
if (CurrentPhase >= ArchitecturePhase.Destroying)
|
||||||
|
{
|
||||||
|
logger.Warn("Architecture destroy called but already in destroying/destroyed state");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 进入销毁阶段并发送销毁开始事件
|
// 进入销毁阶段并发送销毁开始事件
|
||||||
|
logger.Info("Starting architecture destruction");
|
||||||
EnterPhase(ArchitecturePhase.Destroying);
|
EnterPhase(ArchitecturePhase.Destroying);
|
||||||
SendEvent(new ArchitectureEvents.ArchitectureDestroyingEvent());
|
SendEvent(new ArchitectureEvents.ArchitectureDestroyingEvent());
|
||||||
|
|
||||||
// 销毁所有系统组件并清空系统列表
|
// 销毁所有系统组件并清空系统列表
|
||||||
|
logger.Info($"Destroying {_allSystems.Count} systems");
|
||||||
foreach (var system in _allSystems)
|
foreach (var system in _allSystems)
|
||||||
|
{
|
||||||
|
logger.Debug($"Destroying system: {system.GetType().Name}");
|
||||||
system.Destroy();
|
system.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
_allSystems.Clear();
|
_allSystems.Clear();
|
||||||
|
|
||||||
// 进入已销毁阶段并发送销毁完成事件
|
// 进入已销毁阶段并发送销毁完成事件
|
||||||
EnterPhase(ArchitecturePhase.Destroyed);
|
EnterPhase(ArchitecturePhase.Destroyed);
|
||||||
SendEvent(new ArchitectureEvents.ArchitectureDestroyedEvent());
|
SendEvent(new ArchitectureEvents.ArchitectureDestroyedEvent());
|
||||||
|
logger.Info("Architecture destruction completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -223,9 +268,12 @@ public abstract class Architecture<T> : IArchitecture
|
|||||||
/// <param name="module">要安装的模块</param>
|
/// <param name="module">要安装的模块</param>
|
||||||
public void InstallModule(IArchitectureModule module)
|
public void InstallModule(IArchitectureModule module)
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("Architecture");
|
||||||
|
logger.Debug($"Installing module: {module.GetType().Name}");
|
||||||
RegisterLifecycleHook(module);
|
RegisterLifecycleHook(module);
|
||||||
_mContainer.RegisterPlurality(module);
|
_mContainer.RegisterPlurality(module);
|
||||||
module.Install(this);
|
module.Install(this);
|
||||||
|
logger.Info($"Module installed: {module.GetType().Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -240,16 +288,28 @@ public abstract class Architecture<T> : IArchitecture
|
|||||||
/// <param name="system">要注册的系统实例</param>
|
/// <param name="system">要注册的系统实例</param>
|
||||||
public void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem
|
public void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("Architecture");
|
||||||
|
|
||||||
if (CurrentPhase >= ArchitecturePhase.Ready && !Options.AllowLateRegistration)
|
if (CurrentPhase >= ArchitecturePhase.Ready && !Options.AllowLateRegistration)
|
||||||
throw new InvalidOperationException(
|
{
|
||||||
"Cannot register system after Architecture is Ready");
|
var errorMsg = "Cannot register system after Architecture is Ready";
|
||||||
|
logger.Error(errorMsg);
|
||||||
|
throw new InvalidOperationException(errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debug($"Registering system: {typeof(TSystem).Name}");
|
||||||
system.SetArchitecture(this);
|
system.SetArchitecture(this);
|
||||||
_mContainer.RegisterPlurality(system);
|
_mContainer.RegisterPlurality(system);
|
||||||
_allSystems.Add(system);
|
_allSystems.Add(system);
|
||||||
if (!_mInited)
|
if (!_mInited)
|
||||||
_mSystems.Add(system);
|
_mSystems.Add(system);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"Immediately initializing system: {typeof(TSystem).Name}");
|
||||||
system.Init();
|
system.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info($"System registered: {typeof(TSystem).Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -260,16 +320,28 @@ public abstract class Architecture<T> : IArchitecture
|
|||||||
/// <param name="model">要注册的模型实例</param>
|
/// <param name="model">要注册的模型实例</param>
|
||||||
public void RegisterModel<TModel>(TModel model) where TModel : IModel
|
public void RegisterModel<TModel>(TModel model) where TModel : IModel
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("Architecture");
|
||||||
|
|
||||||
if (CurrentPhase >= ArchitecturePhase.Ready && !Options.AllowLateRegistration)
|
if (CurrentPhase >= ArchitecturePhase.Ready && !Options.AllowLateRegistration)
|
||||||
throw new InvalidOperationException(
|
{
|
||||||
"Cannot register system after Architecture is Ready");
|
var errorMsg = "Cannot register model after Architecture is Ready";
|
||||||
|
logger.Error(errorMsg);
|
||||||
|
throw new InvalidOperationException(errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debug($"Registering model: {typeof(TModel).Name}");
|
||||||
model.SetArchitecture(this);
|
model.SetArchitecture(this);
|
||||||
_mContainer.RegisterPlurality(model);
|
_mContainer.RegisterPlurality(model);
|
||||||
|
|
||||||
if (!_mInited)
|
if (!_mInited)
|
||||||
_mModels.Add(model);
|
_mModels.Add(model);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"Immediately initializing model: {typeof(TModel).Name}");
|
||||||
model.Init();
|
model.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info($"Model registered: {typeof(TModel).Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -280,7 +352,10 @@ public abstract class Architecture<T> : IArchitecture
|
|||||||
/// <param name="utility">要注册的工具实例</param>
|
/// <param name="utility">要注册的工具实例</param>
|
||||||
public void RegisterUtility<TUtility>(TUtility utility) where TUtility : IUtility
|
public void RegisterUtility<TUtility>(TUtility utility) where TUtility : IUtility
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("Architecture");
|
||||||
|
logger.Debug($"Registering utility: {typeof(TUtility).Name}");
|
||||||
_mContainer.RegisterPlurality(utility);
|
_mContainer.RegisterPlurality(utility);
|
||||||
|
logger.Info($"Utility registered: {typeof(TUtility).Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
namespace GFramework.Core.events;
|
using GFramework.Core.logging;
|
||||||
|
|
||||||
|
namespace GFramework.Core.events;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TypeEventSystem
|
/// TypeEventSystem
|
||||||
@ -10,22 +12,43 @@ public class TypeEventSystem
|
|||||||
|
|
||||||
public void Send<T>() where T : new()
|
public void Send<T>() where T : new()
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("Event");
|
||||||
|
var eventType = typeof(T);
|
||||||
|
|
||||||
|
logger.Debug($"Sending event: {eventType.Name}");
|
||||||
_mEvents.GetEvent<EasyEvent<T>>()?.Trigger(new T());
|
_mEvents.GetEvent<EasyEvent<T>>()?.Trigger(new T());
|
||||||
|
logger.Info($"Event sent: {eventType.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send<T>(T e)
|
public void Send<T>(T e)
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("Event");
|
||||||
|
var eventType = typeof(T);
|
||||||
|
|
||||||
|
logger.Debug($"Sending event: {eventType.Name}");
|
||||||
_mEvents.GetEvent<EasyEvent<T>>()?.Trigger(e);
|
_mEvents.GetEvent<EasyEvent<T>>()?.Trigger(e);
|
||||||
|
logger.Info($"Event sent: {eventType.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public IUnRegister Register<T>(Action<T> onEvent)
|
public IUnRegister Register<T>(Action<T> onEvent)
|
||||||
{
|
{
|
||||||
return _mEvents.GetOrAddEvent<EasyEvent<T>>().Register(onEvent);
|
var logger = Log.CreateLogger("Event");
|
||||||
|
var eventType = typeof(T);
|
||||||
|
|
||||||
|
logger.Debug($"Registering event handler for: {eventType.Name}");
|
||||||
|
var result = _mEvents.GetOrAddEvent<EasyEvent<T>>().Register(onEvent);
|
||||||
|
logger.Info($"Event handler registered for: {eventType.Name}");
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UnRegister<T>(Action<T> onEvent)
|
public void UnRegister<T>(Action<T> onEvent)
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("Event");
|
||||||
|
var eventType = typeof(T);
|
||||||
|
|
||||||
|
logger.Debug($"Unregistering event handler for: {eventType.Name}");
|
||||||
var e = _mEvents.GetEvent<EasyEvent<T>>();
|
var e = _mEvents.GetEvent<EasyEvent<T>>();
|
||||||
e?.UnRegister(onEvent);
|
e?.UnRegister(onEvent);
|
||||||
|
logger.Info($"Event handler unregistered for: {eventType.Name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
using GFramework.Core.logging;
|
||||||
using GFramework.Core.system;
|
using GFramework.Core.system;
|
||||||
|
|
||||||
namespace GFramework.Core.ioc;
|
namespace GFramework.Core.ioc;
|
||||||
@ -57,20 +58,27 @@ public class IocContainer
|
|||||||
public void RegisterSingleton<T>(T instance)
|
public void RegisterSingleton<T>(T instance)
|
||||||
{
|
{
|
||||||
var type = typeof(T);
|
var type = typeof(T);
|
||||||
|
var logger = Log.CreateLogger("IOC");
|
||||||
|
|
||||||
_lock.EnterWriteLock();
|
_lock.EnterWriteLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_frozen)
|
if (_frozen)
|
||||||
throw new InvalidOperationException("IocContainer is frozen");
|
{
|
||||||
|
var errorMsg = "IocContainer is frozen";
|
||||||
|
logger.Error(errorMsg);
|
||||||
|
throw new InvalidOperationException(errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
if (_typeIndex.TryGetValue(type, out var set) && set.Count > 0)
|
if (_typeIndex.TryGetValue(type, out var set) && set.Count > 0)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
var errorMsg = $"Singleton already registered for type: {type.Name}";
|
||||||
$"Singleton already registered for type: {type.Name}");
|
logger.Error(errorMsg);
|
||||||
|
throw new InvalidOperationException(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterInternal(type, instance!);
|
RegisterInternal(type, instance!);
|
||||||
|
logger.Debug($"Singleton registered: {type.Name}");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -87,6 +95,8 @@ public class IocContainer
|
|||||||
public void RegisterPlurality<T>(T instance)
|
public void RegisterPlurality<T>(T instance)
|
||||||
{
|
{
|
||||||
var concreteType = instance!.GetType();
|
var concreteType = instance!.GetType();
|
||||||
|
var logger = Log.CreateLogger("IOC");
|
||||||
|
|
||||||
// 获取实例类型直接实现的所有接口,并筛选出可以赋值给T类型的接口
|
// 获取实例类型直接实现的所有接口,并筛选出可以赋值给T类型的接口
|
||||||
var interfaces = concreteType.GetInterfaces()
|
var interfaces = concreteType.GetInterfaces()
|
||||||
.Where(typeof(T).IsAssignableFrom);
|
.Where(typeof(T).IsAssignableFrom);
|
||||||
@ -96,11 +106,13 @@ public class IocContainer
|
|||||||
{
|
{
|
||||||
// 注册具体类型
|
// 注册具体类型
|
||||||
RegisterInternal(concreteType, instance);
|
RegisterInternal(concreteType, instance);
|
||||||
|
logger.Debug($"Registered concrete type: {concreteType.Name}");
|
||||||
|
|
||||||
// 注册所有匹配的接口类型
|
// 注册所有匹配的接口类型
|
||||||
foreach (var itf in interfaces)
|
foreach (var itf in interfaces)
|
||||||
{
|
{
|
||||||
RegisterInternal(itf, instance);
|
RegisterInternal(itf, instance);
|
||||||
|
logger.Debug($"Registered interface: {itf.Name} for {concreteType.Name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -117,7 +129,11 @@ public class IocContainer
|
|||||||
private void RegisterInternal(Type type, object instance)
|
private void RegisterInternal(Type type, object instance)
|
||||||
{
|
{
|
||||||
if (_frozen)
|
if (_frozen)
|
||||||
throw new InvalidOperationException("IocContainer is frozen");
|
{
|
||||||
|
var errorMsg = "IocContainer is frozen";
|
||||||
|
Log.CreateLogger("IOC").Error(errorMsg);
|
||||||
|
throw new InvalidOperationException(errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
_objects.Add(instance);
|
_objects.Add(instance);
|
||||||
|
|
||||||
@ -193,14 +209,19 @@ public class IocContainer
|
|||||||
/// <returns>找到的第一个实例;如果未找到则返回 null</returns>
|
/// <returns>找到的第一个实例;如果未找到则返回 null</returns>
|
||||||
public T? Get<T>() where T : class
|
public T? Get<T>() where T : class
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("IOC");
|
||||||
|
|
||||||
_lock.EnterReadLock();
|
_lock.EnterReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_typeIndex.TryGetValue(typeof(T), out var set) && set.Count > 0)
|
if (_typeIndex.TryGetValue(typeof(T), out var set) && set.Count > 0)
|
||||||
{
|
{
|
||||||
return set.First() as T;
|
var result = set.First() as T;
|
||||||
|
logger.Debug($"Retrieved instance: {typeof(T).Name}");
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Debug($"No instance found for type: {typeof(T).Name}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -218,14 +239,29 @@ public class IocContainer
|
|||||||
/// <exception cref="InvalidOperationException">当没有注册实例或注册了多个实例时抛出</exception>
|
/// <exception cref="InvalidOperationException">当没有注册实例或注册了多个实例时抛出</exception>
|
||||||
public T GetRequired<T>() where T : class
|
public T GetRequired<T>() where T : class
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("IOC");
|
||||||
var list = GetAll<T>();
|
var list = GetAll<T>();
|
||||||
|
|
||||||
// 根据实例数量进行判断和处理
|
// 根据实例数量进行判断和处理
|
||||||
return list.Count switch
|
return list.Count switch
|
||||||
{
|
{
|
||||||
0 => throw new InvalidOperationException($"No instance registered for {typeof(T).Name}"),
|
0 =>
|
||||||
> 1 => throw new InvalidOperationException($"Multiple instances registered for {typeof(T).Name}"),
|
{
|
||||||
_ => list[0]
|
var errorMsg = $"No instance registered for {typeof(T).Name}";
|
||||||
|
logger.Error(errorMsg);
|
||||||
|
throw new InvalidOperationException(errorMsg);
|
||||||
|
},
|
||||||
|
> 1 =>
|
||||||
|
{
|
||||||
|
var errorMsg = $"Multiple instances registered for {typeof(T).Name}";
|
||||||
|
logger.Error(errorMsg);
|
||||||
|
throw new InvalidOperationException(errorMsg);
|
||||||
|
},
|
||||||
|
_ =>
|
||||||
|
{
|
||||||
|
logger.Debug($"Retrieved required instance: {typeof(T).Name}");
|
||||||
|
return list[0];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,11 +363,14 @@ public class IocContainer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Freeze()
|
public void Freeze()
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("IOC");
|
||||||
|
|
||||||
// 获取写锁以确保线程安全的状态修改
|
// 获取写锁以确保线程安全的状态修改
|
||||||
_lock.EnterWriteLock();
|
_lock.EnterWriteLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_frozen = true;
|
_frozen = true;
|
||||||
|
logger.Info("IOC Container frozen - no further registrations allowed");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
128
GFramework.Core/logging/ConsoleLogger.cs
Normal file
128
GFramework.Core/logging/ConsoleLogger.cs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace GFramework.Core.logging;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 控制台日志记录器实现,支持日志级别控制和格式化输出
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ConsoleLogger : ILog
|
||||||
|
{
|
||||||
|
private readonly LogLevel _minLevel;
|
||||||
|
private readonly string? _category;
|
||||||
|
private readonly TextWriter? _writer;
|
||||||
|
private readonly bool _useColors;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="category">日志类别</param>
|
||||||
|
/// <param name="minLevel">最小日志级别(默认Info)</param>
|
||||||
|
/// <param name="writer">输出流(默认控制台)</param>
|
||||||
|
/// <param name="useColors">是否使用颜色输出(默认true)</param>
|
||||||
|
public ConsoleLogger(
|
||||||
|
string? category = null,
|
||||||
|
LogLevel minLevel = LogLevel.Info,
|
||||||
|
TextWriter? writer = null,
|
||||||
|
bool useColors = true)
|
||||||
|
{
|
||||||
|
_category = category;
|
||||||
|
_minLevel = minLevel;
|
||||||
|
_writer = writer ?? Console.Out;
|
||||||
|
_useColors = useColors && _writer == Console.Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录日志消息
|
||||||
|
/// </summary>
|
||||||
|
public void Log(LogLevel level, string message, Exception? exception = null, object? context = null)
|
||||||
|
{
|
||||||
|
if (!IsEnabled(level))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||||
|
var levelStr = level.ToString().ToUpper().PadRight(7);
|
||||||
|
var categoryStr = _category != null ? $"[{_category}] " : "";
|
||||||
|
var contextStr = context != null ? $" | Context: {FormatContext(context)}" : "";
|
||||||
|
var exceptionStr = exception != null ? $"\nException: {exception}" : "";
|
||||||
|
|
||||||
|
var logMessage = $"[{timestamp}] {levelStr} {categoryStr}{message}{contextStr}{exceptionStr}";
|
||||||
|
|
||||||
|
if (_useColors)
|
||||||
|
{
|
||||||
|
WriteColored(level, logMessage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_writer.WriteLine(logMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查指定日志级别是否启用
|
||||||
|
/// </summary>
|
||||||
|
public bool IsEnabled(LogLevel level) => level >= _minLevel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前最小日志级别
|
||||||
|
/// </summary>
|
||||||
|
public LogLevel MinLevel => _minLevel;
|
||||||
|
|
||||||
|
private void WriteColored(LogLevel level, string message)
|
||||||
|
{
|
||||||
|
var originalColor = Console.ForegroundColor;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = GetColor(level);
|
||||||
|
_writer.WriteLine(message);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = originalColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConsoleColor GetColor(LogLevel level)
|
||||||
|
{
|
||||||
|
return level switch
|
||||||
|
{
|
||||||
|
LogLevel.Trace => ConsoleColor.Gray,
|
||||||
|
LogLevel.Debug => ConsoleColor.Cyan,
|
||||||
|
LogLevel.Info => ConsoleColor.White,
|
||||||
|
LogLevel.Warning => ConsoleColor.Yellow,
|
||||||
|
LogLevel.Error => ConsoleColor.Red,
|
||||||
|
LogLevel.Fatal => ConsoleColor.Magenta,
|
||||||
|
_ => ConsoleColor.White
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private string FormatContext(object context)
|
||||||
|
{
|
||||||
|
return context switch
|
||||||
|
{
|
||||||
|
string str => str,
|
||||||
|
int num => num.ToString(),
|
||||||
|
null => "null",
|
||||||
|
_ => $"{context.GetType().Name}: {context}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 快捷方法实现
|
||||||
|
public void Info(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Info, msg, null, ctx);
|
||||||
|
|
||||||
|
public void Error(string msg, Exception? ex = null, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Error, msg, ex, ctx);
|
||||||
|
|
||||||
|
public void Debug(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Debug, msg, null, ctx);
|
||||||
|
|
||||||
|
public void Trace(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Trace, msg, null, ctx);
|
||||||
|
|
||||||
|
public void Warn(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Warning, msg, null, ctx);
|
||||||
|
|
||||||
|
public void Fatal(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Fatal, msg, null, ctx);
|
||||||
|
}
|
||||||
@ -20,9 +20,52 @@ public interface ILog
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检查指定日志级别是否已启用
|
/// 检查指定日志级别是否启用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="level">要检查的日志级别</param>
|
/// <param name="level">要检查的日志级别</param>
|
||||||
/// <returns>如果指定级别已启用则返回true,否则返回false</returns>
|
/// <returns>如果指定级别已启用则返回true,否则返回false</returns>
|
||||||
bool IsEnabled(LogLevel level);
|
bool IsEnabled(LogLevel level);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录信息级别日志
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息</param>
|
||||||
|
/// <param name="ctx">日志上下文信息(可选)</param>
|
||||||
|
void Info(string msg, object? ctx = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录错误级别日志
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息</param>
|
||||||
|
/// <param name="ex">相关异常对象(可选)</param>
|
||||||
|
/// <param name="ctx">日志上下文信息(可选)</param>
|
||||||
|
void Error(string msg, Exception? ex = null, object? ctx = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录调试级别日志
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息</param>
|
||||||
|
/// <param name="ctx">日志上下文信息(可选)</param>
|
||||||
|
void Debug(string msg, object? ctx = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录跟踪级别日志
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息</param>
|
||||||
|
/// <param name="ctx">日志上下文信息(可选)</param>
|
||||||
|
void Trace(string msg, object? ctx = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录警告级别日志
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息</param>
|
||||||
|
/// <param name="ctx">日志上下文信息(可选)</param>
|
||||||
|
void Warn(string msg, object? ctx = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录致命错误级别日志
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息</param>
|
||||||
|
/// <param name="ctx">日志上下文信息(可选)</param>
|
||||||
|
void Fatal(string msg, object? ctx = null);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,19 +5,90 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Log
|
public static class Log
|
||||||
{
|
{
|
||||||
|
private static ILoggerFactory? _factory;
|
||||||
|
private static LogConfig? _config;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置当前的日志记录器实例
|
/// 获取当前的日志记录器实例
|
||||||
/// 默认使用 NullLogger,不输出任何日志
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static ILog Instance { get; private set; } = new NullLogger();
|
public static ILog Instance { get; private set; } = new ConsoleLogger(null, LogLevel.Info);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前的日志配置
|
||||||
|
/// </summary>
|
||||||
|
public static LogConfig Config => _config ??= new LogConfig();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置日志记录器实例
|
/// 设置日志记录器实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">要设置的日志记录器,如果为 null 则使用 NullLogger</param>
|
/// <param name="logger">要设置的日志记录器,如果为 null 则使用默认的ConsoleLogger</param>
|
||||||
public static void SetLogger(ILog? logger)
|
public static void SetLogger(ILog? logger)
|
||||||
{
|
{
|
||||||
Instance = logger ?? new NullLogger();
|
Instance = logger ?? new ConsoleLogger(null, LogLevel.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用日志工厂创建日志记录器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factory">日志工厂实例</param>
|
||||||
|
public static void SetLoggerFactory(ILoggerFactory factory)
|
||||||
|
{
|
||||||
|
_factory = factory ?? throw new ArgumentNullException(nameof(factory));
|
||||||
|
Instance = _factory.CreateGlobalLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用日志配置初始化日志系统
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config">日志配置</param>
|
||||||
|
public static void Initialize(LogConfig config)
|
||||||
|
{
|
||||||
|
_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||||
|
_factory = new LoggerFactory(config);
|
||||||
|
Instance = _factory.CreateGlobalLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 快速配置日志系统
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minLevel">最小日志级别(默认为Info)</param>
|
||||||
|
/// <param name="enableConsole">是否启用控制台输出(默认为true)</param>
|
||||||
|
/// <param name="useColors">是否使用彩色输出(默认为true)</param>
|
||||||
|
/// <param name="enableFile">是否启用文件输出(默认为false)</param>
|
||||||
|
/// <param name="logFilePath">日志文件路径(可选)</param>
|
||||||
|
public static void Configure(
|
||||||
|
LogLevel minLevel = LogLevel.Info,
|
||||||
|
bool enableConsole = true,
|
||||||
|
bool useColors = true,
|
||||||
|
bool enableFile = false,
|
||||||
|
string? logFilePath = null)
|
||||||
|
{
|
||||||
|
var config = new LogConfig
|
||||||
|
{
|
||||||
|
DefaultMinLevel = minLevel,
|
||||||
|
EnableConsole = enableConsole,
|
||||||
|
UseColors = useColors,
|
||||||
|
EnableFile = enableFile,
|
||||||
|
LogFilePath = logFilePath
|
||||||
|
};
|
||||||
|
|
||||||
|
Initialize(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建指定类别的日志记录器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="category">日志类别</param>
|
||||||
|
/// <returns>日志记录器实例</returns>
|
||||||
|
public static ILog CreateLogger(string category)
|
||||||
|
{
|
||||||
|
if (_factory != null)
|
||||||
|
{
|
||||||
|
return _factory.Create(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有设置工厂,使用默认配置
|
||||||
|
return new ConsoleLogger(category, Config.GetCategoryLevel(category));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
106
GFramework.Core/logging/LogConfig.cs
Normal file
106
GFramework.Core/logging/LogConfig.cs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace GFramework.Core.logging;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日志配置类,用于配置日志记录器的行为
|
||||||
|
/// </summary>
|
||||||
|
public sealed class LogConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置默认的最小日志级别(默认为Info)
|
||||||
|
/// </summary>
|
||||||
|
public LogLevel DefaultMinLevel { get; set; } = LogLevel.Info;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置是否启用控制台输出(默认为true)
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableConsole { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置是否使用彩色输出(默认为true)
|
||||||
|
/// </summary>
|
||||||
|
public bool UseColors { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置是否启用文件输出(默认为false)
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableFile { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置日志文件路径(当EnableFile为true时使用)
|
||||||
|
/// </summary>
|
||||||
|
public string? LogFilePath { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取特定类别的日志级别配置
|
||||||
|
/// </summary>
|
||||||
|
private readonly Dictionary<string, LogLevel> _categoryLevels = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置特定类别的日志级别
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="category">日志类别</param>
|
||||||
|
/// <param name="level">日志级别</param>
|
||||||
|
public void SetCategoryLevel(string category, LogLevel level)
|
||||||
|
{
|
||||||
|
_categoryLevels[category] = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取类别的日志级别,如果没有特定配置则返回默认级别
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="category">日志类别</param>
|
||||||
|
/// <returns>日志级别</returns>
|
||||||
|
public LogLevel GetCategoryLevel(string? category)
|
||||||
|
{
|
||||||
|
if (category != null && _categoryLevels.TryGetValue(category, out var level))
|
||||||
|
{
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefaultMinLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建控制台日志记录器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="category">日志类别</param>
|
||||||
|
/// <returns>日志记录器实例</returns>
|
||||||
|
public ILog CreateConsoleLogger(string? category = null)
|
||||||
|
{
|
||||||
|
var level = GetCategoryLevel(category);
|
||||||
|
return new ConsoleLogger(category, level, null, UseColors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建文件日志记录器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="category">日志类别</param>
|
||||||
|
/// <returns>日志记录器实例</returns>
|
||||||
|
public ILog CreateFileLogger(string? category = null)
|
||||||
|
{
|
||||||
|
if (!EnableFile || string.IsNullOrEmpty(LogFilePath))
|
||||||
|
return new NullLogger();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var level = GetCategoryLevel(category);
|
||||||
|
var directory = Path.GetDirectoryName(LogFilePath);
|
||||||
|
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
var writer = new StreamWriter(LogFilePath, append: true);
|
||||||
|
return new ConsoleLogger(category, level, writer, useColors: false);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 如果创建文件失败,返回空日志记录器
|
||||||
|
return new NullLogger();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
131
GFramework.Core/logging/LoggerFactory.cs
Normal file
131
GFramework.Core/logging/LoggerFactory.cs
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace GFramework.Core.logging;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日志工厂实现,使用LogConfig配置创建日志记录器
|
||||||
|
/// </summary>
|
||||||
|
public class LoggerFactory : ILoggerFactory
|
||||||
|
{
|
||||||
|
private readonly LogConfig _config;
|
||||||
|
private readonly Dictionary<string, ILog> _loggers = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config">日志配置</param>
|
||||||
|
public LoggerFactory(LogConfig config)
|
||||||
|
{
|
||||||
|
_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建指定类别的日志记录器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="category">日志类别</param>
|
||||||
|
/// <returns>日志记录器实例</returns>
|
||||||
|
public ILog Create(string category)
|
||||||
|
{
|
||||||
|
if (_loggers.TryGetValue(category, out var existingLogger))
|
||||||
|
{
|
||||||
|
return existingLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger = CreateLogger(category);
|
||||||
|
_loggers[category] = logger;
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建全局日志记录器实例
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>全局日志记录器</returns>
|
||||||
|
public ILog CreateGlobalLogger()
|
||||||
|
{
|
||||||
|
return Create("Global");
|
||||||
|
}
|
||||||
|
|
||||||
|
private ILog CreateLogger(string category)
|
||||||
|
{
|
||||||
|
var level = _config.GetCategoryLevel(category);
|
||||||
|
var consoleLogger = new ConsoleLogger(category, level, null, _config.UseColors);
|
||||||
|
|
||||||
|
if (_config.EnableFile && !string.IsNullOrEmpty(_config.LogFilePath))
|
||||||
|
{
|
||||||
|
// 创建一个组合日志记录器,同时输出到控制台和文件
|
||||||
|
return new CompositeLogger(category, level, consoleLogger, CreateFileLogger(category));
|
||||||
|
}
|
||||||
|
|
||||||
|
return consoleLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ILog CreateFileLogger(string category)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var level = _config.GetCategoryLevel(category);
|
||||||
|
var directory = System.IO.Path.GetDirectoryName(_config.LogFilePath);
|
||||||
|
if (!string.IsNullOrEmpty(directory) && !System.IO.Directory.Exists(directory))
|
||||||
|
{
|
||||||
|
System.IO.Directory.CreateDirectory(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
var writer = new System.IO.StreamWriter(_config.LogFilePath!, append: true);
|
||||||
|
return new ConsoleLogger(category, level, writer, useColors: false);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new NullLogger();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 组合日志记录器,将日志同时输出到多个目标
|
||||||
|
/// </summary>
|
||||||
|
private class CompositeLogger : ILog
|
||||||
|
{
|
||||||
|
private readonly string _category;
|
||||||
|
private readonly LogLevel _minLevel;
|
||||||
|
private readonly ILog _consoleLogger;
|
||||||
|
private readonly ILog _fileLogger;
|
||||||
|
|
||||||
|
public CompositeLogger(string category, LogLevel minLevel, ILog consoleLogger, ILog fileLogger)
|
||||||
|
{
|
||||||
|
_category = category;
|
||||||
|
_minLevel = minLevel;
|
||||||
|
_consoleLogger = consoleLogger;
|
||||||
|
_fileLogger = fileLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(LogLevel level, string message, Exception? exception = null, object? context = null)
|
||||||
|
{
|
||||||
|
if (!IsEnabled(level))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_consoleLogger.Log(level, message, exception, context);
|
||||||
|
_fileLogger.Log(level, message, exception, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnabled(LogLevel level) => level >= _minLevel;
|
||||||
|
|
||||||
|
// 快捷方法实现
|
||||||
|
public void Info(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Info, msg, null, ctx);
|
||||||
|
|
||||||
|
public void Error(string msg, Exception? ex = null, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Error, msg, ex, ctx);
|
||||||
|
|
||||||
|
public void Debug(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Debug, msg, null, ctx);
|
||||||
|
|
||||||
|
public void Trace(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Trace, msg, null, ctx);
|
||||||
|
|
||||||
|
public void Warn(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Warning, msg, null, ctx);
|
||||||
|
|
||||||
|
public void Fatal(string msg, object? ctx = null)
|
||||||
|
=> Log(LogLevel.Fatal, msg, null, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
263
GFramework.Core/logging/LoggingExample.cs
Normal file
263
GFramework.Core/logging/LoggingExample.cs
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
using GFramework.Core.architecture;
|
||||||
|
using GFramework.Core.logging;
|
||||||
|
using GFramework.Core.system;
|
||||||
|
using GFramework.Core.model;
|
||||||
|
using GFramework.Core.events;
|
||||||
|
|
||||||
|
namespace GFramework.Core.Examples;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日志系统使用示例
|
||||||
|
/// 演示如何在实际项目中使用GFramework.Core的日志功能
|
||||||
|
/// </summary>
|
||||||
|
public class LoggingExample
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 演示基本的日志配置和使用
|
||||||
|
/// </summary>
|
||||||
|
public static void DemonstrateBasicUsage()
|
||||||
|
{
|
||||||
|
Console.WriteLine("=== 基本日志使用示例 ===");
|
||||||
|
|
||||||
|
// 1. 快速配置日志系统(默认Info级别)
|
||||||
|
Log.Configure(
|
||||||
|
minLevel: LogLevel.Info,
|
||||||
|
enableConsole: true,
|
||||||
|
useColors: true
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2. 使用全局日志
|
||||||
|
Log.Info("应用程序启动");
|
||||||
|
Log.Warn("这是一个警告");
|
||||||
|
Log.Error("这是一个错误信息");
|
||||||
|
|
||||||
|
// 3. 创建特定类别的日志记录器
|
||||||
|
var userLogger = Log.CreateLogger("UserService");
|
||||||
|
userLogger.Info("用户服务初始化完成", new { ServiceVersion = "1.0" });
|
||||||
|
|
||||||
|
var dbLogger = Log.CreateLogger("Database");
|
||||||
|
dbLogger.Debug("连接数据库", new { Server = "localhost", Database = "MyApp" });
|
||||||
|
dbLogger.Info("数据库连接成功");
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 演示高级日志配置
|
||||||
|
/// </summary>
|
||||||
|
public static void DemonstrateAdvancedConfiguration()
|
||||||
|
{
|
||||||
|
Console.WriteLine("=== 高级日志配置示例 ===");
|
||||||
|
|
||||||
|
// 创建详细的日志配置
|
||||||
|
var config = new LogConfig
|
||||||
|
{
|
||||||
|
DefaultMinLevel = LogLevel.Info,
|
||||||
|
EnableConsole = true,
|
||||||
|
UseColors = true,
|
||||||
|
EnableFile = true,
|
||||||
|
LogFilePath = "logs/example-{yyyy-MM-dd}.log"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 为不同模块设置不同的日志级别
|
||||||
|
config.SetCategoryLevel("Architecture", LogLevel.Info);
|
||||||
|
config.SetCategoryLevel("IOC", LogLevel.Debug);
|
||||||
|
config.SetCategoryLevel("Event", LogLevel.Info);
|
||||||
|
config.SetCategoryLevel("UserService", LogLevel.Debug);
|
||||||
|
config.SetCategoryLevel("Database", LogLevel.Debug);
|
||||||
|
config.SetCategoryLevel("Network", LogLevel.Trace); // 最详细的网络日志
|
||||||
|
|
||||||
|
// 初始化日志系统
|
||||||
|
Log.Initialize(config);
|
||||||
|
|
||||||
|
// 演示不同级别的日志记录
|
||||||
|
var networkLogger = Log.CreateLogger("Network");
|
||||||
|
networkLogger.Trace("网络请求开始", new { Url = "https://api.example.com/users", Method = "GET" });
|
||||||
|
networkLogger.Debug("添加请求头", new { Headers = new[] { "Authorization: Bearer xxx", "Content-Type: application/json" } });
|
||||||
|
networkLogger.Info("网络请求完成", new { StatusCode = 200, ResponseTime = "120ms" });
|
||||||
|
|
||||||
|
var userServiceLogger = Log.CreateLogger("UserService");
|
||||||
|
userServiceLogger.Debug("查询用户信息", new { UserId = 123 });
|
||||||
|
userServiceLogger.Info("用户登录成功", new { UserId = 123, UserName = "张三", LoginTime = DateTime.Now });
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 演示在框架组件中使用日志
|
||||||
|
/// </summary>
|
||||||
|
public static void DemonstrateFrameworkLogging()
|
||||||
|
{
|
||||||
|
Console.WriteLine("=== 框架组件日志示例 ===");
|
||||||
|
|
||||||
|
// 配置日志系统
|
||||||
|
Log.Configure(
|
||||||
|
minLevel: LogLevel.Info,
|
||||||
|
enableConsole: true,
|
||||||
|
useColors: true
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建示例架构
|
||||||
|
var architecture = ExampleArchitecture.Instance;
|
||||||
|
|
||||||
|
Console.WriteLine($"架构当前阶段: {architecture.CurrentPhase}");
|
||||||
|
|
||||||
|
// 注册组件(会自动记录日志)
|
||||||
|
architecture.RegisterSystem(new ExampleSystem());
|
||||||
|
architecture.RegisterModel(new ExampleModel());
|
||||||
|
architecture.RegisterUtility(new ExampleUtility());
|
||||||
|
|
||||||
|
// 发送事件(会自动记录日志)
|
||||||
|
architecture.SendEvent(new ExampleEvent { Message = "框架日志示例事件" });
|
||||||
|
|
||||||
|
// 注册事件监听器(会自动记录日志)
|
||||||
|
architecture.RegisterEvent<ExampleEvent>(evt =>
|
||||||
|
{
|
||||||
|
Log.CreateLogger("EventListener").Info($"收到事件: {evt.Message}");
|
||||||
|
});
|
||||||
|
|
||||||
|
// 再次发送事件
|
||||||
|
architecture.SendEvent(new ExampleEvent { Message = "框架日志示例事件2" });
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 演示异常日志记录
|
||||||
|
/// </summary>
|
||||||
|
public static void DemonstrateExceptionLogging()
|
||||||
|
{
|
||||||
|
Console.WriteLine("=== 异常日志记录示例 ===");
|
||||||
|
|
||||||
|
Log.Configure(LogLevel.Debug, enableConsole: true, useColors: true);
|
||||||
|
|
||||||
|
var serviceLogger = Log.CreateLogger("UserService");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 模拟业务逻辑中的异常
|
||||||
|
throw new InvalidOperationException("用户数据验证失败");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
serviceLogger.Error("用户注册失败", ex, new
|
||||||
|
{
|
||||||
|
Operation = "UserRegistration",
|
||||||
|
UserEmail = "user@example.com",
|
||||||
|
ValidationErrors = new[] { "邮箱格式无效", "密码强度不足" }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 演示Fatal级别的使用
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw new SystemException("数据库连接完全中断");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
serviceLogger.Fatal("系统发生致命错误", ex, new
|
||||||
|
{
|
||||||
|
ErrorCode = "DB_CONNECTION_FAILED",
|
||||||
|
RetryAttempts = 3,
|
||||||
|
LastRetryTime = DateTime.Now.AddMinutes(-5)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 演示生产环境日志配置
|
||||||
|
/// </summary>
|
||||||
|
public static void DemonstrateProductionConfiguration()
|
||||||
|
{
|
||||||
|
Console.WriteLine("=== 生产环境日志配置示例 ===");
|
||||||
|
|
||||||
|
// 生产环境推荐配置
|
||||||
|
var productionConfig = new LogConfig
|
||||||
|
{
|
||||||
|
DefaultMinLevel = LogLevel.Info, // 只记录Info及以上级别
|
||||||
|
EnableConsole = false, // 生产环境通常不输出到控制台
|
||||||
|
UseColors = false,
|
||||||
|
EnableFile = true, // 启用文件日志
|
||||||
|
LogFilePath = "logs/production-{yyyy-MM-dd}.log"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 为关键模块设置更详细的日志级别
|
||||||
|
productionConfig.SetCategoryLevel("Architecture", LogLevel.Info);
|
||||||
|
productionConfig.SetCategoryLevel("Security", LogLevel.Debug); // 安全相关日志更详细
|
||||||
|
productionConfig.SetCategoryLevel("Payment", LogLevel.Debug); // 支付相关日志更详细
|
||||||
|
productionConfig.SetCategoryLevel("IOC", LogLevel.Warning); // 减少IOC调试日志
|
||||||
|
|
||||||
|
Log.Initialize(productionConfig);
|
||||||
|
|
||||||
|
var securityLogger = Log.CreateLogger("Security");
|
||||||
|
securityLogger.Info("用户登录尝试", new { UserId = 456, IpAddress = "192.168.1.100" });
|
||||||
|
securityLogger.Warn("密码错误", new { UserId = 456, FailedAttempts = 2 });
|
||||||
|
securityLogger.Info("登录成功", new { UserId = 456, SessionId = "sess_abc123" });
|
||||||
|
|
||||||
|
var paymentLogger = Log.CreateLogger("Payment");
|
||||||
|
paymentLogger.Debug("开始处理支付", new { OrderId = "ORD_789", Amount = 99.99m, Currency = "CNY" });
|
||||||
|
paymentLogger.Info("支付成功", new { OrderId = "ORD_789", TransactionId = "txn_456" });
|
||||||
|
|
||||||
|
Console.WriteLine("生产环境日志已配置完成,日志文件将保存到 logs/ 目录");
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 示例架构类
|
||||||
|
/// </summary>
|
||||||
|
public class ExampleArchitecture : Architecture<ExampleArchitecture>
|
||||||
|
{
|
||||||
|
protected override void Init()
|
||||||
|
{
|
||||||
|
Log.CreateLogger("Architecture").Info("ExampleArchitecture 初始化");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 示例系统
|
||||||
|
/// </summary>
|
||||||
|
public class ExampleSystem : AbstractSystem
|
||||||
|
{
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
Log.CreateLogger("System").Info("ExampleSystem 初始化完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDestroy()
|
||||||
|
{
|
||||||
|
Log.CreateLogger("System").Info("ExampleSystem 销毁");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 示例模型
|
||||||
|
/// </summary>
|
||||||
|
public class ExampleModel : AbstractModel
|
||||||
|
{
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
Log.CreateLogger("Model").Info("ExampleModel 初始化完成");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 示例工具
|
||||||
|
/// </summary>
|
||||||
|
public class ExampleUtility : IUtility
|
||||||
|
{
|
||||||
|
public void DoSomething()
|
||||||
|
{
|
||||||
|
Log.CreateLogger("Utility").Debug("ExampleUtility 执行操作");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 示例事件
|
||||||
|
/// </summary>
|
||||||
|
public class ExampleEvent
|
||||||
|
{
|
||||||
|
public string Message { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
@ -20,5 +20,12 @@ internal sealed class NullLogger : ILog
|
|||||||
/// <param name="level">要检查的日志级别</param>
|
/// <param name="level">要检查的日志级别</param>
|
||||||
/// <returns>始终返回 false,表示所有日志级别都被禁用</returns>
|
/// <returns>始终返回 false,表示所有日志级别都被禁用</returns>
|
||||||
public bool IsEnabled(LogLevel level) => false;
|
public bool IsEnabled(LogLevel level) => false;
|
||||||
}
|
|
||||||
|
|
||||||
|
// 快捷方法实现(空实现)
|
||||||
|
public void Info(string msg, object? ctx = null) { }
|
||||||
|
public void Error(string msg, Exception? ex = null, object? ctx = null) { }
|
||||||
|
public void Debug(string msg, object? ctx = null) { }
|
||||||
|
public void Trace(string msg, object? ctx = null) { }
|
||||||
|
public void Warn(string msg, object? ctx = null) { }
|
||||||
|
public void Fatal(string msg, object? ctx = null) { }
|
||||||
|
}
|
||||||
|
|||||||
207
GFramework.Core/logging/README.md
Normal file
207
GFramework.Core/logging/README.md
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
# GFramework.Core 日志系统
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
GFramework.Core 提供了一个灵活、可配置的日志系统,支持多级别、多类别和多种输出方式的日志记录。默认日志级别为 `Info`,确保框架的关键操作都能被记录下来。
|
||||||
|
|
||||||
|
## 主要特性
|
||||||
|
|
||||||
|
- **多级别日志支持**: Trace、Debug、Info、Warning、Error、Fatal
|
||||||
|
- **类别化日志**: 支持按模块分类记录日志
|
||||||
|
- **可配置输出**: 支持控制台输出和文件输出
|
||||||
|
- **彩色控制台输出**: 提供不同级别的颜色区分
|
||||||
|
- **灵活的级别控制**: 可全局设置或按类别设置不同的日志级别
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 1. 基本配置
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using GFramework.Core.logging;
|
||||||
|
|
||||||
|
// 快速配置(推荐)
|
||||||
|
Log.Configure(
|
||||||
|
minLevel: LogLevel.Info, // 默认级别为Info
|
||||||
|
enableConsole: true, // 启用控制台输出
|
||||||
|
useColors: true, // 使用彩色输出
|
||||||
|
enableFile: false, // 不启用文件输出
|
||||||
|
logFilePath: null // 无文件输出
|
||||||
|
);
|
||||||
|
|
||||||
|
// 或者使用详细的配置
|
||||||
|
var config = new LogConfig
|
||||||
|
{
|
||||||
|
DefaultMinLevel = LogLevel.Info,
|
||||||
|
EnableConsole = true,
|
||||||
|
UseColors = true,
|
||||||
|
EnableFile = true,
|
||||||
|
LogFilePath = "logs/gframework.log"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置特定模块的日志级别
|
||||||
|
config.SetCategoryLevel("Architecture", LogLevel.Debug);
|
||||||
|
config.SetCategoryLevel("IOC", LogLevel.Debug);
|
||||||
|
config.SetCategoryLevel("Event", LogLevel.Info);
|
||||||
|
|
||||||
|
Log.Initialize(config);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 使用日志记录
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// 使用全局日志实例
|
||||||
|
Log.Info("应用程序启动完成");
|
||||||
|
Log.Warn("这是一个警告信息");
|
||||||
|
Log.Error("这是一个错误信息", exception);
|
||||||
|
|
||||||
|
// 创建特定类别的日志记录器
|
||||||
|
var logger = Log.CreateLogger("MyModule");
|
||||||
|
|
||||||
|
logger.Debug("调试信息:连接数据库");
|
||||||
|
logger.Info("用户登录成功", new { UserId = 123, UserName = "张三" });
|
||||||
|
logger.Warn("连接超时,正在重试", new { RetryCount = 2 });
|
||||||
|
logger.Error("数据库连接失败", ex, new { DatabaseUrl = "localhost:1433" });
|
||||||
|
logger.Fatal("系统发生严重错误", new { SystemState = "Critical" });
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 高级配置
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// 创建自定义配置的日志记录器
|
||||||
|
var config = new LogConfig
|
||||||
|
{
|
||||||
|
DefaultMinLevel = LogLevel.Warning, // 默认只显示Warning及以上
|
||||||
|
EnableConsole = true,
|
||||||
|
UseColors = true,
|
||||||
|
EnableFile = true,
|
||||||
|
LogFilePath = "logs/app-{yyyy-MM-dd}.log"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 为不同模块设置不同的日志级别
|
||||||
|
config.SetCategoryLevel("Architecture", LogLevel.Info); // 架构信息
|
||||||
|
config.SetCategoryLevel("IOC", LogLevel.Debug); // IOC详细日志
|
||||||
|
config.SetCategoryLevel("Event", LogLevel.Info); // 事件日志
|
||||||
|
config.SetCategoryLevel("System", LogLevel.Info); // 系统日志
|
||||||
|
config.SetCategoryLevel("Database", LogLevel.Debug); // 数据库日志
|
||||||
|
config.SetCategoryLevel("Network", LogLevel.Trace); // 网络日志(最详细)
|
||||||
|
|
||||||
|
Log.Initialize(config);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 日志级别说明
|
||||||
|
|
||||||
|
- **Trace**: 最详细的跟踪信息,用于调试复杂的执行流程
|
||||||
|
- **Debug**: 调试信息,用于开发和测试阶段
|
||||||
|
- **Info**: 一般信息,记录重要的业务流程和系统状态
|
||||||
|
- **Warning**: 警告信息,可能的问题但不中断程序执行
|
||||||
|
- **Error**: 错误信息,影响功能但不致命
|
||||||
|
- **Fatal**: 致命错误,导致程序无法继续运行
|
||||||
|
|
||||||
|
## 框架内部日志
|
||||||
|
|
||||||
|
GFramework.Core 在以下关键位置自动添加了日志记录:
|
||||||
|
|
||||||
|
### 架构模块 (Architecture)
|
||||||
|
- 架构初始化流程
|
||||||
|
- 组件注册和初始化
|
||||||
|
- 生命周期阶段变更
|
||||||
|
- 模块安装和卸载
|
||||||
|
|
||||||
|
### IOC容器 (IOC)
|
||||||
|
- 对象注册和获取
|
||||||
|
- 容器冻结操作
|
||||||
|
- 重复注册检测
|
||||||
|
|
||||||
|
### 事件系统 (Event)
|
||||||
|
- 事件发送和接收
|
||||||
|
- 事件处理器注册和注销
|
||||||
|
|
||||||
|
### 系统模块 (System)
|
||||||
|
- 系统初始化和销毁
|
||||||
|
- 组件生命周期管理
|
||||||
|
|
||||||
|
## 输出格式
|
||||||
|
|
||||||
|
### 控制台输出示例
|
||||||
|
```
|
||||||
|
[2025-12-23 12:34:56.789] INFO Architecture Architecture initialized
|
||||||
|
[2025-12-23 12:34:56.790] INFO Architecture Initializing 3 systems
|
||||||
|
[2025-12-23 12:34:56.791] DEBUG Architecture Initializing system: GameSystem
|
||||||
|
[2025-12-23 12:34:56.792] INFO Architecture System registered: GameSystem
|
||||||
|
[2025-12-23 12:34:56.793] INFO Architecture Architecture is ready - all components initialized
|
||||||
|
```
|
||||||
|
|
||||||
|
### 日志输出级别颜色
|
||||||
|
- **Trace**: 灰色
|
||||||
|
- **Debug**: 青色
|
||||||
|
- **Info**: 白色
|
||||||
|
- **Warning**: 黄色
|
||||||
|
- **Error**: 红色
|
||||||
|
- **Fatal**: 洋红色
|
||||||
|
|
||||||
|
## 最佳实践
|
||||||
|
|
||||||
|
1. **使用合适的日志级别**:
|
||||||
|
- 使用 `Info` 记录重要业务流程
|
||||||
|
- 使用 `Debug` 记录调试信息
|
||||||
|
- 使用 `Warning` 记录异常情况
|
||||||
|
- 使用 `Error` 记录错误但不影响程序运行
|
||||||
|
- 使用 `Fatal` 记录严重错误
|
||||||
|
|
||||||
|
2. **提供上下文信息**:
|
||||||
|
```csharp
|
||||||
|
Log.Info("用户登录成功", new { UserId = userId, UserName = userName });
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **异常日志记录**:
|
||||||
|
```csharp
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 业务逻辑
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("数据库操作失败", ex, new { Operation = "InsertUser", UserId = userId });
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **分类使用日志**:
|
||||||
|
```csharp
|
||||||
|
var dbLogger = Log.CreateLogger("Database");
|
||||||
|
var netLogger = Log.CreateLogger("Network");
|
||||||
|
|
||||||
|
dbLogger.Info("查询用户数据");
|
||||||
|
netLogger.Debug("发送HTTP请求");
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置建议
|
||||||
|
|
||||||
|
### 开发环境
|
||||||
|
```csharp
|
||||||
|
Log.Configure(
|
||||||
|
minLevel: LogLevel.Debug,
|
||||||
|
enableConsole: true,
|
||||||
|
useColors: true,
|
||||||
|
enableFile: false
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 生产环境
|
||||||
|
```csharp
|
||||||
|
var config = new LogConfig
|
||||||
|
{
|
||||||
|
DefaultMinLevel = LogLevel.Info,
|
||||||
|
EnableConsole = false, // 生产环境通常不需要控制台输出
|
||||||
|
UseColors = false,
|
||||||
|
EnableFile = true,
|
||||||
|
LogFilePath = "logs/production-{yyyy-MM-dd}.log"
|
||||||
|
};
|
||||||
|
|
||||||
|
config.SetCategoryLevel("Architecture", LogLevel.Info);
|
||||||
|
config.SetCategoryLevel("IOC", LogLevel.Warning); // 减少IOC日志
|
||||||
|
config.SetCategoryLevel("Event", LogLevel.Info);
|
||||||
|
|
||||||
|
Log.Initialize(config);
|
||||||
|
```
|
||||||
|
|
||||||
|
通过这个日志系统,你可以全面追踪GFramework.Core的执行过程,快速定位问题,并监控应用程序的运行状态。
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using GFramework.Core.architecture;
|
using GFramework.Core.architecture;
|
||||||
|
using GFramework.Core.logging;
|
||||||
using GFramework.Core.rule;
|
using GFramework.Core.rule;
|
||||||
|
|
||||||
namespace GFramework.Core.system;
|
namespace GFramework.Core.system;
|
||||||
@ -34,7 +35,12 @@ public abstract class AbstractSystem : ISystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void ISystem.Init()
|
void ISystem.Init()
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("System");
|
||||||
|
logger.Debug($"Initializing system: {GetType().Name}");
|
||||||
|
|
||||||
OnInit();
|
OnInit();
|
||||||
|
|
||||||
|
logger.Info($"System initialized: {GetType().Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -42,7 +48,12 @@ public abstract class AbstractSystem : ISystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void ISystem.Destroy()
|
void ISystem.Destroy()
|
||||||
{
|
{
|
||||||
|
var logger = Log.CreateLogger("System");
|
||||||
|
logger.Debug($"Destroying system: {GetType().Name}");
|
||||||
|
|
||||||
OnDestroy();
|
OnDestroy();
|
||||||
|
|
||||||
|
logger.Info($"System destroyed: {GetType().Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -46,4 +46,34 @@ public sealed class GodotLogger : ILog
|
|||||||
/// <param name="level">日志级别</param>
|
/// <param name="level">日志级别</param>
|
||||||
/// <returns>始终返回 true</returns>
|
/// <returns>始终返回 true</returns>
|
||||||
public bool IsEnabled(LogLevel level) => true;
|
public bool IsEnabled(LogLevel level) => true;
|
||||||
|
|
||||||
|
public void Info(string msg, object? ctx = null)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string msg, Exception? ex = null, object? ctx = null)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Debug(string msg, object? ctx = null)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Trace(string msg, object? ctx = null)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warn(string msg, object? ctx = null)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Fatal(string msg, object? ctx = null)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user