能否在TCL logger自定义logproc中访问日志器名称以定制输出?
Tcl Logger 自定义日志格式时获取日志器名称的方法
以下代码参考Tcl Wiki及官方文档编写:
package require logger 0.3 proc log_custom_timestamp {level txt} { puts "\[[clock format [clock seconds]]\] \[$level\] $txt" } set log [logger::init main] ${log}::info "hello world" foreach level [logger::levels] { interp alias {} log_custom_timestamp_$level {} log_custom_timestamp $level ${log}::logproc $level log_custom_timestamp_$level } ${log}::info "hello world"
运行后输出如下:
[Mon Aug 12 16:36:58 PDT 2024] [main] [info] 'hello world' [Mon Aug 12 16:36:58 PDT 2024] [info] hello world
可以看到,原始输出包含日志器名称main,但自定义日志处理函数的输出中没有该名称。
问题:是否可以在logproc中访问日志器名称,以便在定制时间戳格式的同时保留日志器名称?
注:已知将logproc嵌入命名空间的解决方案,但希望找到更通用的方法获取该名称——因为嵌入命名空间意味着每个日志器都需要单独的命名空间和logproc副本。
解决方案
可以通过两种通用方式实现,无需为每个日志器创建独立的命名空间和处理函数:
方法1:用闭包绑定日志器名称
Tcl 8.5及以上支持闭包,可通过apply创建携带日志器名称的匿名函数,让每个日志级别处理函数记住所属的日志器名称:
package require logger 0.3 proc create_log_handler {logger_name} { return apply {{logger_name level txt} { puts "\[[clock format [clock seconds]]\] \[$logger_name\] \[$level\] $txt" }} $logger_name } set log [logger::init main] ${log}::info "hello world" foreach level [logger::levels] { set handler [create_log_handler [namespace tail $log]] ${log}::logproc $level $handler } ${log}::info "hello world"
方法2:读取日志器命名空间的内置变量
logger::init创建的命名空间中会存储name变量记录日志器名称,可在处理函数中直接读取该变量:
package require logger 0.3 proc log_custom_timestamp {logger_ns level txt} { set logger_name [set ${logger_ns}::name] puts "\[[clock format [clock seconds]]\] \[$logger_name\] \[$level\] $txt" } set log [logger::init main] ${log}::info "hello world" foreach level [logger::levels] { interp alias {} log_custom_timestamp_${log}_$level {} log_custom_timestamp $log $level ${log}::logproc $level log_custom_timestamp_${log}_$level } ${log}::info "hello world"
两种方法运行后,输出都会包含日志器名称main,既保留了自定义时间戳格式,又实现了通用化处理。
内容的提问来源于stack exchange,提问作者merlin2011
相关产品推荐
相关产品推荐

