{"action":"created","comment":{"url":"https://api.github.com/repos/zendframework/zf3-web/pulls/comments/138351019","pull_request_review_id":62132264,"id":138351019,"diff_hunk":"@@ -0,0 +1,387 @@\n+---\n+layout: post\n+title: Logging PHP applications\n+date: 2017-09-12T11:24:00-05:00\n+author: Enrico Zimuel\n+url_author: https://www.zimuel.it\n+permalink: /blog/2017-09-12-zend-log.html\n+categories:\n+- blog\n+- psr3\n+- log\n+- zend-log\n+\n+---\n+\n+Every PHP application generates errors, warnings, notices and throws exceptions.\n+If we do not store these information in a log system, we are losing a way\n+to identify and solve problems at runtime. Moreover, we may need to log specific\n+actions like a user's login and logout. All these information should be filtered\n+and stored in an efficient way.\n+\n+PHP offers the functions [error_log()](http://php.net/manual/en/function.error-log.php)\n+to send an error message to the defined log system and [set_error_handler()](http://php.net/manual/en/function.set-error-handler.php)\n+to intercept the warnings, errors, and notices generated by PHP.\n+\n+These functions can be used to customize the error management but it's up to the\n+developer to write the logic to filter and store the data.\n+\n+Zend Framework offers a specific component for logging, [zend-log](https://github.com/zendframework/zend-log). This library can be used\n+as general purpose logging system. It supports multiple log backends, formatting\n+messages sent to the log, and filtering messages from being logged.\n+\n+Last but not least, `zend-log` is compliant with the [PSR-3](http://www.php-fig.org/psr/psr-3/)\n+logger interface standard.\n+\n+## Installation\n+\n+You can install [zend-log](https://github.com/zendframework/zend-log) using the\n+following [composer](https://getcomposer.org) command:\n+\n+```bash\n+composer require zendframework/zend-log\n+```\n+\n+## Usage\n+\n+Zend-log can be used to write log in different formats using multiple backends.\n+You can also filter the log data from being saved and processes the log event\n+prior to filtering or writing, allowing the ability to substitute, add, remove,\n+or modify data to be logged.\n+\n+To use `zend-log` you need tp have at least a writer and a logger instance.\n+The writer performs the storage of the log into a backend, and the logger\n+consumes the writer to perform the log.\n+\n+A usage example is reported as follows:\n+\n+```php\n+use Zend\\Log\\Logger;\n+use Zend\\Log\\Writer\\Stream;\n+\n+$logger = new Logger;\n+$writer = new Stream('php://output');\n+\n+$logger->addWriter($writer);\n+$logger->log(Logger::INFO, 'Informational message');\n+```\n+\n+An example of output is reported as follows:\n+\n+```\n+2017-09-11T15:07:46+02:00 INFO (6): Informational message\n+```\n+\n+The output is a string containing a timestamp, a priority `INFO (6)` and the\n+message `Informational message`. The output format can be changed using the\n+`setFormatter()` function of the writer object (`$writer`).\n+The default log format, used by [Simple](https://github.com/zendframework/zend-log/blob/master/src/Formatter/Simple.php)\n+formatter is as follows:\n+\n+```\n+%timestamp% %priorityName% (%priority%): %message% %extra%\n+```\n+\n+where `%extra%` is an optional value containing additional info.\n+\n+For instance, to change the format using the `log %message%` string you can use\n+the following code:\n+\n+```php\n+$formatter = new Zend\\Log\\Formatter\\Simple('log %message%' . PHP_EOL);\n+$writer->setFormatter($formatter);\n+```\n+\n+## Log PHP events\n+\n+Zend-log can also be used to log PHP errors and intercept exceptions. You can\n+log PHP errors using the static function `registerErrorHandler($logger)` and\n+intercept exceptions using the static function `registerExceptionHandler($logger)`.\n+\n+An example is reported as follows:\n+\n+```php\n+use Zend\\Log\\Logger;\n+use Zend\\Log\\Writer;\n+\n+$logger = new Logger;\n+$writer = new Writer\\Stream(__DIR__ . '/test.log');\n+$logger->addWriter($writer);\n+\n+// Log PHP errors\n+Logger::registerErrorHandler($logger);\n+// Log exceptions\n+Logger::registerExceptionHandler($logger);\n+```\n+\n+## Filtering data\n+\n+As mentioned, we can filter the data to be logged. We can use the `addFilter()`\n+functions of the [Writer interface](https://github.com/zendframework/zend-log/blob/master/src/Writer/WriterInterface.php)\n+to add a specific filter.\n+\n+For instance, we can filter by priority, accepting only log with priority less\n+than or equal to a specific value. An example is reported as follows:\n+\n+```php\n+$filter = new Zend\\Log\\Filter\\Priority(Logger::CRIT);\n+$writer->addFilter($filter);\n+```\n+\n+Using this example, the logger will store only the log with priority less or\n+equal to *Critical*. The priorities are defined by the `Zend\\Log\\Logger` class:\n+\n+```\n+EMERG   = 0;  // Emergency: system is unusable\n+ALERT   = 1;  // Alert: action must be taken immediately\n+CRIT    = 2;  // Critical: critical conditions\n+ERR     = 3;  // Error: error conditions\n+WARN    = 4;  // Warning: warning conditions\n+NOTICE  = 5;  // Notice: normal but significant condition\n+INFO    = 6;  // Informational: informational messages\n+DEBUG   = 7;  // Debug: debug messages\n+```\n+\n+We can also filter log data based on regular expressions, timestamp, etc.\n+Moreover, we can use a [zend-validator](https://github.com/zendframework/zend-validator)\n+class to filter the log or implementing a custom `Zend\\Validator\\ValidatorInterface`.\n+\n+## Processing data\n+\n+If you need to provide additional information to logs in an automated fashion,\n+you can use a `Zend\\Log\\Processer` class. A processor is executed before the\n+log data are passed to the writer. The input of a processor is a *log event*,\n+an array containing all the information log. The output is still a *log event*.\n+The processor can modify the *log event* before it sent to the writer.\n+\n+You can read about the processor adapters offered by zend-log [here](https://zendframework.github.io/zend-log/processors/)\n+in the documentation.\n+\n+## Multiple backends\n+\n+One of the cool feature of `zend-log` is the possibility to write log using\n+multiple backends. For instance, you can write a log in a file and in a\n+database using the following code:\n+\n+```php\n+use Zend\\Db\\Adapter\\Adapter as DbAdapter;\n+use Zend\\Log\\Formatter;\n+use Zend\\Log\\Writer;\n+use Zend\\Log\\Logger;\n+\n+$dbconfig = [\n+    'driver' => 'Pdo',\n+    'dsn' => 'mysql:dbname=testlog;host=localhost',\n+    'username' => 'root',\n+    'password' => 'password'\n+];\n+$db = new DbAdapter($dbconfig);\n+$mapping = [\n+    'timestamp' => 'date',\n+    'priority'  => 'type',\n+    'message'   => 'event',\n+];\n+$writer1 = new Writer\\Db($db, 'log', $mapping); // log table\n+$formatter = new Formatter\\Base();\n+$formatter->setDateTimeFormat(\"Y-m-d H:i:s\"); // MySQL DATETIME format\n+$writer1->setFormatter($formatter);\n+\n+$writer2 = new Writer\\Stream(__DIR__ . '/test.log');","path":"data/posts/2017-09-12-zend-log.md","position":189,"original_position":189,"commit_id":"cbe0c67b43fa025c10ea7cb433d72b436a6f2df7","original_commit_id":"cbe0c67b43fa025c10ea7cb433d72b436a6f2df7","user":{"login":"froschdesign","id":103362,"avatar_url":"https://avatars2.githubusercontent.com/u/103362?v=4","gravatar_id":"","url":"https://api.github.com/users/froschdesign","html_url":"https://github.com/froschdesign","followers_url":"https://api.github.com/users/froschdesign/followers","following_url":"https://api.github.com/users/froschdesign/following{/other_user}","gists_url":"https://api.github.com/users/froschdesign/gists{/gist_id}","starred_url":"https://api.github.com/users/froschdesign/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/froschdesign/subscriptions","organizations_url":"https://api.github.com/users/froschdesign/orgs","repos_url":"https://api.github.com/users/froschdesign/repos","events_url":"https://api.github.com/users/froschdesign/events{/privacy}","received_events_url":"https://api.github.com/users/froschdesign/received_events","type":"User","site_admin":false},"body":"I would replace `$writer2` with `$writerStream`.","created_at":"2017-09-12T13:42:29Z","updated_at":"2017-09-12T13:42:43Z","html_url":"https://github.com/zendframework/zf3-web/pull/72#discussion_r138351019","pull_request_url":"https://api.github.com/repos/zendframework/zf3-web/pulls/72","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/zendframework/zf3-web/pulls/comments/138351019"},"html":{"href":"https://github.com/zendframework/zf3-web/pull/72#discussion_r138351019"},"pull_request":{"href":"https://api.github.com/repos/zendframework/zf3-web/pulls/72"}}},"pull_request":{"url":"https://api.github.com/repos/zendframework/zf3-web/pulls/72","id":140577644,"html_url":"https://github.com/zendframework/zf3-web/pull/72","diff_url":"https://github.com/zendframework/zf3-web/pull/72.diff","patch_url":"https://github.com/zendframework/zf3-web/pull/72.patch","issue_url":"https://api.github.com/repos/zendframework/zf3-web/issues/72","number":72,"state":"open","locked":false,"title":"Blog post proposal about zend-log","user":{"login":"ezimuel","id":475967,"avatar_url":"https://avatars2.githubusercontent.com/u/475967?v=4","gravatar_id":"","url":"https://api.github.com/users/ezimuel","html_url":"https://github.com/ezimuel","followers_url":"https://api.github.com/users/ezimuel/followers","following_url":"https://api.github.com/users/ezimuel/following{/other_user}","gists_url":"https://api.github.com/users/ezimuel/gists{/gist_id}","starred_url":"https://api.github.com/users/ezimuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ezimuel/subscriptions","organizations_url":"https://api.github.com/users/ezimuel/orgs","repos_url":"https://api.github.com/users/ezimuel/repos","events_url":"https://api.github.com/users/ezimuel/events{/privacy}","received_events_url":"https://api.github.com/users/ezimuel/received_events","type":"User","site_admin":false},"body":"","created_at":"2017-09-12T13:20:47Z","updated_at":"2017-09-12T13:42:43Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5c6fd2d03001375a37115e424afb80dbc5b68dfa","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/zendframework/zf3-web/pulls/72/commits","review_comments_url":"https://api.github.com/repos/zendframework/zf3-web/pulls/72/comments","review_comment_url":"https://api.github.com/repos/zendframework/zf3-web/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zendframework/zf3-web/issues/72/comments","statuses_url":"https://api.github.com/repos/zendframework/zf3-web/statuses/cbe0c67b43fa025c10ea7cb433d72b436a6f2df7","head":{"label":"ezimuel:feature/zend-log-post","ref":"feature/zend-log-post","sha":"cbe0c67b43fa025c10ea7cb433d72b436a6f2df7","user":{"login":"ezimuel","id":475967,"avatar_url":"https://avatars2.githubusercontent.com/u/475967?v=4","gravatar_id":"","url":"https://api.github.com/users/ezimuel","html_url":"https://github.com/ezimuel","followers_url":"https://api.github.com/users/ezimuel/followers","following_url":"https://api.github.com/users/ezimuel/following{/other_user}","gists_url":"https://api.github.com/users/ezimuel/gists{/gist_id}","starred_url":"https://api.github.com/users/ezimuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ezimuel/subscriptions","organizations_url":"https://api.github.com/users/ezimuel/orgs","repos_url":"https://api.github.com/users/ezimuel/repos","events_url":"https://api.github.com/users/ezimuel/events{/privacy}","received_events_url":"https://api.github.com/users/ezimuel/received_events","type":"User","site_admin":false},"repo":{"id":62312187,"name":"zf3-web","full_name":"ezimuel/zf3-web","owner":{"login":"ezimuel","id":475967,"avatar_url":"https://avatars2.githubusercontent.com/u/475967?v=4","gravatar_id":"","url":"https://api.github.com/users/ezimuel","html_url":"https://github.com/ezimuel","followers_url":"https://api.github.com/users/ezimuel/followers","following_url":"https://api.github.com/users/ezimuel/following{/other_user}","gists_url":"https://api.github.com/users/ezimuel/gists{/gist_id}","starred_url":"https://api.github.com/users/ezimuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ezimuel/subscriptions","organizations_url":"https://api.github.com/users/ezimuel/orgs","repos_url":"https://api.github.com/users/ezimuel/repos","events_url":"https://api.github.com/users/ezimuel/events{/privacy}","received_events_url":"https://api.github.com/users/ezimuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ezimuel/zf3-web","description":"Website of Zend Framework 3","fork":true,"url":"https://api.github.com/repos/ezimuel/zf3-web","forks_url":"https://api.github.com/repos/ezimuel/zf3-web/forks","keys_url":"https://api.github.com/repos/ezimuel/zf3-web/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ezimuel/zf3-web/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ezimuel/zf3-web/teams","hooks_url":"https://api.github.com/repos/ezimuel/zf3-web/hooks","issue_events_url":"https://api.github.com/repos/ezimuel/zf3-web/issues/events{/number}","events_url":"https://api.github.com/repos/ezimuel/zf3-web/events","assignees_url":"https://api.github.com/repos/ezimuel/zf3-web/assignees{/user}","branches_url":"https://api.github.com/repos/ezimuel/zf3-web/branches{/branch}","tags_url":"https://api.github.com/repos/ezimuel/zf3-web/tags","blobs_url":"https://api.github.com/repos/ezimuel/zf3-web/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ezimuel/zf3-web/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ezimuel/zf3-web/git/refs{/sha}","trees_url":"https://api.github.com/repos/ezimuel/zf3-web/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ezimuel/zf3-web/statuses/{sha}","languages_url":"https://api.github.com/repos/ezimuel/zf3-web/languages","stargazers_url":"https://api.github.com/repos/ezimuel/zf3-web/stargazers","contributors_url":"https://api.github.com/repos/ezimuel/zf3-web/contributors","subscribers_url":"https://api.github.com/repos/ezimuel/zf3-web/subscribers","subscription_url":"https://api.github.com/repos/ezimuel/zf3-web/subscription","commits_url":"https://api.github.com/repos/ezimuel/zf3-web/commits{/sha}","git_commits_url":"https://api.github.com/repos/ezimuel/zf3-web/git/commits{/sha}","comments_url":"https://api.github.com/repos/ezimuel/zf3-web/comments{/number}","issue_comment_url":"https://api.github.com/repos/ezimuel/zf3-web/issues/comments{/number}","contents_url":"https://api.github.com/repos/ezimuel/zf3-web/contents/{+path}","compare_url":"https://api.github.com/repos/ezimuel/zf3-web/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ezimuel/zf3-web/merges","archive_url":"https://api.github.com/repos/ezimuel/zf3-web/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ezimuel/zf3-web/downloads","issues_url":"https://api.github.com/repos/ezimuel/zf3-web/issues{/number}","pulls_url":"https://api.github.com/repos/ezimuel/zf3-web/pulls{/number}","milestones_url":"https://api.github.com/repos/ezimuel/zf3-web/milestones{/number}","notifications_url":"https://api.github.com/repos/ezimuel/zf3-web/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ezimuel/zf3-web/labels{/name}","releases_url":"https://api.github.com/repos/ezimuel/zf3-web/releases{/id}","deployments_url":"https://api.github.com/repos/ezimuel/zf3-web/deployments","created_at":"2016-06-30T13:19:45Z","updated_at":"2016-07-01T16:22:49Z","pushed_at":"2017-09-12T13:03:52Z","git_url":"git://github.com/ezimuel/zf3-web.git","ssh_url":"git@github.com:ezimuel/zf3-web.git","clone_url":"https://github.com/ezimuel/zf3-web.git","svn_url":"https://github.com/ezimuel/zf3-web","homepage":"http://framework.zend.com","size":31836,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"zendframework:master","ref":"master","sha":"2d1d8522f463cf812a5576ea41d7c46a4df26c02","user":{"login":"zendframework","id":296074,"avatar_url":"https://avatars2.githubusercontent.com/u/296074?v=4","gravatar_id":"","url":"https://api.github.com/users/zendframework","html_url":"https://github.com/zendframework","followers_url":"https://api.github.com/users/zendframework/followers","following_url":"https://api.github.com/users/zendframework/following{/other_user}","gists_url":"https://api.github.com/users/zendframework/gists{/gist_id}","starred_url":"https://api.github.com/users/zendframework/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zendframework/subscriptions","organizations_url":"https://api.github.com/users/zendframework/orgs","repos_url":"https://api.github.com/users/zendframework/repos","events_url":"https://api.github.com/users/zendframework/events{/privacy}","received_events_url":"https://api.github.com/users/zendframework/received_events","type":"Organization","site_admin":false},"repo":{"id":55622913,"name":"zf3-web","full_name":"zendframework/zf3-web","owner":{"login":"zendframework","id":296074,"avatar_url":"https://avatars2.githubusercontent.com/u/296074?v=4","gravatar_id":"","url":"https://api.github.com/users/zendframework","html_url":"https://github.com/zendframework","followers_url":"https://api.github.com/users/zendframework/followers","following_url":"https://api.github.com/users/zendframework/following{/other_user}","gists_url":"https://api.github.com/users/zendframework/gists{/gist_id}","starred_url":"https://api.github.com/users/zendframework/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zendframework/subscriptions","organizations_url":"https://api.github.com/users/zendframework/orgs","repos_url":"https://api.github.com/users/zendframework/repos","events_url":"https://api.github.com/users/zendframework/events{/privacy}","received_events_url":"https://api.github.com/users/zendframework/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zendframework/zf3-web","description":"Website of Zend Framework 3","fork":false,"url":"https://api.github.com/repos/zendframework/zf3-web","forks_url":"https://api.github.com/repos/zendframework/zf3-web/forks","keys_url":"https://api.github.com/repos/zendframework/zf3-web/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zendframework/zf3-web/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zendframework/zf3-web/teams","hooks_url":"https://api.github.com/repos/zendframework/zf3-web/hooks","issue_events_url":"https://api.github.com/repos/zendframework/zf3-web/issues/events{/number}","events_url":"https://api.github.com/repos/zendframework/zf3-web/events","assignees_url":"https://api.github.com/repos/zendframework/zf3-web/assignees{/user}","branches_url":"https://api.github.com/repos/zendframework/zf3-web/branches{/branch}","tags_url":"https://api.github.com/repos/zendframework/zf3-web/tags","blobs_url":"https://api.github.com/repos/zendframework/zf3-web/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zendframework/zf3-web/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zendframework/zf3-web/git/refs{/sha}","trees_url":"https://api.github.com/repos/zendframework/zf3-web/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zendframework/zf3-web/statuses/{sha}","languages_url":"https://api.github.com/repos/zendframework/zf3-web/languages","stargazers_url":"https://api.github.com/repos/zendframework/zf3-web/stargazers","contributors_url":"https://api.github.com/repos/zendframework/zf3-web/contributors","subscribers_url":"https://api.github.com/repos/zendframework/zf3-web/subscribers","subscription_url":"https://api.github.com/repos/zendframework/zf3-web/subscription","commits_url":"https://api.github.com/repos/zendframework/zf3-web/commits{/sha}","git_commits_url":"https://api.github.com/repos/zendframework/zf3-web/git/commits{/sha}","comments_url":"https://api.github.com/repos/zendframework/zf3-web/comments{/number}","issue_comment_url":"https://api.github.com/repos/zendframework/zf3-web/issues/comments{/number}","contents_url":"https://api.github.com/repos/zendframework/zf3-web/contents/{+path}","compare_url":"https://api.github.com/repos/zendframework/zf3-web/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zendframework/zf3-web/merges","archive_url":"https://api.github.com/repos/zendframework/zf3-web/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zendframework/zf3-web/downloads","issues_url":"https://api.github.com/repos/zendframework/zf3-web/issues{/number}","pulls_url":"https://api.github.com/repos/zendframework/zf3-web/pulls{/number}","milestones_url":"https://api.github.com/repos/zendframework/zf3-web/milestones{/number}","notifications_url":"https://api.github.com/repos/zendframework/zf3-web/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zendframework/zf3-web/labels{/name}","releases_url":"https://api.github.com/repos/zendframework/zf3-web/releases{/id}","deployments_url":"https://api.github.com/repos/zendframework/zf3-web/deployments","created_at":"2016-04-06T16:36:55Z","updated_at":"2017-08-09T06:29:56Z","pushed_at":"2017-09-12T13:20:48Z","git_url":"git://github.com/zendframework/zf3-web.git","ssh_url":"git@github.com:zendframework/zf3-web.git","clone_url":"https://github.com/zendframework/zf3-web.git","svn_url":"https://github.com/zendframework/zf3-web","homepage":"http://framework.zend.com","size":31855,"stargazers_count":27,"watchers_count":27,"language":"PHP","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":26,"mirror_url":null,"open_issues_count":7,"forks":26,"open_issues":7,"watchers":27,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/zendframework/zf3-web/pulls/72"},"html":{"href":"https://github.com/zendframework/zf3-web/pull/72"},"issue":{"href":"https://api.github.com/repos/zendframework/zf3-web/issues/72"},"comments":{"href":"https://api.github.com/repos/zendframework/zf3-web/issues/72/comments"},"review_comments":{"href":"https://api.github.com/repos/zendframework/zf3-web/pulls/72/comments"},"review_comment":{"href":"https://api.github.com/repos/zendframework/zf3-web/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zendframework/zf3-web/pulls/72/commits"},"statuses":{"href":"https://api.github.com/repos/zendframework/zf3-web/statuses/cbe0c67b43fa025c10ea7cb433d72b436a6f2df7"}},"author_association":"OWNER"}}
{"actor":{"display_login":"froschdesign"}}