[walkthrough] 在Asp.net MVC6 RC里使用NLog,并且把配置集成到config.json

说明一下:本文基于随visual studio 2015 RC公开的DNX1.0.0-beta4,git上最新的aspnet的开发版本已经发生了很大变化。

首先,理论部分看[汤姆大叔的博客] 解读ASP.NET 5 & MVC6系列(9):日志框架

实际上aspnet的开发人员已经在最近版的系统里开始集成nlog了。 本文的目的主要帮助大家理解aspnet mvc 6的框架。

新建工程 "NlogTest"

选“asp.net 5”的”web site”,  然后不要认证模块,我们主要演示NLog的用法,对auth认证没兴趣。

◎添加Nlog参照

打开project.json, 添加 NLog,同时删除dnxcore50,Nlog还没有支持coreclr,所以先删了。

修改frameworks部分,修改后的样子。

 "frameworks": {
    "dnx451": {
      "dependencies": { "NLog": "3.2.0" }
    }
  },

◎添加nlog的配置到config.json里,5行以下为本次追加内容。

 1 {
 2   "AppSettings": {
 3     "SiteTitle": "NLogTest"
 4   },
 5   "nlog": {
 6     "targets": {
 7       "file": {
 8         "type": "File",
 9         "layout": "${date:format=HH\\:MM\\:ss} ${logger} ${message}",
10         "fileName": "c:\\work\\aaa.txt"
11       },
12       "file2": {
13         "type": "File",
14         "fileName": "c:\\work\\bbb.txt"
15       }
16       "mail1": {
17
18       }
19     },
20     "rules": {
21       "rule1": {
22         "minlevel": "Debug",
23         "writeTo": "file"
24       },
25       "rule2": {
26         "name": "*",
27         "minlevel": "Info",
28         "writeTo": "file2"
29       }
30     }
31   }
32 }

配置到此为止,下面开始编程。

◎添加一个NLogProvider类, 实现ILoggerProvider并在其内部实现ILogger

先上代码,我是微软的实现中搬过来的,做了一些修改。

 1 using Microsoft.Framework.Logging;
 2 using System;
 3
 4 namespace NLogTest
 5 {
 6     public class NLogProvider:ILoggerProvider
 7     {
 8         private readonly global::NLog.LogFactory _logFactory;
 9
10         public NLogProvider(global::NLog.LogFactory logFactory)
11         {
12             _logFactory = logFactory;
13         }
14
15         public ILogger CreateLogger(string name)
16         {
17             return new Logger(_logFactory.GetLogger(name));
18         }
19
20         private class Logger : ILogger
21         {
22             private readonly global::NLog.Logger _logger;
23
24             public Logger(global::NLog.Logger logger)
25             {
26                 _logger = logger;
27             }
28
29             public IDisposable BeginScope(object state)
30             {
31                 return global::NLog.NestedDiagnosticsContext.Push(state.ToString());
32             }
33
34             public bool IsEnabled(LogLevel logLevel)
35             {
36                 return _logger.IsEnabled(GetLogLevel(logLevel));
37             }
38
39             public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
40             {
41                 var nLogLogLevel = GetLogLevel(logLevel);
42                 var message = string.Empty;
43                 if (formatter != null)
44                 {
45                     message = formatter(state, exception);
46                 }
47                 else
48                 {
49                     message = LogFormatter.Formatter(state, exception);
50                 }
51
52                 if (!string.IsNullOrEmpty(message))
53                 {
54                     var eventInfo = global::NLog.LogEventInfo.Create(nLogLogLevel, _logger.Name, message);
55                     eventInfo.Properties["EventId"] = eventId;
56                     _logger.Log(eventInfo);
57                 }
58             }
59
60             private global::NLog.LogLevel GetLogLevel(LogLevel logLevel)
61             {
62                 switch (logLevel)
63                 {
64                     case LogLevel.Verbose: return global::NLog.LogLevel.Debug;
65                     case LogLevel.Information: return global::NLog.LogLevel.Info;
66                     case LogLevel.Warning: return global::NLog.LogLevel.Warn;
67                     case LogLevel.Error: return global::NLog.LogLevel.Error;
68                     case LogLevel.Critical: return global::NLog.LogLevel.Fatal;
69                 }
70                 return global::NLog.LogLevel.Debug;
71             }
72         }
73     }
74 }

