我有一个日志记录器类(在PHP中,但这并不重要),它输出日志消息。日志记录器是一个自定义实现,运行良好。但是,我想扩展它,为日志消息的每个类型提供一个事件ID。例如,"用户登录消息"是事件ID 1,"表单验证失败"是事件ID 2。
此事件ID的目的是在查看长日志列表时过滤不重要的事件。我相信按事件ID对日志进行分类和查询比在数据库中进行子字符串搜索更快。
我有以下的想法,但欢迎可行的替代方案。我在这个例子中使用了PHP,但一些足够通用的东西,可以应用于大多数语言,如PHP/Java/c#等,将是有用的。1)在日志函数调用中隐式包含ID:
abstract class EventId {
const LOGIN = 1;
const VALIDATION_FAILURE = 2;
// etc
}
Logger::messageDebug(EventID::LOGIN, $username . " logged in");
Logger::messageWarning(EventID::VALIDATION_FAILURE, "Form failed to validate, etc.");
这样做的优点是简单,但我担心它会变得有点乱。
2)将变量参数作为单独的参数传递给日志消息,然后对第一个字符串
进行散列Logger::messageDebug("%s logged in", $username);
Logger::messageWarning("The %s form failed to validate", $form);
优点是简单,缺点是事件ID依赖于第一个字符串的散列(或其他函数)来区分日志消息的类型。
3)回溯和做一些肮脏
function messageDebug($message) {
$trace = obtainTraceOfCallToMessageDebug();
$callToMessageDebug = $trace[0];
$eventId = "";
$eventId .= $eventId->file;
$eventId .= $eventId->line;
$eventId = sha1($eventId);
messageImpl($eventId, $message);
}
这是相当讨厌的,但它确实有一个优点,即不需要更改现有的日志消息,另外,在编写新的日志消息时,它不那么脆弱。在PHP中,获得回溯很容易,也很便宜,而在其他语言中,你可能不得不抛出一个异常,这非常糟糕。不管怎样,这是个好主意。
期待您的意见。我的主要要求是可维护性而不是速度。我目前正朝着第1 -保持简单。
我会选择第一个稍微修改的:
假设您使用以下语句调用记录器:
Logger::messageWarning($message)
换成
Logger::messageWarning($message, EventId:someconstant)
和定义你的EventId类为
abstract class EventId {
const UNSPECIFIED = 1;
const LOGIN = 2;
const VALIDATION_FAILURE = 3;
// etc
}
和您的记录器函数将接受第二个参数,但使用默认值EventId:UNSPECIFIED
。
class Logger {
...
function messageWarning($message, $message_type = EventId:UNSPECIFIED) {
...
}
}
这样你就不会破坏现有的代码,不需要做第3条中概述的hack,并且可以通过添加事件类型来随时随地替换日志调用。