前言
默认log4net配置写入的日志文件都是写入到一个日志文件当中,最多根据时间进行拆分文件,当日志过多时不好排除问题,单个文件也会过大
实现方式
using log4net.Appender;
using log4net.Core;
using log4net.Layout;
using log4net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// 动态生成日志配置文件,根据传入的Type,该类不影响默认 log4net.config 配置文件
/// </summary>
public static class LoggerManager
{
public static ILog GetLogger(Type type)
{
DateTime Now = DateTime.Now;
// All Level 日志存储位置
string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs", Now.ToString("yyyy-MM-dd"), $"{type.Name}.log");
// 异常 Error Level 日志存储位置
string logErrorFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs", "Error",Now.ToString("yyyy-MM-dd"), $"{type.Name}.log");
var hierarchy = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository();
var logger = hierarchy.GetLogger(type.FullName) as log4net.Repository.Hierarchy.Logger;
if (logger != null && logger.Appenders.Count > 0)
{
return new LogImpl(logger);
}
// 全局等级的配置 RollingFileAppender
var appender = new RollingFileAppender
{
Name = $"{type.Name}Appender",
File = logFilePath,
AppendToFile = true,
RollingStyle = RollingFileAppender.RollingMode.Size,
MaxFileSize = 10 * 1024 * 1024, // 10MB
MaxSizeRollBackups = 5,
StaticLogFileName = true,
Layout = new PatternLayout("[%date{yyyy-MM-dd HH:mm:ss,fff}] [%level] %message%newline"),
Threshold = Level.All,
LockingModel = new FileAppender.MinimalLock(),
Encoding = Encoding.UTF8
};
// 异常的配置
var errAppender = new RollingFileAppender
{
Name = $"{type.Name}Appender",
File = logErrorFilePath,
AppendToFile = true,
RollingStyle = RollingFileAppender.RollingMode.Size,
MaxFileSize = 10 * 1024 * 1024, // 10MB
MaxSizeRollBackups = 5,
StaticLogFileName = true,
Layout = new PatternLayout("[%date{yyyy-MM-dd HH:mm:ss,fff}] [%level] %message%newline"),
Threshold = Level.Error,
LockingModel = new FileAppender.MinimalLock(),
Encoding = Encoding.UTF8
};
appender.ActivateOptions();
errAppender.ActivateOptions();
logger.AddAppender(appender);
logger.AddAppender(errAppender);
logger.Repository.Configured = true;
return new LogImpl(logger);
}
}
上述方法可以在不允许原有配置log4net.config 情况下进行
使用案例
下面代码是SuperSocket的一个命令(Socket)接收方法
private static readonly log4net.ILog sg_log = LoggerManager.GetLogger(typeof(DevAlarmReport));
使用动态记录
记录Info日志
sg_log.Info($"DevAlarmReport,来源方IP:{ip},接受数据:{receivedData}");
记录Error日志
sg_log.Error(Error);
Error 等级日志根据动态配置会存储在
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Configuration;
using log4net;
using JMT.FrmXinYiChangCommunication.Common;
using JMT.FrmXinYiChangCommunication.Entity;
namespace JMT.FrmXinYiChangLightState
{
//接收设备停机开机状态信息-过滤器
public class DevAlarmReport : CommandBase<SocketSession, BinaryRequestInfo>
{
//SqlSugarClient Db;
//List<Device> devices = new List<Device>();
//public XYCBll bll = new XYCBll();
//public XmlBuilders XmlBuilders = new XmlBuilders();
Dictionary<string, string> response = new Dictionary<string, string>();
//日志
private static readonly log4net.ILog sg_log = LoggerManager.GetLogger(typeof(DevAlarmReport));
// public SuperSocketService service = new SuperSocketService();
public static string CmdName = "DevAlarmReport";
int light;
public override void ExecuteCommand(SocketSession session, BinaryRequestInfo requestInfo)
{
try
{
string ip = session.RemoteEndPoint.Address.ToString();
string receivedData = Encoding.UTF8.GetString(requestInfo.Body);
截取头部4个字节长度
var startIndex = receivedData.IndexOf("{");
var dataStartStr = receivedData.Substring(startIndex, receivedData.Length - startIndex);
var endIndex = dataStartStr.IndexOf("}");
// string str = receivedData.Substring(3, receivedData.Length - 4);
var dataStr = dataStartStr.Substring(0, endIndex + 1);
sg_log.Info($"DevAlarmReport,来源方IP:{ip},接受数据:{receivedData}");
// 处理数据
DevStatusRecord report = JsonConvert.DeserializeObject<DevStatusRecord>(dataStr);
CheckRequestMsg(report);
report.MessagePushTime = DateTime.Now;
// 添加到队列
// 响应机台
string ResposeResult = JsonConvert.SerializeObject(CommandResponseResult.Success(CmdName));
byte[] sendData = ResposeResult.ToByteByStr();
session.Send(sendData, 0, sendData.Length);
}
catch(Exception ex)
{
string Error = $"命令:[{CmdName}],解析处理数据出现问题:{ex.Message}";
string ResposeResult = JsonConvert.SerializeObject(CommandResponseResult.Error(CmdName, Error));
byte[] sendData = ResposeResult.ToByteByStr();
session.Send(sendData, 0, sendData.Length);
sg_log.Error(Error);
}
}
/// <summary>
/// 校验请求参数
/// </summary>
/// <param name="record"></param>
/// <exception cref="Exception"></exception>
public void CheckRequestMsg(DevStatusRecord record)
{
if (string.IsNullOrEmpty(record.EqNo))
{
throw new Exception($"机台号不能为空!");
}
}
}
}
不会影响原有的log4net.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- This section contains the log4net configuration settings -->
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
</appender>
<appender name="LogInfoAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs/Info/" />
<appendToFile value="true" />
<!-- 文件的编码方式 -->
<param name="Encoding" value="UTF-8"/>
<rollingStyle value="Date" />
<staticLogFileName value="false" />
<datePattern value="yyyyMMdd_HH'.log'" />
<maximumFileSize value="15MB" />
<!--最小锁定模型以允许多个进程可以写入同一个文件-->
<param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value=" -------------------------------------------------------------------------------------- %n日志时间:%d [%t] %n日志级别:%-5p %n日 志 类:%c [%x] %n%m" />
<!--<param name="Header" value=" ====================================================================================== " />-->
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="INFO"/>
</filter>
<param name="Encoding" value="utf-8" />
</appender>
<appender name="RollingErrorLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs/Error/" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<staticLogFileName value="false" />
<datePattern value="yyyyMMdd_HH'Err.log'" />
<maximumFileSize value="15MB" />
<!--最小锁定模型以允许多个进程可以写入同一个文件-->
<param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%n -------------------------------------------------------------------------------------- %n日志时间:%d [%t] %n日志级别:%-5p %n日 志 类:%c [%x] %n%m" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="WARN"/>
<param name="LevelMax" value="FATAL"/>
</filter>
<param name="Encoding" value="utf-8" />
</appender>
<!-- 设备联机日志 -->
<appender name="ConnectedClosed" type="log4net.Appender.RollingFileAppender">
<file value="Logs/ConnectedClosed/" />
<appendToFile value="true" />
<!-- 文件的编码方式 -->
<param name="Encoding" value="UTF-8"/>
<rollingStyle value="Date" />
<staticLogFileName value="false" />
<datePattern value="yyyyMMdd'ConnectedClosed.log'" />
<maximumFileSize value="15MB" />
<!--最小锁定模型以允许多个进程可以写入同一个文件-->
<param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value=" -------------------------------------------------------------------------------------- %n日志时间:%d [%t] %n日志级别:%-5p %n日 志 类:%c [%x] %n%m" />
<!--<param name="Header" value=" ====================================================================================== " />-->
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="INFO"/>
</filter>
<param name="Encoding" value="utf-8" />
</appender>
<!-- 发送命令接收命令日志 -->
<appender name="SendGet" type="log4net.Appender.RollingFileAppender">
<file value="Logs/SendGet/" />
<appendToFile value="true" />
<!-- 文件的编码方式 -->
<param name="Encoding" value="UTF-8"/>
<rollingStyle value="Date" />
<staticLogFileName value="false" />
<datePattern value="yyyyMMdd'SendGet.log'" />
<maximumFileSize value="15MB" />
<!--最小锁定模型以允许多个进程可以写入同一个文件-->
<param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value=" -------------------------------------------------------------------------------------- %n日志时间:%d [%t] %n日志级别:%-5p %n日 志 类:%c [%x] %n%m" />
<!--<param name="Header" value=" ====================================================================================== " />-->
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="INFO"/>
</filter>
<param name="Encoding" value="utf-8" />
</appender>
<!-- 数据上传日志 -->
<appender name="DataMes" type="log4net.Appender.RollingFileAppender">
<file value="Logs/DataMes/" />
<appendToFile value="true" />
<!-- 文件的编码方式 -->
<param name="Encoding" value="UTF-8"/>
<rollingStyle value="Date" />
<staticLogFileName value="false" />
<datePattern value="yyyyMMdd_HH'DataMes.log'" />
<maximumFileSize value="15MB" />
<!--最小锁定模型以允许多个进程可以写入同一个文件-->
<param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value=" -------------------------------------------------------------------------------------- %n日志时间:%d [%t] %n日志级别:%-5p %n日 志 类:%c [%x] %n%m" />
<!--<param name="Header" value=" ====================================================================================== " />-->
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="INFO"/>
</filter>
<param name="Encoding" value="utf-8" />
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<!--<root>
<level value="ALL" />
<appender-ref ref="LogInfo" />
<appender-ref ref="RollingErrorLogFileAppender" />
<appender-ref ref="ResolveLogInfo" />
</root>-->
<logger name="LogInfo">
<appender-ref ref="LogInfoAppender" />
</logger>
<logger name="ConnectedClosed">
<appender-ref ref="ConnectedClosed" />
</logger>
<logger name="SendGet">
<appender-ref ref="SendGet"/>
</logger>
<logger name="DataMes">
<appender-ref ref="DataMes"/>
</logger>
<!--<logger name="ConsoleLog" additivity="true">
--><!--additivity 是否确认子日志对象继承父日志对象的appender列表,默认为True:确认--><!--
--><!--注意优先级,优先级低的要放在后面--><!--
<level value="ALL" />
<appender-ref ref="ConsoleAppender" />
</logger>-->
</log4net>
</configuration>