代码很简单,就是在微软的日志框架和NLog的函数间实现一个桥接。

◎添加一个NLogLoggerFactoryExtensions类,追加ILoggerFactory的扩张函数,这里是本次演示的重点了。

using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.Logging;
using System;
using System.Linq;
using System.Text;

namespace NLogTest
{
    public static  class NLogLoggerFactoryExtensions
    {
        public static ILoggerFactory AddNLog(
                this ILoggerFactory factory,
                IConfiguration configuration)
        {
            var config = new global::NLog.Config.LoggingConfiguration();

            var targets = configuration.GetSubKey("targets");

            foreach (var item in targets.GetSubKeys())
            {
                AddTargets(config, item.Key, item.Value);
            }

            var rules = configuration.GetSubKey("rules");
            foreach (var item in rules.GetSubKeys())
            {
                AddLoggingRule(config, item.Value);
            }

            factory.AddProvider(new NLogProvider(new global::NLog.LogFactory(config)));
            return factory;
        }

        private static void AddTargets(global::NLog.Config.LoggingConfiguration configuration, string targetName, IConfiguration targetConf)
        {
            string targetType = "";
            if (targetConf.TryGet("type", out targetType))
            {
                switch (targetType.ToLower())
                {
                    case "file":
                        configuration.AddTarget(targetName, GenFileTarget(targetName, targetConf));
                        break;
                    case "mail":
                        configuration.AddTarget(targetName, GenMailTarget(targetName, targetConf));
                        break;
                    default:
                        break;
                }
            }
        }

        private static global::NLog.Targets.Target GenFileTarget(string targetName, IConfiguration targetConf)
        {
            var fileTarget = new global::NLog.Targets.FileTarget();
            fileTarget.Name = targetName;

            string confVal = GetVal(targetConf, "fileName");
            if (string.IsNullOrEmpty(confVal))
            {
                //Filename is not setting , throw exception!
                throw new ArgumentNullException("fileTarget‘s filename is empty.");
            }

            fileTarget.FileName = confVal;

            confVal = GetVal(targetConf, "layout");
            if (!string.IsNullOrEmpty(confVal))
            {
                fileTarget.Layout = confVal;
            }

            confVal = GetVal(targetConf, "keepfileopen");
            if (!string.IsNullOrEmpty(confVal))
            {
                fileTarget.KeepFileOpen = (confVal.ToLower() == "true");
            }

            confVal = GetVal(targetConf, "encoding");
            if (!string.IsNullOrEmpty(confVal))
            {
                fileTarget.Encoding = Encoding.GetEncoding(confVal);
            }

            fileTarget.AutoFlush = true;

            return fileTarget;
        }

        private static global::NLog.Targets.Target GenMailTarget(string targetName, IConfiguration targetConf)
        {
            var mailTarget = new global::NLog.Targets.MailTarget();
            mailTarget.Name = targetName;

            string confVal = GetVal(targetConf, "to");
            if (string.IsNullOrEmpty(confVal))
            {
                //to is not setting , throw exception!
                throw new ArgumentNullException("mailTarget‘s [to] is empty.");
            }

            mailTarget.To = confVal;

            confVal = GetVal(targetConf, "from");
            if (string.IsNullOrEmpty(confVal))
            {
                //to is not setting , throw exception!
                throw new ArgumentNullException("mailTarget‘s [from] is empty.");
            }

            mailTarget.From = confVal;

            confVal = GetVal(targetConf, "layout");
            if (!string.IsNullOrEmpty(confVal))
            {
                mailTarget.Layout = confVal;
            }

            confVal = GetVal(targetConf, "subject");
            if (!string.IsNullOrEmpty(confVal))
            {
                mailTarget.Subject = confVal;
            }

            confVal = GetVal(targetConf, "smtpusername");
            if (!string.IsNullOrEmpty(confVal))
            {
                mailTarget.SmtpUserName = confVal;
            }
            confVal = GetVal(targetConf, "smtppassword");
            if (!string.IsNullOrEmpty(confVal))
            {
                mailTarget.SmtpPassword = confVal;
            }

            confVal = GetVal(targetConf, "smtpserver");
            if (!string.IsNullOrEmpty(confVal))
            {
                mailTarget.SmtpServer = confVal;
            }

            confVal = GetVal(targetConf, "smtpport");
            if (!string.IsNullOrEmpty(confVal))
            {
                int nPort = 25;
                if (int.TryParse(confVal, out nPort))
                {
                    mailTarget.SmtpPort = nPort;
                }
            }

            return mailTarget;
        }

