using log4net;
using log4net.Config;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LB_SmartVisionCommon
{
///
/// 异步记录日志类
///
public static class AsyncLogHelper
{
static string LineT = "记录信息:";
private static BlockingCollection _logQueue;
private static Task _backgroundTask;
private static CancellationTokenSource _cancellationTokenSource;
private static readonly ILog _logger;
private static bool _isInitialized = false;
static AsyncLogHelper()
{
_logger = LogManager.GetLogger(typeof(AsyncLogHelper));
}
///
/// 初始化日志系统
///
public static void Initialize()
{
if (_isInitialized) return;
try
{
// 初始化队列和任务
_logQueue = new BlockingCollection(2000);
_cancellationTokenSource = new CancellationTokenSource();
// 确保log4net已配置
if (LogManager.GetRepository().Configured == false)
{
var configFile = new FileInfo("log4net.config");
if (configFile.Exists)
{
XmlConfigurator.ConfigureAndWatch(configFile);
//Debug.WriteLine("log4net已从配置文件初始化");
}
else
{
// 如果配置文件不存在,使用基本配置
BasicConfigurator.Configure();
//Debug.WriteLine("log4net使用基本配置");
}
}
// 检查配置是否加载成功
var repository = LogManager.GetRepository();
var appenders = repository.GetAppenders();
//Debug.WriteLine($"找到 {appenders.Length} 个 appender");
//foreach (var appender in appenders)
//{
// Debug.WriteLine($"Appender: {appender.Name}, Type: {appender.GetType().Name}");
//}
// 启动后台日志处理任务
_backgroundTask = Task.Factory.StartNew(
ProcessLogQueue,
_cancellationTokenSource.Token,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
// 注册应用程序退出时的清理
AppDomain.CurrentDomain.ProcessExit += (s, e) => Dispose();
AppDomain.CurrentDomain.DomainUnload += (s, e) => Dispose();
_isInitialized = true;
//Debug.WriteLine("AsyncLogHelper初始化完成");
}
catch (Exception ex)
{
//Debug.WriteLine($"AsyncLogHelper初始化失败: {ex.Message}");
throw ex;
}
}
///
/// Info类型 - 异步记录
///
public static void Info(string message)
{
EnqueueLog(LogLevel.Info, message);
}
///
/// Debug类型 - 异步记录
///
public static void Debug(string message)
{
EnqueueLog(LogLevel.Debug, message);
}
///
/// Warn类型 - 异步记录
///
public static void Warn(string message)
{
EnqueueLog(LogLevel.Warn, message);
}
///
/// Error类型 - 异步记录
///
public static void Error(string message)
{
EnqueueLog(LogLevel.Error, message);
}
///
/// Error类型 - 异步记录异常
///
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;
}
}
///
/// 释放资源,确保所有日志都被处理
///
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; }
}
}