队列写日志
/// <summary>
/// 多线程安全Log记录工具20180314
/// lqx
/// </summary>
public class LogHelper
{
//为了使用DBGView进行在线调试:
//System.Diagnostics.Debug.WriteLine("Debug模式可见")
//System.Diagnostics.Trace.WriteLine("Debug、Release都可见");
private static Thread WriteThread;
private static readonly Queue<string[]> MsgQueue;
private static readonly string FilePath;
private static Boolean autoResetEventFlag = false;
private static AutoResetEvent aEvent = new AutoResetEvent(false);
private static bool flag = true;
public static bool LogFlag = true;
private static string xmlPath = System.AppDomain.CurrentDomain.BaseDirectory + @"/log.xml";
static LogHelper()
{
FilePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "Log\\";
WriteThread = new Thread(WriteMsg);
MsgQueue = new Queue<string[]>();
WriteThread.Start();
}
public static void LogInfo(string msg)
{
Monitor.Enter(MsgQueue);
StringBuilder sb = GetCallerMethodBaseInfo(out MethodBase callerMethod, out string fileName);
sb.Insert(0, string.Format("{0} {1} ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"), msg));
string[] data = new string[2] { fileName + "_Info", sb.ToString() };
MsgQueue.Enqueue(data);
Monitor.Exit(MsgQueue);
if (autoResetEventFlag)
{
aEvent.Set();
}
}
public static void LogError(string msg)
{
Monitor.Enter(MsgQueue);
StringBuilder sb = GetCallerMethodBaseInfo(out MethodBase callerMethod, out string fileName);
sb.Insert(0, string.Format("{0} {1} ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"), msg));
string[] data = new string[2] { fileName + "_Error", sb.ToString() };
MsgQueue.Enqueue(data);
Monitor.Exit(MsgQueue);
if (autoResetEventFlag)
{
aEvent.Set();
}
}
public static void LogWarn(string msg)
{
Monitor.Enter(MsgQueue);
StringBuilder sb = GetCallerMethodBaseInfo(out MethodBase callerMethod, out string fileName);
sb.Insert(0, string.Format("{0} {1} ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"), msg));
string[] data = new string[2] { fileName + "_Warn", sb.ToString() };
MsgQueue.Enqueue(data);
Monitor.Exit(MsgQueue);
if (autoResetEventFlag)
{
aEvent.Set();
}
}
/// <summary>
/// ExitThread是退出日志记录线程的方法,一旦退出,无法开启,一般在程序关闭时执行
/// </summary>
public static void ExitThread()
{
flag = false;
aEvent.Set();//恢复线程执行
}
private static void WriteMsg()
{
try
{
while (flag)
{
//进行记录
if (LogFlag)
{
autoResetEventFlag = false;
if (!Directory.Exists(FilePath))
{
Directory.CreateDirectory(FilePath);
}
//写日志前先删除日志
if (File.Exists(xmlPath))
{
new AsyDispose().LogDeal(false, xmlPath);
}
//读取配置日志文件最大容量大小,默认10M
int maxsize = LogConfig.logfliesize == 0 ? 10 : LogConfig.logfliesize;
while (MsgQueue.Count > 0)
{
Monitor.Enter(MsgQueue);
string[] msg = MsgQueue.Dequeue();
Monitor.Exit(MsgQueue);
string fileName = FilePath + DateTime.Now.ToString("yyyy-MM-dd") + "_" + msg[0] + "_.log";
var logStreamWriter = new StreamWriter(fileName, true);
logStreamWriter.WriteLine(msg[1]);
if (GetFileSize(fileName) > 1024 * maxsize)//大于10M
{
logStreamWriter.Flush();
logStreamWriter.Close();
CopyToBak(fileName);
logStreamWriter = new StreamWriter(fileName, false);
logStreamWriter.Write("");
logStreamWriter.Flush();
logStreamWriter.Close();
logStreamWriter = new StreamWriter(fileName, true);
}
//下面用于DbgView.exe工具进行在线调试
//System.Diagnostics.Debug.WriteLine("BS_Debug:" + msg);
//System.Diagnostics.Trace.WriteLine("BS_Release:" + msg);
logStreamWriter.Flush();
logStreamWriter.Close();
}
autoResetEventFlag = true;
aEvent.WaitOne();
}
else
{
autoResetEventFlag = true;
aEvent.WaitOne();
}
}
}
catch (Exception ex) { }
}
private static long GetFileSize(string fileName)
{
long strRe = 0;
if (File.Exists(fileName))
{
var myFs = new FileInfo(fileName);
strRe = myFs.Length / 1024;
//Console.WriteLine(strRe);
}
return strRe;
}
private static void CopyToBak(string sFileName)
{
int fileCount = 0;
string sBakName = "";
do
{
fileCount++;
sBakName = sFileName + "." + fileCount + ".BAK";
}
while (File.Exists(sBakName));
File.Copy(sFileName, sBakName);
}
public static StringBuilder GetCallerMethodBaseInfo(out MethodBase outCallerMethod, out string fileName)
{
var result = new StringBuilder();
fileName = "";
result.AppendLine();
outCallerMethod = null;
try
{
MethodBase callerMethod = null;
var i = 2;
while (true)
{
var curstackFrame = new System.Diagnostics.StackFrame(i, true);
if (curstackFrame == null)
{
break;
}
if (curstackFrame.GetILOffset() < 0)
{
break;
}
callerMethod = curstackFrame?.GetMethod();
if (callerMethod == null)
{
break;
}
if (outCallerMethod == null)
{
outCallerMethod = callerMethod;
}
if (i == 2)
{
string className = "";
if (callerMethod.DeclaringType.Name.ToString().Length > 20)
className = callerMethod.DeclaringType.Name.ToString().Substring(0, 20);
else
className = callerMethod.DeclaringType.Name.ToString();
fileName = className + "_" + callerMethod.Name;
fileName = fileName.Replace("<", "").Replace(">", "");//预防非法字符
}
result.AppendLine("调用栈:" + callerMethod.DeclaringType + "." + callerMethod.Name + " (" + curstackFrame.GetFileLineNumber() + ")");
i++;
}
return result;
}
catch (Exception ex) { return result; }
}
}
/// <summary>
/// 获取配置
/// </summary>
public class LogConfig
{
private static string xmlPath = "";
/// <summary>
/// 文件夹名称
/// </summary>
public static string folderstr { get; set; }
/// <summary>
/// 文件尾缀
/// </summary>
public static string postfixStr { get; set; }
/// <summary>
/// 保留天数
/// </summary>
public static string obligateStr { get; set; }
/// <summary>
/// 单个日志文件最大容量,单位M,默认10M
/// </summary>
public static int logfliesize { get; set; }
static LogConfig()
{
xmlPath = System.AppDomain.CurrentDomain.BaseDirectory + @"/Lib.LogManager.xml";
if (File.Exists(xmlPath))
{
XDocument document = XDocument.Load(xmlPath);
XElement root = document.Root;
//获取根元素下的所有子元素
IEnumerable<XElement> enumerable = root.Elements();
foreach (XElement item in enumerable)
{
if (item.Name == "folder")
{
folderstr = item.Value;
}
else if (item.Name == "postfix")
{
postfixStr = item.Value;
}
else if (item.Name == "obligate")
{
obligateStr = item.Value;
}
else if (item.Name == "logfliesize")
{
if (string.IsNullOrEmpty(item.Value))
logfliesize = 10;
else
{
int temp = 10;
if (int.TryParse(item.Value, out temp))
{
logfliesize = temp;
}
else
logfliesize = 10;
}
}
}
}
}
}
/// <summary>
/// 自动清除日志处理类
/// </summary>
public class AsyDispose
{
#region log.xml
//<?xml version = "1.0" encoding="utf-8" ?>
//<config>
// <!--配置文件夹的名称(中间用英文逗号隔开)-->
// <folder>log,test</folder>
// <!--配置文件后缀(中间用英文逗号隔开)-->
// <postfix>.log,.txt</postfix>
// <!--预留时间-->
// <obligate>30</obligate>
// <!--单个日志文件最大容量,单位M,默认10M-->
// <logfliesize>10</logfliesize>
//</config>
#endregion
//string xmlPath = System.AppDomain.CurrentDomain.BaseDirectory + @"/log.xml";
/// <summary>
/// 文件夹名称
/// </summary>
public string folderstr { get; set; }
/// <summary>
/// 文件尾缀
/// </summary>
public string postfixStr { get; set; }
/// <summary>
/// 保留天数
/// </summary>
public string obligateStr { get; set; }
public void LogDeal(bool isStop, string xmlPath)
{
if (System.IO.File.Exists(xmlPath))
{
//异步执行
if (!string.IsNullOrEmpty(LogConfig.folderstr) && !string.IsNullOrEmpty(LogConfig.postfixStr) && !string.IsNullOrEmpty(LogConfig.obligateStr))
{
OptLogFile(folderstr, postfixStr, obligateStr);
}
}
}
public bool isParms { get; set; }
internal void OptLogFile(string folderstr, string postfixStr, string obligateStr)
{
int obligateDu = 0;
if (int.TryParse(obligateStr, out obligateDu) && obligateDu <= 0)
{
obligateDu = 30;
}
string pathSource = System.AppDomain.CurrentDomain.BaseDirectory;
string[] folderArr = null;
string[] pathList = null;
if (!string.IsNullOrEmpty(folderstr))
{
folderArr = folderstr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
pathList = new string[folderArr.Length];
for (int itfo = 0; itfo < folderArr.Length; itfo++)
{
pathList[itfo] = pathSource + "\\" + folderArr[itfo];
}
foreach (string path in pathList)
{
string[] postfixArr = postfixStr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (Directory.Exists(path))
{
DirectoryInfo dyinfo = new DirectoryInfo(path);
foreach (FileInfo fi in dyinfo.GetFiles())
{
foreach (string fix in postfixArr)
{
if (fi.Extension.Contains(fix)
&& (DateTime.Now - fi.LastWriteTime).Days > obligateDu)
{
File.Delete(path + "\\" + fi.Name);
LogHelper.LogInfo("记录删除日志:"+ path + "\\" + fi.Name + "(" + fi.LastWriteTime + ")");
continue;
}
if (fi.Name.Contains("AsyDispose") && fi.Length > 200 * 1024)
{
File.Delete(path + "\\" + fi.Name);
}
}
}
}
}
//if (isParms)
//{
// System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName("lis.client.LogDispose");
// foreach (System.Diagnostics.Process p in ps)
// {
// p.Kill();
// }
//}
}
}
}