【发布时间】:2018-01-03 16:17:21
【问题描述】:
我已经打开调试,所以我很确定它正在连接到数据库。我这么说是因为如果我拼错了数据库名称,它会在输出中写入错误。
我不确定我做错了什么。我知道我的参数尚未使用。
我所做的是将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);
}
}
}
【问题讨论】:
-
也许只有我一个人,但对于一个人来说,链接的解决方案似乎太笨拙并且把事情颠倒过来:恕我直言,日志记录应该尽可能顺畅和快速,同时分析日志不会受到伤害,如果您需要 ETL一点。此外,您似乎不打算使用建议的序列化功能 - 无需任何代码即可轻松配置多个日志目标和日志级别。如果你只是想登录到你的数据库,博客会让你误入歧途。
-
是的,我开始认为这是一种有缺陷的方法。我被它的粒度所吸引,尤其是因为我不确定现在和将来的日志记录要求是什么。
-
相信@George 和我:Log4Net 和可用的附加程序足够灵活,几乎可以满足您的任何想象。最好从基本设置开始,稍后再添加花里胡哨。如果你发现没有非常具体的功能就不能做,最好考虑开发一个合适的 appender,而不是按照博客中显示的方式修改现有的 appender。
标签: c# iis log4net log4net-configuration log4net-appender