http://nlog-project.org/2015/06/30/extending-nlog-is-easy.html
新建一个类库,命名规则为NLog.*.dll
定义一个类输出日志到RabbitMQ
[Target("MQ")] public class MQTarget : TargetWithLayout { public MQTarget() { } public string Host { get; set; } public string UserName { get; set; } public string Password { get; set; } public string VirtualHost { get; set; } protected override void Write(LogEventInfo logEvent) { string message = this.Layout.Render(logEvent); SendMessageToMQ(Host,message); } private void SendMessageToMQ(string host,string message) { var factory = new ConnectionFactory() { HostName = Host,UserName= UserName, Password= Password, VirtualHost= VirtualHost}; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "apicenter", durable: false, exclusive: false, autoDelete: false, arguments: null); //string message = "Hello World!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: "apicenter", basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); } } }
nlog.config
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="info" internalLogFile="Logs\internal-nlog.txt"> <!-- enable asp.net core layout renderers --> <extensions> <add assembly="NLog.Web.AspNetCore"/> <add assembly="NLog.MQ"/> </extensions> <!-- the targets to write to --> <targets> <!-- write logs to file --> <target xsi:type="File" name="allfile" fileName="Logs\nlog-all-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" /> <!-- another file log, only own logs. Uses some ASP.NET core renderers --> <target xsi:type="File" name="info" fileName="Logs\nlog-info-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" /> <target xsi:type="File" name="error" fileName="Logs\nlog-error-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" /> <target xsi:type="MQ" name="mq" host="10.202.80.196" UserName="bm" Password="bm_p@ss" VirtualHost="NIST" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" /> </targets> <!-- rules to map from logger name to target --> <rules> <!--All logs, including from Microsoft--> <logger name="*" minlevel="Info" writeTo="allfile" /> <!--Skip non-critical Microsoft logs and so log only own logs--> <logger name="Microsoft.*" maxLevel="Info" final="true" /> <!-- BlackHole without writeTo --> <logger name="*" level="Info" writeTo="info" /> <logger name="*" level="Error" writeTo="error" /> <logger name="*" level="Error" writeTo="mq" /> </rules> </nlog>
这里需要注意一点,部署到Linux中的话,需要把nlog.config中的\ 替换成 /
Filter
定义一个日志记录sql
namespace LogExtension { public class NLogSql { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); public static void Info(string message) { logger.Info(message); } } }
调用方法
public static void LogSql(string txt) { NLogSql.Info(txt); }
配置target
<target xsi:type="File" name="sql" fileName="Logs/sql/nlog-sql-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" /> <target xsi:type="File" name="info" fileName="Logs/info/nlog-info-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
配置rule
<logger name="*" level="Info" writeTo="info" /> <logger name="LogExtension.NLogSql" level="Info" writeTo="sql" />
这样日志不仅会写到sql文件中,也会写到info中
定义filter
<logger name="*" level="Info" writeTo="info" > <filters> <when condition="equals(logger,'LogExtension.NLogSql')" action="Ignore"/> </filters> </logger>
这样就在info中排除了sql的日志。
File
<target xsi:type="File" name="info" fileName="Logs/info/nlog-info-${shortdate}.log" archiveAboveSize="10240" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
文件大小每超过1M就生成一个新的文件
<?xml version="1.0" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <!-- Log in a separate thread, possibly queuing up to 5000 messages. When the queue overflows, discard any extra messages--> <target name="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard"> <target xsi:type="File" fileName="${basedir}/logs/${level}.txt" keepFileOpen="true" /> </target> </targets> <rules> <logger name="*" minlevel="Debug" writeTo="file" /> </rules> </nlog>
支持异步写文件
wrapper
https://github.com/nlog/nlog/wiki/Configuration-file#default-wrappers
https://github.com/nlog/nlog/wiki/Configuration-file#asynchronous-processing-and-wrapper-targets