using log4net;
|
using System;
|
using System.Collections.Concurrent;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
|
namespace LB_SmartVisionCommon
|
{
|
/// <summary>
|
/// 异步记录日志类
|
/// </summary>
|
public static class AsyncLogHelper
|
{
|
private static readonly BlockingCollection<LogItem> _logQueue = new BlockingCollection<LogItem>(2000);
|
private static readonly Task _backgroundTask;
|
private static readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
|
|
static string LineT = "记录信息:";
|
static readonly ILog _logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
static AsyncLogHelper()
|
{
|
// 启动后台日志处理任务
|
_backgroundTask = Task.Factory.StartNew(
|
ProcessLogQueue,
|
_cancellationTokenSource.Token,
|
TaskCreationOptions.LongRunning,
|
TaskScheduler.Default);
|
|
// 注册应用程序退出时的清理
|
AppDomain.CurrentDomain.ProcessExit += (s, e) => Dispose();
|
AppDomain.CurrentDomain.DomainUnload += (s, e) => Dispose();
|
}
|
|
/// <summary>
|
/// Info类型 - 异步记录
|
/// </summary>
|
public static void Info(string message)
|
{
|
EnqueueLog(LogLevel.Info, message);
|
}
|
|
/// <summary>
|
/// Debug类型 - 异步记录
|
/// </summary>
|
public static void Debug(string message)
|
{
|
EnqueueLog(LogLevel.Debug, message);
|
}
|
|
/// <summary>
|
/// Warn类型 - 异步记录
|
/// </summary>
|
public static void Warn(string message)
|
{
|
EnqueueLog(LogLevel.Warn, message);
|
}
|
|
/// <summary>
|
/// Error类型 - 异步记录
|
/// </summary>
|
public static void Error(string message)
|
{
|
EnqueueLog(LogLevel.Error, message);
|
}
|
|
/// <summary>
|
/// Error类型 - 异步记录异常
|
/// </summary>
|
public static void Error(string message, Exception exception)
|
{
|
EnqueueLog(LogLevel.Error, message, exception);
|
}
|
|
private static void EnqueueLog(LogLevel level, string message, Exception exception = null)
|
{
|
if (!_logQueue.IsAddingCompleted)
|
{
|
var logItem = new LogItem
|
{
|
Level = level,
|
Message = LineT + message,
|
Exception = exception,
|
Timestamp = DateTime.Now
|
};
|
|
// 如果队列已满,等待一段时间
|
if (!_logQueue.TryAdd(logItem, 100))
|
{
|
// 队列满时的降级处理:同步记录或丢弃
|
try
|
{
|
WriteLogSync(logItem);
|
}
|
catch
|
{
|
// 忽略同步记录时的异常
|
}
|
}
|
}
|
}
|
|
private static void ProcessLogQueue()
|
{
|
foreach (var logItem in _logQueue.GetConsumingEnumerable(_cancellationTokenSource.Token))
|
{
|
try
|
{
|
WriteLogSync(logItem);
|
}
|
catch (Exception ex)
|
{
|
System.Diagnostics.Debug.WriteLine($"异步日志记录失败: {ex.Message}");
|
}
|
}
|
}
|
|
private static void WriteLogSync(LogItem logItem)
|
{
|
switch (logItem.Level)
|
{
|
case LogLevel.Debug:
|
_logger.Debug(logItem.Message, logItem.Exception);
|
break;
|
case LogLevel.Info:
|
_logger.Info(logItem.Message, logItem.Exception);
|
break;
|
case LogLevel.Warn:
|
_logger.Warn(logItem.Message, logItem.Exception);
|
break;
|
case LogLevel.Error:
|
_logger.Error(logItem.Message, logItem.Exception);
|
break;
|
}
|
}
|
|
/// <summary>
|
/// 释放资源,确保所有日志都被处理
|
/// </summary>
|
public static void Dispose()
|
{
|
try
|
{
|
_logQueue.CompleteAdding();
|
_cancellationTokenSource.CancelAfter(5000); // 5秒后强制取消
|
|
// 等待任务完成,最多等待10秒
|
if (!_backgroundTask.Wait(10000))
|
{
|
System.Diagnostics.Debug.WriteLine("日志任务未在超时时间内完成");
|
}
|
}
|
catch (Exception ex)
|
{
|
System.Diagnostics.Debug.WriteLine($"释放日志资源时出错: {ex.Message}");
|
}
|
}
|
}
|
|
internal enum LogLevel
|
{
|
Debug,
|
Info,
|
Warn,
|
Error
|
}
|
|
internal class LogItem
|
{
|
public LogLevel Level { get; set; }
|
public string Message { get; set; }
|
public Exception Exception { get; set; }
|
public DateTime Timestamp { get; set; }
|
}
|
}
|