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.
421 lines
14 KiB
421 lines
14 KiB
using System;
|
|
|
|
|
|
using Sog;
|
|
using Sog.Log;
|
|
|
|
using ProtoCSStruct;
|
|
using Sog.Service;
|
|
|
|
namespace BillLog
|
|
{
|
|
public class BillLogMsgHandler : BaseReloadableService
|
|
{
|
|
private ServerApp m_app;
|
|
|
|
// 本地bill日志
|
|
private Logger m_billLogger;
|
|
private DateTime m_lastLogTime;
|
|
|
|
// 本地bdc日志
|
|
private Logger m_bdcLogger;
|
|
private DateTime m_lastBdcLogTime;
|
|
|
|
// bdc客户端日志
|
|
private Logger m_clibdcLogger;
|
|
private DateTime m_cliLastBdcLogTime;
|
|
|
|
private int noUidCount;
|
|
|
|
//ta日志
|
|
private Logger m_taLogger;
|
|
private DateTime m_lastTaLogTime;
|
|
//ta客户端日志
|
|
private Logger m_clitaLogger;
|
|
private DateTime m_lastCliTaLogTime;
|
|
|
|
//ta过滤日志,关闭的日志是数数数量太多了不要了,我们这最好存好不上报吧
|
|
private Logger m_taFilterLogger;
|
|
private DateTime m_lastTaFilterLogTime;
|
|
|
|
// todo 这个值需要存盘, 否则会有重复的问题
|
|
private static long uuidSeq;
|
|
|
|
public override int GetServiceType()
|
|
{
|
|
return BillLogServiceType.BillLogMsgHandler;
|
|
}
|
|
|
|
//销毁的时候置空
|
|
public override void Dispose()
|
|
{
|
|
m_app = null;
|
|
m_billLogger = null;
|
|
m_bdcLogger = null;
|
|
m_clibdcLogger = null;
|
|
m_taLogger = null;
|
|
m_taFilterLogger = null;
|
|
}
|
|
|
|
public BillLogMsgHandler(ServerApp app)
|
|
{
|
|
m_app = app;
|
|
|
|
var logPaths = BillLogServerUtils.GetServerConfig().logpatchs;
|
|
|
|
//先写死,to do 放到配置文件
|
|
m_billLogger = new Logger(logPaths.bill, "", LogLevel.Debug);
|
|
//关闭文件自动滚动功能,自己实现按时间(每小时)滚动
|
|
m_billLogger.CloseShift();
|
|
|
|
|
|
m_bdcLogger = new Logger(logPaths.bdc, "", LogLevel.Debug);
|
|
//关闭文件自动滚动功能,自己实现按时间(每小时)滚动
|
|
m_bdcLogger.CloseShift();
|
|
|
|
m_clibdcLogger = new Logger(logPaths.bdcCli, "", LogLevel.Debug);
|
|
//关闭文件自动滚动功能,自己实现按时间(每小时)滚动
|
|
m_clibdcLogger.CloseShift();
|
|
|
|
m_taLogger = new Logger(logPaths.ta, "", LogLevel.Debug);
|
|
//关闭文件自动滚动功能,自己实现按时间(每小时)滚动
|
|
m_taLogger.CloseShift();
|
|
|
|
m_clitaLogger = new Logger(logPaths.taCli, "", LogLevel.Debug);
|
|
//关闭文件自动滚动功能,自己实现按时间(每小时)滚动
|
|
m_clitaLogger.CloseShift();
|
|
|
|
m_taFilterLogger = new Logger(logPaths.taFilter, "", LogLevel.Debug);
|
|
//关闭文件自动滚动功能,自己实现按时间(每小时)滚动
|
|
m_taFilterLogger.CloseShift();
|
|
|
|
}
|
|
|
|
public ServerApp GetApp()
|
|
{
|
|
return m_app;
|
|
}
|
|
|
|
public void HandlerMessage(uint remoteAppID, MessageData message)
|
|
{
|
|
StructPacket packet;
|
|
bool bSuccess = BillLogServerUtils.GetProtoPacker().UnpackMessage(message, out packet);
|
|
if(bSuccess == false)
|
|
{
|
|
TraceLog.Error("HandlerMessage ,unpack msg failed {0}, remoteAppID {1}", message.Header.Type, remoteAppID);
|
|
return;
|
|
}
|
|
|
|
//预先判断,提高效率
|
|
if (TraceLog.GetLogLevel() <= (int)Sog.Log.LogLevel.TraceDetail)
|
|
{
|
|
TraceLog.TraceDetail("recv message from server {0}, message type {1} length {2} : {3}->{4}"
|
|
, ServerIDUtils.IDToString(remoteAppID)
|
|
, message.Header.Type
|
|
, message.Header.Length
|
|
, packet.MessageName()
|
|
, packet.ToString());
|
|
}
|
|
|
|
switch (packet.MsgID)
|
|
{
|
|
case (int)SSGameMsgID.BillLogReq:
|
|
OnBillLogReq(remoteAppID, packet);
|
|
break;
|
|
|
|
case (int)SSGameMsgID.BdcLogReq:
|
|
OnBDCLogReq(remoteAppID, packet);
|
|
break;
|
|
case (int)CSGameMsgID.LogClientBdcReq:
|
|
OnBdcClientLogReq(remoteAppID, packet);
|
|
break;
|
|
case (int)SSGameMsgID.TaLogReq:
|
|
OnTALogReq(remoteAppID, packet);
|
|
break;
|
|
case (int)CSGameMsgID.LogClientTaReq:
|
|
OnTAClientLogReq(remoteAppID, packet);
|
|
break;
|
|
default:
|
|
TraceLog.Error("MsgHandler unknow MsgID {0}", packet.MsgID);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
private void OnBillLogReq(uint remoteAppID, StructPacket packet)
|
|
{
|
|
ref SSBillLogReq billLogReq = ref packet.GetMessage<SSBillLogReq>();
|
|
|
|
string logmessage = billLogReq.StrLogMessage.ToString();
|
|
|
|
TraceLog.Debug("OnBillLogReq log message from server {0} log:{1}", ServerIDUtils.IDToString(remoteAppID), logmessage);
|
|
|
|
WriteBillLog(logmessage);
|
|
}
|
|
|
|
private void OnBdcClientLogReq(uint remoteAppID, StructPacket packet)
|
|
{
|
|
ref CsLogClientBDCReq billLogReq = ref packet.GetMessage<CsLogClientBDCReq>();
|
|
|
|
string logmessage = billLogReq.StrLogMessage.ToString();
|
|
|
|
TraceLog.Debug("OnBdcClientLogReq log message from server {0} log:{1}", ServerIDUtils.IDToString(remoteAppID), logmessage);
|
|
|
|
WriteClientBdcLog(logmessage);
|
|
}
|
|
|
|
private void OnTAClientLogReq(uint remoteAppID, StructPacket packet)
|
|
{
|
|
ref CsLogClientTAReq taLogReq = ref packet.GetMessage<CsLogClientTAReq>();
|
|
|
|
string logmessage = taLogReq.StrLogMessage.ToString();
|
|
|
|
TraceLog.Debug("OnTAClientLogReq log message from server {0} log:{1}", ServerIDUtils.IDToString(remoteAppID), logmessage);
|
|
|
|
WriteClientTALog(logmessage);
|
|
}
|
|
|
|
|
|
private void WriteBillLog(string strMessage)
|
|
{
|
|
DateTime now = DateTime.Now;
|
|
|
|
if(IsLogFileNameChanged(m_lastLogTime, now))
|
|
{
|
|
m_lastLogTime = now;
|
|
m_billLogger.SetFileName(CalcLogFileName(now));
|
|
}
|
|
|
|
//时间就用这个now,写的时候不用再取了,取2次会有时间不一致问题
|
|
m_billLogger.WriteLogWithTime(now,strMessage);
|
|
}
|
|
|
|
private void WriteLocalBdcLog(string strMessage)
|
|
{
|
|
DateTime now = DateTime.Now;
|
|
|
|
if (IsLogFileNameChanged(m_lastBdcLogTime, now))
|
|
{
|
|
m_lastBdcLogTime = now;
|
|
m_bdcLogger.SetFileName(CalcLogFileName(now, 1));
|
|
}
|
|
|
|
//时间就用这个now,写的时候不用再取了,取2次会有时间不一致问题
|
|
m_bdcLogger.WriteLogWithTime(now, strMessage);
|
|
}
|
|
|
|
private void WriteLocalTALog(string strMessage)
|
|
{
|
|
DateTime now = DateTime.Now;
|
|
|
|
if (IsLogFileNameChanged(m_lastTaLogTime, now))
|
|
{
|
|
m_lastTaLogTime = now;
|
|
m_taLogger.SetFileName(CalcLogFileName(now, 3));
|
|
}
|
|
|
|
m_taLogger.WriteTALog(strMessage);
|
|
}
|
|
|
|
private void WriteLocalTAFilterLog(string strMessage)
|
|
{
|
|
DateTime now = DateTime.Now;
|
|
|
|
if (IsLogFileNameChanged(m_lastTaFilterLogTime, now))
|
|
{
|
|
m_lastTaFilterLogTime = now;
|
|
m_taFilterLogger.SetFileName(CalcLogFileName(now, 5));
|
|
}
|
|
|
|
m_taFilterLogger.WriteTALog(strMessage);
|
|
}
|
|
|
|
private void WriteClientBdcLog(string strMessage)
|
|
{
|
|
DateTime now = DateTime.Now;
|
|
|
|
if (IsLogFileNameChanged(m_cliLastBdcLogTime, now))
|
|
{
|
|
m_cliLastBdcLogTime = now;
|
|
m_clibdcLogger.SetFileName(CalcLogFileName(now, 2));
|
|
}
|
|
|
|
//时间就用这个now,写的时候不用再取了,取2次会有时间不一致问题
|
|
m_clibdcLogger.WriteLogWithTime(now, strMessage);
|
|
}
|
|
|
|
private void WriteClientTALog(string strMessage)
|
|
{
|
|
DateTime now = DateTime.Now;
|
|
|
|
if (IsLogFileNameChanged(m_lastCliTaLogTime, now))
|
|
{
|
|
m_lastCliTaLogTime = now;
|
|
m_clitaLogger.SetFileName(CalcLogFileName(now, 4));
|
|
}
|
|
|
|
m_clitaLogger.WriteLogWithTime(now, strMessage);
|
|
}
|
|
private string CalcLogFileName(DateTime now, int logType = 0)
|
|
{
|
|
// "2016-10-01 01:13:59"
|
|
string nowTimeFormat = now.ToString("u");
|
|
string nowDay = nowTimeFormat.Substring(0, 10);
|
|
string nowHour = nowTimeFormat.Substring(11, 2);
|
|
|
|
if (logType == 1)
|
|
{
|
|
return string.Format("bdcSvr_{0}_{1}.log", nowDay, nowHour);
|
|
}
|
|
else if(logType == 2)
|
|
{
|
|
return string.Format("bdcCli_{0}_{1}.log", nowDay, nowHour);
|
|
}
|
|
else if (logType == 3)
|
|
{
|
|
return string.Format("talog_{0}_{1}.log", nowDay, nowHour);
|
|
}
|
|
else if (logType == 4)
|
|
{
|
|
return string.Format("clitalog_{0}_{1}.log", nowDay, nowHour);
|
|
}
|
|
else if (logType == 5)
|
|
{
|
|
return string.Format("tafilterlog_{0}_{1}.log", nowDay, nowHour);
|
|
}
|
|
|
|
return string.Format("bill_{0}_{1}.log", nowDay, nowHour);
|
|
}
|
|
|
|
private bool IsLogFileNameChanged(DateTime lastLogTime, DateTime now)
|
|
{
|
|
if(lastLogTime.Hour == now.Hour
|
|
&& lastLogTime.Day == now.Day
|
|
&& lastLogTime.Month == now.Month
|
|
&& lastLogTime.Year == now.Year)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private string GenUUID()
|
|
{
|
|
uuidSeq++;
|
|
if (uuidSeq > 1000000)
|
|
{
|
|
uuidSeq = 1;
|
|
}
|
|
|
|
return $"{BillLogServerUtils.GetDateTime().ToString("yyyyMMdd-HHmmss")}-{uuidSeq.ToString().PadLeft(7, '0')}";
|
|
}
|
|
|
|
private void OnBDCLogReq(uint remoteAppID, StructPacket packet)
|
|
{
|
|
var cfg = BillLogServerUtils.GetServerConfig().bdcCfg;
|
|
if (cfg.isBdcOpen == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//因为需要放入每个线程的队列,所以需要clone 一个新的对象,UnpackMessage出来的消息每次其实是同一个
|
|
//如果存在性能问题,可以根据消息类型进行缓冲
|
|
packet = packet.Clone();
|
|
|
|
string uuid = GenUUID();
|
|
ref SSBDCLogReq req = ref packet.GetMessage<SSBDCLogReq>();
|
|
req.Event_uuid.SetString(uuid);
|
|
|
|
// 本地bdc日志在主线程里面写入bdc_xxx_xxx.log
|
|
// 本地bdc日志比远端bdc日志少了2个字段, appKey, platform, 这2个字段读取的配置文件, 运行期间不会改变
|
|
// 另外, 本地和远端的event_time可能不一致, 按照bdc要求event_time是日志上报时间
|
|
// 远端event_time是work线程实际提交http请求时的时间.
|
|
// 目前选择不统一本地和远端的event_time, 保留时间差以便性能分析
|
|
var localBdcMsg = string.Format("{0}|event_uuid={1}|event_time={2}|event_time2={3}|platform={4}|time_zone={5}"
|
|
, req.LogMsg.GetString()
|
|
, uuid
|
|
, BillLogServerUtils.GetTimeSecond().ToString()
|
|
, BillLogServerUtils.GetDateTime().ToString("yyyy-MM-dd"),
|
|
BillLogServerUtils.GetServerConfig().bdcCfg.Bdcplatform,
|
|
"UTC+" + AppTime.TimeZone.ToString() + ":00");
|
|
|
|
WriteLocalBdcLog(localBdcMsg);
|
|
|
|
bool isFilter = false;
|
|
if (req.EventId > 0 && cfg.FilterLogEventIds != null && cfg.FilterLogEventIds.Length > 0)
|
|
{
|
|
for (int i = 0; i < cfg.FilterLogEventIds.Length; i++)
|
|
{
|
|
if (req.EventId == cfg.FilterLogEventIds[i])
|
|
{
|
|
isFilter = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (!isFilter)
|
|
{
|
|
int iTaskIndex = CalcTaskIndex(noUidCount);
|
|
noUidCount++;
|
|
if (noUidCount < 0)
|
|
{
|
|
noUidCount = 1;
|
|
}
|
|
|
|
MessageTaskDistributor.Instance.Distribute(remoteAppID, packet, iTaskIndex);
|
|
}
|
|
|
|
}
|
|
|
|
private void OnTALogReq(uint remoteAppID, StructPacket packet)
|
|
{
|
|
if (BillLogServerUtils.GetServerConfig().isTALogOpen == 0)
|
|
{
|
|
return;
|
|
}
|
|
ref SSTALogReq req = ref packet.GetMessage<SSTALogReq>();
|
|
if(IsTaFilterEvent(req.EventName.ToString())) //是过滤事件
|
|
{
|
|
WriteLocalTAFilterLog(req.LogMsg.ToString());
|
|
}
|
|
else
|
|
{
|
|
WriteLocalTALog(req.LogMsg.ToString());
|
|
}
|
|
|
|
}
|
|
|
|
private bool IsTaFilterEvent(string eventName)
|
|
{
|
|
if(string.IsNullOrEmpty(eventName)) //不是事件,是上报属性
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var cfg = BillLogServerUtils.GetServerConfig().taCfg;
|
|
//没有配置过滤
|
|
if(cfg == null || cfg.isOpenFilter == false || cfg.filterEvents == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
foreach(var filter in cfg.filterEvents)
|
|
{
|
|
if(filter == eventName)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
return false;
|
|
}
|
|
private int CalcTaskIndex(long uid)
|
|
{
|
|
return (int)(uid % MessageTaskHandler.TaskCount);
|
|
}
|
|
}
|
|
}
|
|
|