namespace NewLife.Log;
/// <summary>写日志事件参数</summary>
public class WriteLogEventArgs : EventArgs
{
#region 属性
/// <summary>日志等级</summary>
public LogLevel Level { get; set; }
/// <summary>日志信息</summary>
public String? Message { get; set; }
/// <summary>异常</summary>
public Exception? Exception { get; set; }
/// <summary>时间</summary>
public DateTime Time { get; set; }
/// <summary>线程编号</summary>
public Int32 ThreadID { get; set; }
/// <summary>是否线程池线程</summary>
public Boolean IsPool { get; set; }
/// <summary>是否Web线程</summary>
public Boolean IsWeb { get; set; }
/// <summary>线程名</summary>
public String? ThreadName { get; set; }
/// <summary>任务编号</summary>
public Int32 TaskID { get; set; }
#endregion
#region 构造
/// <summary>实例化一个日志事件参数</summary>
internal WriteLogEventArgs() { }
#endregion
#region 线程专有实例
/*2015-06-01 @宁波-小董
* 将Current以及Set方法组从internal修改为Public
* 原因是 Logger在进行扩展时,重载OnWrite需要用到该静态属性以及方法,internal无法满足扩展要求
* */
[ThreadStatic]
private static WriteLogEventArgs? _Current;
/// <summary>线程专有实例。线程静态,每个线程只用一个,避免GC浪费</summary>
public static WriteLogEventArgs Current => _Current ??= new WriteLogEventArgs();
#endregion
#region 方法
/// <summary>初始化为新日志</summary>
/// <param name="level">日志等级</param>
/// <returns>返回自身,链式写法</returns>
public WriteLogEventArgs Set(LogLevel level)
{
Level = level;
return this;
}
/// <summary>初始化为新日志</summary>
/// <param name="message">日志</param>
/// <param name="exception">异常</param>
/// <returns>返回自身,链式写法</returns>
public WriteLogEventArgs Set(String? message, Exception? exception)
{
Message = message;
Exception = exception;
Init();
return this;
}
void Init()
{
// todo: 如果系统使用utc时间,可以把日志时间转换为本地时间
Time = DateTime.Now.AddHours(Setting.Current.UtcIntervalHours);
var thread = Thread.CurrentThread;
ThreadID = thread.ManagedThreadId;
IsPool = thread.IsThreadPoolThread;
ThreadName = CurrentThreadName ?? thread.Name;
var tid = Task.CurrentId;
TaskID = tid != null ? tid.Value : -1;
//IsWeb = System.Web.HttpContext.Current != null;
}
/// <summary>重置日志事件对象,释放内存</summary>
public void Reset()
{
Level = LogLevel.Info;
Message = null;
Exception = null;
Time = default;
ThreadID = 0;
IsPool = false;
IsWeb = false;
ThreadName = null;
TaskID = 0;
}
/// <summary>获取日志全文,并重置对象释放内存</summary>
/// <returns></returns>
public String GetAndReset()
{
var msg = ToString();
Reset();
return msg;
}
/// <summary>已重载。</summary>
/// <returns></returns>
public override String ToString()
{
if (Exception != null) Message += Exception.GetMessage();
var name = ThreadName;
if (name.IsNullOrEmpty()) name = TaskID >= 0 ? TaskID + "" : "-";
if (name.EqualIgnoreCase("Threadpool worker", ".NET ThreadPool Worker")) name = TaskID >= 0 ? TaskID + "" : "P";
if (name.EqualIgnoreCase("IO Threadpool worker")) name = "IO";
if (name.EqualIgnoreCase(".NET Long Running Task")) name = "LongTask";
if (name.EqualIgnoreCase(".NET TP Worker")) name = "TP";
return $"{Time:HH:mm:ss.fff} {ThreadID,2} {(IsPool ? (IsWeb ? 'W' : 'Y') : 'N')} {name} {Message}";
}
#endregion
#region 日志线程名
[ThreadStatic]
private static String? _threadName;
/// <summary>设置当前线程输出日志时的线程名</summary>
public static String? CurrentThreadName { get => _threadName; set => _threadName = value; }
#endregion
}
|