change - 多实例日志修改

master
wenjy 2 months ago
parent feb3052bd3
commit 3b208a6d8a

@ -37,25 +37,102 @@ namespace SlnMesnac.Serilog
{
public static void UseSerilogExtensions(this IServiceProvider service)
{
#region 通过配置文件读取日志存放位置
var appConfig = service.GetService<AppConfig>();
var logPath = $"{appConfig.logPath}/Logs/";
var logPath = appConfig?.logPath ?? "Logs";
// 如果是多实例,使用实例专用的日志路径
// 注意App类中的InstanceDataPath已经是实例专用的路径
if (appConfig?.InstanceDataPath != null)
{
// 使用实例数据路径下的Logs目录
logPath = Path.Combine(appConfig.InstanceDataPath, "Logs");
}
// 确保日志目录存在
EnsureLogDirectories(logPath);
#endregion
Log.Logger = new LoggerConfiguration().MinimumLevel.Information().WriteTo.Console()
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey("Module") && logEvent.Properties["Module"].ToString().Contains("Info"))
.WriteTo.File(Path.Combine($"{logPath}/Info/", "Info.log"), rollingInterval: RollingInterval.Day))
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey("Module") && logEvent.Properties["Module"].ToString().Contains("data"))
.WriteTo.File(Path.Combine($"{logPath}/data/", "data.log"), rollingInterval: RollingInterval.Day))
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey("Module") && logEvent.Properties["Module"].ToString().Contains("Error"))
.WriteTo.File(Path.Combine($"{logPath}/Error/", "Error.log"), rollingInterval: RollingInterval.Day))
.CreateLogger();
// 构建日志配置包含实例ID作为上下文
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.Enrich.WithProperty("InstanceId", appConfig?.InstanceId ?? "Unknown")
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3} {InstanceId}] {Message:lj}{NewLine}{Exception}")
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent =>
logEvent.Properties.ContainsKey("Module") &&
logEvent.Properties["Module"].ToString().Contains("Info"))
.WriteTo.File(
Path.Combine($"{logPath}/Info/", "Info.log"),
rollingInterval: RollingInterval.Day,
outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3} {InstanceId}] {Message:lj}{NewLine}{Exception}",
retainedFileCountLimit: 7)) // 保留最近7天的日志文件
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent =>
logEvent.Properties.ContainsKey("Module") &&
logEvent.Properties["Module"].ToString().Contains("Data"))
.WriteTo.File(
Path.Combine($"{logPath}/Data/", "Data.log"),
rollingInterval: RollingInterval.Day,
outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3} {InstanceId}] {Message:lj}{NewLine}{Exception}",
retainedFileCountLimit: 7))
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent =>
logEvent.Properties.ContainsKey("Module") &&
logEvent.Properties["Module"].ToString().Contains("Error"))
.WriteTo.File(
Path.Combine($"{logPath}/Error/", "Error.log"),
rollingInterval: RollingInterval.Day,
outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3} {InstanceId}] {Message:lj}{NewLine}{Exception}",
retainedFileCountLimit: 30)) // 错误日志保留更长时间
.CreateLogger();
}
/// <summary>
/// 确保日志目录存在
/// </summary>
private static void EnsureLogDirectories(string baseLogPath)
{
try
{
// 确保基础日志目录存在
if (!Directory.Exists(baseLogPath))
{
Directory.CreateDirectory(baseLogPath);
}
// 确保各模块日志子目录存在
string[] subDirectories = { "Info", "Data", "Error", "Debug", "Audit" };
foreach (var subDir in subDirectories)
{
string dirPath = Path.Combine(baseLogPath, subDir);
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
}
// 创建当前实例的启动日志文件
string startupLog = Path.Combine(baseLogPath, "Startup.log");
File.AppendAllText(startupLog,
$"=== Instance Startup ===\r\n" +
$"Time: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}\r\n" +
$"Base Log Path: {baseLogPath}\r\n" +
$"=================================================================\r\n");
}
catch (Exception ex)
{
// 如果无法创建目录,使用临时目录
Console.WriteLine($"无法创建日志目录 {baseLogPath}: {ex.Message}");
// 尝试使用临时目录作为后备
string tempLogPath = Path.Combine(Path.GetTempPath(), "SlnMesnac", "Logs");
if (!Directory.Exists(tempLogPath))
{
Directory.CreateDirectory(tempLogPath);
}
}
}
}
}

