3
我打開了調試,所以我很確定它連接到數據庫。我說這是因爲如果我拼錯了數據庫名稱,它會輸出一個錯誤。Log4Net似乎連接到數據庫,但不插入
我不知道我在做什麼錯。我知道我有參數尚未使用。
我所做的是將this tutorial修改爲一個項目。如果您需要了解更多信息,請告訴我。
Log4Net.config
<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
<root>
<level value="ALL"/>
<appender-ref ref="AdoNetAppender"/>
<appender-ref ref="DebugAppender"/>
</root>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="Data Source=server;Initial Catalog=db; User Id=user; Password=pass" />
<commandText value="INSERT INTO LogException ([LogLevel],[LogMessage],[StackTrace],[Object],[CreateDateTime]) VALUES (@log_level, @message, @stacktrace, @exception, @date)" />
<parameter>
<parameterName value="@log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="@exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
<parameter>
<parameterName value="@entryAssembly" />
<dbType value="String" />
<size value="200" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{entryAssembly}" />
</layout>
</parameter>
<parameter>
<parameterName value="@callingAssembly" />
<dbType value="String" />
<size value="200" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{callingAssembly}" />
</layout>
</parameter>
<parameter>
<parameterName value="@method" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{method}" />
</layout>
</parameter>
<parameter>
<parameterName value="@stacktrace" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%stacktrace" />
</layout>
</parameter>
</appender>
</log4net>
Log4netLoggingService.cs
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Logging.Contracts.Log;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Filter;
using log4net.Util;
namespace Logging
{
public class Log4NetLoggingService : ILoggingService
{
private readonly ILog _logger;
static Log4NetLoggingService()
{
var log4NetConfigFilePath = @"C:\Work\folder\Main\Logging\Log4Net.config";
XmlConfigurator.ConfigureAndWatch(new FileInfo(log4NetConfigFilePath));
}
//targets reads from and enum to know where to save.
public Log4NetLoggingService(LogTarget targets = LogTarget.All)
{
_logger = LogManager.GetLogger(new StackFrame(1).GetMethod().DeclaringType);
#if DEBUG
var error = LogManager.GetRepository().ConfigurationMessages.Cast<LogLog>();
#endif
if (targets.HasFlag(LogTarget.All))
return;
SwitchOffLogTargets(targets);
}
protected ILog logger { get { return _logger; } }
public void Fatal(ErrorLogEntry logEntry)
{
logEntry.Level = Level.Fatal.ToString();
if (_logger.IsFatalEnabled)
_logger.Fatal(logEntry);
}
public void Error(ErrorLogEntry logEntry)
{
logEntry.Level = Level.Error.ToString();
if (_logger.IsErrorEnabled)
_logger.Error(logEntry);
}
public void Warn(LogEntry logEntry)
{
logEntry.Level = Level.Warn.ToString();
if (_logger.IsWarnEnabled)
_logger.Warn(logEntry);
}
public void Info(LogEntry logEntry)
{
logEntry.Level = Level.Info.ToString();
if (_logger.IsInfoEnabled)
_logger.Info(logEntry);
}
public void Debug(LogEntry logEntry)
{
logEntry.Level = Level.Debug.ToString();
if (_logger.IsDebugEnabled)
_logger.Debug(logEntry);
}
private void SwitchOffLogTargets(LogTarget targets)
{
var appenders = _logger.Logger.Repository.GetAppenders().ToList();
if (!targets.HasFlag(LogTarget.Database))
{
var db = appenders.FirstOrDefault(piA => piA is AdoNetAppender);
if (db != null)
((AdoNetAppender)db).AddFilter(new DenyAllFilter());
}
if (!targets.HasFlag(LogTarget.TextFile))
{
var file = appenders.FirstOrDefault(piA => piA is RollingFileAppender);
if (file != null)
((RollingFileAppender)file).AddFilter(new DenyAllFilter());
}
if (!targets.HasFlag(LogTarget.Trace))
{
var trace = appenders.FirstOrDefault(piA => piA is AspNetTraceAppender);
if (trace != null)
((AspNetTraceAppender)trace).AddFilter(new DenyAllFilter());
}
}
}
}
更新:
事實證明我的最新嘗試的作品。我拼錯了配置文件名。我希望這可以幫助未來的人。我打算寫一篇關於此的博客文章。
Log4Net.config
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<root>
<level value="ALL" debug="true"/>
<!--Add the appenders you want to use here-->
<appender-ref ref="AdoNetAppender"/>
<!--to debug log4net. check the output window of Visual Studio-->
<appender-ref ref="DebugAppender"/>
</root>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="data source=(localdb)\MSSQLLocalDB;initial catalog=log4NetTestDB;integrated security=false;persist security info=True;" />
<commandText value="INSERT INTO LogException ([Message]) VALUES (@message)" />
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
</appender>
</log4net>
ILoggingAdapter
namespace Logging
{
public interface ILoggingAdapter
{
TimeSpan ExecutionTime { get; set; }
int Counter { get; set; }
void Info(string message);
void Warn(string message);
}
}
記錄器
namespace Logging
{
public sealed class Logger : ILoggingAdapter
{
private ILog _log = LogManager.GetLogger(typeof(Logger));
public TimeSpan ExecutionTime { get; set; }
public int Counter { get; set; }
public string Info { get; set; }
public string Warn { get; set; }
void ILoggingAdapter.Info(string message)
{
throw new NotImplementedException();
}
void ILoggingAdapter.Warn(string message)
{
_log.Warn(message);
}
}
}
也許這只是我,但對於一個鏈接的解決方案似乎太笨拙,並將事情顛倒:Imho日誌記錄應儘可能無摩擦,儘可能快速,如果您需要ETL一點,分析日誌不會受到傷害。此外,您似乎並未打算使用建議的序列化功能 - 可以輕鬆配置多個日誌目標和日誌級別,而無需任何代碼。如果你只是想登錄到你的數據庫,這個博客會讓你誤入歧途。 – Filburt
是的,我開始認爲這是一個有缺陷的方法。我被它的粒度所吸引,特別是因爲我不確定現在和將來的日誌需求是什麼。 –
Trust @George和我:Log4Net和可用的appender幾乎可以滿足任何你想象的靈活性。最好你從基本設置開始,並在稍後添加花裏胡哨的功能。如果你發現你不能沒有非常具體的功能,那麼最好考慮開發一個適當的appender,而不是按照博客中顯示的方式修改現有的appender。 – Filburt