我有一个使用Log4perl进行日志记录的mojolicious Web应用程序。它是一个多用户应用程序,有时当多个用户访问该应用程序时,很难跟踪日志文件中的各个线程。我想要做的是让每个用户(人口不足25个用户)活动记录到一个单独的文件中。例如。 ./log/userX.log ./log/userY.log等
我想在配置文件中使用这样的东西: log4perl.appender.MAIN.filename = sub {return get_user_filename(); } 但是记录器是在Mojolicious启动子程序中定义的,直到请求时才知道用户。
另一个看起来更有希望的想法是编写一个桥接路由,为用户创建一个appender,然后将其分配给记录器。然后我可以缓存appender以便以后重用(或者销毁和重新创建)。
我会玩第二种选择,但如果有人试图这样做并希望分享他们的智慧,我会很感激。
- 更新 - 所以在我的桥路线上,我正在做以下事情:
my $user = $self->req->headers->header('authuser'); # from apache
my $appender = Log::Log4perl::Appender->new(
'Log::Log4perl::Appender::File',
name => $user . "_file_appender",
filename => "/tmp/$user.log",
mode => "append",
);
$appender->layout($layout); # previously defined
$appender->level($loglevel); # again previously defined and omitted for brevity
Log::Log4perl::get_logger($user)->add_appender($appender);
$self->app->log(Log::Log4perl::get_logger($user));
但是我收到了以下错误:
Can't locate object method File:() in Log::Log4perl::Appender at /usr/local/share/perl/5.14.2/Log/Log4perl/Appender.pm line 282, <DATA> line 747.
/tmp/user.log正在创建(零长度)Log :: Log4perl的最新CPAN安装。有什么想法吗?
答案 0 :(得分:1)
我喜欢理查德的评论,并且在你说你不想进入数据库路线之前已经写完了。所以我把它包括在其他人中。除此之外:我认为有时DB记录非常繁重,我个人通常也会选择文件。
位于请求/调度周期顶部的某处(Catalyst示例) -
Log::Log4perl::MDC->put( "user", $ctx->user_exists ? $ctx->user->id : 0 );
然后在Log4perl配置 -
log4perl.appender.toDBI = Log::Log4perl::Appender::DBI
log4perl.appender.toDBI.Threshold = INFO
log4perl.appender.toDBI.layout = Log::Log4perl::Layout::NoopLayout
log4perl.appender.toDBI.datasource = sub { "DBI:mysql:" . db_name_function() }
log4perl.appender.toDBI.attrs.f_encoding = utf8
log4perl.appender.toDBI.username = db_username
log4perl.appender.toDBI.password = s3cr37
log4perl.appender.toDBI.sql = INSERT INTO toDBI \
( user, file, line, message ) \
VALUES ( ?, ?, ?, ? )
log4perl.appender.toDBI.usePreparedStmt = 1
log4perl.appender.toDBI.params.1 = %X{user}
log4perl.appender.toDBI.params.2 = %F
log4perl.appender.toDBI.params.3 = %L
log4perl.appender.toDBI.params.4 = %m
就文件而言,我认为这可能是有可能的,但不会很有趣,似乎可能会引入错误,而且可能过头了。将user:{userid}
之类的内容添加到日志记录中,然后grep/ack
添加日志文件以获取用户的请求/日志线程,这是微不足道的。