@ -0,0 +1,95 @@
using Serilog;
using System;
using System.Collections.Generic;
using System.Text;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* T14-GEN3-7895
* SlnMesnac.Serilog
* fae9d68d-1992-4a03-b299-19edd9fc786d
*
* WenJY
*
* 2024-12-26 8:46:21
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Serilog
{
/// <summary>
/// Serilog日志类
/// </summary>
public class SerilogHelper
{
private readonly ILogger? Info_logger = Log.ForContext("Module", "Info");
private readonly ILogger? Data_logger = Log.ForContext("Module", "Data");
private readonly ILogger? Error_logger = Log.ForContext("Module", "Error");
/// <summary>
/// Info日志
/// </summary>
/// <param name="msg"></param>
public void Info(string msg)
{
if (Info_logger != null)
{
this.Info_logger.Information(msg);
}
}
/// <summary>
/// Data日志
/// </summary>
/// <param name="msg"></param>
public void Data(string msg)
{
if (Data_logger != null)
{
this.Data_logger.Information(msg);
}
}
/// <summary>
/// Error日志
/// </summary>
/// <param name="msg"></param>
/// <param name="ex"></param>
public void Error(string msg, Exception ex = null)
{
if (!string.IsNullOrEmpty(msg) && ex == null)
{
this.Error_logger.Information("【附加信息】 : {0}<br>", new object[] { msg });
}
else if (!string.IsNullOrEmpty(msg) && ex != null)
{
string errorMsg = BeautyErrorMsg(ex);
this.Error_logger.Information("【附加信息】 : {0}<br>{1}", new object[] { msg, errorMsg });
}
else if (string.IsNullOrEmpty(msg) && ex != null)
{
string errorMsg = BeautyErrorMsg(ex);
this.Error_logger.Information(errorMsg);
}
}
private string BeautyErrorMsg(Exception ex)
{
string errorMsg = string.Format("【异常类型】:{0} <br>【异常信息】:{1} <br>【堆栈调用】:{2}", new object[] { ex.GetType().Name, ex.Message, ex.StackTrace });
errorMsg = errorMsg.Replace("\r\n", "<br>");
errorMsg = errorMsg.Replace("位置", "<strong style=\"color:red\">位置</strong>");
return errorMsg;
}
}
}

@ -102,11 +102,6 @@ namespace SlnMesnac.WPF
// 根据实例ID调整数据库连接如果需要
// AdjustDatabaseConnectionForInstance(appConfig);
}
Log.Information($"应用程序启动 - 实例ID: {_instanceId}, 进程ID: {Process.GetCurrentProcess().Id}");
Log.Information($"日志目录: {appConfig?.logPath}");
Log.Information($"数据目录: {_instanceDataPath}");
// 显示主窗口
var loginWindow = ServiceProvider.GetRequiredService<MainWindow>();
loginWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
@ -114,6 +109,13 @@ namespace SlnMesnac.WPF
// 在窗口标题显示实例信息
loginWindow.Title = $"{loginWindow.Title} [{_instanceId}]";
loginWindow.Show();
var serilog = ServiceProvider.GetRequiredService<SerilogHelper>();
serilog.Info($"应用程序启动 - 实例ID: {_instanceId}, 进程ID: {Process.GetCurrentProcess().Id}");
serilog.Info($"日志目录: {appConfig?.logPath}");
serilog.Data($"数据目录: {_instanceDataPath}");
serilog.Error($"日志目录: {appConfig?.logPath}");
}
catch (Exception exception)
{
@ -169,11 +171,11 @@ namespace SlnMesnac.WPF
_instanceDataPath = Path.Combine(baseDataRoot, appName, "Instances", _instanceId);
Directory.CreateDirectory(_instanceDataPath);
Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Data"));
//Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Data"));
Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Logs"));
Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Config"));
Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Cache"));
Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Temp"));
//Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Config"));
//Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Cache"));
//Directory.CreateDirectory(Path.Combine(_instanceDataPath, "Temp"));
SaveInstanceInfo();
@ -183,13 +185,42 @@ namespace SlnMesnac.WPF
/// <summary>
/// 获取数据存储根路径
/// </summary>
//private string GetDataRootPath()
//{
// string envPath = Environment.GetEnvironmentVariable("SLNMESNAC_DATA_ROOT");
// if (!string.IsNullOrEmpty(envPath) && Directory.Exists(envPath))
// return envPath;
// return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
//}
private string GetDataRootPath()
{
string envPath = Environment.GetEnvironmentVariable("SLNMESNAC_DATA_ROOT");
if (!string.IsNullOrEmpty(envPath) && Directory.Exists(envPath))
return envPath;
// 使用当前系统目录 + InstanceData 路径
string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
string instanceDataPath = Path.Combine(currentDirectory, "InstanceData");
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
// 如果无法访问当前目录,使用应用程序数据目录作为后备
try
{
// 尝试访问当前目录,确保我们有权限
if (!Directory.Exists(instanceDataPath))
{
Directory.CreateDirectory(instanceDataPath);
}
return instanceDataPath;
}
catch
{
// 如果没有权限,使用用户应用程序数据目录
string fallbackPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
Assembly.GetExecutingAssembly().GetName().Name,
"InstanceData"
);
Directory.CreateDirectory(fallbackPath);
return fallbackPath;
}
}
/// <summary>
@ -325,7 +356,7 @@ namespace SlnMesnac.WPF
return appConfig;
});
//services.AddSingleton<SerilogHelper>();
services.AddSingleton<SerilogHelper>();
// 加载程序集
Assembly[] assemblies = {

@ -9,6 +9,7 @@
"AllowedHosts": "*",
"AppConfig": {
"logPath": "D:\\net6.0-windows\\log",
"InstanceDataPath": "D:\\net6.0-windows\\InstanceData",
"SqlConfig": [
{
"configId": "mes",

Loading…
Cancel
Save