Конфигурация log4net с чистым кодом с фильтром в С#
Я пытаюсь настроить Log4Net чисто по коду, но когда я делал это с минимальной конфигурацией, я был затоплен путем записи сообщений из NHibernate и свободного интерфейса.
Итак, я пытаюсь сделать это просто. Скажите Log4Net, чтобы показать мне только сообщения журнала моего одного класса. Я немного поиграл, но не могу понять это...
Может кто-нибудь помочь, я думаю, что следующий код иллюстрирует мою идею:
var filter = new log4net.Filter.LoggerMatchFilter();
filter.LoggerToMatch = typeof(DatabaseDirectory).ToString();
filter.AcceptOnMatch = false;
var x = new log4net.Appender.ConsoleAppender();
x.Layout = new log4net.Layout.SimpleLayout();
x.AddFilter(filter);
log4net.Config.BasicConfigurator.Configure(x);
Хорошо, спасибо за вашу помощь, но здесь должна быть какая-то проблема. Но я сближаюсь. Я попробовал XML-конфигурацию, которая имеет гораздо больше документации. И мне удалось достичь желаемого результата, используя следующую конфигурацию XML. Должна быть некоторая неправильная конфигурация в версии "чистого кода" выше.
Следующая конфигурация XML предоставляет "правильный" вывод, который не совпадает с конфигурацией в коде выше. Кто-нибудь видит разницу?
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
</root>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="Examples.FirstProject.Entities.DatabaseDirectory"/>
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%C.%M] %-5p %m%n" />
</layout>
</appender>
Ответы
Ответ 1
Я понял это. Иногда, просто записывая его, вы открываете глаза...
var filter = new log4net.Filter.LoggerMatchFilter();
filter.LoggerToMatch = typeof(DatabaseDirectory).ToString();
filter.AcceptOnMatch = true;
var filterDeny = new log4net.Filter.DenyAllFilter();
var x = new log4net.Appender.ConsoleAppender();
x.Layout = new log4net.Layout.SimpleLayout();
x.AddFilter(filter);
x.AddFilter(filterDeny);
log4net.Config.BasicConfigurator.Configure(x);
Посмотрите, что не хватает:-) Фильтр denyALL!
Несколько примеров кода:
public static void AllToConsoleSetup()
{
var x = new log4net.Appender.ConsoleAppender { Layout = new log4net.Layout.SimpleLayout() };
log4net.Config.BasicConfigurator.Configure(x);
SetupDone = true;
}
public static void ShowOnlyLogOf(Type t)
{
var filter = new log4net.Filter.LoggerMatchFilter {LoggerToMatch = t.ToString(), AcceptOnMatch = true};
var filterDeny = new log4net.Filter.DenyAllFilter();
var x = new log4net.Appender.ConsoleAppender {Layout = new log4net.Layout.SimpleLayout()};
x.AddFilter(filter);
x.AddFilter(filterDeny);
log4net.Config.BasicConfigurator.Configure(x);
SetupDone = true;
}
Действительно UGLY, но работающий (он завинчивает подсветку, не пропустите последние строки):
public static void DefaultSetup()
{
// AllToConsoleSetup();
XmlConfigurator.Configure(XmlSetup());
// DbConfig();
}
private static Stream XmlSetup()
{
const string x = @" <log4net>
<root>
<level value=""ALL"" />
<appender-ref ref=""AdoNetAppender"">
</appender-ref>
</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=Christian-PC\SQLEXPRESS;initial catalog=log4net_2;integrated security=false;persist security info=True;User ID=log4net;Password=XXXX"" />
<commandText value=""INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)"" />
<parameter>
<parameterName value=""@log_date"" />
<dbType value=""DateTime"" />
<layout type=""log4net.Layout.RawTimeStampLayout"" />
</parameter>
<parameter>
<parameterName value=""@thread"" />
<dbType value=""String"" />
<size value=""655"" />
<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=""655"" />
<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>
<filter type=""log4net.Filter.LoggerMatchFilter"">
<param name=""LoggerToMatch"" value=""Ruppert"" />
</filter>
<filter type=""log4net.Filter.DenyAllFilter"">
</filter>
</appender>
</log4net>";
return new MemoryStream(ASCIIEncoding.Default.GetBytes(x));
}
Ответ 2
Здесь вы можете настроить log4net с помощью XML с помощью кода, используя XmlDocument для загрузки xml. Отличие от христианского примера заключается в том, что я использую перегрузку XmlConfigurator.Configure
, которая принимает параметр XmlElement
в качестве параметра. Я также использовал одиночные отметки, а не удвоение двойных кавычек. В общем, я думаю, что это самый маленький чистящий инструмент.
string xml =
@"<log4net>
<appender name='file1' type='log4net.Appender.RollingFileAppender'>
<!-- Log file locaation -->
<param name='File' value='log4net.log'/>
<param name='AppendToFile' value='true'/>
<!-- Maximum size of a log file -->
<maximumFileSize value='2KB'/>
<!--Maximum number of log file -->
<maxSizeRollBackups value='8'/>
<!--Set rolling style of log file -->
<param name='RollingStyle' value='Composite'/>
<param name='StaticLogFileName' value='false'/>
<param name='DatePattern' value='.yyyy-MM-dd.lo\g'/>
<layout type='log4net.Layout.PatternLayout'>
<param name='ConversionPattern' value='%d [%t] %-5p %m%n'/>
</layout>
</appender>
<!-- Appender layout fix to view in console-->
<appender name='console' type='log4net.Appender.ConsoleAppender'>
<layout type='log4net.Layout.PatternLayout'>
<param name='Header' value='[Header]\r\n'/>
<param name='Footer' value='[Footer]\r\n'/>
<param name='ConversionPattern' value='%d [%t] %-5p %m%n'/>
</layout>
</appender>
<appender name='debug' type='log4net.Appender.DebugAppender'>
<layout type='log4net.Layout.PatternLayout'>
<param name='ConversionPattern' value='%d [%t] %logger %-5p %m%n'/>
</layout>
</appender>
<root>
<level value='INFO'/>
<!--
Log level priority in descending order:
FATAL = 1 show log -> FATAL
ERROR = 2 show log -> FATAL ERROR
WARN = 3 show log -> FATAL ERROR WARN
INFO = 4 show log -> FATAL ERROR WARN INFO
DEBUG = 5 show log -> FATAL ERROR WARN INFO DEBUG
-->
<!-- To write log in file -->
<appender-ref ref='debug'/>
<appender-ref ref='file1'/>
</root>
</log4net>";
//
// Use XmlDocument to load the xml string then pass the DocumentElement to
// XmlConfigurator.Configure.
//
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
log4net.Config.XmlConfigurator.Configure(doc.DocumentElement);
Ответ 3
Следующие коды работают над тем, как настроить AdoNetAppender в кодах. Если вы хотите добавить фильтр, вам нужно добавить экземпляр фильтра в экземпляр приложения в GetAppender(). Для использования регистратора в приложении рекомендуется использовать Injection Dependency для изоляции реализации и интерфейса регистратора. Кроме того, используйте концепцию области DI, чтобы сделать ее одиночной, чтобы избежать отдыха объекта.
Примечание. Класс CrmConfigHelper используется для доступа к разделу appSettings файла конфигурации приложения.
Образцы кодов показаны ниже
public sealed class SqlLogger:ILogger
{
private ILog _logger;
public SqlLogger()
{
log4net.Config.BasicConfigurator.Configure(GetAppender());
this._logger = log4net.LogManager.GetLogger(CrmConfigHelper.GetString(Constants.LOG4NET_LOGGER_NAME));
}
private log4net.Appender.AdoNetAppender GetAppender()
{
log4net.Appender.AdoNetAppender appender = new log4net.Appender.AdoNetAppender();
appender.ConnectionType = CrmConfigHelper.GetString(Constants.LOG4NET_CONNECTION_TYPE);
appender.ConnectionString = CrmConfigHelper.GetString(Constants.LOG4NET_DB_CONNECTION);
appender.BufferSize = CrmConfigHelper.getInteger(Constants.LOG4NET_BUFFER_SIZE);
appender.CommandText = "INSERT INTO [EventLog] ([Date],[HostName],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @hostname, @log_level, @logger, @message,@exception)";
appender.CommandType = System.Data.CommandType.Text;
appender.AddParameter(new log4net.Appender.AdoNetAppenderParameter() {
ParameterName = "@log_date",
DbType = System.Data.DbType.DateTime,
Size = 100,
Layout = new RawLayoutConverter().ConvertFrom(new PatternLayout("%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}")) as IRawLayout
});
appender.AddParameter(new log4net.Appender.AdoNetAppenderParameter()
{
ParameterName = "@hostname",
DbType = System.Data.DbType.String,
Size = 50,
Layout = new RawLayoutConverter().ConvertFrom(new PatternLayout("%property{log4net:HostName}")) as IRawLayout
});
appender.AddParameter(new log4net.Appender.AdoNetAppenderParameter()
{
ParameterName = "@log_level",
DbType = System.Data.DbType.String,
Size = 50,
Layout = new RawLayoutConverter().ConvertFrom(new PatternLayout("%level")) as IRawLayout
});
appender.AddParameter(new log4net.Appender.AdoNetAppenderParameter()
{
ParameterName = "@logger",
DbType = System.Data.DbType.String,
Size = 50,
Layout = new RawLayoutConverter().ConvertFrom(new PatternLayout("%logger")) as IRawLayout
});
appender.AddParameter(new log4net.Appender.AdoNetAppenderParameter()
{
ParameterName = "@message",
DbType = System.Data.DbType.String,
Size = 4000,
Layout = new RawLayoutConverter().ConvertFrom(new PatternLayout("%message")) as IRawLayout
});
appender.AddParameter(new log4net.Appender.AdoNetAppenderParameter()
{
ParameterName = "@exception",
DbType = System.Data.DbType.String,
Size = 2000,
Layout = new RawLayoutConverter().ConvertFrom(new ExceptionLayout()) as IRawLayout
});
appender.ActivateOptions();
return appender;
}
public void Error(Message context)
{
_logger.Error(context.ToJsonString());
}
public void Error(Message context, Exception exception)
{
_logger.Error(context.ToJsonString(), exception);
}
public void Warn(Message context)
{
_logger.Warn(context.ToJsonString());
}
public void Warn(Message context, Exception exception)
{
_logger.Warn(context.ToJsonString(), exception);
}
public void Info(Message context)
{
_logger.Info(context.ToJsonString());
}
public void Info(Message context, Exception exception)
{
_logger.Info(context.ToJsonString(), exception);
}
}
public interface ILogger
{
void Error(Message context);
void Error(Message context, Exception exception);
void Warn(Message context);
void Warn(Message context, Exception exception);
void Info(Message context);
void Info(Message context, Exception exception);
}
public sealed class Message
{
public string RunDate { get; set; }
public string RunBy { get; set; }
public string Message { get; set; }
public string ToJsonString()
{
return new JavaScriptSerializer().Serialize(this);
}
}