        private static void AddLoggingRule(global::NLog.Config.LoggingConfiguration configuration, IConfiguration ruleConf)
        {
            string namePattern = "*";
            string confVal = GetVal(ruleConf, " name");
            if (!string.IsNullOrEmpty(confVal))
            {
                namePattern = confVal;
            }

            confVal = GetVal(ruleConf, "minlevel");
            global::NLog.LogLevel minLevel = global::NLog.LogLevel.Debug;
            if (!string.IsNullOrEmpty(confVal))
            {
                minLevel = GetLogLevel(confVal, global::NLog.LogLevel.Trace);
            }

            confVal = GetVal(ruleConf, "writeto");
            global::NLog.Targets.Target target = null;
            if (!string.IsNullOrEmpty(confVal))
            {
                target = configuration.ConfiguredNamedTargets.Where(t => t.Name == confVal).FirstOrDefault();
            }

            if (target != null)
            {
                configuration.LoggingRules.Add(new global::NLog.Config.LoggingRule(namePattern, minLevel, target));
            }
        }

        private static string GetVal(IConfiguration configuration, string key)
        {
            string val = "";
            if (configuration.TryGet(key, out val))
            {
                return val;
            }
            else
            {
                return null;
            }
        }

        private static global::NLog.LogLevel GetLogLevel(string logLevel, global::NLog.LogLevel defaultLevel = null)
        {
            switch (logLevel.ToLower())
            {
                case "debug": return global::NLog.LogLevel.Debug;
                case "info": return global::NLog.LogLevel.Info;
                case "warn": return global::NLog.LogLevel.Warn;
                case "error": return global::NLog.LogLevel.Error;
                case "fatal": return global::NLog.LogLevel.Fatal;
            }
            return defaultLevel;
        }
    }
}

实例化Nlog.LogFactory类,并从config里读取的配置,设置到该LogFactory里。

下面是NLog的使用了。

◎打开 Startup.cs文件,并在Configure函数里AddLog。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
        {
            // Configure the HTTP request pipeline.

            // Add the console logger.
            loggerfactory.AddConsole();

            //Add the NLog logger
            loggerfactory.AddNLog(Configuration.GetSubKey("nlog"));

            //Log Output Test.
            var logger = loggerfactory.CreateLogger("NLogTest");
            logger.LogInformation("this is infomation from startup");

            try
            {
                var i = 100 - 100;
                var j = 100 / i;
            }
            catch (DivideByZeroException ex)
            {
                logger.LogError("error log test", ex);
            }

           。。。。。。。。。。以下略

        }

◎在Controller里使用

打开HomeController.cs文件,并追加代码。

public class HomeController : Controller
    {
        private ILogger _logger = null;

        public HomeController(ILoggerFactory logFactory)
        {
            _logger = logFactory.CreateLogger(nameof(HomeController));

            _logger.LogWarning("I am created.");
        }

        public IActionResult Index()
        {
            _logger.LogWarning("hello from index of home control... ");
            return View();
        }
    ???????????以下略
  }

编译通过后,F5一下,看看自己的成果吧。

本文完结。

另外,俺不会提供完整的project代码,大家还是自己敲吧,因为偷懒的木匠从来都不是好司机。

时间: 2024-08-28 07:28:20

[walkthrough] 在Asp.net MVC6 RC里使用NLog,并且把配置集成到config.json的相关文章

解读ASP.NET 5 &amp; MVC6系列(5):Configuration配置信息管理

解读ASP.NET 5 & MVC6系列(5):Configuration配置信息管理 2015-05-18 07:44 by 汤姆大叔, 7103 阅读, 18 评论, 收藏, 编辑 在前面的章节中,我们知道新版的MVC程序抛弃了原来的web.config文件机制,取而代替的是config.json,今天我们就来深入研究一下配置文件的相关内容. 基本用法 新版的配置信息机制在Microsoft.Framework.ConfigurationModel命名空间下进行了重写,重写以后不仅支持XML

