You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
11 KiB

1 month ago
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading;
using Sog;
namespace BillLog
{
public static class LogTransferHandler
{
private static Thread m_thread;
private static ParameterizedThreadStart m_parStart;
private static AutoResetEvent m_eventWorkList;
private static bool m_isStop = false;
private static long m_times = 0;//记录下检查次数
private static long m_errorTimes = 0;//记录下异常次数
private static long m_tickMs;
//目录相关
private static Dictionary<string,string> logDir;
private static Dictionary<string, string> transferDir;
private static int intervalDay = 30;
//按类型,按天存放文件
private static Dictionary<string, Dictionary<int,List<string>>> tmpDir = new Dictionary<string, Dictionary<int, List<string>>>();
public static void InitLogTransferHandler()
{
StartThread();
}
//停服
public static void OnStop()
{
TraceLog.Debug("LogTransferHandler stop server begin");
m_isStop = true;
m_eventWorkList?.Set();
m_thread?.Join();//最多打完一天的包就会退出
TraceLog.Debug("LogTransferHandler stop server end");
}
//释放
public static void OnDispose()
{
TraceLog.Debug("LogTransferHandler OnDispose begin");
m_isStop = true;
m_eventWorkList?.Set();
m_thread?.Join();
//清空
m_eventWorkList = null;
m_thread = null;
m_parStart = null;
logDir = null;
transferDir = null;
TraceLog.Debug("LogTransferHandler OnDispose end");
}
private static void StartThread()
{
TraceLog.Debug("LogTransferHandler StartThread");
logDir = new Dictionary<string, string>();
transferDir = new Dictionary<string, string>();
m_eventWorkList = new AutoResetEvent(false);
m_parStart = DoThreadWork;
m_thread = new Thread(m_parStart, 1024 * 1024 * 10);
//设置成后台线程,如果不是后台线程,线程不是主动关闭,则会一直运行,那怕进程主线程退出也没用
m_thread.IsBackground = true;
m_thread.Start();
}
private static void DoThreadWork(object obj)
{
while (!m_isStop)
{
//执行一次
m_eventWorkList.WaitOne();
if (m_isStop)
{
break;
}
//todo
try
{
m_times++;
TraceLog.Debug("LogTransferHandler DoThreadWork Times {0}", m_times);
LogTransfer(AppTime.GetNowSysSecond());
}
catch (Exception e)
{
m_errorTimes++;
TraceLog.Error("LogTransferHandler DoThreadWork Error Times {0} ",m_times);
TraceLog.Exception(e);
BillLogServerUtils.GetApp()?.Alerter?.AlertException(e);
}
//重置
m_eventWorkList.Reset();
}
}
public static void TickDaily(long nowMs)
{
if (m_tickMs == 0)
{
m_tickMs = nowMs;
}
//每小时
if (m_tickMs + 3600 * 1000 > nowMs)
{
return;
}
m_tickMs = nowMs;
//暂时每天3点检查下
if (AppTime.GetHour(nowMs / 1000) != 3)
{
return;
}
//检查一次数据
m_eventWorkList?.Set();
}
public static void InitLogPath()
{
if (logDir == null || transferDir == null) return;
var cfg = BillLogServerUtils.GetServerConfig();
if (cfg.logTransfer == null || string.IsNullOrEmpty(cfg.logTransfer.transferPath) ||
cfg.logTransfer.transferLogs == null ||
cfg.logTransfer.transferLogs.Length == 0)
{
return;
}
if (!Directory.Exists(cfg.logTransfer.transferPath))
{
Directory.CreateDirectory(cfg.logTransfer.transferPath);
}
logDir.Clear();
transferDir.Clear();
if (cfg.logTransfer.intervalDay > 0)
{
intervalDay = cfg.logTransfer.intervalDay;
}
foreach (var logs in cfg.logTransfer.transferLogs)
{
switch (logs)
{
case "bill":
GetTransferPath(cfg.logpatchs.bill,cfg,logs);
break;
case "bdc":
GetTransferPath(cfg.logpatchs.bdc, cfg, logs);
break;
case "bdcCli":
GetTransferPath(cfg.logpatchs.bdcCli, cfg, logs);
break;
case "ta":
GetTransferPath(cfg.logpatchs.ta, cfg, logs);
break;
case "taCli":
GetTransferPath(cfg.logpatchs.taCli, cfg, logs);
break;
case "taFilter":
GetTransferPath(cfg.logpatchs.taFilter, cfg, logs);
break;
}
}
//不存在,创建目录
foreach (var log in transferDir)
{
if (!Directory.Exists(log.Value))
{
Directory.CreateDirectory(log.Value);
}
}
}
private static void GetTransferPath(string logsDir,BillLogServerConfig cfg,string logs)
{
var split = logsDir.Split("/");
if (split.Length == 0)
{
return;
}
string tpath = null;
if (string.IsNullOrEmpty(split[split.Length - 1]))
{
if (split.Length >= 2)
{
tpath = split[split.Length - 2];
}
}
else
{
tpath = split[split.Length - 1];
}
if (string.IsNullOrEmpty(tpath))
{
return;
}
tpath = cfg.logTransfer.transferPath + "/" + tpath;
logDir.Add(logs, logsDir);
transferDir.Add(logs, tpath);
}
private static void LogTransfer(long nowSec)
{
if (logDir == null || transferDir == null) return;
if (logDir.Count == 0 || transferDir.Count == 0) return;
tmpDir.Clear();
//找到所有的文件
foreach (var log in logDir)
{
if (m_isStop)
{
//如果开始停服了
return;
}
if (!transferDir.ContainsKey(log.Key))
{
continue;
}
string[] files = Directory.GetFiles(log.Value, "*.log");
foreach (var file in files)
{
var createTime = Directory.GetCreationTime(file);
var diffday = AppTime.GetDayElapse(nowSec, AppTime.GetTimeSecond(createTime),0);
if (diffday >= intervalDay)
{
if (!tmpDir.ContainsKey(log.Key))
{
tmpDir.Add(log.Key,new Dictionary<int, List<string>>());
}
if (!tmpDir[log.Key].ContainsKey(diffday))
{
tmpDir[log.Key].Add(diffday,new List<string>());
}
//同一天的文件放在一起压缩打包
tmpDir[log.Key][diffday].Add(file);
}
}
}
//压缩文件和删除文件
foreach (var tmp in tmpDir)//一个类型所有文件
{
if (m_isStop)
{
//如果开始停服了
return;
}
if (!transferDir.ContainsKey(tmp.Key))
{
continue;
}
foreach (var dayFile in tmp.Value)//每天所有文件
{
if (m_isStop)
{
//如果开始停服了
return;
}
if (dayFile.Value.Count == 0 || !File.Exists(dayFile.Value.First()))
{
continue;
}
string timeformat = Directory.GetCreationTime(dayFile.Value.First()).ToString("yyyy-MM-dd");
var targzpath = transferDir[tmp.Key] + "/" + $"{tmp.Key}_{timeformat}.zip";
var mvPath = transferDir[tmp.Key] + "/tmp/";
if (!Directory.Exists(mvPath))
{
Directory.CreateDirectory(mvPath);
}
//先移动文件到指定位置
try
{
foreach (var oneFile in dayFile.Value)
{
File.Move(oneFile, mvPath + Path.GetFileName(oneFile));
}
//打包zip
if (File.Exists(targzpath))
{
File.Delete(targzpath);
}
ZipFile.CreateFromDirectory(mvPath, targzpath);
//删除临时目录文件
if (Directory.Exists(mvPath))
{
DirectoryInfo di = new DirectoryInfo(mvPath);
di.Delete(true);
}
}
catch (Exception e)
{
//如果出问题了,要把临时目录的文件再移动回去
if (Directory.Exists(mvPath))
{
foreach (var oneFile in dayFile.Value)
{
var mvfilepath = mvPath + Path.GetFileName(oneFile);
if (File.Exists(mvfilepath))
{
File.Move(mvfilepath, oneFile);
}
}
}
throw;
}
}
}
//清空
tmpDir.Clear();
}
}
}