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.
 
 
 
 
 
 

339 lines
9.2 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Sog.Log
{
public class NetMsgStat
{
public int MsgID;
//发送数量
public int SendNum;
//发送的数据长度,字节
public long SendLength;
//接收数量
public int RecvNum;
//接收的数据长度,字节
public long RecvLength;
//接受消息总耗时
public long RecvTotalTime;
//接受消息最大耗时
public long RecvMaxTime;
//接受消息最小耗时
public long RecvMinTime;
public void Clear()
{
SendNum = 0;
SendLength = 0;
RecvNum = 0;
RecvLength = 0;
RecvTotalTime = 0;
RecvMaxTime = 0;
RecvMinTime = 0;
}
}
public class StatIDValue
{
public string ID;
public long Value;
//log后不清空,缺省都清空
public bool NotClearAfterLog;
}
/// <summary>
/// 服务器统计类
/// </summary>
public class ServerStat : Singleton<ServerStat>
{
//字符串为索引
private SortedDictionary<string, StatIDValue> m_statIDValuesMap;
//每个消息发送,接收信息
private SortedDictionary<int, NetMsgStat> m_statNetMsgMap;
private int TotalSendNum;
private int TotalRecvNum;
private long TotalSendLength;
private long TotalRecvLength;
private long m_lastLogTime;
private int m_logInterval;
private object m_threadLock = new object();
public ServerStat()
{
//缺省60秒log一次
m_logInterval = 60*1000;
m_statIDValuesMap = new SortedDictionary<string, StatIDValue>();
m_statNetMsgMap = new SortedDictionary<int, NetMsgStat>();
}
public void Tick(long tNowMs)
{
if(m_lastLogTime == 0)
{
m_lastLogTime = tNowMs;
}
if (tNowMs < m_lastLogTime + m_logInterval)
{
return;
}
m_lastLogTime = tNowMs;
LogHead();
LogContent();
LogTail();
}
private void LogContent_imp()
{
LogNetMsg();
LogIDValues();
LogGCMonitor();
}
private void LogContent()
{
lock (m_threadLock)
{
LogContent_imp();
}
}
//搞个头,看起来方便点
private void LogHead()
{
TraceLog.Stat("ServerStat begin =================================================================");
}
private void LogTail()
{
TraceLog.Stat("ServerStat end.\n");
}
private void LogIDValues()
{
//没有就算了
if(m_statIDValuesMap.Count == 0)
{
return;
}
TraceLog.Stat(" ID Value");
foreach(var idvalue in m_statIDValuesMap.Values)
{
TraceLog.Stat("{0,-40}{1,-20}", idvalue.ID, idvalue.Value);
//log完后清空这项数值
if (idvalue.NotClearAfterLog == false)
{
idvalue.Value = 0;
}
}
/*
var keys = m_statIDValuesMap.Keys;
var keyarray = keys.ToArray<string>();
foreach (string id in keyarray)
{
StatIDValue idvalue = m_statIDValuesMap[id];
TraceLog.Stat("{0,-40}{1,-20}",id, idvalue.Value);
//log完后清空这项数值
if (idvalue.NotClearAfterLog == false)
{
idvalue.Value = 0;
}
}*/
}
/// <summary>
/// 给id项目加value
/// </summary>
/// <param name="id"></param>
/// <param name="value"></param>
private void AddValue_imp(string id,long value, bool clearAfterLog = true)
{
if (m_statIDValuesMap.ContainsKey(id) == false)
{
StatIDValue idvalue = new StatIDValue();
idvalue.ID = id;
idvalue.Value = value;
idvalue.NotClearAfterLog = !clearAfterLog;
m_statIDValuesMap.Add(id, idvalue);
}
else
{
StatIDValue idvalue = m_statIDValuesMap[id];
idvalue.Value += value;
idvalue.NotClearAfterLog = !clearAfterLog;
}
}
public void AddValue(string id, long value, bool clearAfterLog = true)
{
lock (m_threadLock)
{
AddValue_imp(id, value, clearAfterLog);
}
}
/// <summary>
/// 设置id项目为value
/// </summary>
/// <param name="id"></param>
/// <param name="value"></param>
private void SetValue_imp(string id, long value, bool clearAfterLog = true)
{
if (m_statIDValuesMap.ContainsKey(id) == false)
{
StatIDValue idvalue = new StatIDValue();
idvalue.ID = id;
idvalue.Value = value;
idvalue.NotClearAfterLog = !clearAfterLog;
m_statIDValuesMap.Add(id, idvalue);
}
else
{
StatIDValue idvalue = m_statIDValuesMap[id];
idvalue.Value = value;
idvalue.NotClearAfterLog = !clearAfterLog;
}
}
public void SetValue(string id, long value, bool clearAfterLog = true)
{
lock (m_threadLock)
{
SetValue_imp(id, value, clearAfterLog);
}
}
//如果不存在则创建
private NetMsgStat GetNetMsgStatByID(int iMsgID)
{
if(!m_statNetMsgMap.ContainsKey(iMsgID))
{
NetMsgStat stat = new NetMsgStat();
stat.MsgID = iMsgID;
m_statNetMsgMap.Add(iMsgID, stat);
}
return m_statNetMsgMap[iMsgID];
}
public void OnNetSend(int iMsgID, int iDataLength)
{
lock (m_threadLock)
{
NetMsgStat stat = GetNetMsgStatByID(iMsgID);
stat.SendLength += iDataLength;
stat.SendNum += 1;
TotalSendLength += iDataLength;
TotalSendNum += 1;
}
}
public void OnNetRecv(int iMsgID, int iDataLength, long time)
{
lock (m_threadLock)
{
NetMsgStat stat = GetNetMsgStatByID(iMsgID);
stat.RecvLength += iDataLength;
stat.RecvNum += 1;
stat.RecvTotalTime += time;
stat.RecvMaxTime = stat.RecvMaxTime < time ? time : stat.RecvMaxTime;
if (stat.RecvNum > 1) //不是第一次
{
stat.RecvMinTime = stat.RecvNum > 0 ? time : stat.RecvMinTime;
}
else
{
stat.RecvMinTime = time;
}
TotalRecvLength += iDataLength;
TotalRecvNum += 1;
}
}
//网络消息,接受,发送数量和长度
private void LogNetMsg()
{
TraceLog.Stat("TotalSendNum:{0,-10} TotalRecvNum:{1,-10} TotalSendLength:{2,-12} TotalRecvLength:{3,-12}",
TotalSendNum, TotalRecvNum, TotalSendLength, TotalRecvLength);
//清空
TotalRecvLength = 0;
TotalRecvNum = 0;
TotalSendLength = 0;
TotalSendNum = 0;
TraceLog.Stat("MsgID SendNum RecvNum SendLength RecvLength RecvTotalTime RecvMaxTime RecvMinTime RecvAvgTime");
foreach(var item in m_statNetMsgMap.Values)
{
long RecvAvgTime = item.RecvNum <= 0 ? 0 : item.RecvTotalTime / item.RecvNum;
TraceLog.Stat("{0,-10}{1,-10}{2,-10}{3,-15}{4,-15}{5,-18}{6,-16}{7,-16}{8,-16}",
item.MsgID, item.SendNum, item.RecvNum, item.SendLength, item.RecvLength, item.RecvTotalTime, item.RecvMaxTime, item.RecvMinTime, RecvAvgTime);
//log完后清空这项数值
item.Clear();
}
/*
var keys = m_statNetMsgMap.Keys;
var keyarray = keys.ToArray<int>();
foreach (int id in keyarray)
{
NetMsgStat stat = m_statNetMsgMap[id];
TraceLog.Stat("{0,-10}{1,-10}{2,-10}{3,-15}{4,-15}", id, stat.SendNum,stat.RecvNum,stat.SendLength,stat.RecvLength);
//log完后清空这项数值
stat.Clear();
}
*/
}
private void LogGCMonitor()
{
GCMonitor.Instance.LogStat();
}
}
}