A:调整日志框架和整体项目配置
This commit is contained in:
1 parent
91b45955fe
commit
807e33eb60
7 files changed
+193
-62
No files matched your search
+14
-13
@@ -14,20 +14,21 @@ public sealed class AppConfig
|
||||
private AppConfig()
|
||||
{
|
||||
var model = ConfigReader.LoadConfig();
|
||||
AppName = model.AppName ?? "MyApp";
|
||||
Version = model.Version ?? "1.0.0";
|
||||
MaxConnection = model.MaxConnection > 0 ? model.MaxConnection : 10;
|
||||
|
||||
// 初始化配置(可以从文件或环境变量读取)
|
||||
AppName = "MyApp";
|
||||
Version = "1.0.0";
|
||||
MaxConnection = 10;
|
||||
ConfigModel = model;
|
||||
}
|
||||
|
||||
// 配置项:只读属性
|
||||
public string AppName { get; }
|
||||
public string Version { get; }
|
||||
public int MaxConnection { get; }
|
||||
/// <summary>
|
||||
/// 全局配置
|
||||
/// </summary>
|
||||
public AppConfigModel ConfigModel { get; }
|
||||
|
||||
// 可扩展其他读取配置的方法
|
||||
/// <summary>
|
||||
/// WebSocket 端口
|
||||
/// </summary>
|
||||
public int WebSocketPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// WebSocket 连接地址
|
||||
/// </summary>
|
||||
public string? WebSocketPath { get; set; }
|
||||
}
|
||||
@@ -10,6 +10,9 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0-preview.4.25258.110" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0-preview.4.25258.110" />
|
||||
<PackageReference Include="Serilog" Version="4.3.1-dev-02373" />
|
||||
<PackageReference Include="Serilog.Enrichers.Environment" Version="3.0.1" />
|
||||
<PackageReference Include="Serilog.Enrichers.Process" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Enrichers.Thread" Version="4.0.0" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.1-dev-02317" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.1-dev-00953" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Common.Logger;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Common.Configuration;
|
||||
@@ -26,4 +27,5 @@ public class AppConfigModel
|
||||
public string AppName { get; set; }
|
||||
public string Version { get; set; }
|
||||
public int MaxConnection { get; set; }
|
||||
public LoggerConfig Logging { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Common.ExpandException;
|
||||
|
||||
public class ExceptionEnum
|
||||
{
|
||||
// region 系统常见错误本地化
|
||||
|
||||
/// <summary>
|
||||
/// 进程信息获取失败
|
||||
/// </summary>
|
||||
public static readonly ExceptionExpand ProcessGetException = new(100001L, "进程消息获取失败,指定线程可能不存在或已关闭!", "以管理员权限重试!");
|
||||
|
||||
|
||||
// endregion
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Common;
|
||||
namespace Common.ExpandException;
|
||||
|
||||
public class ExceptionExpand : Exception
|
||||
{
|
||||
@@ -34,16 +34,3 @@ public class ExceptionExpand : Exception
|
||||
return $"Error Code: {ErrorCode}\nMessage: {Message}\nSuggestion: {Suggestion}\n{base.ToString()}";
|
||||
}
|
||||
}
|
||||
|
||||
public class ExceptionEnum
|
||||
{
|
||||
// region 系统常见错误本地化
|
||||
|
||||
/// <summary>
|
||||
/// 进程信息获取失败
|
||||
/// </summary>
|
||||
public static readonly ExceptionExpand ProcessGetException = new(100001L, "进程消息获取失败,指定线程可能不存在或已关闭!", "以管理员权限重试!");
|
||||
|
||||
|
||||
// endregion
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Serilog;
|
||||
|
||||
namespace Common.FunExpand;
|
||||
|
||||
public static class StringExpand
|
||||
{
|
||||
/// <summary>
|
||||
/// 检测是否是 url
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidUrl(this string str)
|
||||
{
|
||||
return Uri.TryCreate(str, UriKind.Absolute, out _);
|
||||
}
|
||||
|
||||
public static int ToInt(this string? str, int defaultValue = default)
|
||||
{
|
||||
return TryToInt(str) ?? defaultValue;
|
||||
}
|
||||
|
||||
public static int? TryToInt(this string? str)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(str))
|
||||
{
|
||||
Log.Error($"数据为空, 返回默认值 {null} .");
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return int.Parse(str);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"数据 {str} 转换失败, 返回默认值 {null} .");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static double ToDouble(this string? str, double defaultValue = default)
|
||||
{
|
||||
return TryToDouble(str) ?? defaultValue;
|
||||
}
|
||||
|
||||
public static double? TryToDouble(this string? str)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(str))
|
||||
{
|
||||
Log.Error($"数据为空, 返回默认值 {null} .");
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return double.Parse(str);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"数据 {str} 转换失败, 返回默认值 {null} .");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,9 @@
|
||||
using System.IO.Compression;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Formatting.Json;
|
||||
using System.Timers;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using Serilog;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
using Serilog.Formatting.Json;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Common.Logger;
|
||||
|
||||
@@ -68,10 +56,11 @@ public class UniversalLogger : IDisposable
|
||||
private Serilog.Core.Logger CreateLogger()
|
||||
{
|
||||
var loggerConfig = new LoggerConfiguration()
|
||||
.MinimumLevel.Is(_config.MinimumLevel)
|
||||
.Enrich.WithProperty("MachineName", Environment.MachineName)
|
||||
.Enrich.WithProperty("ProcessId", Environment.ProcessId)
|
||||
.Enrich.WithProperty("ThreadId", Environment.CurrentManagedThreadId);
|
||||
.MinimumLevel.Is(_config.MinimumLevel)
|
||||
.Enrich.WithThreadId()
|
||||
.Enrich.WithProcessId()
|
||||
// .Enrich.WithMachineName() // 推荐添加机器名 enrich 扩展
|
||||
;
|
||||
|
||||
// 配置控制台输出
|
||||
if (_config.EnableConsole)
|
||||
@@ -86,17 +75,17 @@ public class UniversalLogger : IDisposable
|
||||
{
|
||||
Directory.CreateDirectory(_config.LogPath);
|
||||
|
||||
string logFileName = Path.Combine(_config.LogPath, "log-.txt");
|
||||
string logFileName = Path.Combine(_config.LogPath, "log-.log");
|
||||
|
||||
if (_config.UseJsonFormat)
|
||||
{
|
||||
loggerConfig = loggerConfig.WriteTo.File(
|
||||
formatter: new JsonFormatter(),
|
||||
path: logFileName,
|
||||
rollingInterval: RollingInterval.Day,
|
||||
rollOnFileSizeLimit: true,
|
||||
fileSizeLimitBytes: _config.MaxFileSizeMB * 1024 * 1024,
|
||||
retainedFileCountLimit: null,
|
||||
rollingInterval: RollingInterval.Day, // 按天分类
|
||||
rollOnFileSizeLimit: true, // 当日志文件大小超过限制时滚动
|
||||
fileSizeLimitBytes: _config.MaxFileSizeMB * 1024 * 1024, // 日志文件大小限制
|
||||
retainedFileCountLimit: null, // 保留最近7天的日志文件
|
||||
restrictedToMinimumLevel: _config.MinimumLevel);
|
||||
}
|
||||
else
|
||||
@@ -108,7 +97,9 @@ public class UniversalLogger : IDisposable
|
||||
rollOnFileSizeLimit: true,
|
||||
fileSizeLimitBytes: _config.MaxFileSizeMB * 1024 * 1024,
|
||||
retainedFileCountLimit: null,
|
||||
restrictedToMinimumLevel: _config.MinimumLevel);
|
||||
restrictedToMinimumLevel: _config.MinimumLevel,
|
||||
shared: true // 允许多个应用程序实例共享同一日志文件
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +133,7 @@ public class UniversalLogger : IDisposable
|
||||
_logger.Error(message, args);
|
||||
}
|
||||
|
||||
public void LogError(Exception exception, string message, params object[] args)
|
||||
public void LogError(Exception? exception, string message, params object[] args)
|
||||
{
|
||||
_logger.Error(exception, message, args);
|
||||
}
|
||||
@@ -152,16 +143,25 @@ public class UniversalLogger : IDisposable
|
||||
_logger.Fatal(message, args);
|
||||
}
|
||||
|
||||
public void LogFatal(Exception exception, string message, params object[] args)
|
||||
public void LogFatal(Exception? exception, string message, params object[] args)
|
||||
{
|
||||
_logger.Fatal(exception, message, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取上下文
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public ILogger GetLogger<T>() => _logger.ForContext<T>();
|
||||
|
||||
public ILogger ForContext(string propertyName, object? value)
|
||||
=> _logger.ForContext(propertyName, value);
|
||||
|
||||
/// <summary>
|
||||
/// 记录带上下文信息的日志
|
||||
/// </summary>
|
||||
public void LogWithContext(LogEventLevel level, string message, Dictionary<string, object> context,
|
||||
Exception exception = null)
|
||||
Exception? exception = null)
|
||||
{
|
||||
var logEvent = new LogEventLevel[] { level };
|
||||
ILogger logger = _logger;
|
||||
@@ -199,7 +199,7 @@ public class UniversalLogger : IDisposable
|
||||
await DeleteOldLogsAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception? ex)
|
||||
{
|
||||
_logger.Error(ex, "执行日志维护任务时发生错误");
|
||||
}
|
||||
@@ -214,7 +214,7 @@ public class UniversalLogger : IDisposable
|
||||
if (!logDirectory.Exists) return;
|
||||
|
||||
var cutoffDate = DateTime.Now.Date.AddDays(-_config.CompressDaysThreshold);
|
||||
var logFiles = logDirectory.GetFiles("log*.txt")
|
||||
var logFiles = logDirectory.GetFiles("log*.log")
|
||||
.Where(f => f.CreationTime.Date < cutoffDate && !f.Name.EndsWith(".gz"))
|
||||
.ToList();
|
||||
|
||||
@@ -230,7 +230,7 @@ public class UniversalLogger : IDisposable
|
||||
|
||||
_logger.Information("已压缩日志文件: {FileName}", file.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception? ex)
|
||||
{
|
||||
_logger.Error(ex, "压缩日志文件失败: {FileName}", file.Name);
|
||||
}
|
||||
@@ -257,7 +257,7 @@ public class UniversalLogger : IDisposable
|
||||
File.Delete(file.FullName);
|
||||
_logger.Information("已删除过期日志文件: {FileName}", file.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception? ex)
|
||||
{
|
||||
_logger.Error(ex, "删除过期日志文件失败: {FileName}", file.Name);
|
||||
}
|
||||
@@ -382,21 +382,81 @@ public static class Log
|
||||
}
|
||||
|
||||
public static void Verbose(string message, params object[] args) => Instance.LogVerbose(message, args);
|
||||
|
||||
public static void Verbose4Ctx(string message, [CallerMemberName] string callerMemberName = "",
|
||||
[CallerFilePath] string filePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
var str = GetLog(callerMemberName, Path.GetFileName(filePath), callerLineNumber, message);
|
||||
Verbose(str);
|
||||
}
|
||||
|
||||
public static void Debug(string message, params object[] args) => Instance.LogDebug(message, args);
|
||||
|
||||
public static void Debug4Ctx(string message, [CallerMemberName] string callerMemberName = "",
|
||||
[CallerFilePath] string filePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
var str = GetLog(callerMemberName, Path.GetFileName(filePath), callerLineNumber, message);
|
||||
Debug(str);
|
||||
}
|
||||
|
||||
public static void Information(string message, params object[] args) => Instance.LogInformation(message, args);
|
||||
|
||||
public static void Information4Ctx(string message, [CallerMemberName] string callerMemberName = "",
|
||||
[CallerFilePath] string filePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
var str = GetLog(callerMemberName, Path.GetFileName(filePath), callerLineNumber, message);
|
||||
Information(str);
|
||||
}
|
||||
|
||||
public static void Warning(string message, params object[] args) => Instance.LogWarning(message, args);
|
||||
|
||||
public static void Warning4Ctx(string message, [CallerMemberName] string callerMemberName = "",
|
||||
[CallerFilePath] string filePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
var str = GetLog(callerMemberName, Path.GetFileName(filePath), callerLineNumber, message);
|
||||
Warning(str);
|
||||
}
|
||||
|
||||
public static void Error(string message, params object[] args) => Instance.LogError(message, args);
|
||||
|
||||
public static void Error(Exception exception, string message, params object[] args) =>
|
||||
Instance.LogError(exception, message, args);
|
||||
public static void Error4Ctx(string message, [CallerMemberName] string callerMemberName = "",
|
||||
[CallerFilePath] string filePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
var str = GetLog(callerMemberName, Path.GetFileName(filePath), callerLineNumber, message);
|
||||
Error(str);
|
||||
}
|
||||
|
||||
|
||||
public static void Error(Exception? exception, string message, [CallerMemberName] string callerMemberName = "",
|
||||
[CallerFilePath] string filePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
var str = GetLog(callerMemberName, Path.GetFileName(filePath), callerLineNumber, message);
|
||||
Instance.LogError(exception, str);
|
||||
}
|
||||
|
||||
public static void Fatal(string message, params object[] args) => Instance.LogFatal(message, args);
|
||||
|
||||
public static void Fatal(Exception exception, string message, params object[] args) =>
|
||||
Instance.LogFatal(exception, message, args);
|
||||
public static void Fatal4Ctx(string message, [CallerMemberName] string callerMemberName = "",
|
||||
[CallerFilePath] string filePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
var str = GetLog(callerMemberName, Path.GetFileName(filePath), callerLineNumber, message);
|
||||
Fatal(str);
|
||||
}
|
||||
|
||||
public static void Fatal(Exception? exception, string message, [CallerMemberName] string callerMemberName = "",
|
||||
[CallerFilePath] string filePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
var str = GetLog(callerMemberName, Path.GetFileName(filePath), callerLineNumber, message);
|
||||
Instance.LogFatal(exception, str);
|
||||
}
|
||||
|
||||
private static string GetLog(string callerMemberName, string getFileName, int callerLineNumber, string message)
|
||||
{
|
||||
return $"[{callerMemberName}] - {getFileName}:{callerLineNumber} :{message}";
|
||||
}
|
||||
|
||||
public static void WithContext(LogEventLevel level, string message, Dictionary<string, object> context,
|
||||
Exception exception = null)
|
||||
Exception? exception = null)
|
||||
=> Instance.LogWithContext(level, message, context, exception);
|
||||
|
||||
public static async Task RunMaintenanceAsync() => await Instance.RunMaintenanceAsync();
|
||||
|
||||
Reference in new issue
Block a user