简体   繁体   English

在Catalyst中使用Plack :: Middleware兼容的异常时,日志输出丢失

[英]Log output missing when using Plack::Middleware compatible exceptions in Catalyst

For my Catalyst project I am using an own Moose based exception type, that is compatible with Catalyst and my command line applications. 对于我的Catalyst项目,我使用自己的基于Moose的异常类型,它与Catalyst和我的命令行应用程序兼容。

To provide clients of my Catalyst REST interface with error messages, I implemented a code subroutine that is providing http status codes as part of my exception class. 为了向我的Catalyst REST接口的客户端提供错误消息,我实现了一个code子例程,它提供了http状态代码作为我的异常类的一部分。 This way, I want to use Plack::Middleware as described in the pod documentation of Plack::Middleware::HTTPExceptions . 这样一来,我想用Plack::Middleware作为荚文档中描述Plack::Middleware::HTTPExceptions

Everything works fine. 一切正常。 The exceptions are returned to the client the way I want to them to be returned. 异常以我希望返回的方式返回给客户端。

My problem is: whenever I throw an exception, that is caught by the middle ware, my logging ( Log::Log4perl ) is lost and I can find neither traces nor errors in Catalyst 's web server perl script output. 我的问题是:每当我抛出异常时,就会被中间件抓住,我的日志记录( Log::Log4perl )就会丢失,我在Catalyst的Web服务器perl脚本输出中找不到任何痕迹或错误。

Whenever I throw errors, that are not encapsulated by my exception class, but rare string (like die "BOOM!" ), the log output is written and the error is documented (obviously, the error is caught by Catalyst and is not re-thrown). 每当我抛出错误时,我的异常类都没有封装,但是罕见的字符串(比如die "BOOM!" ),会写入日志输出并记录错误(显然,错误是由Catalyst捕获的并且不是抛出)。

How can I tell Catalyst to keep logging requests, even though the exception has to be re-thrown to the middle ware? 我怎么能告诉Catalyst保持记录请求,即使异常必须重新抛给中间件?

There sort of seems to be two parts to this question but I think this covers it. 这个问题似乎有两个部分,但我认为这涵盖了它。 It really is more of a question of setting up Log4perl to log the errors, but there are Catalyst and Plack considerations. 这确实是设置Log4perl以记录错误的问题,但有Catalyst和Plack考虑因素。

First, here would be a typical log4perl config setup I would have: 首先,这将是我将拥有的典型log4perl配置设置:

log4perl.logger                       = DEBUG, FileAppndr, Screen, DebugPanel
log4perl.appender.FileAppndr          = Log::Log4perl::Appender::File
log4perl.appender.FileAppndr.filename = log/server.log
log4perl.appender.FileAppndr.autoflush = 1
log4perl.appender.FileAppndr.stderr   = 1
log4perl.appender.FileAppndr.layout   = PatternLayout
log4perl.appender.FileAppndr.layout.ConversionPattern=%d [%p] - %m%n

log4perl.appender.Screen              = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.stderr       = 1
log4perl.appender.Screen.autoflush    = 1
log4perl.appender.Screen.layout       = PatternLayout
log4perl.appender.Screen.layout.ConversionPattern=%d [%p] - %m%n

Note the inclusion of the stderr value in there as 1 . 请注意,其中的stderr值包含为1 So this tells log4perl to capture stderr for logging. 因此,这告诉log4perl捕获stderr以进行日志记录。

On the Catalyst side, I actually have some very custom init code for the context but there are essentially two things being set; 在Catalyst方面,我实际上有一些非常自定义的上下文初始化代码,但基本上有两件事情正在设置中;

  1. Set the context logger to Log::Log4perl::Catalyst essentially via $c->log 基本上通过$c->log将上下文记录器设置为Log :: Log4perl :: Catalyst

  2. Load the PSGI middleware Plack::Middleware::Log4perl . 加载PSGI中间件Plack :: Middleware :: Log4perl I actually do this via the psgi_middleware config key when loading catalyst config. 我实际上在加载catalyst配置时通过psgi_middleware配置键执行此操作。 So there is nothing more in the config line than "Log4perl" as everything is already in the "Plack::Middleware" context path. 所以在配置行中没有比“Log4perl”更多的了,因为一切都已经在“Plack :: Middleware”上下文路径中了。

The second part there will "pick-up" the loaded "log4perl" instance and assign to the psgi.logger so that any PSGI components can then access the logger as required. 第二部分将“拾取”加载的“log4perl”实例并分配给psgi.logger以便任何PSGI组件可以根据需要访问记录器。

So then, any later statements that will be "re-throw" in code such as this: 那么,任何后来的语句都会在代码中“重新抛出”,例如:

  my $e = HTTP::Exception->new(404);
  $e->status_message("BOOM!!");
  $e->throw;

Will actually be picked up in the "log4perl" output, as well any raw die statements. 实际上会在“log4perl”输出中获取,以及任何原始的die语句。

At least that is the case on Catalyst 5.90060 and up. 至少催化剂5.90060及以上就是这种情况。 There are still some extra niceties that would like to be added regarding HTTP::Exception type classes. 关于HTTP :: Exception类型类,还有一些额外的细节需要添加。

Even though Neil's answer contains several correct statements, that I applied to my Catalyst application, I didn't get any output. 即使Neil的答案包含几个正确的陈述,我应用于我的Catalyst应用程序,但我没有得到任何输出。 I work around that problem, by sub classing Catalyst::Engine . 我通过对Catalyst::Engine进行子类化来解决这个问题。 This subclass is redefining finalize_error only and leaves the rest of its functionality untouched. 此子类仅重新定义finalize_error并保持其余功能不变。 In case of finding my own exceptions types I set an individual response body and status code to achieve the same result as I do by re-throwing the exception "the ladder up". 在找到我自己的异常类型的情况下,我设置了一个单独的响应主体和状态代码,以通过重新抛出异常“梯形图”来实现与我相同的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM