要讓 NLog 可以拋出 Exception 必須設定 ThrowExceptions 屬性、如要輸出錯誤訊息至檔案可以透過 InternalLogger 來做到
InternalLogger.LogFile
InternalLogger.LogFile 是 NLog Exception 的檔案路徑,但並不是全部的 Layout Renderers 都支援,看 官方文章 - Internal Logging 介紹,從 NLog4.6 開始才開始逐漸可以使用
模擬 NLog 內發生錯誤
關鍵錯誤訊息,這樣呼叫 Store Procedure 是錯誤的
using NLog;
using NLog.Common;
using NLog.Config;
using NLog.Layouts;
using NLog.Targets;
using System;
using System.Data;
namespace NLogSample
{
internal class Program
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
ExceptionThrowConfig();
try
{
ExceptionMethod();
}
catch (Exception ex)
{
_logger.Error(ex);
}
}
private static void ExceptionMethod()
{
int numerator = 1;
int denominator = 0;
Console.WriteLine(numerator / denominator);
}
private static void ExceptionThrowConfig()
{
InternalLogger.LogFile = @"d:\Logs\InternalLog.txt";
InternalLogger.LogLevel = LogLevel.Error;
LogManager.ThrowExceptions = true;
DatabaseTarget target = new DatabaseTarget();
target.ConnectionString = "Data Source=.;Initial Catalog=AdventureWorks2019;Integrated Security=True";
// 錯誤的呼叫 Store Procedure 方式
target.CommandType = CommandType.StoredProcedure;
target.CommandText = "exec uspLogInsert @LogTime , @Message";
target.Parameters.Add(new DatabaseParameterInfo() { Name = "@LogTime", Layout = "${date}" });
target.Parameters.Add(new DatabaseParameterInfo("@Message", new SimpleLayout("${exception}")));
SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);
}
}
}
關鍵錯誤訊息,這樣呼叫 Store Procedure 是錯誤的
2022-06-15 22:51:55.7917 Error DatabaseTarget([unnamed]): Error when writing to database. Exception: System.Data.SqlClient.SqlException (0x80131904): 找不到預存程序 'exec uspLogInsert @LogTime , @Message'。完整錯誤訊息
2022-06-15 22:51:55.7917 Error DatabaseTarget([unnamed]): Error when writing to database. Exception: System.Data.SqlClient.SqlException (0x80131904): 找不到預存程序 'exec uspLogInsert @LogTime , @Message'。
於 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
於 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
於 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
於 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
於 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
於 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
於 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
於 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
於 System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
於 NLog.Targets.DatabaseTarget.ExecuteDbCommandWithParameters(LogEventInfo logEvent, IDbConnection dbConnection, IDbTransaction dbTransaction)
於 NLog.Targets.DatabaseTarget.WriteLogEventSuppressTransactionScope(LogEventInfo logEvent, String connectionString)
ClientConnectionId:404d03a2-984b-4b6e-81bf-ad66fb425678
Error Number:2812,State:62,Class:16
沒有留言:
張貼留言