[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行以下为本次追加内容。
{
"AppSettings": {
"SiteTitle": "NLogTest"
},
"nlog": {
"targets": {
"file": {
"type": "File",
"layout": "${date:format=HH\\:MM\\:ss} ${logger} ${message}",
"fileName": "c:\\work\\aaa.txt"
},
"file2": {
"type": "File",
"fileName": "c:\\work\\bbb.txt"
}
"mail1": {
}
},
"rules": {
"rule1": {
"minlevel": "Debug",
"writeTo": "file"
},
"rule2": {
"name": "*",
"minlevel": "Info",
"writeTo": "file2"
}
}
}
}
配置到此为止,下面开始编程。
◎添加一个NLogProvider类, 实现ILoggerProvider并在其内部实现ILogger
先上代码,我是微软的实现中搬过来的,做了一些修改。
using Microsoft.Framework.Logging;
using System; namespace NLogTest
{
public class NLogProvider:ILoggerProvider
{
private readonly global::NLog.LogFactory _logFactory; public NLogProvider(global::NLog.LogFactory logFactory)
{
_logFactory = logFactory;
} public ILogger CreateLogger(string name)
{
return new Logger(_logFactory.GetLogger(name));
} private class Logger : ILogger
{
private readonly global::NLog.Logger _logger; public Logger(global::NLog.Logger logger)
{
_logger = logger;
} public IDisposable BeginScope(object state)
{
return global::NLog.NestedDiagnosticsContext.Push(state.ToString());
} public bool IsEnabled(LogLevel logLevel)
{
return _logger.IsEnabled(GetLogLevel(logLevel));
} public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
{
var nLogLogLevel = GetLogLevel(logLevel);
var message = string.Empty;
if (formatter != null)
{
message = formatter(state, exception);
}
else
{
message = LogFormatter.Formatter(state, exception);
} if (!string.IsNullOrEmpty(message))
{
var eventInfo = global::NLog.LogEventInfo.Create(nLogLogLevel, _logger.Name, message);
eventInfo.Properties["EventId"] = eventId;
_logger.Log(eventInfo);
}
} private global::NLog.LogLevel GetLogLevel(LogLevel logLevel)
{
switch (logLevel)
{
case LogLevel.Verbose: return global::NLog.LogLevel.Debug;
case LogLevel.Information: return global::NLog.LogLevel.Info;
case LogLevel.Warning: return global::NLog.LogLevel.Warn;
case LogLevel.Error: return global::NLog.LogLevel.Error;
case LogLevel.Critical: return global::NLog.LogLevel.Fatal;
}
return global::NLog.LogLevel.Debug;
}
}
}
}
代码很简单,就是在微软的日志框架和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 = ;
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 = - ;
var j = / 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代码,大家还是自己敲吧,因为偷懒的木匠从来都不是好司机。
[walkthrough] 在Asp.net MVC6 RC里使用NLog,并且把配置集成到config.json的更多相关文章
- 解读ASP.NET 5 & MVC6系列(5):Configuration配置信息管理
在前面的章节中,我们知道新版的MVC程序抛弃了原来的web.config文件机制,取而代替的是config.json,今天我们就来深入研究一下配置文件的相关内容. 基本用法 新版的配置信息机制在Mic ...
- 认识ASP.NET MVC6
认识ASP.NET MVC6 这篇文章说明下如何在普通编辑器下面开发mvc6应用程序. 上篇文章: 十分钟轻松让你认识ASP.NET 5(MVC6) 首先安装mvc6的nuget包: 可以看到在pro ...
- ASP.NET5 MVC6入门教学之一(自己动手)
等待微软开源大动作已经好几年了,终于ASP.NET 5发布了.今天给新手们写一个简单地教程,教你认识一下ASP.NET5 MVC6 1.安装kvm 首先,你需要以管理员权限打开cmd,执行如下的脚本: ...
- asp.net mvc6学习资料整理
十分钟轻松让你认识ASP.NET MVC6 http://www.cnblogs.com/n-pei/p/4272105.html ASP.NET 5系列教程 (六): 在 MVC6 中创建 Web ...
- [转]ASP.NET Core 开发-Logging 使用NLog 写日志文件
本文转自:http://www.cnblogs.com/Leo_wl/p/5561812.html ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 . ...
- ASP.NET Core 开发-Logging 使用NLog 写日志文件
ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 .NET Core 和 ASP.NET Core . ASP.NET Core已经内置了日志支持,可以 ...
- ASP.NET Core 实战:使用 NLog 将日志信息记录到 MongoDB
一.前言 在项目开发中,日志系统是系统的一个重要组成模块,通过在程序中记录运行日志.错误日志,可以让我们对于系统的运行情况做到很好的掌控.同时,收集日志不仅仅可以用于诊断排查错误,由于日志同样也是大量 ...
- EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真
EF Core使用SQL调用返回其他类型的查询 假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法 ...
- 在web.config里使用configSource分隔各类配置
转:http://www.yongfa365.com/Item/using-configSource-Split-Configs.html 大型项目中,可能有多个Service,也就是会有一堆配置,而 ...
随机推荐
- Spring注入-Map
在spring框架中为Map注入属性 1map映射的对象创建 package com; /** * Map集合在spring中的使用测试 */ public class User { private ...
- 关于封装unity3d的dll时候的进一步总结
在进行新项目的开发或者接手.后期维护其他一些项目时,经常性的,我们会遇到以下情况: 1.使用新的插件替换已有的bug比较多或者不在维护的插件: 2.因策划需求或美术资源的变更,而不得不更换游戏中的游戏 ...
- 浅谈UML中类之间的五种关系及其在代码中的表现形式
本文转载:http://www.cnblogs.com/DebugLZQ/archive/2013/05/13/3066715.html 什么是类? 将某类东西归纳在一起,可以成为一个类. 类有很多种 ...
- Linux编程---线程
首先说一下线程的概念.事实上就是运行在进程的上下文环境中的一个运行流.普通进程仅仅有一条运行流,可是线程提供了多种运行的路径并行的局面. 同一时候,线程还分为核心级线程和用户级线程.主要差别在属于核内 ...
- myNote
源码地址 :http://450640526.ys168.com/ 编辑器是WEBBWOSER制作的 你的Internet Explorer的版本至少要是8.0的否则用不了 还有很多BUG 很多功能没 ...
- 构造Scala开发环境并创建ApiDemos演示样例项目
从2011年開始写Android ApiDemos 以来.Android的版本号也更新了非常多,眼下的版本号已经是4.04. ApiDemos中的样例也添加了不少,有必要更新Android ApiDe ...
- UIPickView的简单介绍
UIPickView的简单介绍 设置UIPickView的时候,我们主要需要设置一下下面的两个属性 UIPickerView *pickView1; pickView1 = [[UIPickerVie ...
- URLConnection类详解
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3753224.html ...
- 14、SQL Server 存储过程
SQL Server 存储过程 存储过程类似函数,可以重复使用.相对于函数,存储过程拥有更强大的功能和更高的灵活性. 存储过程中可以包含逻辑控制语句和数据操作语句,可以接受参数,输出参数,返回单个值或 ...
- Java中JIN机制及System.loadLibrary() 的执行过程
Android平台Native开发与JNI机制详解 http://mysuperbaby.iteye.com/blog/915425 个人认为下面这篇转载的文章写的很清晰很不错. 注意Android平 ...