LazyLogNet 1.0.10
See the version list below for details.
dotnet add package LazyLogNet --version 1.0.10
NuGet\Install-Package LazyLogNet -Version 1.0.10
<PackageReference Include="LazyLogNet" Version="1.0.10" />
<PackageVersion Include="LazyLogNet" Version="1.0.10" />
<PackageReference Include="LazyLogNet" />
paket add LazyLogNet --version 1.0.10
#r "nuget: LazyLogNet, 1.0.10"
#:package LazyLogNet@1.0.10
#addin nuget:?package=LazyLogNet&version=1.0.10
#tool nuget:?package=LazyLogNet&version=1.0.10
LazyLogNet
一个高性能、轻量级的 .NET 日志库,专为现代应用程序设计。支持异步日志记录、智能文件管理、文件轮转和结构化日志。
✨ 核心特性
- 🚀 高性能异步处理 - 基于自定义队列的无锁设计,优化的批量写入
- 📁 智能文件管理 - 自动轮转、大小控制、智能路径选择
- 🗂️ 可配置日志文件夹 - 支持为不同应用程序配置专用日志目录
- 🔄 日志轮转 - 支持基于文件大小的自动日志轮转
- 📊 结构化日志 - 支持 JSON、键值对等多种格式,支持属性字典和模板替换
- 🎯 零配置启动 - 开箱即用,智能默认配置
- 🌈 彩色控制台输出 - 不同日志级别使用不同颜色
- 🔒 线程安全 - 完全线程安全的设计
- 📦 最小依赖 - 仅依赖 .NET Standard 2.0 和 Newtonsoft.Json
- 🔄 自动资源管理 - 程序退出时自动清理,无需手动调用
- ✅ 配置验证 - 内置参数验证,确保配置合理性
- 🔌 Microsoft.Extensions.Logging 集成 - 完整的标准日志接口支持,无缝集成现有代码
🎯 兼容性
- .NET Framework 4.6.1+
- .NET Core 2.0+
- .NET 5/6/7/8+
- Xamarin
- Unity (部分支持)
📚 依赖与版本
- 目标框架:
netstandard2.0 - NuGet 依赖
Microsoft.Extensions.DependencyInjection.Abstractions 9.0.10:依赖注入扩展方法(用于IServiceCollection扩展)Microsoft.Extensions.Logging.Abstractions 9.0.10:Microsoft.Extensions.Logging 集成支持Microsoft.Extensions.Logging 9.0.10:Microsoft.Extensions.Logging 完整支持Newtonsoft.Json 13.0.1:结构化日志的 JSON 序列化
📦 安装
通过 NuGet 包引用
<ItemGroup>
<PackageReference Include="LazyLogNet" Version="1.0.10" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.10" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
通过 DLL 引用
直接引用编译生成的 LazyLogNet.dll 文件。
依赖注入支持
LazyLogNet 支持依赖注入模式,可以轻松集成到 ASP.NET Core、WPF、WinForms 等应用程序中。需要安装 Microsoft.Extensions.DependencyInjection.Abstractions 包。
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.10" />
Microsoft.Extensions.Logging 支持
LazyLogNet 提供与 Microsoft.Extensions.Logging 的完整集成支持,需要安装 Microsoft.Extensions.Logging.Abstractions 包。
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.10" />
🚀 快速开始
基础使用
using LazyLogNet;
// 直接使用静态辅助类,自动初始化(零配置启动)
LazyLogHelper.Debug("调试信息");
LazyLogHelper.Info("应用程序启动");
LazyLogHelper.Warn("这是一个警告");
LazyLogHelper.Error("发生了错误");
LazyLogHelper.Fatal("严重错误");
// 结构化日志记录
var userInfo = new Dictionary<string, object>
{
["UserId"] = 12345,
["UserName"] = "john_doe",
["Action"] = "Login",
["Timestamp"] = DateTime.Now
};
LazyLogHelper.InfoStructured("用户登录成功", userInfo);
// 带异常的日志记录
try
{
// 可能抛出异常的代码
throw new InvalidOperationException("测试异常");
}
catch (Exception ex)
{
LazyLogHelper.Error("操作失败", ex);
}
// 无需调用 Shutdown,程序退出时自动清理资源
LazyLogHelper 静态类完整功能
using LazyLogNet;
using System.Collections.Generic;
// 1. 初始化配置(可选,默认已自动初始化)
LazyLogHelper.Initialize(new LazyLoggerConfiguration
{
EnableConsole = true,
EnableFile = true,
MinLevel = LazyLogLevel.Debug,
MaxFileSize = 10 * 1024 * 1024 // 10MB
});
// 2. 基本日志方法
LazyLogHelper.Debug("调试级别消息");
LazyLogHelper.Info("信息级别消息");
LazyLogHelper.Warn("警告级别消息");
LazyLogHelper.Error("错误级别消息");
LazyLogHelper.Fatal("致命级别消息");
// 3. 带异常的日志
LazyLogHelper.Error("操作失败", new Exception("详细错误信息"));
LazyLogHelper.Fatal("系统崩溃", new OutOfMemoryException("内存不足"));
// 4. 结构化日志方法
var orderData = new Dictionary<string, object>
{
["OrderId"] = "ORD-123456",
["CustomerId"] = 789,
["Amount"] = 199.99m,
["Items"] = new[] { "ProductA", "ProductB" },
["CreatedAt"] = DateTime.UtcNow
};
LazyLogHelper.DebugStructured("调试结构化数据", orderData);
LazyLogHelper.InfoStructured("订单创建成功", orderData);
LazyLogHelper.WarnStructured("订单警告", orderData);
LazyLogHelper.ErrorStructured("订单错误", orderData);
LazyLogHelper.FatalStructured("订单致命错误", orderData);
// 5. 手动关闭(通常不需要,程序退出时自动清理)
// LazyLogHelper.Shutdown();
文件日志配置
using LazyLogNet;
// 启用文件输出
LazyLogHelper.Initialize(new LazyLoggerConfiguration
{
EnableConsole = true,
EnableFile = true,
FilePath = "logs/app.log"
});
LazyLogHelper.Info("日志将同时输出到控制台和文件");
依赖注入使用
using Microsoft.Extensions.DependencyInjection;
using LazyLogNet;
// 创建服务容器
var services = new ServiceCollection();
// 注册LazyLogNet服务
services.AddLazyLogNet();
// 注册业务服务
services.AddTransient<UserService>();
// 构建服务提供者
using var serviceProvider = services.BuildServiceProvider();
// 获取服务并使用
var userService = serviceProvider.GetRequiredService<UserService>();
// 业务服务类
public class UserService
{
private readonly ILazyLogger _logger;
public UserService(ILazyLogger logger)
{
_logger = logger;
}
public void CreateUser(string name)
{
_logger.Info($"创建用户: {name}");
}
}
文件路径配置
using LazyLogNet;
// 使用默认文件路径配置
LazyLogHelper.Initialize(new LazyLoggerConfiguration
{
EnableFile = true
});
LazyLogHelper.Info("使用默认文件路径的日志");
// 使用自定义文件路径
LazyLogHelper.Initialize(new LazyLoggerConfiguration
{
EnableFile = true,
FilePath = "D:/MyApp/logs/app.log"
});
LazyLogHelper.Info("使用自定义文件路径的日志");
// 使用配置对象
var config = new LazyLoggerConfiguration
{
EnableFile = true,
FilePath = "custom-app.log"
};
using var logger = new LazyLogger(config);
logger.Info("自定义文件路径的日志");
🔌 依赖注入配置
扩展方法
LazyLogNet 提供了扩展方法来简化依赖注入配置:
using Microsoft.Extensions.DependencyInjection;
using LazyLogNet;
var services = new ServiceCollection();
// 使用默认配置
services.AddLazyLogNet();
// 使用自定义配置
services.AddLazyLogNet(config =>
{
config.EnableConsole = true;
config.EnableFile = true;
config.FilePath = "my-app.log";
config.MinLevel = LazyLogLevel.Debug;
config.MaxFileSize = 10 * 1024 * 1024; // 10MB
config.MaxRetainedFiles = 5;
});
// 使用预设配置
services.AddLazyLogNetConsole(); // 仅控制台
services.AddLazyLogNetFile("my-logs"); // 仅文件(使用默认文件名)
services.AddLazyLogNetFileWithPath("D:/logs/app.log"); // 仅文件(指定路径)
ASP.NET Core 集成
// Program.cs (ASP.NET Core 6+)
using LazyLogNet;
var builder = WebApplication.CreateBuilder(args);
// 添加LazyLogNet服务
builder.Services.AddLazyLogNet(config =>
{
config.EnableConsole = true;
config.EnableFile = true;
config.FilePath = "webapp.log";
config.MinLevel = LazyLogLevel.Debug;
config.MaxFileSize = 50 * 1024 * 1024; // 50MB
config.MaxRetainedFiles = 10;
});
// 添加其他服务
builder.Services.AddControllers();
builder.Services.AddScoped<IUserService, UserService>();
var app = builder.Build();
// 配置管道
app.MapControllers();
app.Run();
// 控制器中使用
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly ILazyLogger _logger;
private readonly IUserService _userService;
public UsersController(ILazyLogger logger, IUserService userService)
{
_logger = logger;
_userService = userService;
}
[HttpPost]
public async Task<IActionResult> CreateUser([FromBody] CreateUserRequest request)
{
_logger.InfoStructured("创建用户请求", new Dictionary<string, object>
{
["UserName"] = request.Name,
["Email"] = request.Email,
["RequestId"] = HttpContext.TraceIdentifier
});
try
{
var user = await _userService.CreateUserAsync(request);
_logger.InfoStructured("用户创建成功", new Dictionary<string, object>
{
["UserId"] = user.Id,
["UserName"] = user.Name
});
return Ok(user);
}
catch (Exception ex)
{
_logger.ErrorStructured("用户创建失败", new Dictionary<string, object>
{
["UserName"] = request.Name,
["Email"] = request.Email,
["Error"] = ex.Message
}, ex);
return BadRequest("用户创建失败");
}
}
}
WPF/WinForms 集成
// App.xaml.cs (WPF) 或 Program.cs (WinForms)
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using LazyLogNet;
public partial class App : Application
{
private IHost _host;
protected override void OnStartup(StartupEventArgs e)
{
_host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
// 添加LazyLogNet
services.AddLazyLogNet(config =>
{
config.EnableConsole = false; // WPF通常不需要控制台输出
config.EnableFile = true;
config.FilePath = "wpf-app.log";
config.MaxFileSize = 20 * 1024 * 1024; // 20MB
});
// 添加窗口和服务
services.AddTransient<MainWindow>();
services.AddSingleton<IDataService, DataService>();
})
.Build();
base.OnStartup(e);
// 显示主窗口
var mainWindow = _host.Services.GetRequiredService<MainWindow>();
mainWindow.Show();
}
protected override void OnExit(ExitEventArgs e)
{
_host?.Dispose();
base.OnExit(e);
}
}
// MainWindow.xaml.cs
public partial class MainWindow : Window
{
private readonly ILazyLogger _logger;
private readonly IDataService _dataService;
public MainWindow(ILazyLogger logger, IDataService dataService)
{
_logger = logger;
_dataService = dataService;
InitializeComponent();
_logger.Info("主窗口已初始化");
}
private async void LoadDataButton_Click(object sender, RoutedEventArgs e)
{
_logger.Info("开始加载数据");
try
{
var data = await _dataService.LoadDataAsync();
_logger.InfoStructured("数据加载完成", new Dictionary<string, object>
{
["RecordCount"] = data.Count,
["LoadTime"] = DateTime.Now
});
}
catch (Exception ex)
{
_logger.Error("数据加载失败", ex);
MessageBox.Show("数据加载失败,请查看日志了解详情。");
}
}
}
控制台应用程序集成
// Program.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using LazyLogNet;
class Program
{
static async Task Main(string[] args)
{
// 创建主机
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
// 添加LazyLogNet
services.AddLazyLogNet(config =>
{
config.EnableConsole = true;
config.EnableFile = true;
config.FilePath = "console-app.log";
config.MinLevel = LazyLogLevel.Debug;
});
// 添加应用服务
services.AddSingleton<IApplication, Application>();
services.AddTransient<IWorkerService, WorkerService>();
})
.Build();
// 运行应用
var app = host.Services.GetRequiredService<IApplication>();
await app.RunAsync();
}
}
public interface IApplication
{
Task RunAsync();
}
public class Application : IApplication
{
private readonly ILazyLogger _logger;
private readonly IWorkerService _workerService;
public Application(ILazyLogger logger, IWorkerService workerService)
{
_logger = logger;
_workerService = workerService;
}
public async Task RunAsync()
{
_logger.Info("应用程序启动");
try
{
await _workerService.DoWorkAsync();
_logger.Info("应用程序正常结束");
}
catch (Exception ex)
{
_logger.Fatal("应用程序异常退出", ex);
throw;
}
}
}
🔌 Microsoft.Extensions.Logging 集成
直接使用 Microsoft.Extensions.Logging.ILogger
LazyLogNet 提供了完整的 Microsoft.Extensions.Logging.ILogger 接口实现,可以直接在现有代码中使用:
using Microsoft.Extensions.Logging;
using LazyLogNet;
// 创建 LazyLogNet 日志器
var lazyLogger = new LazyLogger(LazyLoggerConfiguration.Default);
// 创建 Microsoft.Extensions.Logging 适配器
ILogger logger = new MicrosoftExtensionsLogger("MyCategory", lazyLogger);
// 使用标准 ILogger 接口记录日志
logger.LogInformation("应用程序启动");
logger.LogWarning("这是一个警告消息");
logger.LogError(new Exception("测试异常"), "发生了错误");
// 支持所有标准日志级别
logger.LogTrace("跟踪信息");
logger.LogDebug("调试信息");
logger.LogInformation("一般信息");
logger.LogWarning("警告信息");
logger.LogError("错误信息");
logger.LogCritical("严重错误");
使用 Logger Factory
using Microsoft.Extensions.Logging;
using LazyLogNet;
// 创建 LazyLogNet 日志器
var lazyLogger = new LazyLogger(LazyLoggerConfiguration.Default);
// 创建 Logger Factory
var loggerFactory = new MicrosoftExtensionsLoggerFactory(lazyLogger);
// 为不同类别创建日志器
ILogger appLogger = loggerFactory.CreateLogger("Application");
ILogger dataLogger = loggerFactory.CreateLogger("DataAccess");
ILogger serviceLogger = loggerFactory.CreateLogger("BusinessService");
// 在不同组件中使用
appLogger.LogInformation("应用程序启动完成");
dataLogger.LogDebug("数据库查询执行");
serviceLogger.LogWarning("服务调用超时");
// 使用完成后释放资源
loggerFactory.Dispose();
日志级别映射
LazyLogNet 自动将 Microsoft.Extensions.Logging 日志级别映射到内部日志级别:
| Microsoft.Extensions.Logging | LazyLogNet |
|---|---|
LogLevel.Trace |
LazyLogLevel.Debug |
LogLevel.Debug |
LazyLogLevel.Debug |
LogLevel.Information |
LazyLogLevel.Info |
LogLevel.Warning |
LazyLogLevel.Warn |
LogLevel.Error |
LazyLogLevel.Error |
LogLevel.Critical |
LazyLogLevel.Fatal |
LogLevel.None |
LazyLogLevel.Info |
集成到现有代码
使用 ILogger<T> 泛型接口
using Microsoft.Extensions.Logging;
using LazyLogNet;
public class OrderService
{
private readonly ILogger<OrderService> _logger;
private readonly IOrderRepository _repository;
// 构造函数注入 ILogger<T>
public OrderService(ILogger<OrderService> logger, IOrderRepository repository)
{
_logger = logger;
_repository = repository;
}
public async Task<Order> CreateOrderAsync(CreateOrderRequest request)
{
// 使用标准 ILogger<T> 方法
_logger.LogInformation("开始创建订单,用户: {UserId}", request.UserId);
try
{
var order = await _repository.CreateAsync(request);
_logger.LogInformation("订单创建成功,订单号: {OrderId}", order.Id);
return order;
}
catch (Exception ex)
{
_logger.LogError(ex, "订单创建失败,用户: {UserId}", request.UserId);
throw;
}
}
}
public class UserService
{
private readonly ILogger<UserService> _logger;
public UserService(ILogger<UserService> logger)
{
_logger = logger;
}
public void CreateUser(string userName)
{
_logger.LogDebug("开始创建用户: {UserName}", userName);
// 业务逻辑
_logger.LogInformation("用户创建成功: {UserName}", userName);
}
}
依赖注入配置
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using LazyLogNet;
// 方法1:使用默认配置
var services = new ServiceCollection();
services.AddLazyLogNet();
// 方法2:使用自定义配置
services.AddLazyLogNet(config =>
{
config.EnableConsole = true;
config.EnableFile = true;
config.FilePath = "myapp.log";
config.MinLevel = LazyLogLevel.Debug;
config.MaxFileSize = 10 * 1024 * 1024; // 10MB
});
// 方法3:设置为默认日志提供程序(清除其他提供程序)
services.AddLazyLogNetAsDefaultLogger(config =>
{
config.EnableConsole = true;
config.EnableFile = true;
});
// 注册业务服务
services.AddScoped<OrderService>();
services.AddScoped<UserService>();
services.AddScoped<IOrderRepository, OrderRepository>();
// 构建服务提供者
var serviceProvider = services.BuildServiceProvider();
// 使用服务 - 自动注入 ILogger<T>
var orderService = serviceProvider.GetRequiredService<OrderService>();
var userService = serviceProvider.GetRequiredService<UserService>();
手动注册 Microsoft.Extensions.Logging(不使用扩展方法)
如果你不想使用本项目提供的扩展方法,可以手动注册 Microsoft.Extensions.Logging 服务:
方法1:手动注册到依赖注入容器
using LazyLogNet;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
// 创建服务集合
var services = new ServiceCollection();
// 手动创建配置和日志器实例
var config = new LazyLoggerConfiguration
{
EnableConsole = true,
EnableFile = true,
MinLevel = LazyLogLevel.Info,
LogFolderName = "my-app-logs"
};
// 创建LazyLogger实例
var lazyLogger = new LazyLogger(config);
// 手动注册服务
services.AddSingleton<ILazyLogger>(lazyLogger);
services.AddSingleton<ILoggerProvider>(serviceProvider =>
new MicrosoftExtensionsLoggerProvider(serviceProvider.GetRequiredService<ILazyLogger>()));
services.AddSingleton<ILoggerFactory>(serviceProvider =>
new MicrosoftExtensionsLoggerFactory(serviceProvider.GetRequiredService<ILazyLogger>()));
// 注册泛型 ILogger<T> 服务
services.AddTransient(typeof(ILogger<>), typeof(MicrosoftExtensionsLogger<>));
// 构建服务提供者
var serviceProvider = services.BuildServiceProvider();
// 使用日志器
var logger = serviceProvider.GetRequiredService<ILogger<MyService>>();
logger.LogInformation("手动注册的日志器工作正常");
方法2:手动创建工厂实例
using LazyLogNet;
using Microsoft.Extensions.Logging;
// 创建配置
var config = new LazyLoggerConfiguration
{
EnableConsole = true,
EnableFile = false, // 仅控制台输出
MinLevel = LazyLogLevel.Debug
};
// 创建LazyLogger实例
var lazyLogger = new LazyLogger(config);
// 手动创建日志提供程序
var loggerProvider = new MicrosoftExtensionsLoggerProvider(lazyLogger);
// 手动创建日志工厂
var loggerFactory = new MicrosoftExtensionsLoggerFactory(lazyLogger);
// 创建特定类别的日志器
var categoryLogger = loggerFactory.CreateLogger("MyCategory");
categoryLogger.LogInformation("类别日志器工作正常");
// 创建泛型日志器
var genericLogger = loggerFactory.CreateLogger<MyService>();
genericLogger.LogDebug("泛型日志器工作正常");
// 使用 MicrosoftExtensionsLogger<T> 直接创建
var directLogger = new MicrosoftExtensionsLogger<MyService>(loggerFactory);
directLogger.LogWarning("直接创建的日志器工作正常");
// 使用后记得释放资源
loggerProvider.Dispose();
loggerFactory.Dispose();
lazyLogger.Dispose();
方法3:在ASP.NET Core中手动配置
using LazyLogNet;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// 手动创建配置
var config = new LazyLoggerConfiguration
{
EnableConsole = true,
EnableFile = true,
MinLevel = LazyLogLevel.Info,
LogFolderName = "aspnet-core-logs"
};
// 手动创建LazyLogger实例
var lazyLogger = new LazyLogger(config);
// 手动注册服务
services.AddSingleton<ILazyLogger>(lazyLogger);
services.AddSingleton<ILoggerProvider>(serviceProvider =>
new MicrosoftExtensionsLoggerProvider(serviceProvider.GetRequiredService<ILazyLogger>()));
// 清除所有现有提供程序,只使用LazyLogNet
services.AddLogging(logging =>
{
logging.ClearProviders();
logging.AddProvider(serviceProvider.GetRequiredService<ILoggerProvider>());
});
// 注册其他服务
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
logger.LogInformation("应用程序启动,使用手动注册的LazyLogNet");
// 配置中间件等
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
手动创建 ILogger<T> 实例
using Microsoft.Extensions.Logging;
using LazyLogNet;
// 创建配置
var config = new LazyLoggerConfiguration
{
EnableConsole = true,
EnableFile = true,
FilePath = "orders.log"
};
// 创建 LazyLogger 实例
var lazyLogger = new LazyLogger(config);
// 创建 Logger Factory
var loggerFactory = new MicrosoftExtensionsLoggerFactory(lazyLogger);
// 创建 ILogger<T> 实例
ILogger<OrderService> orderLogger = loggerFactory.CreateLogger<OrderService>();
ILogger<UserService> userLogger = loggerFactory.CreateLogger<UserService>();
// 使用日志器
orderLogger.LogInformation("订单服务初始化完成");
userLogger.LogDebug("用户服务准备就绪");
// 创建服务实例
var orderService = new OrderService(orderLogger, new OrderRepository());
var userService = new UserService(userLogger);
ILogger<T> 泛型接口使用
LazyLogNet 完全支持 Microsoft.Extensions.Logging.ILogger<T> 泛型接口,这是现代.NET应用程序中最常用的日志接口模式。
在ASP.NET Core中使用
// Program.cs
using Microsoft.Extensions.DependencyInjection;
using LazyLogNet;
var builder = WebApplication.CreateBuilder(args);
// 添加LazyLogNet作为默认日志提供程序
builder.Services.AddLazyLogNetAsDefaultLogger(config =>
{
config.EnableConsole = true;
config.EnableFile = true;
config.FilePath = "aspnetcore-app.log";
});
// 添加控制器服务
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
// 控制器中使用 ILogger<T>
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly ILogger<ProductsController> _logger;
public ProductsController(ILogger<ProductsController> logger)
{
_logger = logger;
}
[HttpGet]
public IActionResult GetProducts()
{
_logger.LogInformation("获取产品列表");
try
{
var products = new[] { "Product1", "Product2", "Product3" };
_logger.LogDebug("找到 {ProductCount} 个产品", products.Length);
return Ok(products);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取产品列表失败");
return StatusCode(500, "内部服务器错误");
}
}
}
在通用主机应用程序中使用
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using LazyLogNet;
// 创建通用主机
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
// 注册LazyLogNet
services.AddLazyLogNet(config =>
{
config.EnableConsole = true;
config.EnableFile = true;
config.MinLevel = LazyLogLevel.Debug;
});
// 注册后台服务
services.AddHostedService<MyBackgroundService>();
services.AddSingleton<IDataProcessor, DataProcessor>();
})
.Build();
await host.RunAsync();
// 后台服务中使用 ILogger<T>
public class MyBackgroundService : BackgroundService
{
private readonly ILogger<MyBackgroundService> _logger;
private readonly IDataProcessor _dataProcessor;
public MyBackgroundService(
ILogger<MyBackgroundService> logger,
IDataProcessor dataProcessor)
{
_logger = logger;
_dataProcessor = dataProcessor;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("后台服务启动");
while (!stoppingToken.IsCancellationRequested)
{
try
{
_logger.LogDebug("开始处理数据");
await _dataProcessor.ProcessAsync(stoppingToken);
_logger.LogDebug("数据处理完成");
}
catch (Exception ex)
{
_logger.LogError(ex, "数据处理失败");
}
await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
}
}
}
优势特性
- 零配置集成: 无需额外配置,直接使用标准
ILogger<T>接口 - 完全兼容: 支持所有
Microsoft.Extensions.Logging功能和方法,包括结构化日志记录 - 类别感知: 自动使用类型名称作为日志类别,便于过滤和诊断
- 依赖注入就绪: 与.NET依赖注入系统完美集成
- 高性能: 保持 LazyLogNet 的高性能特性
- 线程安全: 完全线程安全的设计
- 自动资源管理: 集成 LazyLogNet 的自动清理功能
📚 详细配置
LazyLoggerConfiguration 属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
EnableConsole |
bool |
true |
启用控制台输出 |
EnableFile |
bool |
false |
启用文件输出 |
LogFolderName |
string |
"logs" |
日志文件夹名称 |
FilePath |
string |
null |
完整的日志文件路径(最高优先级) |
MinLevel |
LazyLogLevel |
LazyLogLevel.Info |
最小日志级别 |
MaxFileSize |
long |
10MB |
单个文件最大大小 |
MaxRetainedFiles |
int |
5 |
最大保留文件数 |
QueueCapacity |
int |
1024 |
日志队列容量 |
BatchSize |
int |
100 |
批处理大小 |
FlushIntervalMs |
int |
1000 |
刷新间隔(毫秒) |
FileBufferSize |
int |
4096 |
文件缓冲区大小 |
EnableLogRotation |
bool |
true |
是否启用日志轮转 |
FileNamePattern |
string |
"{0}_{1:yyyyMMdd_HHmmss}.log" |
日志文件名模式 |
LogFormat |
LazyLogFormat |
LazyLogFormat.Text |
日志格式类型 |
IncludeStructuredData |
bool |
false |
是否在日志中包含结构化数据(当设置为true时,结构化数据会以JSON格式包含在日志消息中) |
日志级别
public enum LazyLogLevel
{
Debug = 0, // 调试信息
Info = 1, // 一般信息
Warn = 2, // 警告信息
Error = 3, // 错误信息
Fatal = 4 // 严重错误
}
预设配置
using LazyLogNet;
// 仅控制台输出
using var consoleLogger = new LazyLogger(LazyLoggerConfiguration.ConsoleOnly);
// 仅文件输出
using var fileLogger = new LazyLogger(LazyLoggerConfiguration.FileOnly);
// 默认配置(控制台 + 文件)
using var defaultLogger = new LazyLogger(LazyLoggerConfiguration.Default);
// 指定日志文件
using var customLogger = new LazyLogger(LazyLoggerConfiguration.WithFilePath("my-app.log"));
// 指定完整文件路径
using var pathLogger = new LazyLogger(LazyLoggerConfiguration.WithFilePath("D:\\MyApp\\logs\\app.log"));
📁 文件路径配置
路径配置优先级
- 完整文件路径 (
FilePath属性) - 最高优先级 - 默认路径 - 使用当前目录下的日志文件
📊 结构化日志
使用示例
using LazyLogNet;
using System.Collections.Generic;
// 记录结构化日志
var properties = new Dictionary<string, object>
{
["UserId"] = 12345,
["Action"] = "登录",
["IP"] = "192.168.1.100"
};
LazyLogHelper.InfoStructured("用户登录成功", properties);
🔧 高级配置
自定义配置
using LazyLogNet;
var config = new LazyLoggerConfiguration
{
EnableConsole = true,
EnableFile = true,
LogFolderName = "my-app-logs",
MinLevel = LazyLogLevel.Debug,
MaxFileSize = 50 * 1024 * 1024, // 50MB
MaxRetainedFiles = 10,
QueueCapacity = 2048,
BatchSize = 200,
FlushIntervalMs = 500,
EnableLogRotation = true,
FileNamePattern = "app_{1:yyyyMMdd_HHmmss}.log"
};
LazyLogHelper.Initialize(config);
Logger 实例使用
using LazyLogNet;
// 使用自定义配置
var config = LazyLoggerConfiguration.WithLogFolder("my-app-logs");
using var logger = new LazyLogger(config);
logger.Debug("调试信息");
logger.Info("一般信息");
logger.Warn("警告信息");
logger.Error("错误信息");
logger.Fatal("严重错误");
// 带异常的日志
try
{
// 可能抛出异常的代码
}
catch (Exception ex)
{
logger.Error("操作失败", ex);
}
// 结构化日志
var userAction = new Dictionary<string, object>
{
["UserId"] = userId,
["Action"] = "CreateProject",
["ProjectId"] = projectId
};
logger.InfoStructured("用户创建项目", userAction);
🔄 日志轮转
自动轮转功能
var config = new LazyLoggerConfiguration
{
EnableFile = true,
EnableLogRotation = true,
MaxFileSize = 10 * 1024 * 1024, // 10MB
MaxRetainedFiles = 5,
FileNamePattern = "app_{1:yyyyMMdd_HHmmss}.log"
};
// 当日志文件达到10MB时,自动创建新文件
// 保留最近5个日志文件,自动删除旧文件
文件命名模式
{0}: 基础文件名(不含扩展名){1}: 时间戳(DateTime格式)
示例:
"app_{1:yyyyMMdd}.log"→app_20240115.log"{0}_{1:yyyyMMdd_HHmmss}.log"→app_20240115_143022.log
✅ 配置验证
自动验证
var config = new LazyLoggerConfiguration
{
QueueCapacity = -1, // 无效值
BatchSize = 0 // 无效值
};
// 验证配置
var (isValid, errors) = config.Validate();
if (!isValid)
{
Console.WriteLine("配置错误:");
foreach (var error in errors)
{
Console.WriteLine($"- {error}");
}
}
// 或者直接抛出异常
try
{
config.ValidateAndThrow();
}
catch (ArgumentException ex)
{
Console.WriteLine($"配置无效: {ex.Message}");
}
🎯 最佳实践
1. 依赖注入模式
// 推荐:使用依赖注入
public class OrderService
{
private readonly ILazyLogger _logger;
private readonly IOrderRepository _repository;
public OrderService(ILazyLogger logger, IOrderRepository repository)
{
_logger = logger;
_repository = repository;
}
public async Task<Order> CreateOrderAsync(CreateOrderRequest request)
{
_logger.InfoStructured("开始创建订单", new Dictionary<string, object>
{
["CustomerId"] = request.CustomerId,
["ProductCount"] = request.Items.Count,
["TotalAmount"] = request.TotalAmount
});
try
{
var order = await _repository.CreateAsync(request);
_logger.InfoStructured("订单创建成功", new Dictionary<string, object>
{
["OrderId"] = order.Id,
["CustomerId"] = order.CustomerId,
["Amount"] = order.TotalAmount
});
return order;
}
catch (Exception ex)
{
_logger.ErrorStructured("订单创建失败", new Dictionary<string, object>
{
["CustomerId"] = request.CustomerId,
["Error"] = ex.Message
}, ex);
throw;
}
}
}
// 服务注册
services.AddLazyLogNet(config =>
{
config.EnableFile = true;
config.LogFolderName = "order-service-logs";
config.LogFormat = LazyLogFormat.Json;
config.IncludeStructuredData = true;
});
services.AddScoped<IOrderService, OrderService>();
services.AddScoped<IOrderRepository, OrderRepository>();
2. 应用程序日志分离
// 为不同的插件或模块配置独立的日志文件夹
LazyLogHelper.Initialize(enableFile: true, logFolderName: "revit-plugin-logs");
LazyLogHelper.Initialize(enableFile: true, logFolderName: "autocad-plugin-logs");
LazyLogHelper.Initialize(enableFile: true, logFolderName: "main-app-logs");
3. 结构化日志记录
// 记录用户操作
var userAction = new Dictionary<string, object>
{
["UserId"] = userId,
["Action"] = "CreateProject",
["ProjectId"] = projectId,
["Duration"] = stopwatch.ElapsedMilliseconds
};
LazyLogHelper.InfoStructured("用户创建项目", userAction);
4. 异常处理
try
{
// 业务逻辑
}
catch (Exception ex)
{
LazyLogHelper.Error($"操作失败: {ex.Message}", ex);
throw; // 重新抛出异常
}
5. 性能监控
var stopwatch = Stopwatch.StartNew();
try
{
// 执行操作
DoSomething();
LazyLogHelper.Info($"操作完成,耗时: {stopwatch.ElapsedMilliseconds}ms");
}
finally
{
stopwatch.Stop();
}
6. 配置管理
// 开发环境
var devConfig = new LazyLoggerConfiguration
{
MinLevel = LazyLogLevel.Debug,
EnableConsole = true,
EnableFile = true,
LogFormat = LazyLogFormat.Text
};
// 生产环境
var prodConfig = new LazyLoggerConfiguration
{
MinLevel = LazyLogLevel.Info,
EnableConsole = false,
EnableFile = true,
LogFormat = LazyLogFormat.Json,
MaxFileSize = 100 * 1024 * 1024, // 100MB
MaxRetainedFiles = 30
};
📈 性能特性
- 异步处理: 基于自定义队列的高性能异步处理
- 批量写入: 减少 I/O 操作次数
- 内存优化: 对象池和高效字符串处理
- 队列优化: 基于基准测试的 1K 队列容量
- 无锁设计: 避免线程竞争
- 智能缓冲: 可配置的文件缓冲区大小
🔒 线程安全
- 所有公共 API 都是线程安全的
- 支持多线程并发日志记录
- 内部使用无锁数据结构
- 自动处理资源竞争
🏗️ 项目结构
LazyLogNet/
├── LazyLogNet/ # 核心库
│ ├── ILogger.cs # 日志接口
│ ├── LazyLogger.cs # 日志实现
│ ├── LazyLogHelper.cs # 静态辅助类
│ ├── LazyLoggerConfiguration.cs # 配置类
│ ├── LazyLogLevel.cs # 日志级别
│ ├── LazyLogFormat.cs # 日志格式
│ └── LazyLogEntry.cs # 日志条目
├── LazyLogNet.Example/ # 示例项目
│ ├── Program.cs # 主程序
│ ├── ConfigurableLogFolderExample.cs
│ ├── StructuredLoggingExample.cs
│ └── ...
└── LazyLogNet.Benchmark/ # 性能测试
├── AdvancedBenchmark.cs
└── Program.cs
📄 许可证
MIT License - 详见 LICENSE 文件。
🤝 贡献
欢迎提交 Issue 和 Pull Request!
📞 支持
如有问题或建议,请通过 GitHub Issues 联系我们。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.10)
- Newtonsoft.Json (>= 13.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
版本 1.0.10 (2024-08-01)
1. 修复了一些已知问题。引用了 Microsoft.Extensions.Logging.Abstractions 9.0.10,但其dll是9.0.0,导致版本错误,已退回9.0.9。
2. 新增对 Microsoft.Extensions.Logging 的完整支持。
3. 添加了 ILogger<T> 泛型接口支持。
4. 提供了依赖注入集成扩展方法。
5. 完善了文档和示例代码。