using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Channels; using System.Threading.Tasks; using TaskManager.Entity; using TaskManager.EntityFramework; namespace Wood.Service.Controllers { public class LogController1 : BackgroundService { private readonly IServiceProvider _serviceProvider; private readonly Channel _logChannel; private readonly string _logDirectory; public LogController1( IServiceProvider serviceProvider, IConfiguration configuration) { _serviceProvider = serviceProvider; _logDirectory = configuration["Logging:Directory"] ?? Path.Combine(Directory.GetCurrentDirectory(), "Logs"); EnsureDirectoryExists(_logDirectory); _logChannel = Channel.CreateUnbounded(); } public void EnqueueLog(TaskLog logMessage) { // 设置日志路径并写入文件 logMessage.Path= WriteLogToFile(logMessage); // 将日志加入处理队列 _logChannel.Writer.TryWrite(logMessage); } private string WriteLogToFile(TaskLog logMessage) { // 获取今天的日期目录 string todayDirectory = Path.Combine(_logDirectory, DateTime.Now.ToString("yyyy-MM-dd")); // 确保目录存在 EnsureDirectoryExists(todayDirectory); // 创建或追加到日志文件 string logFilePath = Path.Combine(todayDirectory, "application.log"); try { // 写入日志内容到文件 File.AppendAllText(logFilePath, $"[{logMessage.CreationTime:yyyy-MM-dd HH:mm:ss}] [{logMessage.Type}] {logMessage.Info}{Environment.NewLine}"); // 返回相对路径(从日志根目录开始) return Path.GetRelativePath(_logDirectory, logFilePath); } catch (Exception ex) { // 记录日志写入失败的错误 Console.WriteLine($"Error writing log to file: {ex.Message}"); return null; } } private void EnsureDirectoryExists(string directoryPath) { if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } } [HttpGet("AddError")] public async Task AddError(string message, string taskname, Guid taskid, Version version) { var log = new TaskLog { Info = message, Type = "错误", TaskName = taskname, CreationTime = DateTime.Now, TaskId = taskid, Version = version?.ToString() }; EnqueueLog(log); return true; // 日志已入队,视为成功 } [HttpGet("AddInfo")] public async Task AddInfo(string message, string taskname, Guid taskid, Version version) { var log = new TaskLog { Info = message, Type = "错误", TaskName = taskname, CreationTime = DateTime.Now, TaskId = taskid, Version = version?.ToString() }; EnqueueLog(log); return true; } [HttpGet("AddInfoRemark")] public async Task AddInfoRemark(string message, string taskname, string remark) { var log = new TaskLog { Info = message, Type = "记录", TaskName = taskname, CreationTime = DateTime.Now, Remark = remark }; EnqueueLog(log); return true; } // 其他方法保持不变... protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await foreach (var logMessage in _logChannel.Reader.ReadAllAsync(stoppingToken)) { // 使用IServiceScopeFactory创建独立的作用域 using var scope = _serviceProvider.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService(); try { dbContext.TaskLogs.Add(logMessage); await dbContext.SaveChangesAsync(stoppingToken); } catch (Exception ex) { Console.WriteLine($"Error saving log: {ex.Message}"); } } } } }