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
|
{
|
/// <summary>
|
/// 异步记录日志类
|
/// </summary>
|
public static class AsyncLogHelper
|
{
|
static string LineT = "记录信息:";
|
private static BlockingCollection<LogItem> _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));
|
}
|
|
/// <summary>
|
/// 初始化日志系统
|
/// </summary>
|
public static void Initialize()
|
{
|
if (_isInitialized) return;
|
|
try
|
{
|
// 初始化队列和任务
|
_logQueue = new BlockingCollection<LogItem>(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;
|
}
|
}
|
|
/// <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; }
|
}
|
}
|