代码之家  ›  专栏  ›  技术社区  ›  Paul Hollingsworth

在日志记录时更改log4net fileappender

  •  0
  • Paul Hollingsworth  · 技术社区  · 15 年前

    我们正在尝试配置一个服务器进程,以便每次它收到请求时,都将该请求记录到一个新的文件名中。

    这个过程通常是单线程的,但我们不能保证代码中的任何其他线程有时都不会尝试向log4net写入内容。

    似乎有效的是:

    第一次收到请求时,我们配置一个“perrequest”文件附加器,如下所示:

    fileAppender = new FileAppender();
    log.InfoFormat("Initializing log4net per request logging");
    log4net.Layout.PatternLayout layout = new Layout.PatternLayout("%date %property{processid} %property{username} %-5level %logger - %message%newline");
    fileAppender.Layout = layout;
    layout.ActivateOptions();
    fileAppender.AppendToFile = true;
    fileAppender.Name = "PerRunLogger";
    fileAppender.File = makeNewRequestLogName(); // Returns a unique filename (uses a Guid)
    log.InfoFormat("Configured PerRequest logger to log to '{0}'", fileAppender.File);
    fileAppender.ActivateOptions();
    log4net.Config.BasicConfigurator.Configure(fileAppender);
    

    然后,每次我们收到新的请求时,我们都会执行以下操作:

    fileAppender.File = makeNewRequestLogName();
    log.InfoFormat("Configured PerRequest logger to log to '{0}'", fileAppender.File);
    fileAppender.ActivateOptions();
    

    在请求结束时,我们“配置”perrequest记录器以记录到单个文件名,因为我们找不到一种令人满意的方法来关闭它。

    这很管用…但是在重载下,我们开始注意到“perrequest”日志文件通常会有大量“丢失”的日志行。例如这样的:

    2009-09-23 19:17:17,133 4332 hollingp DEBUG PostProcessInfrastructure.PostProcessRunner - Started post processing
    * normal log lines here, omitted for brevity *
    2009-09-23 19:17:36,414 4332 hollingp DEBUG PluginRegistry.PostProcessVersions.PostProcessPluginCacheVersion - About to run pub_GetPostProcessingVersion stored proc
    
    *Normally lots of log lines here, but every now and then, NOTHING *
    
    2009-09-23 19:17:37,742 4332 hollingp DEBUG PostProcessInfrastructure.PostProcessRunner - Finished post processing
    

    对于我们在日志文件中看到的内容没有很好的解释——没有能够解释“丢失”日志行的代码路径(即使抛出了异常)。- 某物 (实际上有很多东西)应该在19:17:36和19:17:37之间的线程上登录。

    诚然,这整个技术都有点不可靠,但我们想不出另一种方法来做到这一点。

    所以第一个问题是:有没有更好的方法来实现我们想要的?

    第二个问题是:有人能解释可能发生的事情吗?怀疑需要执行一些线程安全/锁定,但在哪里?如果是这样的话,需要锁定什么?

    不会再有危险的 过程 试图登录到同一个文件,因为正如代码中的注释所示,我们使用一个guid来分配日志文件名-其他进程不可能试图登录到同一个文件…但是另一条线呢?我们不能排除这种可能性。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Zack Elan    15 年前

    log4net FAQ :

    许多开发人员面临着区分来自同一类但不同客户机请求的日志输出的问题。他们想出了巧妙的机制将日志输出扇出到不同的文件中。在大多数情况下,这不是正确的方法。

    使用上下文属性或堆栈(threadcontext)更简单。通常,当开始处理客户机的请求时,可以使用threadcontext.properties[“id”]=“xxx”客户机特定信息,例如客户机的主机名、ID或任何其他区别信息。此后,日志输出将自动包含上下文数据,以便您可以区分不同客户机请求的日志,即使它们输出到同一个文件。

    有关详细信息,请参见ThreadContext和PatternLayout类。

        2
  •  2
  •   si618    15 年前

    所以第一个问题是:有没有 更好的方法来实现我们想要的?

    每个请求都必须是单独的文件吗?

    如果不是,那么如何创建自己的自定义模式布局并将请求详细信息作为日志模式的一部分? An example 谷歌发现。

    如果是这样的话,扩展一下怎么样 RollingFileAppender 并更改新的文件条件,使其不与文件大小(或其他内容)相关,而是基于请求?

    我想你已经用 LockingModel ?