是否可以使用Log4perl创建每个用户的日志文件?

是否可以使用Log4perl创建每个用户的日志文件?,perl,mojolicious,log4perl,Perl,Mojolicious,Log4perl,我有一个非常有趣的web应用程序,它使用Log4perl进行日志记录。它是一个多用户应用程序,当多个用户访问应用程序时,有时很难跟踪日志文件中的各个线程。我想做的是将每个用户(用户总数不到25个)的活动记录到一个单独的文件中。例如../log/userX.log./log/userY.log等 我考虑在配置文件中使用类似的内容: log4perl.appender.MAIN.filename=sub{return get_user_filename();} 但是记录器是在mojolicous启动

我有一个非常有趣的web应用程序,它使用Log4perl进行日志记录。它是一个多用户应用程序,当多个用户访问应用程序时,有时很难跟踪日志文件中的各个线程。我想做的是将每个用户(用户总数不到25个)的活动记录到一个单独的文件中。例如../log/userX.log./log/userY.log等

我考虑在配置文件中使用类似的内容: log4perl.appender.MAIN.filename=sub{return get_user_filename();} 但是记录器是在mojolicous启动子例程中定义的,用户直到请求时才知道

另一个似乎更有希望的想法是,编写一个桥接路由,为用户创建一个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.
在/usr/local/share/perl/5.14.2/Log/Log4perl/Appender.pm第282行、第747行的Log::Log4perl::Appender中找不到对象方法文件()。

/正在创建tmp/user.log,不过(零长度)是最新的CPAN安装的log::Log4perl。有什么想法吗?

我喜欢Richard的评论,在你说你不想走DB路线之前,我已经写了这个。所以我把它包括在其他人身上。旁白:我认为DB日志记录有时非常繁重,我个人通常也会选择文件

请求/分派周期顶部的某个位置(Catalyst示例)-

然后在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
日志文件,以准确获取用户的请求/日志线程,这很简单。

您考虑过登录到DBI吗?这将使事件发生后按用户进行拆分/筛选变得容易。是的,但我没有使用DBI数据库。(我知道,我可以从十几个不同的数据库中选择不同的模块)文件是我的愿望,易于阅读和操作。你的错误可能是由于打字错误。它在Appender类中查找“File:”。大概是拼错了“::File”在什么地方。谢谢,但我已经三次检查过了。请参阅Log::Log4perl::Appender的第一个参数-'Log::Log4perl::Appender::File'错误消息中的':“after文件来自Appener.pm die消息。我看不到。它只是“$AUTOLOAD()“-谢谢你的建议。我可能不得不重新使用用户param和grep,但我觉得上面的代码已经很接近了。我不知道为什么会出现这样的错误。我会尝试以下方法,看看会发生什么:内联并简化“先前定义的”布局,内联级别,将其更改为屏幕日志。其中之一可能会显示文件追加器的问题所在。
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