菜的像徐坤
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

nlog 设置全局变量

1597人阅读 2023/11/30 11:19 总访问:865406 评论:0 收藏:0 手机
分类: Csharp

前言

在使用nlog 记录日志时,需要在配置文件传递许多通用的参数,比如人员信息,IP,端口等等这些常用且通用的参数,但是又不想去每次记录日志时都去传递这些参数。
因此可以把他设置为nlog的全局变量,在配置文件中仅仅只需要将需要记录的信息使用  ${username} 这样的方式来直接使用

新增全局变量注入类

 public class NKLayoutRenderer
    {
        /// <summary>
        /// 注册Nlog全局变量
        /// </summary>
        public static void RegisterLogGlobalParameters()
        {
            // 获取当前程序集中所有类型
            var allTypes = Assembly.GetExecutingAssembly().GetTypes().ToList();
            // 获取当前命名空间名称
            var currentNamespace = typeof(NKLayoutRenderer).Namespace;
            // 查找带有指定标签的类
            var matchingTypes = allTypes.Where(t => t.Namespace == currentNamespace && t.GetCustomAttributes(typeof(LayoutRendererAttribute), true).Length > 0)
                .ToList();
            foreach (var type in matchingTypes)
            {
                //创建对应实例
                var layoutRenderer = Activator.CreateInstance(type);
                //获取标签中的参数
                var attribute = type.GetCustomAttribute<LayoutRendererAttribute>();
                //获取LayoutRenderer中注册全局变量的方法
                var methodInfo = typeof(LayoutRenderer).GetMethod("Register", new Type[] { typeof(string) });
                // 创建泛型类型参数数组
                var typeArguments = new Type[] { type };
                // 为泛型方法提供类型参数
                var genericMethod = methodInfo.MakeGenericMethod(typeArguments);
                // 调用泛型方法,注册日志全局变量
                genericMethod.Invoke(layoutRenderer, new object[]
                {
                    attribute.Name
                });
            }
        }
    }
    //日志记录地址
    [LayoutRenderer("LogRootPath")]
    public class LogRootPathLayoutRenderer : LayoutRenderer
    {
        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            var path = GlobalContext.SystemConfig.LogRootPath ?? "/app/log/";
            builder.Append(path);
        }
    }
    //用户名
    [LayoutRenderer("UserName")]
    public class UserNameLayoutRenderer : LayoutRenderer
    {
        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            var user = GlobalContext.ServiceProvider.GetCurrentUser();
            builder.Append(user?.Name);
        }
    }
 }

根据自身项目,修改和扩展需要传递的参数,一般只传递通用参数
然后在去注入一下

   /// <summary>
        /// 注册Nlog全局变量
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddNLogLayoutRenderer(this IServiceCollection services)
        {
            NKLayoutRenderer.RegisterLogGlobalParameters();
            return services;
        }

完成后,在nlog 配置文件中就可以直接使用 ${UserName}和${LogRootPath}


那么如何单独传递某一个参数呢?假设,我需要记录一个登录日志,需要传递一个登录名,和密码。
这个登录名仅仅只在登录日志中使用到了,所以就不建议做成全局的,只需要在记录登录日志的地方,单独的将登录名传递给nlog

 //单独设置某一个参数
 LogManager.Configuration.Variables["LoginName"] ="张三";

然后,配置文件中需要通过${var:LoginName} 来获取对应的参数
类似于这样



如果是LogManager 的配置为空或者报错,请先检查你的nlog 是否成功注册,上述例子。必须在nlog 注册之后才能正常使用。
也就是下边这段代码之后

 //加载nlog 配置文件
 LogManager.LoadConfiguration("nlog配置文件地址");


评价