From dcbd4934d063f471c01cbcf93574c2e2ac5f16b5 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期五, 27 三月 2026 09:37:36 +0800
Subject: [PATCH] feat: 提交WCS与WMS代码调整
---
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/LogHelper/QuartzLogger.cs | 358 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 309 insertions(+), 49 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/LogHelper/QuartzLogger.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/LogHelper/QuartzLogger.cs
index f50d7a0..8789c83 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/LogHelper/QuartzLogger.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/LogHelper/QuartzLogger.cs
@@ -1,85 +1,345 @@
-锘縰sing System;
+using OfficeOpenXml.FormulaParsing.Excel.Functions.Numeric;
+using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
using WIDESEAWCS_Core.Helper;
namespace WIDESEAWCS_Core.LogHelper
{
- public class QuartzLogger
+ /// <summary>
+ /// 鏃ュ織绛夌骇鏋氫妇
+ /// </summary>
+ public enum LogLevel
{
- static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
- static string folderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"Log\\{DateTime.Now.ToString("yyyy-MM-dd")}");
+ DEBUG = 0,
+ INFO = 1,
+ WARN = 2,
+ ERROR = 3,
+ FATAL = 4
+ }
- public static void WriteLogToFile(string fileName, string log)
+ /// <summary>
+ /// 鏃ュ織鏉$洰锛氬皝瑁呭崟鏉℃棩蹇楃殑瀹屾暣淇℃伅
+ /// </summary>
+ public class LogEntry
+ {
+ /// <summary>
+ /// 鏃ュ織鏃堕棿
+ /// </summary>
+ public DateTime Time { get; set; }
+
+ /// <summary>
+ /// 鏃ュ織绛夌骇
+ /// </summary>
+ public LogLevel Level { get; set; }
+
+ /// <summary>
+ /// 鏃ュ織娑堟伅鍐呭
+ /// </summary>
+ public string Message { get; set; } = string.Empty;
+
+ /// <summary>
+ /// 鏃ュ織鏉ユ簮/鏂囦欢鍚�
+ /// </summary>
+ public string? Source { get; set; }
+
+ /// <summary>
+ /// 寮傚父淇℃伅锛堝彲閫夛級
+ /// </summary>
+ public string? Exception { get; set; }
+
+ /// <summary>
+ /// 鏍煎紡鍖栦负鏍囧噯鏃ュ織瀛楃涓�
+ /// </summary>
+ public string ToFormattedString()
{
+ var sb = new StringBuilder();
+ sb.Append($"銆恵Time:HH:mm:ss}銆戙�恵Level}銆戯細銆恵Message}銆�");
+ if (!string.IsNullOrEmpty(Exception))
+ {
+ sb.AppendLine();
+ sb.Append($"銆愬紓甯搞�戯細{Exception}");
+ }
+ return sb.ToString();
+ }
+ }
+
+ /// <summary>
+ /// 闃熷垪鍖栭泦涓棩蹇楀啓鍏ュ櫒
+ /// 浣跨敤鐢熶骇鑰�-娑堣垂鑰呮ā寮忥紝鍚庡彴绾跨▼鎵归噺鍐欏叆鏂囦欢锛屾彁楂樻�ц兘
+ /// </summary>
+ public class QueuedLogWriter : IDisposable
+ {
+ private static readonly Lazy<QueuedLogWriter> _instance = new Lazy<QueuedLogWriter>(() => new QueuedLogWriter());
+ public static QueuedLogWriter Instance => _instance.Value;
+
+ private readonly BlockingCollection<LogEntry> _logQueue;
+ private readonly CancellationTokenSource _cts;
+ private readonly Task _writeTask;
+ private readonly ReaderWriterLockSlim _fileLock = new ReaderWriterLockSlim();
+ private readonly string _logFolder;
+ private readonly int _maxFileSize;
+ private readonly string _fileExt;
+ private bool _disposed;
+
+ /// <summary>
+ /// 鏃ュ織闃熷垪鍐欏叆鍣ㄥ崟渚�
+ /// </summary>
+ private QueuedLogWriter()
+ {
+ _logFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"Log{Path.DirectorySeparatorChar}{DateTime.Now:yyyy-MM-dd}");
+ _maxFileSize = 10 * 1024 * 1024; // 10MB
+ _fileExt = ".log";
+ _logQueue = new BlockingCollection<LogEntry>(new ConcurrentQueue<LogEntry>());
+ _cts = new CancellationTokenSource();
+
+ // 纭繚鏃ュ織鐩綍瀛樺湪
+ if (!Directory.Exists(_logFolder))
+ {
+ Directory.CreateDirectory(_logFolder);
+ }
+
+ // 鍚姩鍚庡彴鍐欏叆绾跨▼
+ _writeTask = Task.Run(WriteLoop, _cts.Token);
+ }
+
+ /// <summary>
+ /// 鍚庡彴鍐欏叆寰幆
+ /// </summary>
+ private void WriteLoop()
+ {
+ var batch = new List<LogEntry>();
+ while (!_cts.Token.IsCancellationRequested)
+ {
+ try
+ {
+ // 鎵归噺鍙栧嚭鏃ュ織锛屾渶澶�100鏉℃垨绛夊緟500ms
+ batch.Clear();
+ if (_logQueue.TryTake(out var entry, 500))
+ {
+ batch.Add(entry);
+ while (batch.Count < 100 && _logQueue.TryTake(out entry, 50))
+ {
+ batch.Add(entry);
+ }
+ WriteBatch(batch);
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ break;
+ }
+ catch (Exception)
+ {
+ // 蹇界暐鍐欏叆寮傚父锛岄槻姝㈠悗鍙扮嚎绋嬪穿婧�
+ }
+ }
+
+ // 鍙栨秷鍓嶅皢鍓╀綑鏃ュ織鍐欏嚭
+ while (_logQueue.TryTake(out var remainingEntry, 100))
+ {
+ batch.Add(remainingEntry);
+ }
+ if (batch.Count > 0)
+ {
+ WriteBatch(batch);
+ }
+ }
+
+ /// <summary>
+ /// 鎵归噺鍐欏叆鏃ュ織鍒版枃浠�
+ /// </summary>
+ private void WriteBatch(List<LogEntry> entries)
+ {
+ if (entries.Count == 0) return;
+
try
{
- // 杩涘叆鍐欓攣
- LogWriteLock.EnterWriteLock();
-
- // 濡傛灉鏂囦欢澶逛笉瀛樺湪锛屽垯鍒涘缓鏂囦欢澶�
- if (!Directory.Exists(folderPath))
+ _fileLock.EnterWriteLock();
+ foreach (var entry in entries)
{
- Directory.CreateDirectory(folderPath);
+ string fileName = GetLogFileName(entry.Source);
+ string filePath = Path.Combine(_logFolder, fileName);
+ string content = entry.ToFormattedString() + Environment.NewLine;
+ ConsoleHelper.WriteInfoLine(content);
+ File.AppendAllText(filePath, content);
}
- // 鑾峰彇鏃ュ織鏂囦欢璺緞
- string logFilePath = Path.Combine(folderPath, GetLastAccessFileName(fileName));
- // 鑾峰彇褰撳墠鏃堕棿
- DateTime now = DateTime.Now;
- // 鏋勯�犳棩蹇楀唴瀹�
- string logContent = $"銆恵now}銆憑Environment.NewLine}{log}";
-
- // 灏嗘棩蹇楀唴瀹硅拷鍔犲埌鏃ュ織鏂囦欢涓�
- File.AppendAllText(logFilePath, logContent);
}
- catch { }
+ catch (Exception)
+ {
+ // 闈欓粯澶勭悊锛岄槻姝㈡枃浠禝O寮傚父褰卞搷涓荤嚎绋�
+ }
finally
{
- // 閫�鍑哄啓閿�
- LogWriteLock.ExitWriteLock();
+ _fileLock.ExitWriteLock();
}
}
- static int size = 10 * 1024 * 1024;
- static string ext = ".log";
- private static string GetLogFilePath(string folderPath, string fileName)
- {
- // 鑾峰彇鎸囧畾鏂囦欢澶逛笅鐨勬墍鏈夋枃浠�
- var allFiles = new DirectoryInfo(folderPath);
- // 鑾峰彇绗﹀悎鏉′欢鐨勬枃浠讹紝鎸夋枃浠跺悕闄嶅簭鎺掑垪
- var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(fileName.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList();
- FileInfo? file = selectFiles.FirstOrDefault();
- // 濡傛灉鏈夌鍚堟潯浠剁殑鏂囦欢锛岃繑鍥炵涓�涓枃浠剁殑瀹屾暣璺緞
- if (file != null)
+ /// <summary>
+ /// 鑾峰彇鎴栧垱寤轰竴涓棩蹇楁枃浠惰矾寰勶紙鎸夊ぇ灏忓垎鏂囦欢锛�
+ /// </summary>
+ private string GetLogFileName(string? source)
+ {
+ string prefix = string.IsNullOrEmpty(source) ? "WCS" : source;
+ string searchPattern = $"{prefix}*.log";
+
+ if (!Directory.Exists(_logFolder))
{
- return file.FullName;
+ Directory.CreateDirectory(_logFolder);
}
- // 濡傛灉娌℃湁绗﹀悎鏉′欢鐨勬枃浠讹紝杩斿洖涓�涓柊鐨勬枃浠惰矾寰勶紝鏂囦欢鍚嶄负鍘熸枃浠跺悕鍔犱笂褰撳墠鏃堕棿
- return Path.Combine(folderPath, $@"{fileName}_{DateTime.Now.ToString("HH-mm-ss")}.log");
- }
+ var files = Directory.GetFiles(_logFolder, searchPattern)
+ .Select(f => new FileInfo(f))
+ .Where(f => f.Extension.Equals(_fileExt, StringComparison.OrdinalIgnoreCase))
+ .OrderByDescending(f => f.Name)
+ .ToList();
- private static string GetLastAccessFileName(string fileName)
- {
- foreach (var m in GetExistLogFileNames(fileName))
+ // 鏌ユ壘鏈夌┖闂寸殑鐜版湁鏂囦欢
+ foreach (var file in files)
{
- FileInfo fileInfo = new FileInfo(m);
- if (fileInfo.Length < size)
+ if (file.Length < _maxFileSize)
{
- return m;
+ return file.Name;
}
}
- // 杩斿洖涓�涓柊鐨勯粯璁ゅ綋鍓嶆椂闂寸殑鏃ュ織鍚嶇О
- return $@"{fileName}_{DateTime.Now.ToString("HH-mm-ss")}.log";
+ // 鍒涘缓鏂版枃浠�
+ return $"{prefix}_{DateTime.Now:HH-mm-ss}{_fileExt}";
}
- public static string[] GetExistLogFileNames(string fileName)
+ /// <summary>
+ /// 鍐欏叆鏃ュ織锛堢敓浜х锛�
+ /// </summary>
+ public void Enqueue(LogEntry entry)
{
- string[] fileNames = Directory.GetFiles(folderPath, fileName + "*.log");
- return fileNames;
+ if (_disposed) return;
+ _logQueue.Add(entry);
+ }
+
+ /// <summary>
+ /// 鍐欏叆鏃ュ織鐨勪究鎹锋柟娉�
+ /// </summary>
+ public void Log(LogLevel level, string message, string? source = null, string? exception = null)
+ {
+ if (_disposed) return;
+ var entry = new LogEntry
+ {
+ Time = DateTime.Now,
+ Level = level,
+ Message = message,
+ Source = source,
+ Exception = exception
+ };
+ _logQueue.Add(entry);
+ }
+
+ /// <summary>
+ /// 鍏抽棴鏃ュ織鍐欏叆鍣�
+ /// </summary>
+ public void Dispose()
+ {
+ if (_disposed) return;
+ _disposed = true;
+ _cts.Cancel();
+ try
+ {
+ _writeTask.Wait(3000);
+ }
+ catch (AggregateException) { }
+ _cts.Dispose();
+ _logQueue.Dispose();
+ _fileLock.Dispose();
+ }
+ }
+
+ /// <summary>
+ /// 闈欐�佹棩蹇楀伐鍏风被锛堝吋瀹瑰師鏈夋帴鍙o級
+ /// 鎻愪緵澶氱鏍煎紡鍖栨柟娉曞拰闃熷垪鍖栧啓鍏�
+ /// </summary>
+ public class QuartzLogger
+ {
+ private static readonly QueuedLogWriter _writer = QueuedLogWriter.Instance;
+
+ /// <summary>
+ /// 鍏煎鏃ф帴鍙o細灏嗘棩蹇楀啓鍏ユ枃浠�
+ /// </summary>
+ /// <param name="fileName">鏃ュ織鏂囦欢鍚嶏紙浣滀负Source锛�</param>
+ /// <param name="log">鏃ュ織鍐呭</param>
+ public static void WriteLogToFile(string fileName, string log)
+ {
+ _writer.Log(LogLevel.INFO, log, fileName);
+ }
+
+ /// <summary>
+ /// 鍐欏叆璋冭瘯鏃ュ織
+ /// </summary>
+ public static void Debug(string message, string? source = null)
+ {
+ _writer.Log(LogLevel.DEBUG, message, source);
+ }
+
+ /// <summary>
+ /// 鍐欏叆淇℃伅鏃ュ織
+ /// </summary>
+ public static void Info(string message, string? source = null)
+ {
+ _writer.Log(LogLevel.INFO, message, source);
+ }
+
+ /// <summary>
+ /// 鍐欏叆璀﹀憡鏃ュ織
+ /// </summary>
+ public static void Warn(string message, string? source = null)
+ {
+ _writer.Log(LogLevel.WARN, message, source);
+ }
+
+ /// <summary>
+ /// 鍐欏叆閿欒鏃ュ織
+ /// </summary>
+ public static void Error(string message, string? source = null, Exception? exception = null)
+ {
+ _writer.Log(LogLevel.ERROR, message, source, exception?.ToString());
+ }
+
+ /// <summary>
+ /// 鍐欏叆鑷村懡閿欒鏃ュ織
+ /// </summary>
+ public static void Fatal(string message, string? source = null, Exception? exception = null)
+ {
+ _writer.Log(LogLevel.FATAL, message, source, exception?.ToString());
+ }
+
+ /// <summary>
+ /// 浣跨敤鎸囧畾鏍煎紡鍐欏叆鏃ュ織
+ /// </summary>
+ /// <param name="format">鏍煎紡鍖栧瓧绗︿覆</param>
+ /// <param name="args">鏍煎紡鍖栧弬鏁�</param>
+ public static void WriteFormatted(string format, params object[] args)
+ {
+ string message = string.Format(format, args);
+ _writer.Log(LogLevel.INFO, message);
+ }
+
+ /// <summary>
+ /// 鐩存帴鍐欏叆涓�涓棩蹇楁潯鐩紙鏈�鐏垫椿锛�
+ /// </summary>
+ public static void WriteLogEntry(LogEntry entry)
+ {
+ _writer.Enqueue(entry);
+ }
+
+ /// <summary>
+ /// 閲婃斁璧勬簮锛堝簲鐢ㄥ叧闂椂璋冪敤锛�
+ /// </summary>
+ public static void Shutdown()
+ {
+ _writer.Dispose();
}
}
}
--
Gitblit v1.9.3