使用 Nuget 引入 log4net,System.Data.SqlClient 包。(数据库使用的是Sql Server)
配置如下:
<?xml version="1.0"?>
<log4net debug="false">
<root>
<!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
<level value="ALL"/>
<appender-ref ref="RollingFile"/>
<appender-ref ref="ADONetAppender"/>
</root>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<!-- 日志文件路径 -->
<file value="Logs/" />
<!--是否是向文件中追加日志-->
<appendToFile value="true" />
<!--记录日志写入文件时,不锁定文本文件-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<!--使用Unicode编码-->
<Encoding value="UTF-8" />
<!--log保留天数-->
<param name="MaxSizeRollBackups" value="30"/>
<!--每个文件最大1M-->
<param name="maximumFileSize" value="1MB" />
<!--日志根据日期滚动-->
<param name="RollingStyle" value="Date" />
<!--日志文件名格式为:logs_20080831.log-->
<param name="DatePattern" value=""logs_"yyyyMMdd".log"" />
<!--日志文件名是否是固定不变的-->
<param name="StaticLogFileName" value="false" />
<!--布局-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %identity [%thread] %-5level %logger scope=[%property{scope}] - %message %exception%newline" />
</layout>
<!-- 日志等级过滤 -->
<!--<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="Info"/>
<param name="LevelMax" value="Fatal"/>
</filter>-->
</appender>
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
<bufferSize value="1"/>
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data"/>
<connectionString value="DefaultConnection"/>
<commandText value="INSERT INTO SysLog ([LogTime],[Thread],[Level],[Logger],[Message],[Exception],[UserName]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @identity)"/>
<parameter>
<parameterName value="@log_date"/>
<dbType value="DateTime"/>
<layout type="log4net.Layout.RawTimeStampLayout"/>
</parameter>
<parameter>
<parameterName value="@thread"/>
<dbType value="String"/>
<size value="255"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread"/>
</layout>
</parameter>
<parameter>
<parameterName value="@log_level"/>
<dbType value="String"/>
<size value="50"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level"/>
</layout>
</parameter>
<parameter>
<parameterName value="@logger"/>
<dbType value="String"/>
<size value="255"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger"/>
</layout>
</parameter>
<parameter>
<parameterName value="@message"/>
<dbType value="String"/>
<size value="4000"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message"/>
</layout>
</parameter>
<parameter>
<parameterName value="@identity"/>
<dbType value="String"/>
<size value="20"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%identity"/>
</layout>
</parameter>
<parameter>
<parameterName value="@exception"/>
<dbType value="String"/>
<size value="2000"/>
<layout type="log4net.Layout.ExceptionLayout"/>
</parameter>
</appender>
</log4net>
代码如下:
public class Log4netUtil
{
private static ILoggerRepository repository { get; set; }
private static ILog _log;
private static ILog log
{
get
{
if (_log == null)
{
Configure();
}
return _log;
}
}
///
/// log4net 配置初始化
///
///
/// 配置文件路径
public static void Configure(string repositoryName = "logRepository")
{
if (LogManager.GetAllRepositories().Any(x => x.Name == repositoryName) == false)
{
repository = LogManager.CreateRepository(repositoryName);
XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
refreshSetting(repository as Hierarchy);
_log = LogManager.GetLogger(repositoryName, "Web");
}
}
///
/// 数据库链接地址使用 appsettings.json 中的数据库配置
///
///
private static void refreshSetting(Hierarchy hierarchy)
{
if (hierarchy != null && hierarchy.Configured)
{
foreach (IAppender appender in hierarchy.GetAppenders())
{
if (appender is AdoNetAppender)
{
var adoNetAppender = (AdoNetAppender)appender;
var Configuration = new ConfigurationBuilder()
.Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true })
.Build();
adoNetAppender.ConnectionString = Configuration.GetConnectionString(adoNetAppender.ConnectionString);
adoNetAppender.ActivateOptions(); // Refresh AdoNetAppenders Settings
}
}
}
}
public static void Debug(object message)
{
log.Debug(message);
}
public static void Debug(object message, Exception exception)
{
log.Debug(message, exception);
}
public static void DebugFormat(string format, object arg0)
{
log.DebugFormat(format, arg0);
}
public static void DebugFormat(string format, object arg0, object arg1)
{
log.DebugFormat(format, arg0, arg1);
}
public static void DebugFormat(string format, object arg0, object arg1, object arg2)
{
log.DebugFormat(format, arg0, arg1, arg2);
}
public static void DebugFormat(string format, params object[] args)
{
log.DebugFormat(format, args);
}
public static void DebugFormat(IFormatProvider provider, string format, params object[] args)
{
log.DebugFormat(provider, format, args);
}
public static void Error(object message)
{
log.Error(message);
}
public static void Error(object message, Exception exception)
{
log.Error(message, exception);
}
public static void ErrorFormat(string format, object arg0)
{
log.ErrorFormat(format, arg0);
}
public static void ErrorFormat(string format, object arg0, object arg1)
{
log.ErrorFormat(format, arg0, arg1);
}
public static void ErrorFormat(string format, object arg0, object arg1, object arg2)
{
log.ErrorFormat(format, arg0, arg1, arg2);
}
public static void ErrorFormat(string format, params object[] args)
{
log.ErrorFormat(format, args);
}
public static void ErrorFormat(IFormatProvider provider, string format, params object[] args)
{
log.ErrorFormat(provider, format, args);
}
public static void Fatal(object message)
{
log.Fatal(message);
}
public static void Fatal(object message, Exception exception)
{
log.Fatal(message, exception);
}
public static void FatalFormat(string format, object arg0)
{
log.FatalFormat(format, arg0);
}
public static void FatalFormat(string format, object arg0, object arg1)
{
log.FatalFormat(format, arg0, arg1);
}
public static void FatalFormat(string format, object arg0, object arg1, object arg2)
{
log.FatalFormat(format, arg0, arg1, arg2);
}
public static void FatalFormat(string format, params object[] args)
{
log.FatalFormat(format, args);
}
public static void FatalFormat(IFormatProvider provider, string format, params object[] args)
{
log.FatalFormat(provider, format, args);
}
public static void Info(object message)
{
log.Info(message);
}
public static void Info(object message, Exception exception)
{
log.Info(message, exception);
}
public static void InfoFormat(string format, object arg0)
{
log.InfoFormat(format, arg0);
}
public static void InfoFormat(string format, object arg0, object arg1)
{
log.InfoFormat(format, arg0, arg1);
}
public static void InfoFormat(string format, object arg0, object arg1, object arg2)
{
log.InfoFormat(format, arg0, arg1, arg2);
}
public static void InfoFormat(string format, params object[] args)
{
log.InfoFormat(format, args);
}
public static void InfoFormat(IFormatProvider provider, string format, params object[] args)
{
log.InfoFormat(provider, format, args);
}
public static void Warn(object message)
{
log.Warn(message);
}
public static void Warn(object message, Exception exception)
{
log.Warn(message, exception);
}
public static void WarnFormat(string format, object arg0)
{
log.WarnFormat(format, arg0);
}
public static void WarnFormat(string format, object arg0, object arg1)
{
log.WarnFormat(format, arg0, arg1);
}
public static void WarnFormat(string format, object arg0, object arg1, object arg2)
{
log.WarnFormat(format, arg0, arg1, arg2);
}
public static void WarnFormat(string format, params object[] args)
{
log.WarnFormat(format, args);
}
public static void WarnFormat(IFormatProvider provider, string format, params object[] args)
{
log.WarnFormat(provider, format, args);
}
}
public class ActionFilter : Attribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
//var userName = context.HttpContext.User.Identity.Name;
string url = AuthUtil.GetUrl(context.HttpContext);
string queryString = context.HttpContext.Request.QueryString.Value;
Log4netUtil.InfoFormat("URL:{0}{1}", url, (queryString == null ? "" : queryString));
return;
}
public void OnActionExecuted(ActionExecutedContext context)
{
Log4netUtil.Info("ActionExecuted");
return;
}
}
可优化点:
1、可自定义参数丰富日志内容;
2、使用依赖注入方式,Logger名称可以设置为类名、程序集名或自定义,方便定位查找;