解读ASP.NET 5 &amp; MVC6系列(15):MvcOptions配置

原文:解读ASP.NET 5 & MVC6系列(15):MvcOptions配置 程序模型处理 IApplicationModelConvention 在MvcOptions的实例对象上,有一个ApplicationModelConventions属性(类型是:List<IApplicationModelConvention>),该属性IApplicationModelConvention类型的接口集合,用于处理应用模型ApplicationModel,该集合是在MVC程序启动的时候进

ASP.NET MVC6启程(一)

ASP.NET MVC6已出炉多时,但现在很多项目都还在使用MVC4,所以MVC6还未到火的时候,但是从各大新闻报纸媒体上都能或多或少的知道它是能够跨平台的,这也就弥补的ASP.NET一直以来的缺憾,所以我也开始加入研究MVC6的阵营中来,这一研究忽然发现有很多似曾相识的地方,又有很多令人拍案叫好的地方.下面我就从我刚开始接触MVC6时所遇到的问题入手,记录一下MVC6的一些基础应用. 1.打开VS2015创建ASP.NET Web Application项目. 图1 然后选择"ASP.NET

ASP.NET5 MVC6入门教学之一(自己动手)

等待微软开源大动作已经好几年了,终于ASP.NET 5发布了.今天给新手们写一个简单地教程,教你认识一下ASP.NET5 MVC6 1.安装kvm 首先,你需要以管理员权限打开cmd,执行如下的脚本: cd \windows\system32 @powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://raw.githu

ASP.NET MVC项目里创建一个aspx视图

先从控制器里添加视图 视图引擎选"ASPX(C#)",使用布局或模板页不要选. 在Views\EAV目录里,生成的aspx是个单独的页面,没有代码文件,所以代码也要写在这个文件里. @ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" @ Import Namespace="System" @ Import Namespace="

asp.net中关于Microsoft 信息完整性、隐私性等集成信息安全服务服务 integrated security=SSPI

string [email protected]"server=(local)\SQLExpress;database=AdventureWorks;integrated security=SSPI";中的 integrated security=SSPI   安全支持提供器接口是定义食物比较全面的公用API,用来验证.Microsoft信息完整性.信息隐私等集成安全服务,以及用于所有分布式应用程序协议的安全方面的服务.应用程序协议的设计者能够利用该接口获得不同的安全性服务而不必修改协

ASP.NET Core 开发-Logging 使用NLog 写日志文件

ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 .NET Core 和 ASP.NET Core . ASP.NET Core已经内置了日志支持,可以轻松输出到控制台. 学习Logging 组件的相关使用,使用NLog 将日志写入到文件记录. Logging 使用 新建一个 ASP.NET Core 项目,为了方便,我选择Web 应用程序,改身份验证 改为 不进行身份验证. 新建好以后,会自动引用好对应的 类库.这样我们就可以直接使用 Logge

ASP.NET Core 实战:使用 NLog 将日志信息记录到 MongoDB

在项目开发中,日志系统是系统的一个重要组成模块,通过在程序中记录运行日志.错误日志,可以让我们对于系统的运行情况做到很好的掌控.同时,收集日志不仅仅可以用于诊断排查错误,由于日志同样也是大量的数据,通过对这些数据进行集中分析,可以产生极大的价值. 在微服务的系统架构中,由于一个系统会被拆成很多个功能模块,每个模块负责不同的功能,对于日志系统的要求也会更高,比较常见的有 EFLK(ElasticSearch + Filebeat + LogStash + Kibana) 方案,而对于我们这种单体应

ASP.NET Core使用Elasticsearch记录NLog日志

ASP.NET Core使用Elasticsearch记录NLog日志 1.新建一个 ASP.NET Core项目 2.安装Nuge包 运行:Install-Package NLog.Web.AspNetCore 运行:Install-Package NLog 运行:Install-package NLog.Targets.ElasticSearch 3.编写NLog配置文件(NLog.config) <?xml version="1.0" encoding="utf-