在实际项目开发中,会涉及日志记录问题,比较常用的有Log4Net,NLog等几个,而小项目小工具的话,则无需费此大驾。而譬如串口开发的话,需要记录串口过来的数据等等,则需要考虑日志记录上线程的问题,为了方便后续使用,封装了下代码,如下:
usingSystem;usingSystem.Diagnostics;usingSystem.IO;usingSystem.Text;usingSystem.Threading;namespaceCSharpUtilHelpV2
{/// <summary>/// 日志类型枚举/// </summary>publicenumLogType
{/// <summary>/// 一般输出/// </summary>Trace,/// <summary>/// 警告/// </summary>Warning,/// <summary>/// 错误/// </summary>Error,/// <summary>/// SQL/// </summary>SQL
}/// <summary>/// 基于.NET 2.0日志工具类/// </summary>publicclassLogToolV2
{PRivatestaticreadonlyThread LogTask;privatestaticreadonlyThreadSafeQueueV2<string> LogColQueue;//自定义线程安全的QueueprivatestaticreadonlyobjectSyncRoot;privatestaticreadonlystringFilePath;privatestaticreadonlylongBackFileSize_MB = 2;//超过2M就开始备份日志文件staticLogToolV2()
{
SyncRoot =newobject();
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));
}
}privatestaticboolCreateFile(stringpath)
{bool_result =true;try{if(!File.Exists(path))
{
FileStream _files = File.Create(path);
_files.Close();
}
}catch(Exception)
{
_result =false;
}return_result;
}privatestaticboolCreateDirectory()
{bool_result =true;try{if(!Directory.Exists(FilePath))
{
Directory.CreateDirectory(FilePath);
}
}catch(Exception)
{
_result =false;
}return_result;
}
}
}
测试代码:
usingCSharpUtilHelpV2;usingSystem;usingSystem.Diagnostics;usingSystem.Threading;namespaceLogUtilHelpV2Test
{classProgram
{staticvoidMain(string[] args)
{try{
Debug.WriteLine("-------------");
Action _writeLog =delegate()
{for(inti = 0; i < 10000; i++)
LogToolV2.Log(Guid.NewGuid().ToString(), LogType.Trace);
};
Thread _wireteLogTask1 =newThread(newThreadStart(_writeLog));
_wireteLogTask1.Start();
Thread _wireteLogTask2 =newThread(newThreadStart(_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();
}
}
}
}
代码效果:
才疏学浅,如有纰漏,敬请指出,希望有所帮助!谢谢