最近有個需求,使用log4net來記錄日誌,而後將數據保存到服務器端。一開始打算寫一個windows service,按期上傳日誌。windows
後來又由於一些場景下不適應,所以直接改成保存內存中,到必定閥值以後將數據post到服務器。服務器
考慮用log4net的MemoryAppender,可是沒辦法控制這個閥值,同時還須要另外配置服務器接受數據地址。app
所以也不適用,還好log4net支持自定義Appender,因而,參考MemoryAppender,自定義一個,問題解決。ide
下面是Appender代碼。post
1 /// <summary> 2 /// Customize Appender, save the Log in the memory 3 /// when it the event queue reach maximum queue size 4 /// the queue will post to sever. 5 /// </summary> 6 public class MyMemAppender : AppenderSkeleton 7 { 8 #region public properties 9 public string RemoteAddress { get; set; } 10 public int QueueSize { get; set; } 11 #endregion 12 13 #region Public Instance Constructors 14 public MyMemAppender() 15 : base() 16 { 17 eventQueue = new ArrayList(); 18 } 19 #endregion 20 21 #region private fields 22 private ArrayList eventQueue; 23 #endregion 24 25 #region Override implementation of AppenderSkeleton 26 protected override void Append(log4net.Core.LoggingEvent loggingEvent) 27 { 28 lock (eventQueue.SyncRoot) 29 { 30 eventQueue.Add(loggingEvent); 31 if (eventQueue.Count >= QueueSize) 32 { 33 this.Clear(); 34 } 35 } 36 } 37 #endregion 38 39 #region Public Instance Methods 40 41 /// <summary> 42 /// Clear the list of events 43 /// </summary> 44 /// <remarks> 45 /// Clear the list of events 46 /// </remarks> 47 virtual public void Clear() 48 { 49 lock (eventQueue.SyncRoot) 50 { 51 SaveToServer(); 52 eventQueue.Clear(); 53 } 54 } 55 56 /// <summary> 57 /// Gets the events that have been logged. 58 /// </summary> 59 /// <returns>The events that have been logged</returns> 60 /// <remarks> 61 /// <para> 62 /// Gets the events that have been logged. 63 /// </para> 64 /// </remarks> 65 virtual public LoggingEvent[] GetEvents() 66 { 67 lock (eventQueue.SyncRoot) 68 { 69 return (LoggingEvent[])eventQueue.ToArray(typeof(LoggingEvent)); 70 } 71 } 72 73 #endregion Public Instance Methods 74 75 #region private methods 76 private void SaveToServer() 77 { 78 lock (eventQueue.SyncRoot) 79 { 80 List<LogModel> logList = new List<LogModel>(); 81 foreach (log4net.Core.LoggingEvent evt in eventQueue) 82 { 83 try 84 { 85 LogModel m = Newtonsoft.Json.JsonConvert.DeserializeObject<LogModel>(evt.RenderedMessage); 86 logList.Add(m); 87 } 88 catch (Exception ex) 89 { 90 Console.Write(ex.ToString()); 91 continue; 92 } 93 } 94 SaveToServer(logList); 95 } 96 } 97 98 private void SaveToServer(List<LogModel> logList) 99 { 100 try 101 { 102 IsoDateTimeConverter timeConverter = new IsoDateTimeConverter(); 103 timeConverter.DateTimeFormat = "yyyy'-'MM'-'dd' 'HH':'mm':'ss"; 104 string str = Newtonsoft.Json.JsonConvert.SerializeObject(logList, Newtonsoft.Json.Formatting.Indented, timeConverter); 105 PostStrToServer(str, RemoteAddress); 106 } 107 catch (Exception ex) 108 { 109 Console.Write(ex.ToString()); 110 return; 111 } 112 } 113 114 private void PostStrToServer(string content, string url) 115 { 116 using (WebClient client = new WebClient()) 117 { 118 client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; 119 client.Encoding = System.Text.Encoding.UTF8; 120 client.UploadStringAsync(new Uri(url), ("logList=" + content)); 121 } 122 } 123 124 #endregion 125 }
配置文件:this
<?xml version="1.0" encoding="utf-8" ?> <log4net debug="true"> <appender name="myMemAppender" type="LogSystem.Common.MyMemAppender"> <param name="QueueSize" value="10"/> <param name="RemoteAddress" value="http://localhost/PostLogData.aspx"/> </appender> <root> <level value="ALL"/> <appender-ref ref="myMemAppender" /> </root> </log4net>
調用方式:url
MyMemAppender logger = new MyMemAppender(); logger.QueueSize = 5; logger.RemoteAddress = "http://localhost:57427/PostLogData.aspx"; log4net.Config.BasicConfigurator.Configure(logger); ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
或者
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(configPath));
log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);spa