优化Nlog日志记录,解决记录到文本IP、请求地址获取不到问题

This commit is contained in:
不做码农 2023-09-07 09:30:50 +08:00
parent 02ffc18a61
commit b01765360d
6 changed files with 50 additions and 27 deletions

View File

@ -5,8 +5,18 @@ namespace Infrastructure
public class CustomException : Exception public class CustomException : Exception
{ {
public int Code { get; set; } public int Code { get; set; }
/// <summary>
/// 前端提示语
/// </summary>
public string Msg { get; set; } public string Msg { get; set; }
/// <summary>
/// 记录到日志的详细内容
/// </summary>
public string LogMsg { get; set; } public string LogMsg { get; set; }
/// <summary>
/// 是否通知
/// </summary>
public bool Notice { get; set; } = true;
public CustomException(string msg) : base(msg) public CustomException(string msg) : base(msg)
{ {
@ -17,9 +27,10 @@ namespace Infrastructure
Msg = msg; Msg = msg;
} }
public CustomException(ResultCode resultCode, string msg) : base(msg) public CustomException(ResultCode resultCode, string msg, bool notice = true) : base(msg)
{ {
Code = (int)resultCode; Code = (int)resultCode;
Notice = notice;
} }
/// <summary> /// <summary>

View File

@ -24,29 +24,29 @@
<!--${basedir}表示当前应用程序域所在的根目录--> <!--${basedir}表示当前应用程序域所在的根目录-->
<target name="allfile" xsi:type="File" <target name="allfile" xsi:type="File"
fileName="${basedir}/adminlogs/all.txt" fileName="${basedir}/adminlogs/all.txt"
archiveFileName="${basedir}/adminlogs/bak/all.{###}.txt" archiveFileName="${basedir}/adminlogs/bak/all/all.{###}.txt"
archiveEvery="Day" archiveEvery="Day"
archiveNumbering="DateAndSequence" archiveNumbering="DateAndSequence"
archiveAboveSize="20000000" archiveAboveSize="20000000"
maxArchiveFiles="30" maxArchiveFiles="30"
keepFileOpen="true" keepFileOpen="true"
layout="${longdate} | ${event-properties:item=EventId_Id} | ${uppercase:${level}} | ${logger} | ${aspnet-request-iP:CheckForwardedForHeader=true} | ${event-properties:item=user} | ${aspnet-request-url} | ${message} | ${event-properties:item=requestParam} | ${event-properties:item=jsonResult} | ${onexception:${exception:format=tostring}"/> layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${aspnet-request-connection-id}|${uppercase:${level}}|${logger}|${aspnet-request-iP:CheckForwardedForHeader=true}|${event-properties:item=user:whenEmpty=-}|url: ${aspnet-request-url}|${message:whenEmpty=-}|${event-properties:item=requestParam}|${event-properties:item=jsonResult}"/>
<!--错误日志--> <!--错误日志-->
<target name="errorfile" xsi:type="File" <target name="errorfile" xsi:type="File"
fileName="${basedir}/adminlogs/error.txt" fileName="${basedir}/adminlogs/error.txt"
archiveFileName="${basedir}/adminlogs/bak/error.{###}.txt" archiveFileName="${basedir}/adminlogs/bak/error/error.{###}.txt"
archiveEvery="Day" archiveEvery="Day"
archiveNumbering="DateAndSequence" archiveNumbering="DateAndSequence"
archiveAboveSize="20000000" archiveAboveSize="20000000"
maxArchiveFiles="30" maxArchiveFiles="30"
keepFileOpen="true" keepFileOpen="true"
layout="${longdate} | ${event-properties:item=EventId_Id} | ${uppercase:${level}} | ${logger} | ${aspnet-request-iP:CheckForwardedForHeader=true} | ${event-properties:item=user} | ${aspnet-request-url} | ${message} | ${event-properties:item=requestParam} | ${event-properties:item=jsonResult} | ${onexception:${exception:format=tostring}"/> layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${uppercase:${level}}|${logger}${newline}用户IP${aspnet-request-iP:CheckForwardedForHeader=true}|${event-properties:item=user}${newline}请求地址:${aspnet-request-url}${newline}错误消息:${message}${newline}请求参数:${event-properties:item=requestParam}${newline}请求结果:${event-properties:item=jsonResult}${newline}${onexception:${exception:format=tostring}"/>
<!--SQL文件--> <!--SQL文件-->
<target name="sqlfile" xsi:type="File" <target name="sqlfile" xsi:type="File"
fileName="${basedir}/adminlogs/admin-sql.txt" fileName="${basedir}/adminlogs/sql.txt"
archiveFileName="${basedir}/adminlogs/bak/admin-sql{###}.txt" archiveFileName="${basedir}/adminlogs/bak/sql/sql{###}.txt"
archiveEvery="Day" archiveEvery="Day"
archiveNumbering="DateAndSequence" archiveNumbering="DateAndSequence"
archiveAboveSize="20000000" archiveAboveSize="20000000"
@ -56,18 +56,17 @@
<!--写入彩色控制台--> <!--写入彩色控制台-->
<target name="consoleSql" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false" <target name="consoleSql" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false"
layout="${date:format=MM-dd HH\:mm\:ss} | ${aspnet-request-iP} | ${aspnet-request-url} ${newline}${message}"> layout="${date:format=MM-dd HH\:mm\:ss}|${aspnet-request-iP}|${aspnet-request-url}${newline}${message}">
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" /> <highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" />
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" /> <highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" /> <highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" /> <highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" /> <highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
<highlight-word regex="SQL语句" foregroundColor="Blue" /> <highlight-word regex="SQL" foregroundColor="Blue" />
<highlight-word regex="【" foregroundColor="Blue" />
<highlight-word regex="】" foregroundColor="Blue" />
</target> </target>
<target name="console" xsi:type="ColoredConsole"
layout="${date:format=MM-dd HH\:mm\:ss} | ${aspnet-request-url} ${newline} ${message}"/>
<!--写入黑洞--> <!--写入黑洞-->
<target name="blackhole" xsi:type="Null" /> <target name="blackhole" xsi:type="Null" />
</targets> </targets>
@ -80,11 +79,10 @@
<!--<logger name="System.*" writeTo="blackhole" final="true" />--> <!--<logger name="System.*" writeTo="blackhole" final="true" />-->
<!-- Quartz --> <!-- Quartz -->
<logger name="Quartz*" minlevel="Trace" maxlevel="Info" final="true" /> <logger name="Quartz*" minlevel="Trace" maxlevel="Info" final="true" />
<logger name="ZR.ServiceCore.Middleware.GlobalExceptionMiddleware" final="true" writeTo="console,errorfile"/> <logger name="*.SqlSugar.SqlsugarSetup" final="true" writeTo="consoleSql,sqlfile"/>
<logger name="ZR.ServiceCore.SqlSugar.SqlsugarSetup" final="true" writeTo="consoleSql,sqlfile"/>
<logger name="*" writeTo="console"/>
<logger name="*" minLevel="Trace" writeTo="allfile" /> <logger name="*" minLevel="Trace" writeTo="allfile" />
<logger name="*.GlobalExceptionMiddleware" final="true" writeTo="consoleSql,errorfile"/>
<!--Skip non-critical Microsoft logs and so log only own logs--> <!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.*,Quartz.Core.QuartzSchedulerThread" maxlevel="Info" final="true" /> <logger name="Microsoft.*,Quartz.Core.QuartzSchedulerThread" maxlevel="Info" final="true" />
</rules> </rules>

View File

@ -1,6 +1,8 @@
using AspNetCoreRateLimit; using AspNetCoreRateLimit;
using Infrastructure.Converter; using Infrastructure.Converter;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.IdentityModel.Tokens;
using NLog.Web;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using ZR.Admin.WebApi.Extensions; using ZR.Admin.WebApi.Extensions;
using ZR.Common.Cache; using ZR.Common.Cache;
@ -9,6 +11,9 @@ using ZR.ServiceCore.Signalr;
using ZR.ServiceCore.SqlSugar; using ZR.ServiceCore.SqlSugar;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// NLog: Setup NLog for Dependency injection
//builder.Logging.ClearProviders();
builder.Host.UseNLog();
// Add services to the container. // Add services to the container.
builder.Services.AddControllers(); builder.Services.AddControllers();
@ -76,6 +81,13 @@ builder.Services.AddDb(app.Environment);
//使用全局异常中间件 //使用全局异常中间件
app.UseMiddleware<GlobalExceptionMiddleware>(); app.UseMiddleware<GlobalExceptionMiddleware>();
//请求头转发
//ForwardedHeaders中间件会自动把反向代理服务器转发过来的X-Forwarded-For客户端真实IP以及X-Forwarded-Proto客户端请求的协议自动填充到HttpContext.Connection.RemoteIPAddress和HttpContext.Request.Scheme中这样应用代码中读取到的就是真实的IP和真实的协议了不需要应用做特殊处理。
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto
});
app.Use((context, next) => app.Use((context, next) =>
{ {
//设置可以多次获取body内容 //设置可以多次获取body内容
@ -116,5 +128,4 @@ app.MapControllerRoute(
pattern: "{controller=Home}/{action=Index}/{id?}"); pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapControllers(); app.MapControllers();
app.Run(); app.Run();

View File

@ -44,16 +44,18 @@ namespace ZR.ServiceCore.Middleware
private async Task HandleExceptionAsync(HttpContext context, Exception ex) private async Task HandleExceptionAsync(HttpContext context, Exception ex)
{ {
NLog.LogLevel logLevel = NLog.LogLevel.Info; LogLevel logLevel = LogLevel.Info;
int code = (int)ResultCode.GLOBAL_ERROR; int code = (int)ResultCode.GLOBAL_ERROR;
string msg; string msg;
string error = string.Empty; string error = string.Empty;
bool notice = true;
//自定义异常 //自定义异常
if (ex is CustomException customException) if (ex is CustomException customException)
{ {
code = customException.Code; code = customException.Code;
msg = customException.Message; msg = customException.Message;
error = customException.LogMsg; error = customException.LogMsg;
notice = customException.Notice;
} }
else if (ex is ArgumentException)//参数异常 else if (ex is ArgumentException)//参数异常
{ {
@ -64,7 +66,7 @@ namespace ZR.ServiceCore.Middleware
{ {
msg = "服务器好像出了点问题,请联系系统管理员..."; msg = "服务器好像出了点问题,请联系系统管理员...";
error = $"{ex.Message}"; error = $"{ex.Message}";
logLevel = NLog.LogLevel.Error; logLevel = LogLevel.Error;
context.Response.StatusCode = 500; context.Response.StatusCode = 500;
} }
var options = new textJson.JsonSerializerOptions var options = new textJson.JsonSerializerOptions
@ -125,7 +127,8 @@ namespace ZR.ServiceCore.Middleware
$"\n> 错误信息:{msg}\n\n> {error}"; $"\n> 错误信息:{msg}\n\n> {error}";
SysOperLogService.InsertOperlog(sysOperLog); SysOperLogService.InsertOperlog(sysOperLog);
WxNoticeHelper.SendMsg("系统出错", errorMsg, "", WxNoticeHelper.MsgType.markdown); if (!notice) return;
WxNoticeHelper.SendMsg("系统异常", errorMsg, msgType: WxNoticeHelper.MsgType.markdown);
} }
public static Endpoint GetEndpoint(HttpContext context) public static Endpoint GetEndpoint(HttpContext context)

View File

@ -52,13 +52,13 @@ namespace ZR.Service.System
{ {
logininfor.Msg = "用户名或密码错误"; logininfor.Msg = "用户名或密码错误";
AddLoginInfo(logininfor); AddLoginInfo(logininfor);
throw new CustomException(ResultCode.LOGIN_ERROR, logininfor.Msg); throw new CustomException(ResultCode.LOGIN_ERROR, logininfor.Msg, false);
} }
if (user.Status == 1) if (user.Status == 1)
{ {
logininfor.Msg = "该用户已禁用"; logininfor.Msg = "该用户已禁用";
AddLoginInfo(logininfor); AddLoginInfo(logininfor);
throw new CustomException(ResultCode.LOGIN_ERROR, logininfor.Msg); throw new CustomException(ResultCode.LOGIN_ERROR, logininfor.Msg, false);
} }
logininfor.Status = "0"; logininfor.Status = "0";

View File

@ -72,7 +72,7 @@ namespace ZR.ServiceCore.SqlSugar
{ {
if (showDbLog) if (showDbLog)
{ {
string log = $"【db{configId} SQL语句】{UtilMethods.GetSqlString(config.DbType, sql, pars)}\n"; string log = $"【db{configId} SQL】{UtilMethods.GetSqlString(config.DbType, sql, pars)}\n";
if (sql.TrimStart().StartsWith("SELECT", StringComparison.OrdinalIgnoreCase)) if (sql.TrimStart().StartsWith("SELECT", StringComparison.OrdinalIgnoreCase))
{ {
logger.Info(log); logger.Info(log);