自定义日志记录 - CakePHP(1.3)

时间:2012-01-10 14:59:24

标签: php cakephp cakephp-1.3

我想扩展cakephp日志记录工具。 使用

$this->log($msg, $level)

您可以使用$msg$level记录到tmp / logs / $ level.log。

我想如何使用日志记录:

  1. 不同级别的单独功能,例如$this->debug($msg) $this->log($msg, 'debug')$this->error($msg)$this->log($msg, 'error')用于记录。
  2. 自动将类的名称放在消息前面,例如如果$this->debug($msg)的类型为“MyClass”,$this将导致“MyClass:$ msg”。
  3. 我知道我可以通过扩展AppModel,AppController等来扩展功能,但是因为我需要在我的应用程序中的所有地方使用功能,我宁愿需要扩展cakephp的Object - 但是没有找到一个稳定的机制(不要我想在蛋糕/文件夹中更改它。 我虽然为该功能实现了一个新类,但我不确定如何在cakephp中提供它。

    你能不能给我一些提示,我可以在哪里/如何整齐地实施这些扩展?

2 个答案:

答案 0 :(得分:2)

全球便利方法

好吧,你不能在PHP中真正做monkey patching(至少5.2),对于那些在你离开后必须维护代码的开发人员来说这可能是一件好事。 :)

CakePHP--是一个具有严格约定的MVC框架 - 让你很难打破MVC范式,只允许你单独扩展所需的部分(即AppModelAppController,并且保持对象导向的基础不受影响(使得很难添加“可以在任何地方使用”的代码以防止潜在的误用)。

至于添加超越所有MVC分离的功能,其位置为app/config/bootstrap.php。当您在此处放置代码时,似乎很清楚它不是框架的一部分(非常正确),但允许您在CakePHP加载之前添加这些基本要素。这里做的几个选项可能是:

  1. 创建一个函数(例如error()的一些自定义函数,以您喜欢的方式调用CakeLog::write()。)
  2. 加载一个类(例如,加载你自己的日志记录类,类似于...... Log,这样你就可以在地方调用Log::error()
  3. 见下文:
  4. 记录器API

    Cake允许对记录器之类的东西进行许多自定义,但不幸的是,在这种情况下,已经在核心中定义了暴露给我们的API。用于登录CakePHP的API如下所示,您可以在任何您喜欢的地方使用这两种方法(好吧,前者仅在类中):

    $this->log($msg, $level) // any class extending `Object` inherits this
    // or
    CakeLog::write($level, $message); // this is actually what is called by the above
    

    您尝试消除的任意$level参数实际上是quite a powerful feature

    $this->log('Cannot connect to SMTP server', 'email'); // logs to app/logs/email.log
    // vs
    $this->email('Cannot connect to SMTP server'); // ambiguous - does this send emails?
    

    我们刚刚创建了一个全新的日志类型而没有编写额外的代码行,而且我们的代码意图非常清楚。

    自定义记录器

    核心开发人员有远见add a condition允许我们完全取代记录器类,如果我们愿意:

    function log($msg, $type = LOG_ERROR) {
        if (!class_exists('CakeLog')) { // winning
            require LIBS . 'cake_log.php';
        }
        // ...
    

    正如您所看到的,核心CakeLog类只有在没有这样的类存在的情况下才会被实例化,这样您就有机会插入自己创建的内容(或者只需要一些调整的精确副本 - 尽管您可能需要同步更改核心 - 手动 - 升级时):

    // app/config/bootstrap.php
    App::import('Lib', 'CakeLog'); // copy cake/libs/cake_log.php to app/lib/cake_log.php
    

    上面的内容可以让您完全控制应用程序中CakeLog类的实现,因此您可以执行一些操作,例如将调用类名称动态添加到日志消息中。但是,更直接的方法(以及其他类型的日志记录 - 例如数据库)将是create a custom log stream

    CakeLog::config('file', array(
        'engine' => 'FileLog', // copy cake/libs/log/file_log.php to app/libs/log/file_log.php
    ));
    

    TL; DR - 虽然您可以在CakePHP引导之前加载自己的代码,或者在提供的每个MVC层中单独使用,但您不应该篡改核心提供的对象层次结构。这使得很难添加全局继承的类方法。

    我的建议:使用给你的API,专注于添加更多功能而不是语法细微之处。 :)

答案 1 :(得分:2)

除了deizel所说的(伟大的文章,顺便说一句,deizel),你不必使用Cake的记录器。欢迎您使用任何您喜欢的日志记录系统。选择您喜欢的现有日志框架可能是最安全的选择。 bootstrap.php是进行任何require调用或初始化的好地方。

否则,如果你想在'Cake'中做一些事情,我建议你创建一个带有三个日志记录接口的插件:一个Component,一个Behavior和一个Helper。这样,日志功能将在您的模型,视图和控制器中可用。至于如何对其进行编码,我喜欢这样的想法,即将蛋糕类精简代理到您的真实日志类,并使用代理中的魔术方法__call()来解析日志记录请求和环境,然后将该信息转发给您记录器统一处理。

您可以编写$this->MyLogger->oops("stubbed my toe")之类的内容,并且可能会在您的消息中添加oops.log文件以及其他任何信息(调用控制器/视图/型号,时间和日期等)我喜欢包括在内。