1、配置文件
<?xml version="1.0" encoding="utf-8"?> <configuration> <!--/............log4net配置 start............--> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <!--站点日志配置部分--> <log4net> <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF 比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录 如果没有定义LEVEL的值,则缺省为DEBUG--> <logger name="logerror"> <level value="Error" /> <appender-ref ref="ErrorAppender" /> </logger> <logger name="loginfo"> <level value="INFO" /> <appender-ref ref="InfoAppender" /> </logger> <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender"> <!--日志文件名开头--> <param name="File" value="App_DataInfo\" /> <!--多线程时采用最小锁定--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/> <!--混合使用日期和文件大小变换日志文件名--> <rollingStyle value="Composite" /> <!--日期的格式--> <datePattern value="yyyyMMdd" /> <!--追加方式--> <param name="AppendToFile" value="true"/> <!--关闭固定文件方式--> <param name="StaticLogFileName" value="false"/> <!--变换的形式为日期,这种情况下每天只有一个日志--> <!--此时MaxSizeRollBackups和maximumFileSize的节点设置没有意义--> <!--<rollingStyle value="Date"/>--> <!--变换的形式为日志大小--> <!--这种情况下MaxSizeRollBackups和maximumFileSize的节点设置才有意义--> <!--<RollingStyle value="Size"/>--> <!--每天记录的日志文件个数,与maximumFileSize配合使用--> <MaxSizeRollBackups value="10"/> <!--每个日志文件的最大大小--> <!--可用的单位:KB|MB|GB--> <!--不要使用小数,否则会一直写入当前日志--> <maximumFileSize value="5KB"/> <!--日志格式--> <layout type="log4net.Layout.PatternLayout"> <!-- <conversionPattern value="%date [%t]%-5p %c - %m%n newline"/>--> <!-- <conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />--> <conversionPattern value="%message%newline" /> </layout> </appender> <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender"> <!--日志文件名开头--> <param name="File" value="App_DataError\" /> <!--多线程时采用最小锁定--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/> <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置 %date{yyyy.MM.dd}WorkSafety.LawEnforcementLog4net.txt--> <param name="RollingStyle" value="Date"/> <!--追加方式--> <param name="AppendToFile" value="true"/> <!--日志文件名--> <param name="DatePattern" value="(yyyy-MM-dd)"WorkSafety.LawEnforcementLog4net.log""/> <!--关闭固定文件方式--> <param name="StaticLogFileName" value="false"/> <!--变换的形式为日期,这种情况下每天只有一个日志--> <!--此时MaxSizeRollBackups和maximumFileSize的节点设置没有意义--> <!--<rollingStyle value="Date"/>--> <!--变换的形式为日志大小--> <!--这种情况下MaxSizeRollBackups和maximumFileSize的节点设置才有意义--> <!--<RollingStyle value="Size"/>--> <!--每天记录的日志文件个数,与maximumFileSize配合使用--> <!--<MaxSizeRollBackups value="10"/>--> <!--每个日志文件的最大大小--> <!--可用的单位:KB|MB|GB--> <!--不要使用小数,否则会一直写入当前日志--> <!--<maximumFileSize value="10MB"/>--> <!--日志格式--> <layout type="log4net.Layout.PatternLayout"> <!-- <conversionPattern value="%date [%t]%-5p %c - %m%n newline"/>--> <!-- <conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />--> <conversionPattern value="%message%newline" /> </layout> </appender> </log4net> <!--............log4net配置 end............/--> <system.web> </system.web> </configuration>
2、loghelper类
public class LogHeper { private static readonly ILog inforLog = LogManager.GetLogger("loginfo"); private static readonly ILog errorLog = LogManager.GetLogger("logerror"); /// <summary> /// 写入日志 /// </summary> /// <param name="message">日志信息</param> /// <param name="messageType">日志类型</param> public static void Write(string message, LogMessageEnum messageType) { DoLog(message, messageType, null, Type.GetType("System.Object")); } /// <summary> /// 写入日志 /// </summary> /// <param name="message">日志信息</param> /// <param name="messageType">日志类型</param> /// <param name="type"></param> public static void Write(string message, LogMessageEnum messageType, Type type) { DoLog(message, messageType, null, type); } /// <summary> /// 写入日志 /// </summary> /// <param name="message">日志信息</param> /// <param name="messageType">日志类型</param> /// <param name="ex">异常</param> public static void Write(string message, LogMessageEnum messageType, Exception ex) { DoLog(message, messageType, ex, Type.GetType("System.Object")); } /// <summary> /// 写入日志 /// </summary> /// <param name="message">日志信息</param> /// <param name="messageType">日志类型</param> /// <param name="ex">异常</param> /// <param name="type"></param> private static void Write(string message, LogMessageEnum messageType, Exception ex, Type type) { DoLog(message, messageType, ex, type); } /// <summary> /// 保存日志 /// </summary> /// <param name="message">日志信息</param> /// <param name="messageType">日志类型</param> /// <param name="ex">异常</param> /// <param name="type">日志类型</param> private static void DoLog(string message, LogMessageEnum messageType, Exception ex, Type type) { switch (messageType) { case LogMessageEnum.Debug: inforLog.Debug(message, ex); break; case LogMessageEnum.Info: inforLog.Info(message, ex); break; case LogMessageEnum.Warn: inforLog.Warn(message, ex); break; case LogMessageEnum.Error: errorLog.Error(message, ex); break; case LogMessageEnum.Fatal: errorLog.Fatal(message, ex); break; } } /// <summary> /// 关闭log4net /// </summary> public static void ShutDown() { LogManager.Shutdown(); } }
3、netframework webapi项目的话在global里面启动时,配置Log
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~") + @"ConfigLog4net.config")); } }
4、在UnitOfWorkFilter中添加日志记录
public class UnitOfWorkAttribute : ActionFilterAttribute { /// <summary> /// Action执行后 /// </summary> /// <param name="actionExecutedContext"></param> public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { string url = actionExecutedContext.Request.RequestUri.AbsoluteUri; string parameters=String.Empty; if (actionExecutedContext.ActionContext.ActionArguments!=null) { parameters = Newtonsoft.Json.JsonConvert.SerializeObject(actionExecutedContext.ActionContext.ActionArguments); } string logInfo = $"request info:{DateTime.Now}(ㄒoㄒ){url}(ㄒoㄒ){parameters}(ㄒoㄒ)"; LogHeper.Write(logInfo, LogMessageEnum.Info); if (actionExecutedContext.Exception != null) { string error = $"Exception:{DateTime.Now}(ㄒoㄒ){url}(ㄒoㄒ){parameters}(ㄒoㄒ){actionExecutedContext.Exception.Message}"; LogHeper.Write(error, LogMessageEnum.Error); } } }
5、添加filter
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 配置和服务 //配置跨域访问 var cors = new EnableCorsAttribute("*", "*", "*"); //CORS预检请求访问有效期(毫秒) cors.PreflightMaxAge = 7200; config.EnableCors(cors); config.Filters.Add(new UnitOfWorkAttribute()); // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "Home", routeTemplate: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = RouteParameter.Optional } ); //默认返回 json GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add( new QueryStringMapping("datatype", "json", "application/json")); //配置返回json格式为 骆驼命名法 config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); } }