ثبت جزئیات استثناهای Entity framework توسط ELMAH
نویسنده: وحید نصیری
تاریخ: ۱۳۹۳/۱۰/۰۸ ۱۱:۲۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public interface IEfExceptionsLogger
{
void LogException<TResult>(DbCommand command,
DbCommandInterceptionContext<TResult> interceptionContext);
}
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
namespace ElmahEFLogger
{
public class EfExceptionsInterceptor : IDbCommandInterceptor
{
private readonly IEfExceptionsLogger _efExceptionsLogger;
public EfExceptionsInterceptor(IEfExceptionsLogger efExceptionsLogger)
{
_efExceptionsLogger = efExceptionsLogger;
}
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
_efExceptionsLogger.LogException(command, interceptionContext);
}
}
} using System;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;
using Elmah;
namespace ElmahEFLogger.CustomElmahLogger
{
public class ElmahEfExceptionsLogger : IEfExceptionsLogger
{
/// <summary>
/// Manually log errors using ELMAH
/// </summary>
public void LogException<TResult>(DbCommand command,
DbCommandInterceptionContext<TResult> interceptionContext)
{
var ex = interceptionContext.OriginalException;
if (ex == null)
return;
var sqlData = CommandDumper.LogSqlAndParameters(command, interceptionContext);
var contextualMessage = string.Format("{0}{1}OriginalException:{1}{2} {1}", sqlData, Environment.NewLine, ex);
if (!string.IsNullOrWhiteSpace(contextualMessage))
{
ex = new Exception(contextualMessage, new ElmahEfInterceptorException(ex.Message));
}
try
{
ErrorSignal.FromCurrentContext().Raise(ex);
}
catch
{
ErrorLog.GetDefault(null).Log(new Error(ex));
}
}
}
} public class ElmahEfInterceptor : EfExceptionsInterceptor
{
public ElmahEfInterceptor()
: base(new ElmahEfExceptionsLogger())
{ }
} DbInterception.Add(new ElmahEfInterceptor());
using System;
using System.Data;
using System.Data.Common;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
namespace Utils
{
public class EfExceptionsInterceptor : DbCommandInterceptor
{
private readonly ILogger<EfExceptionsInterceptor> _logger;
public EfExceptionsInterceptor(ILogger<EfExceptionsInterceptor> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public override void CommandFailed(DbCommand command, CommandErrorEventData eventData)
{
logError(command, eventData);
}
public override Task CommandFailedAsync(DbCommand command, CommandErrorEventData eventData, CancellationToken cancellationToken = default)
{
logError(command, eventData);
return Task.CompletedTask;
}
private void logError(DbCommand command, CommandErrorEventData eventData)
{
if (command == null || eventData == null)
{
return;
}
var ex = eventData.Exception;
if (ex == null)
{
return;
}
var sqlData = logSqlAndParameters(command);
var contextualMessage = $"{sqlData}{Environment.NewLine}OriginalException:{Environment.NewLine}{ex} {Environment.NewLine}";
_logger.LogError(contextualMessage);
}
private static string logSqlAndParameters(DbCommand command)
{
// -- Name: [Value] (Type = {}, Direction = {}, IsNullable = {}, Size = {}, Precision = {} Scale = {})
var builder = new StringBuilder();
var commandText = command.CommandText ?? "<null>";
builder.AppendFormat(CultureInfo.InvariantCulture, "{0}Command: {0}{1}", Environment.NewLine, commandText)
.AppendLine();
var parameters = command.Parameters.OfType<DbParameter>().ToList();
if (parameters.Any())
{
builder.AppendFormat(CultureInfo.InvariantCulture, "{0}Parameters: ", Environment.NewLine)
.AppendLine();
}
foreach (var parameter in parameters)
{
builder.Append("-- ")
.Append(parameter.ParameterName)
.Append(": '")
.Append((parameter.Value == null || parameter.Value == DBNull.Value) ? "null" : parameter.Value)
.Append("' (Type = ")
.Append(parameter.DbType);
if (parameter.Direction != ParameterDirection.Input)
{
builder.Append(", Direction = ").Append(parameter.Direction);
}
if (!parameter.IsNullable)
{
builder.Append(", IsNullable = false");
}
if (parameter.Size != 0)
{
builder.Append(", Size = ").Append(parameter.Size);
}
if (((IDbDataParameter)parameter).Precision != 0)
{
builder.Append(", Precision = ").Append(((IDbDataParameter)parameter).Precision);
}
if (((IDbDataParameter)parameter).Scale != 0)
{
builder.Append(", Scale = ").Append(((IDbDataParameter)parameter).Scale);
}
builder.Append(')').Append(Environment.NewLine);
}
return builder.ToString();
}
}
} services.AddScoped<EfExceptionsInterceptor>();
services.AddDbContextPool<ApplicationDbContext>((serviceProvider, optionsBuilder) =>
optionsBuilder
.UseSqlServer(
connectionString,
sqlServerOptionsBuilder =>
{
// ...
})
.AddInterceptors(serviceProvider.GetRequiredService<EfExceptionsInterceptor>()));