2012-01-10 140 views
2

我想扩展cakephp日志记录工具。 使用自定义日志记录 - CakePHP(1.3)

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

就可以登录一个$msg$level到TMP /日志/ $ level.log。

我想怎么用日志记录是:

  1. 不同层次,如独立的功能$this->debug($msg)$this->log($msg, 'debug')$this->error($msg)$this->log($msg, 'error')等用于记录。
  2. 自动将类的名称放在消息前面,例如如果$this属于“MyClass”类型,则将导致“MyClass:$ msg”的$this->debug($msg)

我知道我可以通过扩展AppModel,AppController的等扩展功能,但正如我处处都需要在我的应用程序的功能,我宁愿需要扩展CakePHP的对象 - 但没有找到一个稳定的机制(不想改变它在蛋糕/文件夹中)。 我虽然要为该功能实现一个新类,但我不确定如何在cakephp中提供该类。

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

回答

2

全球便利的方法

好了,你不能真正做到monkey patching在PHP(5.2至少),这可能是为有你后保持你的代码开发者是好事不见了。 :)

CakePHP - 作为一个具有严格约定的MVC框架 - 使您很难打破MVC范例,只允许您扩展需要隔离的部分(即AppModelAppController等)并保留面向对象的基础在核心中未被触及(这使得难以添加“可以在任何地方使用”以防潜在滥用的代码)。

至于增加超越所有MVC分离的功能,这个地方是app/config/bootstrap.php。当你在这里放置代码时,它看起来很清楚它不是框架的一部分(非常正确),但是允许你在CakePHP加载之前添加这些要素。什么在这里做一些选项可能是:(。例如,一些自定义功能,如error()在你喜欢的方式调用CakeLog::write())。

  1. 创建功能
  2. 加载类(如加载所谓像.. Log,这样你就可以在地方叫Log::error()自己的日志类)
  3. 见下文:

记录器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​​给你,并专注于增加更多的功能,而不是语法上的细微之处。 :)

+0

谢谢deizel,这是我从中学到了很多东西的广泛见解。使用日志消息的类名只是帮助跟踪错误消息。你是对的,功能更重要,但我只是好奇,想扩大我对cakephp的知识:) – 2012-01-11 10:34:24

+0

没问题。添加调用类名是个好主意。我会采取创建自定义日志流的方法,它不应该太难:https://github.com/cakephp/cakephp/blob/340a9fd60425e73bea5e2f130fc6c4ece8e769d1/cake/libs/log/file_log.php#L61 – deizel 2012-01-11 12:59:52

2

除了什么deizel说(伟大的书面,顺便说一下,deizel),你不必使用蛋糕的记录器。欢迎您使用任何您喜欢的日志记录系统。选择一个你喜欢的现有日志框架可能是最安全的选择。 bootstrap.php是进行任何require调用或初始化的好地方。否则,如果你想在'Cake'中做些事情,我建议创建一个带三个日志接口的插件:一个组件,一个行为和一个助手。这样日志功能可以在你的模型,视图和控制器中使用。至于如何编码它,我喜欢这样的想法:将蛋糕类代理变为真正的日志类,并在代理中使用魔术方法__call()来解析记录请求和环境,然后将该信息转发给记录器以统一处理。

你最好能写的东西像$this->MyLogger->oops("stubbed my toe"),并可能有一个oops.log文件,邮件和任何附加信息(呼叫控制器/视图/模型,时间&日期等),你想要包含。

+0

当然是。当你提到使用现有的日志框架时,它提出了一个有效的观点。你可以在“Cake”中“做些事情”,但最终会得到一个行为/组件/视图“三重奏”,它只能(也应该)通过将其封装为插件来重用。如果你可以找到一个现有的库并将其放到'app/vendors'(或者如果你写了'app/libs'(http://goo.gl/uJ5MU)),那么不要重新发明轮子。或者,你使用[magic __call()'方法](http://goo.gl/bSNvN)(正确)的建议可以实现OP的渴望,只需调用'$ thing-> fillInTheBlank($ stuff)'即可。 – deizel 2012-01-11 01:42:07