基于PostgreSQL的NLog数据库日志配置问题排查
Let's break down the issues stopping your NLog database target from working and fix them step by step:
1. Fix Logger Rule Matching
Your current NLog rule for the database target is configured with <logger name="db" minlevel="Trace" writeTo="db" /> — but the logger instance in your LoggerService is created with LogManager.GetCurrentClassLogger(), which sets the logger name to the full class name (BEBKA.Infrastructure.Services.LoggerService), not "db". This means the rule never triggers for your actual logger.
Fix:
Update the rule to match your logger's name (or all loggers if you want all logs to go to the database):
<rules> <logger name="*" minlevel="Trace" writeTo="allfile" /> <!-- Option 1: Match your specific LoggerService --> <logger name="BEBKA.Infrastructure.Services.LoggerService" minlevel="Info" writeTo="db" /> <!-- Option 2: Match all loggers (like your file target) --> <!-- <logger name="*" minlevel="Trace" writeTo="db" /> --> </rules>
2. Correct Custom Property Layout Syntax
You're trying to access custom event properties with ${type} and similar syntax, but NLog requires the event-properties layout renderer to access properties added via LogEventInfo.Properties. Also, note the case sensitivity — your code uses uppercase property names like "Type", so the layout must match.
Fix:
Update all parameter layouts in your database target:
<parameter name="@Type" layout="${event-properties:item=Type}"/> <parameter name="@Method" layout="${event-properties:item=Method}"/> <parameter name="@StatusCode" layout="${event-properties:item=StatusCode}"/> <parameter name="@StackTrace" layout="${event-properties:item=StackTrace}"/> <parameter name="@MethodName" layout="${event-properties:item=MethodName}"/> <parameter name="@Message" layout="${event-properties:item=Message}"/> <parameter name="@RequestData" layout="${event-properties:item=RequestData}"/> <parameter name="@ResponseData" layout="${event-properties:item=ResponseData}"/> <parameter name="@Ip" layout="${event-properties:item=Ip}"/> <parameter name="@CreatedDate" layout="${event-properties:item=CreatedDate}"/> <parameter name="@CreatedId" layout="${event-properties:item=CreatedId}"/>
3. Verify Npgsql Package Installation
Your database target specifies dbProvider="Npgsql.NpgsqlConnection, Npgsql", but you need to ensure the Npgsql NuGet package is installed and compatible with .NET 5. For .NET 5, use Npgsql version 5.x (e.g., 5.0.17).
Install via NuGet Package Manager or CLI:
Install-Package Npgsql -Version 5.0.17
4. Validate Database Table & Connection
- Check connection string: Confirm the server, port, database name, credentials, and PostgreSQL service status are all correct. Test the connection string with a simple standalone code snippet to rule out connectivity issues.
- Match table schema: Ensure your
public."Logs"table's column types align with the data you're passing:CreatedDateshould be atimestamptype (anddata.CreatedDateshould be a validDateTimevalue)- Text columns (like
Message,StackTrace) should have sufficient length to avoid truncation errors - No required columns are missing values (e.g., if
CreatedIdis non-nullable, ensuredata.CreatedIdis always populated)
5. Enable NLog Internal Logging for Debugging
To uncover hidden errors (like failed database connections or SQL execution issues), enable NLog's internal logging. Add these attributes to your root <nlog> node:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" internalLogFile="D:\BEBKA.JobTracking.logs\nlog-internal.log" internalLogLevel="Debug">
Run your application, then check the nlog-internal.log file — it will detail exactly what NLog is doing when trying to write to the database, including any exceptions.
6. Extend Database Logging to Other Methods
Right now, only your LogInfo(ILog log) method creates a LogEventInfo with custom properties. If you want LogError, LogDebug, etc., to also write to the database, update those methods to use the same pattern as LogInfo:
public void LogError(ILog log) { LogEventInfo theEvent = new(LogLevel.Error, logger.Name, log.Message); SetLogEventInfo(theEvent, log); logger.Log(theEvent); }
内容的提问来源于stack exchange,提问作者Vedat Baysal




