如何从头开始以编程方式配置log4net(无配置)

Joh*_*ant 84 .net logging log4net

这是一个坏主意,我知道,但是...我想从头开始以编程方式配置log4net,没有配置文件.我正在为我和我的团队开发一个简单的日志记录应用程序,用于我们负责的一些相对较小的部门应用程序.我希望他们都登录到同一个数据库.日志记录应用程序只是log4net的一个包装器,预先配置了AdoNetAppender.

所有应用程序都是ClickOnce部署的,这对部署配置文件提出了一个小问题.如果配置文件是核心项目的一部分,我可以设置其属性以使用程序集进行部署.但它是链接应用程序的一部分,因此我无法选择将其与主应用程序一起部署.(如果那不是真的,请有人告诉我).

可能因为它是一个坏主意,似乎没有太多的示例代码可用于从头开始以编程方式配置log4net.这是我到目前为止所拥有的.

Dim apndr As New AdoNetAppender()
apndr.CommandText = "INSERT INTO LOG_ENTRY (LOG_DTM, LOG_LEVEL, LOGGER, MESSAGE, PROGRAM, USER_ID, MACHINE, EXCEPTION) VALUES (@log_date, @log_level, @logger, @message, @program, @user, @machine, @exception)"
apndr.ConnectionString = connectionString
apndr.ConnectionType = "System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
apndr.CommandType = CommandType.Text
Dim logDate As New AdoNetAppenderParameter()
logDate.ParameterName = "@log_date"
logDate.DbType = DbType.DateTime
logDate.Layout = New RawTimeStampLayout()
apndr.AddParameter(logDate)
Dim logLevel As New AdoNetAppenderParameter()
logLevel.ParameterName = "@log_level"
'And so forth...
Run Code Online (Sandbox Code Playgroud)

配置完所有参数后apndr,我首先尝试了这个...

Dim hier As Hierarchy = DirectCast(LogManager.GetRepository(), Hierarchy)
hier.Root.AddAppender(apndr)
Run Code Online (Sandbox Code Playgroud)

它没用.然后,在黑暗中拍摄,我尝试了这个.

BasicConfigurator.Configure(apndr)
Run Code Online (Sandbox Code Playgroud)

那也行不通.有没有人对如何在没有配置文件的情况下从头编程配置log4net有任何好的参考?

Tod*_*out 121

这是一个在代码中完全创建log4net配置的示例类.我应该提一下,通过静态方法创建一个记录器通常被认为是坏的,但在我的上下文中,这就是我想要的.无论如何,您可以分割代码以满足您的需求.

using log4net;
using log4net.Repository.Hierarchy;
using log4net.Core;
using log4net.Appender;
using log4net.Layout;

namespace dnservices.logging
{
public class Logger
{
    private PatternLayout _layout = new PatternLayout();
    private const string LOG_PATTERN = "%d [%t] %-5p %m%n";

    public string DefaultPattern
    {
        get { return LOG_PATTERN; }
    }

    public Logger()
    {
        _layout.ConversionPattern = DefaultPattern;
        _layout.ActivateOptions();
    }

    public PatternLayout DefaultLayout
    {
        get { return _layout; }
    }

    public void AddAppender(IAppender appender)
    {
        Hierarchy hierarchy = 
            (Hierarchy)LogManager.GetRepository();

        hierarchy.Root.AddAppender(appender);
    }

    static Logger()
    {
        Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
        TraceAppender tracer = new TraceAppender();
        PatternLayout patternLayout = new PatternLayout();

        patternLayout.ConversionPattern = LOG_PATTERN;
        patternLayout.ActivateOptions();

        tracer.Layout = patternLayout;
        tracer.ActivateOptions();
        hierarchy.Root.AddAppender(tracer);

        RollingFileAppender roller = new RollingFileAppender();
        roller.Layout = patternLayout;
        roller.AppendToFile = true;
        roller.RollingStyle = RollingFileAppender.RollingMode.Size;
        roller.MaxSizeRollBackups = 4;
        roller.MaximumFileSize = "100KB";
        roller.StaticLogFileName = true;
        roller.File = "dnservices.txt";
        roller.ActivateOptions();
        hierarchy.Root.AddAppender(roller);

        hierarchy.Root.Level = Level.All;
        hierarchy.Configured = true;
    }

    public static ILog Create()
    {
        return LogManager.GetLogger("dnservices");
    }
}
Run Code Online (Sandbox Code Playgroud)

}

  • `hierarchy.Configured = true;`这对我有用 (7认同)
  • 从我这里得到+1,似乎你得到了如何在没有配置文件的情况下以编程方式执行此操作的答案. (6认同)

Jon*_*upp 36

我过去做过这种方法的一种方法是将配置文件包含为嵌入式资源,并使用log4net.Config.Configure(Stream).

这样,我可以使用我熟悉的配置语法,并且不必担心部署文件.

  • 完整的方法名称是log4net.Config.XmlConfigurator.Configure(如链接中所示) (2认同)

Pav*_*uva 30

更简洁的解决方案:

var layout = new PatternLayout("%-4timestamp [%thread] %-5level %logger %ndc - %message%newline");
var appender = new RollingFileAppender {
    File = "my.log",
    Layout = layout
};
layout.ActivateOptions();
appender.ActivateOptions();
BasicConfigurator.Configure(appender);
Run Code Online (Sandbox Code Playgroud)

不要忘记调用ActivateOptions方法:

在设置配置属性后,必须在此对象上调用ActivateOptions方法.在调用ActivateOptions之前,此对象处于未定义状态,不得使用.


Joe*_*Joe 5

正如Jonathan所说,使用资源是一个很好的解决方案.

这有点限制,因为嵌入式资源内容将在编译时修复.我有一个日志组件生成一个带有基本Log4Net配置的XmlDocument,使用定义为appSettings的变量(例如,RollingFileAppender的文件名,默认日志记录级别,如果你想使用AdoNetAppender,可能是连接字符串名称).然后我调用log4net.Config.XmlConfigurator.Configure使用生成的XmlDocument的根元素配置Log4Net.

然后,管理员可以通过修改一些appSettings(通常是level,filename,...)来自定义"标准"配置,或者可以指定外部配置文件以获得更多控制.


ole*_*sii 5

聚会有点晚了。但这是对我有用的最小配置。

样板课

public class Bar
{
    private readonly ILog log = LogManager.GetLogger(typeof(Bar));
    public void DoBar() { log.Info("Logged"); }
}
Run Code Online (Sandbox Code Playgroud)

最小 log4net 跟踪配置(在 NUnit 测试中)

[Test]
public void Foo()
{
    var tracer = new TraceAppender();
    var hierarchy = (Hierarchy)LogManager.GetRepository();
    hierarchy.Root.AddAppender(tracer);
    var patternLayout = new PatternLayout {ConversionPattern = "%m%n"};
    tracer.Layout = patternLayout;
    hierarchy.Configured = true;

    var bar = new Bar();
    bar.DoBar();
}
Run Code Online (Sandbox Code Playgroud)

打印到跟踪侦听器

Namespace+Bar: Logged
Run Code Online (Sandbox Code Playgroud)

  • 这几乎可以工作,但我需要在 PatternLayout 和 Appender 上调用 .ActiveOptions 才能完全工作。 (2认同)