簡單的檔案讀寫來寫log,功能不多但能滿足日常使用,資源占用小,上代碼:
示例程式百度云鏈接:
鏈接:https://pan.baidu.com/s/15bc2Q52Jwzysv6_xnWD41w
提取碼:afms
復制這段內容后打開百度網盤手機App,操作更方便哦
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// 日志記錄工具
/// </summary>
public static class Log
{
private static readonly Thread LogThread;
private static readonly ConcurrentQueue<string> LogQueue; //自定義執行緒安全的Queue
private static readonly object SyncRoot;
private static readonly string FilePath;
private static bool IsRun;
public static bool IsWriteLog;//可以設定是否啟用日志,一般只需要前期寫大量的日志方便排查bug,后期程式穩定了則不需要了.例外日志建議都開啟
/// <summary>
/// 日志型別列舉
/// </summary>
public enum LogType
{
/// <summary>
/// 一般輸出
/// </summary>
Trace,
/// <summary>
/// 警告
/// </summary>
Warning,
/// <summary>
/// 錯誤
/// </summary>
Error,
/// <summary>
/// SQL陳述句
/// </summary>
SQL
}
/// <summary>
/// 因為執行緒是死回圈讀取佇列,在沒有日志資料的時候可能會消耗不必要的資源,所有當佇列沒有資料的時候用該類控制執行緒的(繼續和暫停)
/// </summary>
private static readonly AutoResetEvent AutoReset = null;
static Log()
{
AutoReset = new AutoResetEvent(false);
SyncRoot = new object();
FilePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "運行日志\\";
LogQueue = new ConcurrentQueue<string>();
IsRun = true;
IsWriteLog = true;
LogThread = new Thread(WriteLog);
LogThread.IsBackground = true;
LogThread.Start();
}
//LogThread.IsBackground =false時,關閉程式時需要主動釋放
public static void Dispose()
{
try
{
if (IsRun)
{
IsRun = false;
AutoReset.Set();
AutoReset.Dispose();
}
}
catch (Exception)
{
throw;
}
}
public static void log(string msg)
{
try
{
if (!IsWriteLog) return;
string _msg = string.Format("{0} : {1}", DateTime.Now.ToString("HH:mm:ss:fff"), msg);
LogQueue.Enqueue(_msg);
if (AutoReset != null)
{
AutoReset.Set();
}
}
catch (Exception)
{
throw;
}
}
public static void MemoryInfo()
{
try
{
if (!IsWriteLog) return;
string msg;
Process CurrentProcess = Process.GetCurrentProcess();
//獲取當前行程占用記憶體:
long memory = CurrentProcess.WorkingSet64 / 1048576;
msg = "當前行程占用記憶體:" + memory.ToString() + "MB;";
string _msg = string.Format("{0} : {1}", DateTime.Now.ToString("HH:mm:ss:fff"), msg);
LogQueue.Enqueue(_msg);
AutoReset.Set();
}
catch (Exception)
{
throw;
}
}
public static void log(string msg, LogType type)
{
try
{
if (!IsWriteLog) return;
string _msg = string.Format("{0} {1}: {2}", DateTime.Now.ToString("HH:mm:ss:fff"), type, msg);
LogQueue.Enqueue(_msg);
AutoReset.Set();
}
catch (Exception)
{
throw;
}
}
public static void log(Exception ex)
{
try
{
if (ex != null)
{
string _newLine = string.Empty;
StringBuilder _builder = new StringBuilder();
_builder.AppendFormat("{0}: {1}{2}", DateTime.Now.ToString("HH:mm:ss:fff"), 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);
LogQueue.Enqueue(_builder.ToString());
AutoReset.Set();
}
}
catch (Exception)
{
throw;
}
}
private static void WriteLog()
{
try
{
while (IsRun)
{
if (LogQueue.Count() > 0)
{
string _msg;
LogQueue.TryDequeue(out _msg);
if (!string.IsNullOrWhiteSpace(_msg))
{
Monitor.Enter(SyncRoot);
if (!CreateDirectory()) continue;
string _path = string.Format("{0}{1}.log", FilePath, DateTime.Now.ToString("yyyy-MM-dd"));
Monitor.Exit(SyncRoot);
lock (SyncRoot)
{
if (CreateFile(_path))
ProcessWriteLog(_path, _msg); //寫入日志到文本
}
}
}
else
{
AutoReset.WaitOne();
}
}
}
catch (Exception)
{
throw;
}
}
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;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/275114.html
標籤:其他
下一篇:Java中的鎖詳解
