開源日誌log4net使用起來很方便,可是項目中不讓用,因此本身重寫了一個類,用來記錄日誌,比較簡單。函數
一、首先是能夠把日誌分紅多個類型,分別記錄到不一樣的文件中spa
1 /// <summary> 2 /// 日誌類型 3 /// </summary> 4 public enum LogType 5 { 6 /// <summary> 7 /// 插入型 8 /// </summary> 9 Insert, 10 /// <summary> 11 /// 更新型 12 /// </summary> 13 Update, 14 /// <summary> 15 /// 全部 16 /// </summary> 17 All, 18 /// <summary> 19 /// 結尾,放在最後 20 /// </summary> 21 End 22 }
個人是分三個,insert插入,update更新,all包括全部的日誌。線程
二、接下來是LogHelper類,代碼中已註釋,很少說,直接上代碼日誌
1 /// <summary> 2 /// 記錄日誌 3 /// </summary> 4 public class LogHelper 5 { 6 7 #region 自定義變量 8 /// <summary> 9 /// 異常信息的隊列 10 /// </summary> 11 private static Queue<string> qMsg = null; 12 /// <summary> 13 /// 文件大小最大值,單位:Mb 14 /// </summary> 15 private static int maxFileSize = 10; 16 /// <summary> 17 /// 當天建立同一類型的日誌文件的個數 18 /// </summary> 19 private static int[] createdFileCounts = new int[(int)LogType.End]; 20 /// <summary> 21 /// 日誌文件存放路徑 22 /// </summary> 23 private static string logFilePath = ""; 24 #endregion 25 26 #region 屬性 27 /// <summary> 28 /// 文件大小最大值,單位:Mb。小於0時則不限制 29 /// </summary> 30 public static int MaxFileSize 31 { 32 get { return maxFileSize; } 33 set { maxFileSize = value; } 34 } 35 /// <summary> 36 /// 日誌文件存放路徑 37 /// </summary> 38 public static string LogFilePath 39 { 40 set { logFilePath = value; } 41 get 42 { 43 if (!String.IsNullOrEmpty(logFilePath)) 44 { 45 return logFilePath; 46 } 47 else 48 { 49 return System.Windows.Forms.Application.StartupPath + "\\Log\\" + DateTime.Now.ToString("yyyy-MM-dd"); 50 } 51 } 52 } 53 #endregion 54 55 #region 構造函數 56 /// <summary> 57 /// 靜態構造函數 58 /// </summary> 59 static LogHelper() 60 { 61 qMsg = new Queue<string>(); 62 SetCreatedFileCount(); 63 RunThread(); 64 } 65 #endregion 66 67 #region 輔助 68 /// <summary> 69 /// 獲取日誌文件的全路徑 70 /// </summary> 71 /// <param name="logType"></param> 72 /// <returns></returns> 73 private static string GetLogPath(LogType logType, bool isCreateNew) 74 { 75 string logPath = LogFilePath; 76 if (!Directory.Exists(logPath)) 77 { 78 Directory.CreateDirectory(logPath); 79 //當作是新的一天,要將昨天的數據清空 80 for (int i = 0; i < createdFileCounts.Length; i++) 81 { 82 createdFileCounts[i] = 0; 83 } 84 } 85 switch (logType) 86 { 87 case LogType.Insert: 88 logPath = logPath + "\\" + "Insert"; 89 break; 90 case LogType.Update: 91 logPath = logPath + "\\" + "Update"; 92 break; 93 default: 94 logPath = logPath + "\\" + "All"; 95 break; 96 } 97 if (isCreateNew) 98 { 99 int num = ++createdFileCounts[(int)logType]; 100 logPath += string.Format("({0}).log", num); 101 return logPath; 102 } 103 104 logPath += ".log"; 105 //createdFileCounts[(int)logType] = 0; 106 if (!File.Exists(logPath)) 107 { 108 //File.Create(logPath); 109 FileStream fs = File.Create(logPath); 110 fs.Close(); 111 fs.Dispose(); 112 } 113 114 return logPath; 115 } 116 117 /// <summary> 118 /// 運行線程 119 /// </summary> 120 private static void RunThread() 121 { 122 ThreadPool.QueueUserWorkItem(u => 123 { 124 while (true) 125 { 126 string tmsg = string.Empty; 127 lock (qMsg) 128 { 129 if (qMsg.Count > 0) 130 tmsg = qMsg.Dequeue(); 131 } 132 133 //往日誌文件中寫錯誤信息 134 if (!String.IsNullOrEmpty(tmsg)) 135 { 136 int index = tmsg.IndexOf("&&"); 137 string logTypeStr = tmsg.Substring(0, index); 138 LogType logType = LogType.All; 139 if (logTypeStr == string.Format("{0}", LogType.Insert)) 140 { 141 logType = LogType.Insert; 142 } 143 else if (logTypeStr == string.Format("{0}", LogType.Update)) 144 { 145 logType = LogType.Update; 146 } 147 148 //記錄全部日誌 149 WriteLog(tmsg.Substring(index + 2)); 150 //分開記錄日誌 151 if (logType != LogType.All) 152 { 153 WriteLog(tmsg.Substring(index + 2), logType); 154 } 155 } 156 157 if (qMsg.Count <= 0) 158 { 159 Thread.Sleep(1000); 160 } 161 } 162 }); 163 } 164 165 /// <summary> 166 /// 程序剛啓動時 檢測已建立的日誌文件個數 167 /// </summary> 168 private static void SetCreatedFileCount() 169 { 170 string logPath = LogFilePath; 171 if (!Directory.Exists(logPath)) 172 { 173 for (int i = 0; i < createdFileCounts.Length; i++ ) 174 { 175 createdFileCounts[i] = 0; 176 } 177 } 178 else 179 { 180 DirectoryInfo dirInfo = new DirectoryInfo(logPath); 181 FileInfo[] fileInfoes = dirInfo.GetFiles("*.log"); 182 foreach (FileInfo fi in fileInfoes) 183 { 184 string fileName = Path.GetFileNameWithoutExtension(fi.FullName).ToLower(); 185 if (fileName.Contains('(') && fileName.Contains(')')) 186 { 187 fileName = fileName.Substring(0, fileName.LastIndexOf('(')); 188 switch (fileName) 189 { 190 case "insert": 191 createdFileCounts[(int)LogType.Insert]++; 192 break; 193 case "update": 194 createdFileCounts[(int)LogType.Update]++; 195 break; 196 case "all": 197 createdFileCounts[(int)LogType.All]++; 198 break; 199 default: 200 break; 201 } 202 } 203 } 204 205 } 206 } 207 #endregion 208 209 #region 寫日誌 210 211 /// <summary> 212 /// 寫日誌 213 /// </summary> 214 /// <param name="strLog">日誌內容</param> 215 public static void WriteLog(string strLog) 216 { 217 WriteLog(strLog, LogType.All); 218 } 219 220 /// <summary> 221 /// 寫日誌 222 /// </summary> 223 /// <param name="strLog">日誌內容</param> 224 /// <param name="logType">日誌類型</param> 225 public static void WriteLog(string strLog, LogType logType) 226 { 227 if (String.IsNullOrEmpty(strLog)) 228 { 229 return; 230 } 231 strLog = strLog.Replace("\n", "\r\n"); 232 233 FileStream fs = null; 234 try 235 { 236 string logPath = GetLogPath(logType, false); 237 FileInfo fileInfo = new FileInfo(logPath); 238 if (MaxFileSize > 0 && fileInfo.Length > (1024 * 1024 * MaxFileSize)) 239 { 240 fileInfo.MoveTo(GetLogPath(logType, true)); 241 } 242 fs = File.Open(logPath, FileMode.OpenOrCreate); 243 //fs = File.OpenWrite(logPath); 244 byte[] btFile = Encoding.UTF8.GetBytes(strLog); 245 //設定書寫的開始位置爲文件的末尾 246 fs.Position = fs.Length; 247 //將待寫入內容追加到文件末尾 248 fs.Write(btFile, 0, btFile.Length); 249 } 250 finally 251 { 252 if (fs != null) 253 { 254 fs.Close(); 255 fs.Dispose(); 256 } 257 } 258 } 259 260 /// <summary> 261 /// 寫入錯誤日誌隊列 262 /// </summary> 263 /// <param name="msg">錯誤信息</param> 264 public static void WriteLogAsync(string strLog, LogType logType) 265 { 266 //將錯誤信息添加到隊列中 267 lock (qMsg) 268 { 269 qMsg.Enqueue(string.Format("{0}&&{1}\r\n", logType, strLog)); 270 } 271 } 272 #endregion 273 274 }
使用時,能夠直接調用WriteLogAsync函數,將消息添加到隊列中,而後在另外的線程中處理隊列中的消息。code
其中,若是沒有給LogFilePath屬性賦值,則有一個默認的文件存放路徑。MaxFileSize屬性是用來限制日誌文件大小的,若是小於等於0則表示不限制。若是有限制,當文件大小超過這個最大值後會將原來的文件重命名,而後再建立一個「本身」。例如:正在存放日誌的文件名爲"All.log",當它滿了之後就成爲「All(n).log」文件,n爲從1開始遞增的數字,而後會從新建立一個「All.log」文件接着存放日誌。orm