原文地址: Integrating Chrome’s Clockwork into your web-app

在 开发者工具 中查看 clockwork 插件

chrome clockwork 下载地址
[译] 在 web 应用中集成 chrome 的 clockwork 插件 - 图1
Clockwork 是个很帅的工具, 他能运行在任何服务端的平台/框架, 我会带你在你的 php 应用中集成这个插件.

Part.1 安装

使用 Composer 安装

  • composer.json 添加 “itsgoingd/clockwork”: “dev-master”
  • 运行 composer.phar update更新

下载安装
作为另外一种替代方式, 你可以使用最古老的方式来下载 或者 克隆 [https://github.com/itsgoingd/clockwork/](https://github.com/itsgoingd/clockwork/) 来安装

Part.2: 和 Web App 集成

讲这个函数库放在你的项目的调用的范围内, 最好和 controller/router 放到一块, header()方法需要在未输出任何内容的前提下使用这个函数, 这个方法会告知 Clockwork 插件来向服务端请求 clockwork 数据.
最后两行 resolveRequest()storeRequest() 必须在你 的 web app 执行完成之后运行, 否则不会出现完整的调用日志, 每个 DataSource 都需要有 resolve() 方法, 这个方法在每个数据源执行的时候进行调用. 这个会分析和保存所有的执行时间, 查询, 日志来供 Clockwork 调用.

  1. // this sends out headers, so unless you are buffering output
  2. // you may want to place this early in your app
  3. $clockwork = new Clockwork();
  4. header("X-Clockwork-Id: " . $clockwork->getRequest()->id);
  5. header("X-Clockwork-Version: " . Clockwork::VERSION);
  6. // spawn your own custom DataSource (explained below)
  7. $clockwork->addDataSource(new YourCustomDataSource($yourAppContext));
  8. // attach a sample datasource that comes with
  9. // the Clockwork library (grabs session info, etc)
  10. $clockwork->addDataSource(new PhpDataSource());
  11. // we could write a custom APC, MemCached, etc here
  12. // or just use the FileStorage that comes with Clockwork
  13. $clockwork->setStorage(new FileStorage("some/path/"));
  14. // run your web-app here
  15. // ...
  16. // once your app is done, tell Clockwork to resolve and store
  17. // data in a file on your server; it will call the resolve()
  18. // method on YourCustomDataSource and PhpDataSource
  19. $clockwork->resolveRequest();
  20. $clockwork->storeRequest();

这会在 some/path/ 目录下创建一个新文件.
在页面加载完成之后, Chrome 的 Clockwork 扩展获取 X-Clockwork 的头信息, 并且向服务器发送一条请求来获取生成的文件, 这个文件的 id 值会存在服务器返回的 header 中, 这个 header 的标识符是 X-Clockwork-Id.
例如: 如果 X-Clockwork-Id1387208177.8923.1394938488, 然后 Chrome 的 Clockwork 扩展会请求 /__clockwork/1387208177.8923.1394938488 这个地址来获取服务器存储的 json 文件.
你可以通过处理 /__clockwork/[*:id] 这个请求来返回这个插件所需要的数据.

  1. $storage = new FileStorage("/some/path/");
  2. $data = $storage->retrieve($ctx->parameters->id);
  3. $data->toJson();

Klein 或者 AltoRouter 路由类能够处理类似于以上的语法, 并且通过控制器文件来获取 request-id, 否则的话你可以通过 $_SERVER[‘REQUEST_URI’] 来手动的获取 request-id , 然后 FileStorage 将会处理后边的事情.

Part.3: 自定义数据源

  1. class YourCustomDataSource extends DataSource
  2. {
  3. protected $context;
  4. /**
  5. * YourAppContext should link to your main web-app
  6. * and fetch timings, queries, and logs
  7. */
  8. function __construct(YourAppContext $context)
  9. {
  10. $this->context = $context;
  11. }
  12. /**
  13. * the entry-point. called by Clockwork itself.
  14. */
  15. function resolve(Request $request)
  16. {
  17. $timings = $this->context->getTimings();
  18. // optionally: pre-sort the timeline
  19. uasort($timeline, function($a, $b) {
  20. if($a['start'] > $b['start'])
  21. return 1;
  22. if($a['start'] == $b['start']) {
  23. if($a['end'] > $b['end'])
  24. return 1;
  25. elseif ($a['end'] < $b['end'])
  26. return -1;
  27. return 0;
  28. }
  29. return -1;
  30. });
  31. $queries = $this->context->getQueries();
  32. $request->timelineData = $timeline;
  33. $request->databaseQueries = $queries;
  34. return $request;
  35. }
  36. }

例如:

  1. $timings[0] = ['start' => 1387208058.1, 'end' => 1387208058.5, 'duration' => 40, 'description' => 'parsing tweets']

startend 标签使用 秒 作为单位, duration 使用毫秒作为单位, startend 标签的时间乘以 1000 ($_SERVER[‘REQUEST_TIME_FLOAT’] * 1000) . 所以使用 microtime(true) 作为时间相对单位好于从 0 开始

  1. $queries[0] = ['query' => "SELECT awesomeness FROM cereals WHERE name = `Captain Crunch`", 'duration' => 13]

这里放了一条查询数据库的语句, 仅供参考, 时间以毫秒记.
更多开发见 clockwork development-notes

Url 重写

这里使用了路由机制使插件访问服务器, 而且地址和请求方式都是写好在 代码中的, 所以需要在服务器中配置重写, 对于不是单入口和不支持路由访问的来说, 需要配置 url 重写
Nginx:

  1. server{
  2. ...
  3. rewrite ^/__clockwork/(.*)$ somefile.php?id=$1
  4. ...
  5. }

Apache: vhosts 模式

  1. <VirtualHost *:80>
  2. ServerAdmin admin@qq.com
  3. DocumentRoot "/var/www/project"
  4. ServerName project.test.com
  5. ErrorLog "logs/project.test.com-error.log"
  6. CustomLog "logs/project.test.com-access.log" common
  7. RewriteEngine on
  8. RewriteRule ^/__clockwork/(.*)$ /extend/debug.php?action=cw&id=$1
  9. </VirtualHost>

译者补充: Laravel 又一个调试利器 anbu