6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
873 lines
30 KiB
C#
873 lines
30 KiB
C#
/********************************
|
||
*
|
||
* 作者:吴隆健
|
||
* 创建时间: 2019-06-09 10:31:40
|
||
*
|
||
********************************/
|
||
|
||
using MrWu.Time;
|
||
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Runtime.InteropServices;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace MrWu.Debug
|
||
{
|
||
/// <summary>
|
||
/// 日志池
|
||
/// </summary>
|
||
public class LogPool : IDebug
|
||
{
|
||
|
||
private LogPool(LogConfig config) {
|
||
this.config = config;
|
||
var now = DateTime.Now;
|
||
//if(!string.IsNullOrEmpty(config.logpath)) {
|
||
logWriter = GetWriter(now);
|
||
//}
|
||
|
||
// 下一版再启用
|
||
var dueTime = (int)(now.Date.AddDays(1) - now).TotalMilliseconds;
|
||
//var dueTime = (int)(now.AddMinutes(1) - now).TotalMilliseconds; //测试
|
||
var period = (int)TimeSpan.FromDays(1).TotalMilliseconds;
|
||
this.logTaskTimer = new Timer(ZeroTask, null, dueTime, period);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 零时任务
|
||
/// </summary>
|
||
/// <param name="obj"></param>
|
||
void ZeroTask(object obj) {
|
||
var now = DateTime.Now;
|
||
SwitchWriter(now);
|
||
DeleteOutdateLogFiles(now);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更换 logWriter
|
||
/// </summary>
|
||
/// <param name="now">当前时间</param>
|
||
void SwitchWriter(DateTime now) {
|
||
using (var oldWriter = this.logWriter) {
|
||
var newWriter = GetWriter(now);
|
||
this.logWriter = newWriter;
|
||
oldWriter.Flush();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除过期日志文件
|
||
/// </summary>
|
||
/// <param name="now">当前时间</param>
|
||
void DeleteOutdateLogFiles(DateTime now) {
|
||
var logFiles = new DirectoryInfo(Directory.GetCurrentDirectory() + "/logs").GetFiles("*.log");
|
||
var outDateLogs = logFiles.Where(p => p.CreationTime.AddDays(config.remainDays) < now).ToList();
|
||
|
||
outDateLogs.ForEach(p => {
|
||
try {
|
||
p.Delete();
|
||
} catch (Exception ex) {
|
||
AddLog($"删除过时日志文件时发生异常!\t{ex.Message}", DebugLevel.Warning);
|
||
}
|
||
});
|
||
}
|
||
|
||
StreamWriter GetWriter(DateTime dateTime) {
|
||
|
||
string path = Directory.GetCurrentDirectory() + "/logs";
|
||
if (!Directory.Exists(path))
|
||
Directory.CreateDirectory(path);
|
||
|
||
return new StreamWriter(path + "/" + getLogFileName(dateTime)/*, false, Encoding.UTF8, 300 * 1024*/);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 定时任务 Timer
|
||
/// </summary>
|
||
Timer logTaskTimer {
|
||
get;
|
||
}
|
||
|
||
string getLogFileName(DateTime curDatetime) {
|
||
return curDatetime.TimeToString(TimeStyle.MMddhhmmss, string.Empty, string.Empty, string.Empty) + ".log";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 实例
|
||
/// </summary>
|
||
private static LogPool instance;
|
||
|
||
/// <summary>
|
||
/// 启动
|
||
/// </summary>
|
||
/// <param name="config"></param>
|
||
public static void Start(LogConfig config) {
|
||
if (config != null) {
|
||
instance = new LogPool(config);
|
||
saveLevel = config.saveLevel;
|
||
Debug.Start(instance, config.logLevel);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 日志流
|
||
/// </summary>
|
||
private StreamWriter logWriter {
|
||
get; set;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 配置
|
||
/// </summary>
|
||
public readonly LogConfig config;
|
||
|
||
/// <summary>
|
||
/// 日志
|
||
/// </summary>
|
||
// private readonly List<LogMessage> logs = new List<LogMessage>();
|
||
|
||
private readonly Queue<LogMessage> logs = new Queue<LogMessage>();
|
||
|
||
/// <summary>
|
||
/// 重要信息
|
||
/// </summary>
|
||
private readonly Queue<LogMessage> Infos = new Queue<LogMessage>();
|
||
|
||
/// <summary>
|
||
/// 警告
|
||
/// </summary>
|
||
private readonly Queue<LogMessage> warnings = new Queue<LogMessage>();
|
||
|
||
/// <summary>
|
||
/// 重要日志
|
||
/// </summary>
|
||
private readonly Queue<LogMessage> ImportantLogs = new Queue<LogMessage>();
|
||
|
||
/// <summary>
|
||
/// 错误
|
||
/// </summary>
|
||
private readonly Queue<LogMessage> errors = new Queue<LogMessage>();
|
||
|
||
/// <summary>
|
||
/// 致命的错误
|
||
/// </summary>
|
||
private readonly Queue<LogMessage> Fatals = new Queue<LogMessage>();
|
||
|
||
private readonly object logidLock = new object();
|
||
private ulong _logid = 0;
|
||
private ulong logid {
|
||
get {
|
||
ulong value;
|
||
lock (logidLock) {
|
||
_logid++;
|
||
value = _logid;
|
||
}
|
||
return value;
|
||
}
|
||
}
|
||
|
||
private ulong GetLogId() {
|
||
lock (logidLock) {
|
||
return _logid;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 日志缓存数量
|
||
/// </summary>
|
||
public int logCacheCount => config.logCacheCount;
|
||
|
||
/// <summary>
|
||
/// 信息缓存数量
|
||
/// </summary>
|
||
public int InfoCacheCount => config.InfoCacheCount;
|
||
|
||
/// <summary>
|
||
/// 警告缓存数量
|
||
/// </summary>
|
||
public int warningCacheCount => config.warningCacheCount;
|
||
|
||
/// <summary>
|
||
/// 重要日志数量
|
||
/// </summary>
|
||
public int ImportantLogCaheCount => config.ImportantLogCacheCount;
|
||
|
||
/// <summary>
|
||
/// 错误数量
|
||
/// </summary>
|
||
public int errorCacheCount => config.errorCacheCount;
|
||
|
||
/// <summary>
|
||
/// 致命错误
|
||
/// </summary>
|
||
public int FatalCacheCount => config.FatalCacheCount;
|
||
|
||
private static ulong _logCount;
|
||
|
||
/// <summary>
|
||
/// 日志数量
|
||
/// </summary>
|
||
public static ulong logCount {
|
||
get {
|
||
return _logCount;
|
||
}
|
||
private set {
|
||
_logCount = value;
|
||
}
|
||
}
|
||
|
||
private static ulong _InfoCount;
|
||
|
||
/// <summary>
|
||
/// 信息数量
|
||
/// </summary>
|
||
public static ulong InfoCount {
|
||
get {
|
||
return _InfoCount;
|
||
}
|
||
private set {
|
||
_InfoCount = value;
|
||
}
|
||
}
|
||
|
||
private static ulong _warningCount;
|
||
|
||
/// <summary>
|
||
/// 警告数量
|
||
/// </summary>
|
||
public static ulong warningCount {
|
||
get => _warningCount;
|
||
private set {
|
||
_warningCount = value;
|
||
}
|
||
}
|
||
|
||
private static ulong _ImportantlogCount;
|
||
|
||
/// <summary>
|
||
/// 重要日志数量
|
||
/// </summary>
|
||
public static ulong ImportantlogCount {
|
||
get => _ImportantlogCount;
|
||
private set {
|
||
_ImportantlogCount = value;
|
||
}
|
||
}
|
||
|
||
private static ulong _errorCount;
|
||
|
||
/// <summary>
|
||
/// 错误总数量
|
||
/// </summary>
|
||
public static ulong errorCount {
|
||
get => _errorCount;
|
||
private set {
|
||
_errorCount = value;
|
||
}
|
||
}
|
||
|
||
private static ulong _fatalCount;
|
||
|
||
/// <summary>
|
||
/// 致命错误数量
|
||
/// </summary>
|
||
public static ulong fatalCount {
|
||
get => _fatalCount;
|
||
private set {
|
||
_fatalCount = value;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 锁定物体
|
||
/// </summary>
|
||
private readonly object lockObj = new object();
|
||
|
||
/// <summary>
|
||
/// 锁写日志
|
||
/// </summary>
|
||
private readonly object lockWrite = new object();
|
||
|
||
/// <summary>
|
||
/// 锁定日志临时缓存
|
||
/// </summary>
|
||
private readonly object locktmpCache = new object();
|
||
|
||
/// <summary>
|
||
/// 临时缓存日志
|
||
/// </summary>
|
||
private Queue<LogMessage> tmpCachelog = new Queue<LogMessage>();
|
||
|
||
/// <summary>
|
||
/// 保存日志
|
||
/// </summary>
|
||
public static DebugLevel saveLevel {
|
||
get {
|
||
return m_saveLevel;
|
||
}
|
||
set {
|
||
m_saveLevel = value;
|
||
if(SaveLevelChange != null)
|
||
SaveLevelChange(m_saveLevel);
|
||
}
|
||
}
|
||
|
||
private static DebugLevel m_saveLevel;
|
||
|
||
/// <summary>
|
||
/// 保存日志的等级变化事件
|
||
/// </summary>
|
||
public static event Action<DebugLevel> SaveLevelChange;
|
||
|
||
/// <summary>
|
||
/// 手动刷新日志文本
|
||
/// </summary>
|
||
public static void Flush() {
|
||
if (instance != null) {
|
||
instance.FlushFile();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 刷新日志文件
|
||
/// </summary>
|
||
private void FlushFile() {
|
||
var writer = this.logWriter;
|
||
if (writer != null) {
|
||
lock (lockWrite) {
|
||
writer.Flush();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 接收到日志
|
||
/// </summary>
|
||
/// <param name="str">日志内容</param>
|
||
/// <param name="level">日志等级 1 普通日志 5警告 10错误日志</param>
|
||
public void AddLog(string str, DebugLevel level) {
|
||
LogMessage msg = new LogMessage(logid, level, str);
|
||
var writer = this.logWriter;
|
||
if (writer != null && ((level & saveLevel) != 0)) {
|
||
lock (lockWrite) {
|
||
writer.WriteLine(msg.logstr);
|
||
writer.Flush();
|
||
}
|
||
}
|
||
//Task.Factory.StartNew(
|
||
// () => {
|
||
//下一版再启用! 挪到外部处理走事件
|
||
//CollectLoggings.Enqueue(msg);
|
||
//if (CollectLoggings.Count > 500000) {
|
||
// //暂存周期为5分钟,日志容器容量为150000,预估最大日志量:3000条 / 每分钟, 足够容纳10个周期的日志量,超期的将不会提交到日志收集模块而被丢弃,但本地保存
|
||
// CollectLoggings.TryDequeue(out var _);
|
||
//}
|
||
lock (locktmpCache) {
|
||
tmpCachelog.Enqueue(msg);
|
||
}
|
||
|
||
|
||
lock (lockObj) {
|
||
switch (level) { //设置日志数量
|
||
case DebugLevel.Log:
|
||
logCount++;
|
||
ReleaseFrist(logs, msg, logCacheCount);
|
||
break;
|
||
case DebugLevel.Info:
|
||
logCount++;
|
||
ReleaseFrist(Infos, msg, InfoCacheCount);
|
||
break;
|
||
case DebugLevel.Warning:
|
||
warningCount++;
|
||
ReleaseFrist(warnings, msg, warningCacheCount);
|
||
break;
|
||
case DebugLevel.ImportantLog:
|
||
ImportantlogCount++;
|
||
ReleaseFrist(ImportantLogs, msg, ImportantLogCaheCount);
|
||
break;
|
||
case DebugLevel.Error:
|
||
errorCount++;
|
||
ReleaseFrist(errors, msg, errorCacheCount);
|
||
break;
|
||
case DebugLevel.Fatal:
|
||
fatalCount++;
|
||
ReleaseFrist(Fatals, msg, FatalCacheCount);
|
||
break;
|
||
}
|
||
}
|
||
// }
|
||
//);
|
||
}
|
||
|
||
/*
|
||
/// <summary>
|
||
/// 如果超过限制,移除并释放第一个
|
||
/// </summary>
|
||
/// <param name="list"></param>
|
||
/// <param name="newLog"></param>
|
||
/// <param name="limit"></param>
|
||
void ReleaseFrist(List<LogMessage> list, LogMessage newLog, int limit) {
|
||
list.Add(newLog);
|
||
if (list.Count > limit) {
|
||
//var log = list[0];
|
||
list.RemoveAt(0);
|
||
}
|
||
}
|
||
*/
|
||
|
||
/// <summary>
|
||
/// 如果超过限制,移除并释放第一个
|
||
/// </summary>
|
||
/// <param name="list"></param>
|
||
/// <param name="newLog"></param>
|
||
/// <param name="limit"></param>
|
||
void ReleaseFrist(Queue<LogMessage> list, LogMessage newLog, int limit) {
|
||
list.Enqueue(newLog);
|
||
if (list.Count > limit) {
|
||
//var log = list[0];
|
||
list.Dequeue();
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 上次获取日志的等级
|
||
/// </summary>
|
||
private DebugLevel lastGetLevel = (DebugLevel)(-1);
|
||
|
||
/// <summary>
|
||
/// 日志id
|
||
/// </summary>
|
||
private ulong log_id = 0;
|
||
|
||
private ulong Info_id = 0;
|
||
|
||
/// <summary>
|
||
/// 警告id
|
||
/// </summary>
|
||
private ulong warning_id = 0;
|
||
|
||
/// <summary>
|
||
/// 重要日志
|
||
/// </summary>
|
||
private ulong ImportantLog_id = 0;
|
||
|
||
/// <summary>
|
||
/// 错误id
|
||
/// </summary>
|
||
private ulong error_id = 0;
|
||
|
||
/// <summary>
|
||
/// 致命的id
|
||
/// </summary>
|
||
private ulong fatal_id = 0;
|
||
|
||
/// <summary>
|
||
/// 获取这段时间的日志
|
||
/// </summary>
|
||
/// <param name="tmplogs"></param>
|
||
/// <param name="tmpinfos"></param>
|
||
/// <param name="tmpwarnings"></param>
|
||
/// <param name="tmpimportantLogs"></param>
|
||
/// <param name="tmperrors"></param>
|
||
/// <param name="tmpfatal"></param>
|
||
/// <param name="level"></param>
|
||
/// <returns></returns>
|
||
private string ResetlogStrs(List<LogMessage> tmplogs, List<LogMessage> tmpinfos, List<LogMessage> tmpwarnings, List<LogMessage> tmpimportantLogs, List<LogMessage> tmperrors, List<LogMessage> tmpfatal, DebugLevel level) {
|
||
|
||
void setlogsId(List<LogMessage> _logs, List<LogMessage> _infos, List<LogMessage> _warnings,
|
||
List<LogMessage> _importantLogs, List<LogMessage> _errors, List<LogMessage> _fatals) {
|
||
|
||
if (_logs.Count == 0)
|
||
log_id = 0;
|
||
else
|
||
log_id = _logs[_logs.Count - 1].logid;
|
||
|
||
if (_infos.Count == 0)
|
||
Info_id = 0;
|
||
else
|
||
Info_id = _infos[_infos.Count - 1].logid;
|
||
|
||
if (_warnings.Count == 0)
|
||
warning_id = 0;
|
||
else
|
||
warning_id = _warnings[_warnings.Count - 1].logid;
|
||
|
||
if (_importantLogs.Count == 0)
|
||
ImportantLog_id = 0;
|
||
else
|
||
ImportantLog_id = _importantLogs[_importantLogs.Count - 1].logid;
|
||
|
||
if (_errors.Count == 0)
|
||
error_id = 0;
|
||
else
|
||
error_id = _errors[_errors.Count - 1].logid;
|
||
|
||
if (_fatals.Count == 0)
|
||
fatal_id = 0;
|
||
else
|
||
fatal_id = _fatals[_fatals.Count - 1].logid;
|
||
}
|
||
|
||
StringBuilder logStrs = new StringBuilder();
|
||
lastGetLevel = level;
|
||
|
||
bool islog = (tmplogs.Count > 0) && ((lastGetLevel & DebugLevel.Log) != 0);
|
||
bool isInfo = (tmpinfos.Count > 0) && ((lastGetLevel & DebugLevel.Info) != 0);
|
||
bool isWarning = (tmpwarnings.Count > 0) && ((lastGetLevel & DebugLevel.Warning) != 0);
|
||
bool isImportantLog = (tmpimportantLogs.Count > 0) && ((lastGetLevel & DebugLevel.ImportantLog) != 0);
|
||
bool isError = (tmperrors.Count > 0) && ((lastGetLevel & DebugLevel.Error) != 0);
|
||
bool isFatal = (tmpfatal.Count > 0) && ((lastGetLevel & DebugLevel.Fatal) != 0);
|
||
|
||
int logidx = 0;
|
||
int infoIdx = 0;
|
||
int warningidx = 0;
|
||
int ImportantLogIdx = 0;
|
||
int erroridx = 0;
|
||
int fatalIdx = 0;
|
||
|
||
DebugLevel mingDebugLevel = (DebugLevel)0;
|
||
ulong minlogidValue = ulong.MaxValue;
|
||
|
||
while (true) {
|
||
if (islog) {
|
||
if (tmplogs[logidx].logid < minlogidValue) {
|
||
minlogidValue = tmplogs[logidx].logid;
|
||
mingDebugLevel = DebugLevel.Log;
|
||
}
|
||
}
|
||
if (isInfo) {
|
||
if (tmpinfos[infoIdx].logid < minlogidValue) {
|
||
minlogidValue = tmpinfos[infoIdx].logid;
|
||
mingDebugLevel = DebugLevel.Info;
|
||
}
|
||
}
|
||
if (isWarning) {
|
||
if (tmpwarnings[warningidx].logid < minlogidValue) {
|
||
minlogidValue = tmpwarnings[warningidx].logid;
|
||
mingDebugLevel = DebugLevel.Warning;
|
||
}
|
||
}
|
||
if (isImportantLog) {
|
||
if (tmpimportantLogs[ImportantLogIdx].logid < minlogidValue) {
|
||
minlogidValue = tmpimportantLogs[ImportantLogIdx].logid;
|
||
mingDebugLevel = DebugLevel.ImportantLog;
|
||
}
|
||
}
|
||
if (isError) {
|
||
if (tmperrors[erroridx].logid < minlogidValue) {
|
||
minlogidValue = tmperrors[erroridx].logid;
|
||
mingDebugLevel = DebugLevel.Error;
|
||
}
|
||
}
|
||
if (isFatal) {
|
||
if (tmpfatal[fatalIdx].logid < minlogidValue) {
|
||
minlogidValue = tmpfatal[fatalIdx].logid;
|
||
mingDebugLevel = DebugLevel.Fatal;
|
||
}
|
||
}
|
||
switch (mingDebugLevel) {
|
||
case DebugLevel.Log:
|
||
logStrs.AppendLine(tmplogs[logidx++].logstr);
|
||
break;
|
||
case DebugLevel.Info:
|
||
logStrs.AppendLine(tmpinfos[infoIdx++].logstr);
|
||
break;
|
||
case DebugLevel.Warning:
|
||
logStrs.AppendLine(tmpwarnings[warningidx++].logstr);
|
||
break;
|
||
case DebugLevel.ImportantLog:
|
||
logStrs.AppendLine(tmpimportantLogs[ImportantLogIdx++].logstr);
|
||
break;
|
||
case DebugLevel.Error:
|
||
logStrs.AppendLine(tmperrors[erroridx++].logstr);
|
||
break;
|
||
case DebugLevel.Fatal:
|
||
logStrs.AppendLine(tmpfatal[fatalIdx++].logstr);
|
||
break;
|
||
}
|
||
|
||
if (logidx >= tmplogs.Count)
|
||
islog = false;
|
||
if (infoIdx >= tmpinfos.Count)
|
||
isInfo = false;
|
||
if (warningidx >= tmpwarnings.Count)
|
||
isWarning = false;
|
||
if (ImportantLogIdx >= tmpimportantLogs.Count)
|
||
isImportantLog = false;
|
||
if (erroridx >= tmperrors.Count)
|
||
isError = false;
|
||
if (fatalIdx >= tmpfatal.Count)
|
||
isFatal = false;
|
||
|
||
if (!islog && !isWarning && !isError && !isInfo && !isImportantLog && !isFatal)
|
||
break;
|
||
minlogidValue = long.MaxValue;
|
||
}
|
||
setlogsId(tmplogs, tmpinfos, tmpwarnings, tmpimportantLogs, tmperrors, tmpfatal);
|
||
|
||
lock (locktmpCache) {
|
||
tmpCachelog.Clear();
|
||
}
|
||
|
||
return logStrs.ToString();
|
||
}
|
||
|
||
private StringBuilder incLogCache = new StringBuilder();
|
||
|
||
/// <summary>
|
||
/// 增量获取日志
|
||
/// </summary>
|
||
private string AddLogs() {
|
||
Queue<LogMessage> tmp;
|
||
lock (locktmpCache) {
|
||
tmp = tmpCachelog;
|
||
tmpCachelog = new Queue<LogMessage>();
|
||
}
|
||
|
||
while (tmp.Count > 0) {
|
||
incLogCache.AppendLine(tmp.Dequeue().logstr);
|
||
}
|
||
string result = incLogCache.ToString();
|
||
if (result == null)
|
||
result = string.Empty;
|
||
incLogCache.Clear();
|
||
return result;
|
||
/*
|
||
StringBuilder logStrs = new StringBuilder();
|
||
bool islog = (logs.Count > 0) && ((lastGetLevel & DebugLevel.Log) != 0);
|
||
bool isInfo = (Infos.Count > 0) && ((lastGetLevel & DebugLevel.Info) != 0);
|
||
bool isWarning = (warnings.Count > 0) && ((lastGetLevel & DebugLevel.Warning) != 0);
|
||
bool isImportantLog = (ImportantLogs.Count > 0) && ((lastGetLevel & DebugLevel.ImportantLog) != 0);
|
||
bool isError = (errors.Count > 0) && ((lastGetLevel & DebugLevel.Error) != 0);
|
||
bool isFatal = (Fatals.Count > 0) && ((lastGetLevel & DebugLevel.Fatal) != 0);
|
||
|
||
//增量如何删除
|
||
DebugLevel mingDebugLevel = (DebugLevel)0;
|
||
ulong minlogidValue = ulong.MaxValue;
|
||
|
||
int logidx = 0;
|
||
int infoidx = 0;
|
||
int warningidx = 0;
|
||
int importantIdx = 0;
|
||
int erroridx = 0;
|
||
int fatalidx = 0;
|
||
|
||
if (islog) {
|
||
for (int i = logs.Count - 1; i >= 0; i--) {
|
||
if (logs[i].logid == log_id) {
|
||
logidx = i + 1;
|
||
break;
|
||
}
|
||
}
|
||
islog = logidx < logs.Count;
|
||
}
|
||
|
||
if (isInfo) {
|
||
for (int i = Infos.Count - 1; i >= 0; i--) {
|
||
if (Infos[i].logid == Info_id) {
|
||
logidx = i + 1;
|
||
break;
|
||
}
|
||
}
|
||
isInfo = logidx < Infos.Count;
|
||
}
|
||
|
||
if (isWarning) {
|
||
for (int i = warnings.Count - 1; i >= 0; i--) {
|
||
if (warnings[i].logid == warning_id) {
|
||
warningidx = i + 1;
|
||
break;
|
||
}
|
||
}
|
||
isWarning = warningidx < warnings.Count;
|
||
}
|
||
|
||
if (isImportantLog) {
|
||
for (int i = ImportantLogs.Count - 1; i >= 0; i--) {
|
||
if (ImportantLogs[i].logid == ImportantLog_id) {
|
||
importantIdx = i + 1;
|
||
break;
|
||
}
|
||
}
|
||
isImportantLog = importantIdx < ImportantLogs.Count;
|
||
}
|
||
|
||
if (isError) {
|
||
for (int i = errors.Count - 1; i >= 0; i--) {
|
||
if (errors[i].logid == error_id) {
|
||
erroridx = i + 1;
|
||
break;
|
||
}
|
||
}
|
||
isError = erroridx < errors.Count;
|
||
}
|
||
|
||
if (isFatal) {
|
||
for (int i = Fatals.Count - 1; i >= 0; i--) {
|
||
if (Fatals[i].logid == fatal_id) {
|
||
fatalidx = i + 1;
|
||
break;
|
||
}
|
||
}
|
||
isFatal = fatalidx < Fatals.Count;
|
||
}
|
||
|
||
while (true) {
|
||
if (islog) {
|
||
if (logs[logidx].logid < minlogidValue) {
|
||
minlogidValue = logs[logidx].logid;
|
||
mingDebugLevel = DebugLevel.Log;
|
||
}
|
||
}
|
||
if (isInfo) {
|
||
if (Infos[infoidx].logid < minlogidValue) {
|
||
minlogidValue = Infos[infoidx].logid;
|
||
mingDebugLevel = DebugLevel.Info;
|
||
}
|
||
}
|
||
if (isWarning) {
|
||
if (warnings[warningidx].logid < minlogidValue) {
|
||
minlogidValue = warnings[warningidx].logid;
|
||
mingDebugLevel = DebugLevel.Warning;
|
||
}
|
||
}
|
||
if (isImportantLog) {
|
||
if (ImportantLogs[importantIdx].logid < minlogidValue) {
|
||
minlogidValue = ImportantLogs[importantIdx].logid;
|
||
mingDebugLevel = DebugLevel.ImportantLog;
|
||
}
|
||
}
|
||
if (isError) {
|
||
if (errors[erroridx].logid < minlogidValue) {
|
||
minlogidValue = errors[erroridx].logid;
|
||
mingDebugLevel = DebugLevel.Error;
|
||
}
|
||
}
|
||
if (isFatal) {
|
||
if (Fatals[fatalidx].logid < minlogidValue) {
|
||
minlogidValue = Fatals[fatalidx].logid;
|
||
mingDebugLevel = DebugLevel.Fatal;
|
||
}
|
||
}
|
||
|
||
switch (mingDebugLevel) {
|
||
case DebugLevel.Log:
|
||
logStrs.AppendLine(logs[logidx++].logstr);
|
||
break;
|
||
case DebugLevel.Info:
|
||
logStrs.AppendLine(Infos[infoidx++].logstr);
|
||
break;
|
||
case DebugLevel.Warning:
|
||
logStrs.AppendLine(warnings[warningidx++].logstr);
|
||
break;
|
||
case DebugLevel.ImportantLog:
|
||
logStrs.AppendLine(ImportantLogs[importantIdx++].logstr);
|
||
break;
|
||
case DebugLevel.Error:
|
||
logStrs.AppendLine(errors[erroridx++].logstr);
|
||
break;
|
||
case DebugLevel.Fatal:
|
||
logStrs.AppendLine(Fatals[fatalidx++].logstr);
|
||
break;
|
||
}
|
||
|
||
if (logidx >= logs.Count)
|
||
islog = false;
|
||
if (infoidx >= Infos.Count)
|
||
isInfo = false;
|
||
if (warningidx >= warnings.Count)
|
||
isWarning = false;
|
||
if (importantIdx >= ImportantLogs.Count)
|
||
isImportantLog = false;
|
||
if (erroridx >= errors.Count)
|
||
isError = false;
|
||
if (fatalidx >= Fatals.Count)
|
||
isFatal = false;
|
||
if (!islog && !isWarning && !isError && !isInfo && !isImportantLog && !isFatal)
|
||
break;
|
||
minlogidValue = long.MaxValue;
|
||
}
|
||
setlogsId();
|
||
return logStrs.ToString();
|
||
*/
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取日志_只获取增量
|
||
/// </summary>
|
||
/// <param name="level">日志等级</param>
|
||
/// <returns></returns>
|
||
public static string GetLog(DebugLevel level = DebugLevel.Log | DebugLevel.Warning | DebugLevel.Error) {
|
||
if (instance == null)
|
||
return string.Empty;
|
||
string result;
|
||
if (level != instance.lastGetLevel) {
|
||
List<LogMessage> tmplogs = null;
|
||
List<LogMessage> tmpinfos = null;
|
||
List<LogMessage> tmpwarnings = null;
|
||
List<LogMessage> tmpimportantLogs = null;
|
||
List<LogMessage> tmperrors = null;
|
||
List<LogMessage> tmpfatal = null;
|
||
lock (instance.lockObj) {
|
||
tmplogs = new List<LogMessage>(instance.logs);
|
||
tmpinfos = new List<LogMessage>(instance.Infos);
|
||
tmpwarnings = new List<LogMessage>(instance.warnings);
|
||
tmpimportantLogs = new List<LogMessage>(instance.ImportantLogs);
|
||
tmperrors = new List<LogMessage>(instance.errors);
|
||
tmpfatal = new List<LogMessage>(instance.Fatals);
|
||
}
|
||
result = instance.ResetlogStrs(tmplogs, tmpinfos, tmpwarnings, tmpimportantLogs, tmperrors, tmpfatal, level);
|
||
} else {
|
||
result = instance.AddLogs();
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/*
|
||
/// <summary>
|
||
/// GetLoggings
|
||
/// </summary>
|
||
/// <param name="currentSeq">当前日志序号</param>
|
||
/// <returns></returns>
|
||
public static LogMessage[] GetLoggings(out ulong currentSeq) {
|
||
currentSeq = instance.GetLogId();
|
||
var seq = currentSeq;
|
||
return CollectLoggings.Where(p => p.logid <= seq).ToArray();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 日志暂存容器,
|
||
/// </summary>
|
||
static ConcurrentQueue<LogMessage> CollectLoggings { get; } = new ConcurrentQueue<LogMessage>();
|
||
static ConcurrentDictionary<ulong, LogMessage> msgs { get; } = new ConcurrentDictionary<ulong, LogMessage>();
|
||
|
||
|
||
/// <summary>
|
||
/// ClearLogging
|
||
/// </summary>
|
||
/// <param name="currentSeq">日志序号</param>
|
||
public static void ClearLogging(ulong currentSeq) {
|
||
while (CollectLoggings.Count > 0) {
|
||
if (CollectLoggings.TryPeek(out var log)) {
|
||
if (log.logid <= currentSeq) {
|
||
CollectLoggings.TryDequeue(out log);
|
||
} else {
|
||
break;
|
||
}
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
}
|
||
} |