using CYQ.Data.Tool;
using System;
using System.Collections.Generic;
using System.Threading;
namespace CYQ.Data
{
///
/// 内部定时日志工作
///
internal class LogWorker
{
///
/// 待处理的工作队列
///
static Queue _LogQueue = new Queue(1024);
///
/// 存档Hash,5分钟内存在相同的错误,则直接忽略
///
static MDictionary hashObj = new MDictionary();
static bool threadIsWorking = false;
public static void Add(SysLogs log)
{
long hash = log.Message.GetHashCode() + log.LogType.GetHashCode() + log.TraceID.GetHashCode();
if (hashObj.ContainsKey(hash))
{
if (hashObj[hash].AddMinutes(3) < DateTime.Now)
{
hashObj.Remove(hash);//超过1分钟的,不再存档。
}
log = null;//直接丢掉。
return;
}
hashObj.Add(hash, DateTime.Now);
_LogQueue.Enqueue(log);
if (!threadIsWorking)
{
threadIsWorking = true;
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), null);
}
}
private static void DoWork(object p)
{
//检测文件夹
string folder = AppConfig.WebRootPath;
string logPath = AppConfig.Log.Path;
logPath = logPath.Trim('/', '\\') + "/";
if (logPath.StartsWith("~/"))
{
logPath = logPath.Substring(2);
}
if (!AppConfig.IsWeb && logPath.Contains(":"))//winform 自定义绝对路径
{
string c = logPath.Contains("\\") ? "\\" : "/";
if (!logPath.EndsWith(c))
{
logPath = logPath + c;
}
folder = logPath;
}
else
{
folder = folder + logPath;
}
if (!System.IO.Directory.Exists(folder))
{
System.IO.Directory.CreateDirectory(folder);
}
int empty = 0;
while (true)
{
empty++;
bool dbErr = false;
while (_LogQueue.Count > 0)
{
empty = 0;
SysLogs sys = _LogQueue.Dequeue();
if (sys == null)
{
continue;
}
string todayKey = DateTime.Today.ToString("yyyyMMdd") + ".txt";
if (!string.IsNullOrEmpty(sys.LogType))
{
todayKey = sys.LogType.TrimEnd('_') + '_' + todayKey;
}
string filePath = folder + todayKey;
//检测数据库
//检测文件路径:
string body = sys.GetFormatterText();
IOHelper.Save(filePath, body, true, false, IOHelper.DefaultEncoding);
try
{
if (!dbErr)
{
if (!sys.IsWriteToTxt)
{
sys.Insert(InsertOp.None);//直接写数据库,日志文件依旧要写。
}
sys.Dispose();
}
}
catch
{
//数据库异常,不处理。
dbErr = true;
}
}
Thread.Sleep(1000);
if (empty > 100)
{
//超过10分钟没日志产生
hashObj.Clear();
threadIsWorking = false;
break;//结束线程。
}
}
}
}
}