998 lines
35 KiB
C#
998 lines
35 KiB
C#
// ***********************************************************************
|
|
// Assembly : GeneratorCode
|
|
// Author : 黄昕 <hzhuangxin01@corp.netease.com>
|
|
// Created : 02-15-2019
|
|
//
|
|
// Last Modified By : 黄昕 <hzhuangxin01@corp.netease.com>
|
|
// Last Modified On : 02-20-2019
|
|
// ***********************************************************************
|
|
// <copyright file="NLog.cs" company="NetEase">
|
|
// Copyright © 2019
|
|
// </copyright>
|
|
// <summary></summary>
|
|
// ***********************************************************************
|
|
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using GeneratorCode.Configure;
|
|
using JetBrains.Annotations;
|
|
using Timer = System.Timers.Timer;
|
|
|
|
namespace GeneratorCode.Logs
|
|
{
|
|
/// <summary>
|
|
/// Enum CacheOptMode
|
|
/// </summary>
|
|
public enum CacheOptMode
|
|
{
|
|
/// <summary>
|
|
/// The drop
|
|
/// </summary>
|
|
Drop = 0,
|
|
|
|
/// <summary>
|
|
/// The replease
|
|
/// </summary>
|
|
Replease
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enum NLogLevel
|
|
/// </summary>
|
|
public enum NLogLevel
|
|
{
|
|
/// <summary>
|
|
/// The fatal
|
|
/// </summary>
|
|
Fatal = 0,
|
|
|
|
/// <summary>
|
|
/// The crash
|
|
/// </summary>
|
|
Crash,
|
|
|
|
/// <summary>
|
|
/// The error
|
|
/// </summary>
|
|
Error,
|
|
|
|
/// <summary>
|
|
/// The warring
|
|
/// </summary>
|
|
Warring,
|
|
|
|
/// <summary>
|
|
/// The information
|
|
/// </summary>
|
|
Info,
|
|
|
|
/// <summary>
|
|
/// The debug
|
|
/// </summary>
|
|
Debug,
|
|
|
|
/// <summary>
|
|
/// The maximum level
|
|
/// </summary>
|
|
MaxLevel
|
|
}
|
|
|
|
/// <summary>
|
|
/// Class NLog.
|
|
/// </summary>
|
|
public static class NLog
|
|
{
|
|
/// <summary>
|
|
/// The log item collection
|
|
/// </summary>
|
|
private static readonly ConcurrentQueue<NLogItem> LogItemCollection = new ConcurrentQueue<NLogItem>();
|
|
|
|
/// <summary>
|
|
/// The log output lock
|
|
/// </summary>
|
|
private static readonly object LogOutputLock = new object();
|
|
|
|
/// <summary>
|
|
/// The log CFG
|
|
/// </summary>
|
|
private static NLogConfig _logCfg;
|
|
|
|
/// <summary>
|
|
/// The log file name
|
|
/// </summary>
|
|
private static string _logFileName = "";
|
|
|
|
/// <summary>
|
|
/// The log file number
|
|
/// </summary>
|
|
private static uint _logFileNum;
|
|
|
|
/// <summary>
|
|
/// The log sw
|
|
/// </summary>
|
|
private static StreamWriter _logSw;
|
|
|
|
/// <summary>
|
|
/// Logs the out.
|
|
/// </summary>
|
|
/// <param name="logMsg">The log MSG.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
public static void LogOut([NotNull] string logMsg = "",
|
|
[CallerFilePath] string fileName = "",
|
|
[CallerMemberName] string funName = "",
|
|
[CallerLineNumber] int lineNo = 0)
|
|
{
|
|
if (NLogLevel.Debug >= _logCfg.LogLevel || !_logCfg.LogEnable) return;
|
|
|
|
if (_logCfg.AsyncMode)
|
|
{
|
|
if (LogItemCollection.Count >= _logCfg.MaxItemsCache)
|
|
{
|
|
if (_logCfg.CacheMode == CacheOptMode.Drop) return;
|
|
|
|
LogItemCollection.TryDequeue(out _);
|
|
}
|
|
|
|
var logItem = new NLogItem(_logCfg.DefaultLevel, logMsg, fileName, funName, lineNo, DateTime.Now);
|
|
LogItemCollection.Enqueue(logItem);
|
|
}
|
|
else
|
|
{
|
|
var logItem = new NLogItem(_logCfg.DefaultLevel, logMsg, fileName, funName, lineNo, DateTime.Now);
|
|
LogOutput(logItem);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// ns the log finish.
|
|
/// </summary>
|
|
public static void NLog_Finish()
|
|
{
|
|
if (_logCfg.EnFile)
|
|
{
|
|
_logSw?.Flush();
|
|
_logSw?.Close();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// ns the log initialize.
|
|
/// </summary>
|
|
public static void NLog_Init()
|
|
{
|
|
_logCfg = new NLogConfig();
|
|
|
|
NLogConfig.OnLogCfgChanged += () =>
|
|
{
|
|
_logSw?.Close();
|
|
|
|
_logCfg.LogConfig();
|
|
|
|
ConfigInit();
|
|
};
|
|
|
|
ConfigInit();
|
|
|
|
var asynWork = new Thread(() =>
|
|
{
|
|
uint cnt = 1;
|
|
|
|
while (cnt++ > 0)
|
|
{
|
|
var lastDt = DateTime.Now;
|
|
var tolOut = Math.Min(_logCfg.NumOutItems, LogItemCollection.Count);
|
|
|
|
for (var i = 0; i < tolOut; i++)
|
|
{
|
|
if (LogItemCollection.TryDequeue(out var logItem))
|
|
{
|
|
LogOutput(logItem);
|
|
}
|
|
}
|
|
|
|
Thread.Sleep(_logCfg.SleepTime);
|
|
|
|
// 每秒执行一次维护工作
|
|
if (cnt % (1000 / _logCfg.SleepTime) != 0) continue;
|
|
|
|
if (_logCfg.EnSplitLog)
|
|
{
|
|
_logSw?.Flush();
|
|
|
|
var isNeedSplit = false;
|
|
|
|
if (_logCfg.SplitByData && lastDt.Day != DateTime.Now.Day)
|
|
{
|
|
isNeedSplit = true;
|
|
}
|
|
else if (_logCfg.SplitBySize > 0 &&
|
|
new FileInfo(_logFileName).Length > _logCfg.SplitBySize * 1024 * 1024)
|
|
{
|
|
isNeedSplit = true;
|
|
}
|
|
|
|
if (isNeedSplit)
|
|
{
|
|
_logSw?.Close();
|
|
_logSw?.Dispose();
|
|
_logSw = null;
|
|
|
|
var parttn = string.Format("*[{0:d3}]_{1}",
|
|
Process.GetCurrentProcess().Id,
|
|
Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName));
|
|
|
|
_logFileName = string.Format("{0}{1}[{3:yyyy-MM-dd_HH-mm}][{4:d}]_{2}",
|
|
_logCfg.DirPath,
|
|
_logCfg.FileNamePre.Length > 0 ? _logCfg.FileNamePre + "_" : "",
|
|
Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName),
|
|
DateTime.Now,
|
|
Process.GetCurrentProcess().Id);
|
|
|
|
if (_logCfg.EnSplitLog && _logCfg.RoolbackFile && _logCfg.MaxFileNum > 0)
|
|
{
|
|
_logFileName += $"_{_logFileNum:d3}";
|
|
parttn += $"_{_logFileNum:d3}";
|
|
_logFileNum = Convert.ToUInt32((_logFileNum + 1) % _logCfg.MaxFileNum);
|
|
}
|
|
|
|
_logFileName += ".log";
|
|
parttn += ".log";
|
|
|
|
foreach (var f in Directory.EnumerateFiles(_logCfg.DirPath, parttn,
|
|
SearchOption.TopDirectoryOnly))
|
|
{
|
|
File.Delete(f);
|
|
Trace.WriteLine("Delect Rollback log: " + f);
|
|
}
|
|
|
|
_logSw = new StreamWriter(_logFileName, true);
|
|
CreateLogFileHead();
|
|
}
|
|
}
|
|
}
|
|
}) {Name = "Log Async Output Thread", IsBackground = true};
|
|
|
|
asynWork.Start();
|
|
|
|
var tm = new Timer(1000) {AutoReset = true};
|
|
|
|
tm.Elapsed += (obj, args) =>
|
|
{
|
|
if (!_logCfg.AutoCleanup) return;
|
|
|
|
var backFileName = string.Format("{0}[{1:yyyy-MM-dd_HH-mm}]_{2}.zip",
|
|
_logCfg.DirPath,
|
|
DateTime.Now,
|
|
Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName));
|
|
|
|
const string regexRule =
|
|
@"\[(?<year>[1,2][0-9][0-9][0-9])-(?<month>[0,1][0-2])-(?<day>[0-3][0-9]).(?<hour>[0-2][0-9])-(?<min>[0-5][0-9])\]";
|
|
var regex = new Regex(regexRule);
|
|
|
|
var backList = new List<string>();
|
|
|
|
foreach (var f in Directory.EnumerateFiles(_logCfg.DirPath, "*.zip",
|
|
SearchOption.TopDirectoryOnly))
|
|
{
|
|
if (regex.IsMatch(f))
|
|
{
|
|
var match = regex.Match(f);
|
|
var dt = DateTime.ParseExact(match.Value,
|
|
"[yyyy-MM-dd_HH-mm]",
|
|
CultureInfo.CurrentCulture);
|
|
|
|
var diff = (DateTime.Now - dt).Days;
|
|
|
|
if (diff > _logCfg.KeepDays)
|
|
{
|
|
File.Delete(f);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var f in Directory.EnumerateFiles(_logCfg.DirPath, "*.log",
|
|
SearchOption.TopDirectoryOnly))
|
|
{
|
|
if (regex.IsMatch(f))
|
|
{
|
|
var match = regex.Match(f);
|
|
var dt = DateTime.ParseExact(match.Value,
|
|
"[yyyy-MM-dd_HH-mm]",
|
|
CultureInfo.CurrentCulture);
|
|
|
|
var diff = (DateTime.Now - dt).Days;
|
|
|
|
if (diff > _logCfg.KeepDays)
|
|
{
|
|
File.Delete(f);
|
|
}
|
|
else if (diff > _logCfg.BackupDays)
|
|
{
|
|
backList.Add(f);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var f in backList)
|
|
{
|
|
if (f == _logFileName) continue;
|
|
|
|
using (var fs = new FileStream(backFileName, FileMode.OpenOrCreate))
|
|
{
|
|
using (var archive = new ZipArchive(fs, ZipArchiveMode.Update))
|
|
{
|
|
archive.CreateEntryFromFile(f, Path.GetFileName(f));
|
|
File.Delete(f);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
tm.Start();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configurations the initialize.
|
|
/// </summary>
|
|
private static void ConfigInit()
|
|
{
|
|
if (_logCfg.EnFile)
|
|
{
|
|
_logFileName = string.Format("{0}{1}[{3:yyyy-MM-dd_HH-mm}][{4:d}]_{2}",
|
|
_logCfg.DirPath,
|
|
_logCfg.FileNamePre.Length > 0 ? _logCfg.FileNamePre + "_" : "",
|
|
Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName),
|
|
DateTime.Now,
|
|
Process.GetCurrentProcess().Id);
|
|
|
|
if (_logCfg.EnSplitLog && _logCfg.RoolbackFile && _logCfg.MaxFileNum > 0)
|
|
{
|
|
_logFileName += $"_{_logFileNum:d3}";
|
|
_logFileNum = Convert.ToUInt32((_logFileNum + 1) % _logCfg.MaxFileNum);
|
|
}
|
|
|
|
_logFileName += ".log";
|
|
|
|
if (File.Exists(_logFileName))
|
|
{
|
|
if (_logCfg.EnSplitLog)
|
|
{
|
|
File.Delete(_logFileName);
|
|
}
|
|
}
|
|
|
|
_logSw = new StreamWriter(_logFileName, true);
|
|
CreateLogFileHead();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates the log file head.
|
|
/// </summary>
|
|
private static void CreateLogFileHead()
|
|
{
|
|
_logSw?.WriteLine("FileName: " + _logFileName);
|
|
_logSw?.WriteLine("CreateTime: " + string.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now));
|
|
_logSw?.WriteLine("Program: " + Process.GetCurrentProcess().MainModule.FileName);
|
|
_logSw?.WriteLine("PID: " + Process.GetCurrentProcess().Id);
|
|
_logSw?.WriteLine("Split Count: " + (_logFileNum - 1));
|
|
_logSw?.WriteLine("--------------------------------------------------");
|
|
_logSw?.Flush();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs the format.
|
|
/// </summary>
|
|
/// <param name="logLevel">The log level.</param>
|
|
/// <param name="logMsg">The log MSG.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
/// <param name="dt">The dt.</param>
|
|
/// <returns>System.String.</returns>
|
|
private static string LogFormat(NLogLevel logLevel, string logMsg, string fileName, string funName, int lineNo,
|
|
DateTime dt)
|
|
{
|
|
var msg = "";
|
|
|
|
if (_logCfg.ShowDate || _logCfg.ShowTime) msg += "[";
|
|
|
|
if (_logCfg.ShowDate)
|
|
{
|
|
msg += dt.ToString("yyyy-MM-dd");
|
|
|
|
if (_logCfg.ShowTime) msg += " ";
|
|
}
|
|
|
|
if (_logCfg.ShowTime)
|
|
{
|
|
msg += dt.ToString("HH:mm:ss");
|
|
|
|
if (_logCfg.ShowMSec) msg += "." + dt.ToString("fff");
|
|
}
|
|
|
|
if (_logCfg.ShowDate || _logCfg.ShowTime) msg += "]";
|
|
|
|
if (_logCfg.ShowLevel) msg += " [" + LogLevelToString(logLevel) + "] ";
|
|
|
|
if (_logCfg.ShowCodeFile) msg += "[" + Path.GetFileName(fileName) + "] ";
|
|
|
|
if (_logCfg.ShowFunction) msg += "- " + funName;
|
|
|
|
if (_logCfg.ShowCodeFile || _logCfg.ShowFunction)
|
|
{
|
|
if (_logCfg.ShowCodeLine)
|
|
{
|
|
msg += "(" + lineNo + ")";
|
|
}
|
|
}
|
|
|
|
msg += ": " + logMsg;
|
|
|
|
return msg;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs the level to string.
|
|
/// </summary>
|
|
/// <param name="logLevel">The log level.</param>
|
|
/// <returns>System.String.</returns>
|
|
private static string LogLevelToString(NLogLevel logLevel)
|
|
{
|
|
string[] level = {"F", "C", "E", "I", "W", "D"};
|
|
|
|
if ((int) logLevel < level.Length && (int) logLevel >= 0)
|
|
{
|
|
return level[(int) logLevel];
|
|
}
|
|
|
|
return "U";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs the out.
|
|
/// </summary>
|
|
/// <param name="logLevel">The log level.</param>
|
|
/// <param name="logMsg">The log MSG.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
private static void LogOut(NLogLevel logLevel = NLogLevel.Info,
|
|
[NotNull] string logMsg = "",
|
|
string fileName = "",
|
|
string funName = "",
|
|
int lineNo = 0)
|
|
{
|
|
if (logLevel >= _logCfg.LogLevel || !_logCfg.LogEnable) return;
|
|
|
|
if (_logCfg.AsyncMode)
|
|
{
|
|
if (LogItemCollection.Count >= _logCfg.MaxItemsCache)
|
|
{
|
|
if (_logCfg.CacheMode == CacheOptMode.Drop) return;
|
|
|
|
LogItemCollection.TryDequeue(out _);
|
|
}
|
|
|
|
var logItem = new NLogItem(NLogLevel.Debug, logMsg, fileName, funName, lineNo, DateTime.Now);
|
|
LogItemCollection.Enqueue(logItem);
|
|
}
|
|
else
|
|
{
|
|
var logItem = new NLogItem(NLogLevel.Debug, logMsg, fileName, funName, lineNo, DateTime.Now);
|
|
LogOutput(logItem);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs the output.
|
|
/// </summary>
|
|
/// <param name="logItem">The log item.</param>
|
|
private static void LogOutput(NLogItem logItem)
|
|
{
|
|
var msg = LogFormat(logItem.LogLevel,
|
|
logItem.LogContent,
|
|
logItem.CodeFile,
|
|
logItem.CodeFunction,
|
|
logItem.CodeLine,
|
|
logItem.LogStamp);
|
|
|
|
if (_logCfg.ForceNewLine) msg += Environment.NewLine;
|
|
|
|
lock (LogOutputLock)
|
|
{
|
|
if (_logCfg.EnConsole) Console.Write(msg);
|
|
|
|
if (_logCfg.EnDebug | _logCfg.EnTrace)
|
|
{
|
|
if (_logCfg.EnTrace)
|
|
{
|
|
Trace.Write(msg);
|
|
}
|
|
else
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(msg);
|
|
}
|
|
}
|
|
|
|
if (_logCfg.EnFile) _logSw?.Write(msg);
|
|
}
|
|
}
|
|
|
|
#region LogOutputMethod
|
|
|
|
/// <summary>
|
|
/// Crashes the specified log MSG.
|
|
/// </summary>
|
|
/// <param name="logMsg">The log MSG.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
public static void Crash([NotNull] string logMsg = "",
|
|
[CallerFilePath] string fileName = "",
|
|
[CallerMemberName] string funName = "",
|
|
[CallerLineNumber] int lineNo = 0)
|
|
{
|
|
LogOut(NLogLevel.Crash, logMsg, fileName, funName, lineNo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Debugs the specified log MSG.
|
|
/// </summary>
|
|
/// <param name="logMsg">The log MSG.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
public static void Debug([NotNull] string logMsg = "",
|
|
[CallerFilePath] string fileName = "",
|
|
[CallerMemberName] string funName = "",
|
|
[CallerLineNumber] int lineNo = 0)
|
|
{
|
|
LogOut(NLogLevel.Debug, logMsg, fileName, funName, lineNo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Errors the specified log MSG.
|
|
/// </summary>
|
|
/// <param name="logMsg">The log MSG.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
public static void Error([NotNull] string logMsg = "",
|
|
[CallerFilePath] string fileName = "",
|
|
[CallerMemberName] string funName = "",
|
|
[CallerLineNumber] int lineNo = 0)
|
|
{
|
|
LogOut(NLogLevel.Error, logMsg, fileName, funName, lineNo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fatals the specified log MSG.
|
|
/// </summary>
|
|
/// <param name="logMsg">The log MSG.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
public static void Fatal([NotNull] string logMsg = "",
|
|
[CallerFilePath] string fileName = "",
|
|
[CallerMemberName] string funName = "",
|
|
[CallerLineNumber] int lineNo = 0)
|
|
{
|
|
LogOut(NLogLevel.Fatal, logMsg, fileName, funName, lineNo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Informations the specified log MSG.
|
|
/// </summary>
|
|
/// <param name="logMsg">The log MSG.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
public static void Info([NotNull] string logMsg = "",
|
|
[CallerFilePath] string fileName = "",
|
|
[CallerMemberName] string funName = "",
|
|
[CallerLineNumber] int lineNo = 0)
|
|
{
|
|
LogOut(NLogLevel.Info, logMsg, fileName, funName, lineNo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Warrings the specified log MSG.
|
|
/// </summary>
|
|
/// <param name="logMsg">The log MSG.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
public static void Warring([NotNull] string logMsg = "",
|
|
[CallerFilePath] string fileName = "",
|
|
[CallerMemberName] string funName = "",
|
|
[CallerLineNumber] int lineNo = 0)
|
|
{
|
|
LogOut(NLogLevel.Warring, logMsg, fileName, funName, lineNo);
|
|
}
|
|
|
|
#endregion LogOutputMethod
|
|
}
|
|
|
|
/// <summary>
|
|
/// Class NLogConfig.
|
|
/// </summary>
|
|
public class NLogConfig
|
|
{
|
|
/// <summary>
|
|
/// Delegate LogCfgChangedHandle
|
|
/// </summary>
|
|
public delegate void LogCfgChangedHandle();
|
|
|
|
/// <summary>
|
|
/// The CFG lock
|
|
/// </summary>
|
|
private readonly object _cfgLock = new object();
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="NLogConfig" /> class.
|
|
/// </summary>
|
|
public NLogConfig()
|
|
{
|
|
LogConfig();
|
|
NConfig.OnConfigChanged += () =>
|
|
{
|
|
LogCfgChanged();
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [asynchronous mode].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [asynchronous mode]; otherwise, <c>false</c>.</value>
|
|
public bool AsyncMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [automatic cleanup].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [automatic cleanup]; otherwise, <c>false</c>.</value>
|
|
public bool AutoCleanup { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the backup days.
|
|
/// </summary>
|
|
/// <value>The backup days.</value>
|
|
public int BackupDays { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the cache mode.
|
|
/// </summary>
|
|
/// <value>The cache mode.</value>
|
|
public CacheOptMode CacheMode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the default level.
|
|
/// </summary>
|
|
/// <value>The default level.</value>
|
|
public NLogLevel DefaultLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the dir path.
|
|
/// </summary>
|
|
/// <value>The dir path.</value>
|
|
public string DirPath { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [en console].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [en console]; otherwise, <c>false</c>.</value>
|
|
public bool EnConsole { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [en debug].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [en debug]; otherwise, <c>false</c>.</value>
|
|
public bool EnDebug { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [en file].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [en file]; otherwise, <c>false</c>.</value>
|
|
public bool EnFile { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [en split log].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [en split log]; otherwise, <c>false</c>.</value>
|
|
public bool EnSplitLog { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [en trace].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [en trace]; otherwise, <c>false</c>.</value>
|
|
public bool EnTrace { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the file name pre.
|
|
/// </summary>
|
|
/// <value>The file name pre.</value>
|
|
public string FileNamePre { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [force new line].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [force new line]; otherwise, <c>false</c>.</value>
|
|
public bool ForceNewLine { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the keep days.
|
|
/// </summary>
|
|
/// <value>The keep days.</value>
|
|
public int KeepDays { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [log enable].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [log enable]; otherwise, <c>false</c>.</value>
|
|
public bool LogEnable { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the log level.
|
|
/// </summary>
|
|
/// <value>The log level.</value>
|
|
public NLogLevel LogLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the maximum file number.
|
|
/// </summary>
|
|
/// <value>The maximum file number.</value>
|
|
public int MaxFileNum { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the maximum items cache.
|
|
/// </summary>
|
|
/// <value>The maximum items cache.</value>
|
|
public int MaxItemsCache { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number out items.
|
|
/// </summary>
|
|
/// <value>The number out items.</value>
|
|
public int NumOutItems { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [roolback file].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [roolback file]; otherwise, <c>false</c>.</value>
|
|
public bool RoolbackFile { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [show code file].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [show code file]; otherwise, <c>false</c>.</value>
|
|
public bool ShowCodeFile { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [show code line].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [show code line]; otherwise, <c>false</c>.</value>
|
|
public bool ShowCodeLine { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [show date].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [show date]; otherwise, <c>false</c>.</value>
|
|
public bool ShowDate { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [show function].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [show function]; otherwise, <c>false</c>.</value>
|
|
public bool ShowFunction { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [show level].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [show level]; otherwise, <c>false</c>.</value>
|
|
public bool ShowLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [show m sec].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [show m sec]; otherwise, <c>false</c>.</value>
|
|
public bool ShowMSec { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [show time].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [show time]; otherwise, <c>false</c>.</value>
|
|
public bool ShowTime { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the sleep time.
|
|
/// </summary>
|
|
/// <value>The sleep time.</value>
|
|
public int SleepTime { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether [split by data].
|
|
/// </summary>
|
|
/// <value><c>true</c> if [split by data]; otherwise, <c>false</c>.</value>
|
|
public bool SplitByData { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the size of the split by.
|
|
/// </summary>
|
|
/// <value>The size of the split by.</value>
|
|
public int SplitBySize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Occurs when [on log CFG changed].
|
|
/// </summary>
|
|
public static event LogCfgChangedHandle OnLogCfgChanged;
|
|
|
|
/// <summary>
|
|
/// Logs the configuration.
|
|
/// </summary>
|
|
public void LogConfig()
|
|
{
|
|
lock (_cfgLock)
|
|
{
|
|
LogEnable = NConfig.GetCfgValue("LogGlobal", "LogEnable", false);
|
|
LogLevel =
|
|
(NLogLevel) NConfig.GetCfgValue("LogGlobal", "LogLevel", (int) NLogLevel.MaxLevel);
|
|
DefaultLevel = (NLogLevel) NConfig.GetCfgValue("LogGlobal", "DefaultLogLevel", (int) NLogLevel.Info);
|
|
AsyncMode = NConfig.GetCfgValue("LogGlobal", "AsyncMode", false);
|
|
ForceNewLine = NConfig.GetCfgValue("LogGlobal", "AutoForceNewLine", false);
|
|
AutoCleanup = NConfig.GetCfgValue("LogGlobal", "AutoCleanup", true);
|
|
|
|
ShowDate = NConfig.GetCfgValue("LogFormat", "ShowDate", true);
|
|
ShowTime = NConfig.GetCfgValue("LogFormat", "ShowTime", true);
|
|
ShowMSec = NConfig.GetCfgValue("LogFormat", "ShowMSec", true);
|
|
ShowLevel = NConfig.GetCfgValue("LogFormat", "ShowLevel", true);
|
|
ShowCodeFile = NConfig.GetCfgValue("LogFormat", "ShowCodeFile", true);
|
|
ShowFunction = NConfig.GetCfgValue("LogFormat", "ShowFunction", true);
|
|
ShowCodeLine = NConfig.GetCfgValue("LogFormat", "ShowCodeLine", true);
|
|
|
|
EnConsole = NConfig.GetCfgValue("LogOutput", "Console", true);
|
|
EnTrace = NConfig.GetCfgValue("LogOutput", "Trace", false);
|
|
EnDebug = NConfig.GetCfgValue("LogOutput", "Debug", true);
|
|
EnFile = NConfig.GetCfgValue("LogOutput", "File", false);
|
|
|
|
if (AsyncMode)
|
|
{
|
|
MaxItemsCache = NConfig.GetCfgValue("AsyncLogSetting", "MaxItemsCache", 0);
|
|
|
|
if (MaxItemsCache == 0) MaxItemsCache = int.MaxValue;
|
|
|
|
CacheMode = (CacheOptMode) NConfig.GetCfgValue("AsyncLogSetting", "CacheFullOpts",
|
|
(int) CacheOptMode.Drop);
|
|
NumOutItems = NConfig.GetCfgValue("AsyncLogSetting", "NumItemsOutEachTime", 10);
|
|
}
|
|
|
|
SleepTime = NConfig.GetCfgValue("AsyncLogSetting", "ThreadSleep", 10);
|
|
|
|
if (EnFile)
|
|
{
|
|
DirPath = NConfig.GetCfgValue("FileLogSetting", "Path", @"");
|
|
|
|
if (DirPath == "" || !Directory.Exists(DirPath) || DirPath == @".\")
|
|
{
|
|
DirPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\";
|
|
}
|
|
|
|
if (!Directory.Exists(DirPath)) Directory.CreateDirectory(DirPath);
|
|
|
|
if (!DirPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
|
|
{
|
|
DirPath += Path.DirectorySeparatorChar;
|
|
}
|
|
|
|
FileNamePre = NConfig.GetCfgValue("FileLogSetting", "FileNamePrefix", "");
|
|
EnSplitLog = NConfig.GetCfgValue("FileLogSetting", "AutoSplitFile", true);
|
|
|
|
if (EnSplitLog)
|
|
{
|
|
SplitByData = NConfig.GetCfgValue("SplitFiles", "SplitByDate", true);
|
|
SplitBySize = NConfig.GetCfgValue("SplitFiles", "SplitBySize", 4);
|
|
RoolbackFile = NConfig.GetCfgValue("SplitFiles", "FileNameRollback", true);
|
|
MaxFileNum = NConfig.GetCfgValue("SplitFiles", "MaxFileNameNum", 10);
|
|
}
|
|
}
|
|
|
|
if (AutoCleanup)
|
|
{
|
|
KeepDays = NConfig.GetCfgValue("CleanUpLog", "KeepSaveDays", 30);
|
|
BackupDays = NConfig.GetCfgValue("CleanUpLog", "ZipBeforDays", 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs the CFG changed.
|
|
/// </summary>
|
|
protected static void LogCfgChanged()
|
|
{
|
|
OnLogCfgChanged?.Invoke();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Class NLogItem.
|
|
/// </summary>
|
|
public class NLogItem
|
|
{
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="NLogItem" /> class.
|
|
/// </summary>
|
|
/// <param name="level">The level.</param>
|
|
/// <param name="logContent">Content of the log.</param>
|
|
/// <param name="fileName">Name of the file.</param>
|
|
/// <param name="funName">Name of the fun.</param>
|
|
/// <param name="lineNo">The line no.</param>
|
|
/// <param name="dt">The dt.</param>
|
|
public NLogItem(NLogLevel level = NLogLevel.Debug,
|
|
[NotNull] string logContent = "",
|
|
[NotNull] string fileName = "",
|
|
[NotNull] string funName = "",
|
|
int lineNo = 0,
|
|
DateTime? dt = null)
|
|
{
|
|
if (dt == null)
|
|
{
|
|
LogStamp = DateTime.Now;
|
|
}
|
|
else
|
|
{
|
|
LogStamp = (DateTime) dt;
|
|
}
|
|
|
|
LogLevel = level;
|
|
LogContent = logContent;
|
|
CodeFile = fileName;
|
|
CodeFunction = funName;
|
|
CodeLine = lineNo;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the code file.
|
|
/// </summary>
|
|
/// <value>The code file.</value>
|
|
public string CodeFile { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the code function.
|
|
/// </summary>
|
|
/// <value>The code function.</value>
|
|
public string CodeFunction { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the code line.
|
|
/// </summary>
|
|
/// <value>The code line.</value>
|
|
public int CodeLine { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the content of the log.
|
|
/// </summary>
|
|
/// <value>The content of the log.</value>
|
|
public string LogContent { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the log level.
|
|
/// </summary>
|
|
/// <value>The log level.</value>
|
|
public NLogLevel LogLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the log stamp.
|
|
/// </summary>
|
|
/// <value>The log stamp.</value>
|
|
public DateTime LogStamp { get; set; }
|
|
}
|
|
} |