using System.Diagnostics;
|
using System.Runtime.CompilerServices;
|
using KH.WMS.Core.Logging.LogEnums;
|
|
namespace KH.WMS.Core.Logging;
|
|
/// <summary>
|
/// 日志模块自动识别器
|
/// </summary>
|
public static class LogModuleDetector
|
{
|
/// <summary>
|
/// 模块命名空间映射配置
|
/// </summary>
|
private static readonly Dictionary<string, LogModule> NamespaceModuleMapping = new(StringComparer.OrdinalIgnoreCase)
|
{
|
// 基础设施层
|
["KH.WMS.Core.Api"] = LogModule.Api,
|
["KH.WMS.Core.Database"] = LogModule.Database,
|
["KH.WMS.Core.Cache"] = LogModule.Cache,
|
["KH.WMS.Core.Authentication"] = LogModule.Auth,
|
["KH.WMS.Core.Security"] = LogModule.Auth,
|
["KH.WMS.Core.Middleware"] = LogModule.Core,
|
["KH.WMS.Core.BackgroundServices"] = LogModule.Job,
|
["KH.WMS.Core.Logging"] = LogModule.Core,
|
|
// WMS 业务层 - 入库管理
|
["KH.WMS.Core.Inbound"] = LogModule.WMS_Inbound,
|
["KH.WMS.Core.Receiving"] = LogModule.WMS_Inbound,
|
["KH.WMS.Core.PutAway"] = LogModule.WMS_Inbound,
|
["KH.WMS.Core.Quality"] = LogModule.WMS_Inbound,
|
|
// WMS 业务层 - 出库管理
|
["KH.WMS.Core.Outbound"] = LogModule.WMS_Outbound,
|
["KH.WMS.Core.Picking"] = LogModule.WMS_Picking,
|
["KH.WMS.Core.Packing"] = LogModule.WMS_Outbound,
|
["KH.WMS.Core.Shipping"] = LogModule.WMS_Outbound,
|
["KH.WMS.Core.Loading"] = LogModule.WMS_Loading,
|
|
// WMS 业务层 - 库存管理
|
["KH.WMS.Core.Inventory"] = LogModule.WMS_Inventory,
|
["KH.WMS.Core.Stock"] = LogModule.WMS_Inventory,
|
["KH.WMS.Core.Stocktaking"] = LogModule.WMS_Counting,
|
["KH.WMS.Core.Counting"] = LogModule.WMS_Counting,
|
|
// WMS 业务层 - 基础数据
|
["WMKH.WMS.CoreS.Owner"] = LogModule.WMS_Owner,
|
["KH.WMS.Core.Product"] = LogModule.WMS_Product,
|
["KH.WMS.Core.Sku"] = LogModule.WMS_Product,
|
["KH.WMS.Core.Warehouse"] = LogModule.WMS_Warehouse,
|
["KH.WMS.Core.Zone"] = LogModule.WMS_Zone,
|
["KH.WMS.Core.Location"] = LogModule.WMS_Location,
|
|
// WMS 业务层 - 其他
|
["KH.WMS.Core.Transfer"] = LogModule.WMS_Transfer,
|
["KH.WMS.Core.Move"] = LogModule.WMS_Transfer,
|
["KH.WMS.Core.Wave"] = LogModule.WMS_Wave,
|
["KH.WMS.Core.Unloading"] = LogModule.WMS_Unloading,
|
["KH.WMS.Core.Processing"] = LogModule.WMS_Processing,
|
["KH.WMS.Core.Replenishment"] = LogModule.WMS_Replenishment,
|
["KH.WMS.Core.Strategy"] = LogModule.WMS_Strategy,
|
["KH.WMS.Core.Order"] = LogModule.WMS_Order,
|
["KH.WMS.Core.Transport"] = LogModule.WMS_Transport,
|
["KH.WMS.Core.Billing"] = LogModule.WMS_Billing,
|
["KH.WMS.Core.Report"] = LogModule.WMS_Report,
|
|
// TODO
|
// 通用业务层
|
["Application.Services"] = LogModule.Business,
|
["Domain.Services"] = LogModule.Business,
|
["Core.Services"] = LogModule.Business,
|
|
// API 层
|
["Controllers"] = LogModule.Api,
|
["Api"] = LogModule.Api,
|
["Controllers.Api"] = LogModule.Api,
|
|
// 外部服务
|
["External"] = LogModule.External,
|
["ThirdParty"] = LogModule.External,
|
["Integration"] = LogModule.External,
|
|
// 文件处理
|
["File"] = LogModule.File,
|
["Storage"] = LogModule.File,
|
["Upload"] = LogModule.File,
|
["Download"] = LogModule.File,
|
};
|
|
/// <summary>
|
/// 从调用栈中自动识别模块
|
/// </summary>
|
/// <param name="skipFrames">跳过的帧数(默认跳过 LoggerService 内部调用)</param>
|
/// <returns>识别出的模块,默认返回 Core</returns>
|
public static LogModule DetectModule(int skipFrames = 2)
|
{
|
try
|
{
|
var stackTrace = new StackTrace(skipFrames, false);
|
|
for (int i = 0; i < stackTrace.FrameCount; i++)
|
{
|
var frame = stackTrace.GetFrame(i);
|
if (frame == null) continue;
|
|
var namespaceName = frame.GetMethod()?.DeclaringType?.Namespace;
|
if (string.IsNullOrEmpty(namespaceName)) continue;
|
|
// 跳过日志系统本身的命名空间
|
if (namespaceName.StartsWith("KH.WMS.Core.Logging", StringComparison.OrdinalIgnoreCase) ||
|
namespaceName.StartsWith("Microsoft.Extensions.Logging", StringComparison.OrdinalIgnoreCase))
|
{
|
continue;
|
}
|
|
// 查找匹配的模块
|
var module = FindModuleByNamespace(namespaceName);
|
if (module != LogModule.Core)
|
{
|
return module;
|
}
|
}
|
|
return LogModule.Core;
|
}
|
catch
|
{
|
return LogModule.Core;
|
}
|
}
|
|
/// <summary>
|
/// 根据命名空间查找对应的模块
|
/// </summary>
|
private static LogModule FindModuleByNamespace(string namespaceName)
|
{
|
// 完全匹配
|
if (NamespaceModuleMapping.TryGetValue(namespaceName, out var module))
|
{
|
return module;
|
}
|
|
// 前缀匹配
|
foreach (var mapping in NamespaceModuleMapping)
|
{
|
if (namespaceName.StartsWith(mapping.Key, StringComparison.OrdinalIgnoreCase))
|
{
|
return mapping.Value;
|
}
|
}
|
|
// 默认返回业务模块
|
if (namespaceName.Contains("Service", StringComparison.OrdinalIgnoreCase) ||
|
namespaceName.Contains("Domain", StringComparison.OrdinalIgnoreCase) ||
|
namespaceName.Contains("Application", StringComparison.OrdinalIgnoreCase))
|
{
|
return LogModule.Business;
|
}
|
|
return LogModule.Core;
|
}
|
|
/// <summary>
|
/// 从类型推断模块
|
/// </summary>
|
public static LogModule DetectModuleFromType(Type type)
|
{
|
if (type == null) return LogModule.Core;
|
|
var namespaceName = type.Namespace;
|
return string.IsNullOrEmpty(namespaceName) ? LogModule.Core : FindModuleByNamespace(namespaceName);
|
}
|
|
/// <summary>
|
/// 添加自定义命名空间映射
|
/// </summary>
|
/// <param name="namespacePrefix">命名空间前缀</param>
|
/// <param name="module">对应的模块</param>
|
public static void AddMapping(string namespacePrefix, LogModule module)
|
{
|
NamespaceModuleMapping[namespacePrefix] = module;
|
}
|
|
/// <summary>
|
/// 批量添加命名空间映射
|
/// </summary>
|
public static void AddMappings(Dictionary<string, LogModule> mappings)
|
{
|
foreach (var mapping in mappings)
|
{
|
NamespaceModuleMapping[mapping.Key] = mapping.Value;
|
}
|
}
|
}
|