C#实现线程安全的简易日志记录方法
程序员文章站
2023-12-18 11:32:22
一般在实际项目的开发中,会要求涉及日志记录的问题,比较常用的有log4net,nlog等几个,而小项目小工具的话,则无需费此大驾。而譬如串口开发的话,需要记录串口过来的数据...
一般在实际项目的开发中,会要求涉及日志记录的问题,比较常用的有log4net,nlog等几个,而小项目小工具的话,则无需费此大驾。而譬如串口开发的话,需要记录串口过来的数据等等,这时候就要考虑日志记录上线程的问题。对此,为了方便后续使用,封装了下代码:
using system; using system.diagnostics; using system.io; using system.text; using system.threading; namespace csharputilhelpv2 { /// <summary> /// 日志类型枚举 /// </summary> public enum logtype { /// <summary> /// 一般输出 /// </summary> trace, /// <summary> /// 警告 /// </summary> warning, /// <summary> /// 错误 /// </summary> error, /// <summary> /// sql /// </summary> sql } /// <summary> /// 基于.net 2.0日志工具类 /// </summary> public class logtoolv2 { private static readonly thread logtask; private static readonly threadsafequeuev2<string> logcolqueue;//自定义线程安全的queue private static readonly object syncroot; private static readonly string filepath; private static readonly long backfilesize_mb = 2;//超过2m就开始备份日志文件 static logtoolv2() { syncroot = new object(); filepath = appdomain.currentdomain.setupinformation.applicationbase + "log\\"; logtask = new thread(writelog); logcolqueue = new threadsafequeuev2<string>(); logtask.start(); debug.writeline("log start......"); } /// <summary> /// 记录日志 /// </summary> /// <param name="msg">日志内容</param> public static void log(string msg) { string _msg = string.format("{0} : {2}", datetime.now.tostring("hh:mm:ss"), msg); logcolqueue.enqueue(msg); } /// <summary> /// 记录日志 /// </summary> /// <param name="msg">日志内容</param> /// <param name="type">日志类型</param> public static void log(string msg, logtype type) { string _msg = string.format("{0} {1}: {2}", datetime.now.tostring("hh:mm:ss"), type, msg); logcolqueue.enqueue(_msg); } /// <summary> /// 记录日志 /// </summary> /// <param name="ex">异常</param> public static void log(exception ex) { if (ex != null) { string _newline = environment.newline; stringbuilder _builder = new stringbuilder(); _builder.appendformat("{0}: {1}{2}", datetime.now.tostring("hh:mm:ss"), ex.message, _newline); _builder.appendformat("{0}{1}", ex.gettype(), _newline); _builder.appendformat("{0}{1}", ex.source, _newline); _builder.appendformat("{0}{1}", ex.targetsite, _newline); _builder.appendformat("{0}{1}", ex.stacktrace, _newline); logcolqueue.enqueue(_builder.tostring()); } } private static void writelog() { while (true) { if (logcolqueue.count() > 0) { string _msg = logcolqueue.dequeue(); monitor.enter(syncroot); if (!createdirectory()) continue; string _path = string.format("{0}{1}.log", filepath, datetime.now.tostring("yyyymmdd")); monitor.exit(syncroot); lock (syncroot) { if (createfile(_path)) processwritelog(_path, _msg);//写入日志到文本 } processbacklog(_path);//日志备份 } } } private static void processbacklog(string path) { lock (syncroot) { if (filetoolv2.getmbsize(path) > backfilesize_mb) { filetoolv2.copytobak(path); } } } private static void processwritelog(string path, string msg) { try { streamwriter _sw = file.appendtext(path); _sw.writeline(msg); _sw.flush(); _sw.close(); } catch (exception ex) { debug.writeline(string.format("写入日志失败,原因:{0}", ex.message)); } } private static bool createfile(string path) { bool _result = true; try { if (!file.exists(path)) { filestream _files = file.create(path); _files.close(); } } catch (exception) { _result = false; } return _result; } private static bool createdirectory() { bool _result = true; try { if (!directory.exists(filepath)) { directory.createdirectory(filepath); } } catch (exception) { _result = false; } return _result; } } }
测试代码如下:
using csharputilhelpv2; using system; using system.diagnostics; using system.threading; namespace logutilhelpv2test { class program { static void main(string[] args) { try { debug.writeline("-------------"); action _writelog = delegate() { for (int i = 0; i < 10000; i++) logtoolv2.log(guid.newguid().tostring(), logtype.trace); }; thread _wiretelogtask1 = new thread(new threadstart(_writelog)); _wiretelogtask1.start(); thread _wiretelogtask2 = new thread(new threadstart(_writelog)); _wiretelogtask2.start(); //throw new exception("test aaa bb cc"); } catch (exception ex) { logtoolv2.log(ex); console.writeline(ex.message.trim()); } finally { console.writeline("ok"); console.readline(); } } } }
代码运行效果如下所示:
感兴趣的读者可以自己测试运行一下,希望能对大家起到一点帮助!