using Microsoft.AspNetCore.Http;
using Serilog.Context;
namespace YourProject.Services;
/// <summary>
/// 中介軟體(ASP.NET Core middleware)。用於強化Serilog取得環境參數。
/// </summary>
/// <see cref="ASP.NET Core 中介軟體(https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.1)"/>
public class CustomMiddleware
{
private readonly RequestDelegate _next;
public CustomMiddleware(RequestDelegate next)
{
_next = next;
}
[System.Diagnostics.DebuggerHidden]
public async Task Invoke(HttpContext context)
{
try
{
using (LogContext.PushProperty("AuthUser", context.User.Identity?.Name))
using (LogContext.PushProperty("ClientIP", context.Connection.RemoteIpAddress))
using (LogContext.PushProperty("UserAgent", context.Request.Headers["User-Agent"].FirstOrDefault()))
using (LogContext.PushProperty("DomainUserName", $"{Environment.UserDomainName}\\{Environment.UserName}"))
using (LogContext.PushProperty("MachineName", Environment.MachineName))
{
// Do work that doesn't write to the Response.
await _next.Invoke(context);
// Do logging or other work that doesn't write to the Response.
}
}
catch (Exception ex)
{
throw new ApplicationException("CustomMiddleware.Invoke 出現例外!", ex);
}
}
}
Serilog.table.sql
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Serilog](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[TimeStamp] [datetime2](7) NOT NULL,
[Level] [nvarchar](128) NULL,
[Message] [nvarchar](max) NULL,
[AuthUser] [nvarchar](128) NULL,
[SysName] [nvarchar](128) NULL,
[ClassName] [nvarchar](128) NULL,
[MethodName] [nvarchar](128) NULL,
[ClientIP] [nvarchar](128) NULL,
[Exception] [nvarchar](max) NULL,
[LogEvent] [nvarchar](max) NULL,
CONSTRAINT [PK_Serilog] PRIMARY KEY CLUSTERED
(
[Id] DESC
))
GO
ILoggerClassExtensions.cs
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
public static class ILoggerClassExtensions
{
public static void LogEx(this ILogger logger, LogLevel logLevel, string message, Exception exception = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
using (LogContext.PushProperty("ClassName", logger.GetType().GenericTypeArguments[0].Name))
using (LogContext.PushProperty("MethodName", memberName))
using (LogContext.PushProperty("SourceFilePath", sourceFilePath))
using (LogContext.PushProperty("SourceLineNumber", sourceLineNumber))
{
logger.Log(logLevel, exception, message);
}
}
public static void CriticalEx(this ILogger logger, string message, Exception exception = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
using (LogContext.PushProperty("ClassName", logger.GetType().GenericTypeArguments[0].Name))
using (LogContext.PushProperty("MethodName", memberName))
using (LogContext.PushProperty("SourceFilePath", sourceFilePath))
using (LogContext.PushProperty("SourceLineNumber", sourceLineNumber))
{
logger.LogCritical(exception, message);
}
}
public static void DebugEx(this ILogger logger, string message, Exception exception = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
using (LogContext.PushProperty("ClassName", logger.GetType().GenericTypeArguments[0].Name))
using (LogContext.PushProperty("MethodName", memberName))
using (LogContext.PushProperty("SourceFilePath", sourceFilePath))
using (LogContext.PushProperty("SourceLineNumber", sourceLineNumber))
{
logger.LogDebug(exception, message);
}
}
public static void ErrorEx(this ILogger logger, string message, Exception exception = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
using (LogContext.PushProperty("ClassName", logger.GetType().GenericTypeArguments[0].Name))
using (LogContext.PushProperty("MethodName", memberName))
using (LogContext.PushProperty("SourceFilePath", sourceFilePath))
using (LogContext.PushProperty("SourceLineNumber", sourceLineNumber))
{
logger.LogError(exception, message);
}
}
public static void InfoEx(this ILogger logger, string message, Exception exception = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
using (LogContext.PushProperty("ClassName", logger.GetType().GenericTypeArguments[0].Name))
using (LogContext.PushProperty("MethodName", memberName))
using (LogContext.PushProperty("SourceFilePath", sourceFilePath))
using (LogContext.PushProperty("SourceLineNumber", sourceLineNumber))
{
logger.LogInformation(exception, message);
}
}
public static void TraceEx(this ILogger logger, string message, Exception exception = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
using (LogContext.PushProperty("ClassName", logger.GetType().GenericTypeArguments[0].Name))
using (LogContext.PushProperty("MethodName", memberName))
using (LogContext.PushProperty("SourceFilePath", sourceFilePath))
using (LogContext.PushProperty("SourceLineNumber", sourceLineNumber))
{
logger.LogTrace(exception, message);
}
}
public static void WarnEx(this ILogger logger, string message, Exception exception = null,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
using (LogContext.PushProperty("ClassName", logger.GetType().GenericTypeArguments[0].Name))
using (LogContext.PushProperty("MethodName", memberName))
using (LogContext.PushProperty("SourceFilePath", sourceFilePath))
using (LogContext.PushProperty("SourceLineNumber", sourceLineNumber))
{
logger.LogWarning(exception, message);
}
}
}