{"id":2445,"date":"2025-03-24T08:47:15","date_gmt":"2025-03-23T23:47:15","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=2445"},"modified":"2025-03-24T08:47:46","modified_gmt":"2025-03-23T23:47:46","slug":"%e3%80%90%e4%bf%9d%e5%ad%98%e7%89%88%e3%80%91php%e3%82%a8%e3%83%b3%e3%82%b8%e3%83%8b%e3%82%a2%e3%81%ae%e3%81%9f%e3%82%81%e3%81%ae%e3%83%a2%e3%83%8e%e3%83%ad%e3%82%b0%e5%ae%8c%e5%85%a8%e3%82%ac","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=2445","title":{"rendered":"\u3010\u4fdd\u5b58\u7248\u3011PHP\u30a8\u30f3\u30b8\u30cb\u30a2\u306e\u305f\u3081\u306e\u30e2\u30ce\u30ed\u30b0\u5b8c\u5168\u30ac\u30a4\u30c92024\uff1a\u5b9f\u8df5\u7684\u306a\u8a2d\u5b9a\u304b\u3089\u904b\u7528\u307e\u3067"},"content":{"rendered":"\n<div class=\"toc\"><br \/>\n<b>Warning<\/b>:  Undefined array key \"is_admin\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>116<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_category_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>121<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>128<\/b><br \/>\n    <div id=\"toc_container\" class=\"sgb-toc--bullets js-smooth-scroll\" data-dialog-title=\"\u76ee\u6b21\">\n      <p class=\"toc_title\">\u76ee\u6b21 <\/p>\n      <ul class=\"toc_list\">  <li class=\"first\">    <a href=\"#i-0\">Monolog\u3068\u306f\uff1aPHP\u3067\u6700\u3082\u4f7f\u308f\u308c\u3066\u3044\u308b\u30ed\u30b0\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u5b9f\u529b<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">Composer\u3067\u7ba1\u7406\u3055\u308c\u308b\u4fe1\u983c\u6027\u306e\u9ad8\u3044\u30ed\u30b0\u30b7\u30b9\u30c6\u30e0<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-2\">PSR-3\u306b\u6e96\u62e0\u3057\u305f\u6a19\u6e96\u7684\u306a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-3\">Monolog\u3092\u5c0e\u5165\u3059\u308b\u5177\u4f53\u7684\u306a\u624b\u9806<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-4\">Composer\u3092\u4f7f\u3063\u305f\u7c21\u5358\u306a\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-5\">\u57fa\u672c\u7684\u306a\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210\u3068\u89e3\u8aac<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-6\">\u5b9f\u8df5\u7684\u306a\u30ed\u30b0\u30ec\u30d9\u30eb\u306e\u4f7f\u3044\u5206\u3051<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-7\">8\u6bb5\u968e\u306e\u30ed\u30b0\u30ec\u30d9\u30eb\u3068\u305d\u306e\u4f7f\u7528\u30b7\u30fc\u30f3<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-8\">\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u5fdc\u3058\u305f\u30ed\u30b0\u30ec\u30d9\u30eb\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-9\">\u30ed\u30b0\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8ce2\u3044\u9078\u629e\u3068\u8a2d\u5b9a<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-10\">\u76ee\u7684\u5225\u304a\u3059\u3059\u3081\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u6bd4\u8f03<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-11\">\u8907\u6570\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u9023\u643a\u306b\u3088\u308b\u67d4\u8edf\u306a\u904b\u7528<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-12\">Monolog\u306b\u3088\u308b\u52b9\u679c\u7684\u306a\u30a8\u30e9\u30fc\u76e3\u8996<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-13\">\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-14\">Slack\u3068\u30e1\u30fc\u30eb\u3068\u306e\u9023\u643a\u306b\u3088\u308b\u5373\u6642\u901a\u77e5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-15\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u30ed\u30b0\u8a2d\u5b9a<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-16\">\u975e\u540c\u671f\u30ed\u30b0\u51e6\u7406\u306b\u3088\u308b\u8ca0\u8377\u8efd\u6e1b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-17\">\u30ed\u30b0\u30ed\u30fc\u30c6\u30fc\u30b7\u30e7\u30f3\u306e\u6700\u9069\u306a\u8a2d\u5b9a\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-18\">\u5b9f\u969b\u306e\u904b\u7528\u3067\u4f7f\u3048\u308bMonolog\u306e\u30d2\u30f3\u30c8\u96c6<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-19\">\u30c7\u30d0\u30c3\u30b0\u6642\u306b\u4f7f\u3048\u308b\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\u30fc\u306e\u6d3b\u7528<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-20\">\u672c\u756a\u74b0\u5883\u3067\u306e\u5b89\u5168\u306a\u30ed\u30b0\u904b\u7528\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li><\/ul>\n      <a href=\"#\" class=\"sgb-toc-button js-toc-button\" rel=\"nofollow\" data-open-dialog=\"true\"><i class=\"fa fa-list\"><\/i><span class=\"sgb-toc-button__text\">\u76ee\u6b21\u3078<\/span><\/a>\n    <\/div><\/div><h2 class=\"wp-block-heading\" id=\"i-0\">Monolog\u3068\u306f\uff1aPHP\u3067\u6700\u3082\u4f7f\u308f\u308c\u3066\u3044\u308b\u30ed\u30b0\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u5b9f\u529b<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">Composer\u3067\u7ba1\u7406\u3055\u308c\u308b\u4fe1\u983c\u6027\u306e\u9ad8\u3044\u30ed\u30b0\u30b7\u30b9\u30c6\u30e0<\/h3>\n\n\n\n<p>Monolog\u306f\u3001PHP\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u304a\u3044\u3066\u6700\u3082\u5e83\u304f\u4f7f\u7528\u3055\u308c\u3066\u3044\u308b\u3001\u4fe1\u983c\u6027\u306e\u9ad8\u3044\u30ed\u30b0\u7ba1\u7406\u30e9\u30a4\u30d6\u30e9\u30ea\u3067\u3059\u3002GitHub\u306749,000\u4ee5\u4e0a\u306e\u30b9\u30bf\u30fc\u3092\u7372\u5f97\u3057\u3001Laravel\u3001Symfony\u306a\u3069\u306e\u4e3b\u8981\u306aPHP\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3067\u3082\u6a19\u6e96\u306e\u30ed\u30b0\u30e9\u30a4\u30d6\u30e9\u30ea\u3068\u3057\u3066\u63a1\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p>Composer\u3092\u901a\u3058\u3066\u7c21\u5358\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u304d\u3001\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3067\u5c0e\u5165\u304c\u53ef\u80fd\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">composer require monolog\/monolog<\/pre>\n\n\n\n<p>\u57fa\u672c\u7684\u306a\u4f7f\u7528\u4f8b\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\/\/ Monolog\u306e\u57fa\u672c\u7684\u306a\u4f7f\u7528\u4f8b\nuse Monolog\\Level;\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\n\n\/\/ \u30ed\u30ac\u30fc\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u4f5c\u6210\n$logger = new Logger('my_app');\n\n\/\/ \u30ed\u30b0\u306e\u51fa\u529b\u5148\u3092\u8a2d\u5b9a\n$logger-&gt;pushHandler(new StreamHandler(__DIR__.'\/logs\/app.log', Level::Debug));\n\n\/\/ \u69d8\u3005\u306a\u30ec\u30d9\u30eb\u3067\u30ed\u30b0\u3092\u51fa\u529b\n$logger-&gt;info('\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304c\u8d77\u52d5\u3057\u307e\u3057\u305f');\n$logger-&gt;warning('\u30e1\u30e2\u30ea\u4f7f\u7528\u7387\u304c80%\u3092\u8d85\u3048\u3066\u3044\u307e\u3059');\n$logger-&gt;error('\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u63a5\u7d9a\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f');<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">PSR-3\u306b\u6e96\u62e0\u3057\u305f\u6a19\u6e96\u7684\u306a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9<\/h3>\n\n\n\n<p>Monolog\u306fPSR-3\uff08PHP\u6a19\u6e96\u52e7\u544a-3\uff09\u306b\u6e96\u62e0\u3057\u3066\u304a\u308a\u3001\u3053\u308c\u306b\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u91cd\u8981\u306a\u610f\u7fa9\u304c\u3042\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4e92\u63db\u6027\u306e\u4fdd\u8a3c<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4ed6\u306ePSR-3\u6e96\u62e0\u306e\u30ed\u30b0\u30e9\u30a4\u30d6\u30e9\u30ea\u3068\u306e\u4e92\u63db\u6027<\/li>\n\n\n\n<li>\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3084\u30e9\u30a4\u30d6\u30e9\u30ea\u9593\u3067\u306e\u4e00\u8cab\u3057\u305f\u4f7f\u7528\u304c\u53ef\u80fd<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6a19\u6e96\u5316\u3055\u308c\u305f\u30ed\u30b0\u30ec\u30d9\u30eb<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY<\/li>\n\n\n\n<li>\u4e00\u822c\u7684\u306a\u30ed\u30b0\u57fa\u6e96\u306b\u5f93\u3063\u305f8\u6bb5\u968e\u306e\u30ec\u30d9\u30eb\u5206\u3051<\/li>\n<\/ul>\n\n\n\n<p>\u4ee5\u4e0b\u306f\u3001PSR-3\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3092\u6d3b\u7528\u3057\u305f\u5b9f\u88c5\u4f8b\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Psr\\Log\\LoggerInterface;\n\nclass UserService\n{\n    private LoggerInterface $logger;\n\n    public function __construct(LoggerInterface $logger)\n    {\n        $this-&gt;logger = $logger;\n    }\n\n    public function createUser(array $userData): bool\n    {\n        try {\n            \/\/ \u30e6\u30fc\u30b6\u30fc\u4f5c\u6210\u51e6\u7406\n            $this-&gt;logger-&gt;info('\u65b0\u898f\u30e6\u30fc\u30b6\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f', ['user' =&gt; $userData['email']]);\n            return true;\n        } catch (\\Exception $e) {\n            $this-&gt;logger-&gt;error('\u30e6\u30fc\u30b6\u30fc\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f', [\n                'error' =&gt; $e-&gt;getMessage(),\n                'user' =&gt; $userData['email']\n            ]);\n            return false;\n        }\n    }\n}<\/pre>\n\n\n\n<p>Monolog\u306e\u7279\u7b46\u3059\u3079\u304d\u6a5f\u80fd\uff1a<\/p>\n\n\n<div id=\"id-ddfc80e9-2ca6-451e-b867-df7bfb838483\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u6a5f\u80fd<\/th><th>\u8aac\u660e<\/th><\/tr><\/thead><tbody><tr><td>\u67d4\u8edf\u306a\u30cf\u30f3\u30c9\u30e9\u30fc\u30b7\u30b9\u30c6\u30e0<\/td><td>\u30d5\u30a1\u30a4\u30eb\u3001\u30e1\u30fc\u30eb\u3001Slack\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306a\u3069\u591a\u69d8\u306a\u51fa\u529b\u5148\u306b\u5bfe\u5fdc<\/td><\/tr><tr><td>\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\u30fc<\/td><td>JSON\u3001HTML\u3001\u30e9\u30a4\u30f3\u5f62\u5f0f\u306a\u3069\u3001\u69d8\u3005\u306a\u51fa\u529b\u5f62\u5f0f\u3092\u30b5\u30dd\u30fc\u30c8<\/td><\/tr><tr><td>\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc<\/td><td>\u30ed\u30b0\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u52a0\u5de5\u3084\u4ed8\u52a0\u60c5\u5831\u306e\u8ffd\u52a0\u304c\u53ef\u80fd<\/td><\/tr><tr><td>\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0<\/td><td>\u30e1\u30e2\u30ea\u52b9\u7387\u3068\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u8a2d\u8a08<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<p>\u3053\u308c\u3089\u306e\u6a5f\u80fd\u306b\u3088\u308a\u3001Monolog\u306f\u958b\u767a\u74b0\u5883\u304b\u3089\u672c\u756a\u74b0\u5883\u307e\u3067\u3001\u3042\u3089\u3086\u308b\u5834\u9762\u3067\u6d3b\u7528\u3067\u304d\u308b\u5f37\u529b\u306a\u30ed\u30b0\u7ba1\u7406\u30bd\u30ea\u30e5\u30fc\u30b7\u30e7\u30f3\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u5f8c\u7d9a\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u6a5f\u80fd\u306e\u5177\u4f53\u7684\u306a\u6d3b\u7528\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8a73\u3057\u304f\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-3\">Monolog\u3092\u5c0e\u5165\u3059\u308b\u5177\u4f53\u7684\u306a\u624b\u9806<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-4\">Composer\u3092\u4f7f\u3063\u305f\u7c21\u5358\u306a\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65b9\u6cd5<\/h3>\n\n\n\n<p>Monolog\u306e\u5c0e\u5165\u306f\u3001\u4ee5\u4e0b\u306e\u624b\u9806\u3067\u9032\u3081\u3066\u3044\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Composer\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u78ba\u8a8d<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Composer\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\ncomposer --version\n\n# \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u4f5c\u6210\u3068\u79fb\u52d5\nmkdir my-logging-project\ncd my-logging-project\n\n# Composer\u306e\u521d\u671f\u5316\uff08\u307e\u3060composer.json\u304c\u306a\u3044\u5834\u5408\uff09\ncomposer init --require=\"monolog\/monolog:^3.0\"<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Monolog\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u65e2\u5b58\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3078\u306e\u8ffd\u52a0\u306e\u5834\u5408\ncomposer require monolog\/monolog\n\n# \u7279\u5b9a\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u6307\u5b9a\u3059\u308b\u5834\u5408\ncomposer require monolog\/monolog:^3.0<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u69cb\u9020\u306e\u6e96\u5099<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ed\u30b0\u4fdd\u5b58\u7528\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u4f5c\u6210\nmkdir logs\nchmod 777 logs  # \u66f8\u304d\u8fbc\u307f\u6a29\u9650\u306e\u4ed8\u4e0e\uff08\u672c\u756a\u74b0\u5883\u3067\u306f\u3088\u308a\u9069\u5207\u306a\u6a29\u9650\u8a2d\u5b9a\u3092\u63a8\u5968\uff09<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">\u57fa\u672c\u7684\u306a\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210\u3068\u89e3\u8aac<\/h3>\n\n\n\n<p>\u57fa\u672c\u7684\u306a\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u4f8b\u3092\u793a\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\/\/ config\/logging.php\n\nreturn [\n    'default' =&gt; [\n        'type' =&gt; 'single',\n        'path' =&gt; __DIR__.'\/..\/logs\/app.log',\n        'level' =&gt; 'debug',\n        'days' =&gt; 14,\n    ],\n    'error' =&gt; [\n        'type' =&gt; 'daily',\n        'path' =&gt; __DIR__.'\/..\/logs\/error.log',\n        'level' =&gt; 'error',\n        'days' =&gt; 30,\n    ],\n    'slack' =&gt; [\n        'type' =&gt; 'slack',\n        'url' =&gt; 'https:\/\/hooks.slack.com\/services\/YOUR\/WEBHOOK\/URL',\n        'channel' =&gt; '#errors',\n        'username' =&gt; 'MonologBot',\n        'level' =&gt; 'critical',\n    ],\n];<\/pre>\n\n\n\n<p>\u5b9f\u969b\u306e\u5b9f\u88c5\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\/\/ src\/Logger\/LoggerFactory.php\n\nnamespace App\\Logger;\n\nuse Monolog\\Level;\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Handler\\RotatingFileHandler;\nuse Monolog\\Handler\\SlackWebhookHandler;\nuse Monolog\\Formatter\\LineFormatter;\n\nclass LoggerFactory\n{\n    private array $config;\n\n    public function __construct(array $config)\n    {\n        $this-&gt;config = $config;\n    }\n\n    public function createLogger(string $name): Logger\n    {\n        $logger = new Logger($name);\n\n        \/\/ \u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u30ed\u30b0\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u8ffd\u52a0\n        if (isset($this-&gt;config['default'])) {\n            $handler = new StreamHandler(\n                $this-&gt;config['default']['path'],\n                $this-&gt;getLogLevel($this-&gt;config['default']['level'])\n            );\n            $handler-&gt;setFormatter($this-&gt;createFormatter());\n            $logger-&gt;pushHandler($handler);\n        }\n\n        \/\/ \u30a8\u30e9\u30fc\u30ed\u30b0\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u8ffd\u52a0\n        if (isset($this-&gt;config['error'])) {\n            $handler = new RotatingFileHandler(\n                $this-&gt;config['error']['path'],\n                $this-&gt;config['error']['days'],\n                $this-&gt;getLogLevel($this-&gt;config['error']['level'])\n            );\n            $handler-&gt;setFormatter($this-&gt;createFormatter());\n            $logger-&gt;pushHandler($handler);\n        }\n\n        \/\/ Slack\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u8ffd\u52a0\n        if (isset($this-&gt;config['slack'])) {\n            $handler = new SlackWebhookHandler(\n                $this-&gt;config['slack']['url'],\n                $this-&gt;config['slack']['channel'],\n                $this-&gt;config['slack']['username'],\n                true,\n                null,\n                false,\n                true,\n                $this-&gt;getLogLevel($this-&gt;config['slack']['level'])\n            );\n            $logger-&gt;pushHandler($handler);\n        }\n\n        return $logger;\n    }\n\n    private function createFormatter(): LineFormatter\n    {\n        \/\/ \u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u3001\u30ed\u30b0\u30ec\u30d9\u30eb\u3001\u30e1\u30c3\u30bb\u30fc\u30b8\u3001\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3092\u542b\u3080\u6a19\u6e96\u7684\u306a\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\n        return new LineFormatter(\n            \"[%datetime%] %channel%.%level_name%: %message% %context% %extra%\\n\",\n            \"Y-m-d H:i:s\"\n        );\n    }\n\n    private function getLogLevel(string $level): Level\n    {\n        return match (strtolower($level)) {\n            'debug' =&gt; Level::Debug,\n            'info' =&gt; Level::Info,\n            'notice' =&gt; Level::Notice,\n            'warning' =&gt; Level::Warning,\n            'error' =&gt; Level::Error,\n            'critical' =&gt; Level::Critical,\n            'alert' =&gt; Level::Alert,\n            'emergency' =&gt; Level::Emergency,\n            default =&gt; Level::Debug,\n        };\n    }\n}<\/pre>\n\n\n\n<p>\u4f7f\u7528\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\/\/ index.php\n\nrequire 'vendor\/autoload.php';\n\n$config = require 'config\/logging.php';\n$loggerFactory = new App\\Logger\\LoggerFactory($config);\n$logger = $loggerFactory-&gt;createLogger('app');\n\n\/\/ \u30ed\u30b0\u306e\u51fa\u529b\n$logger-&gt;info('\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304c\u8d77\u52d5\u3057\u307e\u3057\u305f');\n$logger-&gt;error('\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u63a5\u7d9a\u30a8\u30e9\u30fc', ['db_host' =&gt; 'localhost']);\n\ntry {\n    \/\/ \u4f55\u3089\u304b\u306e\u51e6\u7406\n    throw new \\Exception('\u30c6\u30b9\u30c8\u30a8\u30e9\u30fc');\n} catch (\\Exception $e) {\n    $logger-&gt;critical('\u91cd\u5927\u306a\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f', [\n        'error' =&gt; $e-&gt;getMessage(),\n        'file' =&gt; $e-&gt;getFile(),\n        'line' =&gt; $e-&gt;getLine()\n    ]);\n}<\/pre>\n\n\n\n<p>\u3088\u304f\u3042\u308b\u30c8\u30e9\u30d6\u30eb\u3068\u89e3\u6c7a\u65b9\u6cd5\uff1a<\/p>\n\n\n<div id=\"id-e4e3bb4a-aaa2-42f1-89c2-011ac34f6b82\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u30c8\u30e9\u30d6\u30eb<\/th><th>\u539f\u56e0<\/th><th>\u89e3\u6c7a\u65b9\u6cd5<\/th><\/tr><\/thead><tbody><tr><td>\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u306b\u66f8\u304d\u8fbc\u3081\u306a\u3044<\/td><td>\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u306e\u554f\u984c<\/td><td><code>chmod<\/code>\u3067\u30ed\u30b0\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u9069\u5207\u306a\u6a29\u9650\u3092\u4ed8\u4e0e<\/td><\/tr><tr><td>\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u304c\u5897\u5927<\/td><td>\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u8a2d\u5b9a\u306e\u554f\u984c<\/td><td><code>BufferHandler<\/code>\u3092\u4f7f\u7528\u3057\u3066\u9069\u5207\u306b\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0<\/td><\/tr><tr><td>\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u304c\u7570\u306a\u308b<\/td><td>PHP\u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u8a2d\u5b9a<\/td><td><code>date.timezone<\/code>\u3092php.ini\u3067\u8a2d\u5b9a<\/td><\/tr><tr><td>\u6587\u5b57\u5316\u3051\u304c\u767a\u751f<\/td><td>\u6587\u5b57\u30a8\u30f3\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u306e\u4e0d\u4e00\u81f4<\/td><td>LineFormatter\u3067\u9069\u5207\u306a\u30a8\u30f3\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u3092\u6307\u5b9a<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<p>\u4ee5\u4e0a\u306e\u8a2d\u5b9a\u3068\u5b9f\u88c5\u306b\u3088\u308a\u3001\u5805\u7262\u306a\u30ed\u30b0\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306e\u57fa\u76e4\u304c\u6574\u3044\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u57fa\u672c\u8a2d\u5b9a\u3092\u6d3b\u7528\u3057\u305f\u5b9f\u8df5\u7684\u306a\u30ed\u30b0\u30ec\u30d9\u30eb\u306e\u4f7f\u3044\u5206\u3051\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-6\">\u5b9f\u8df5\u7684\u306a\u30ed\u30b0\u30ec\u30d9\u30eb\u306e\u4f7f\u3044\u5206\u3051<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-7\">8\u6bb5\u968e\u306e\u30ed\u30b0\u30ec\u30d9\u30eb\u3068\u305d\u306e\u4f7f\u7528\u30b7\u30fc\u30f3<\/h3>\n\n\n\n<p>Monolog\u306f\u3001PSR-3\u306b\u6e96\u62e0\u3057\u305f8\u6bb5\u968e\u306e\u30ed\u30b0\u30ec\u30d9\u30eb\u3092\u63d0\u4f9b\u3057\u3066\u3044\u307e\u3059\u3002\u5404\u30ec\u30d9\u30eb\u306e\u9069\u5207\u306a\u4f7f\u7528\u65b9\u6cd5\u3092\u5177\u4f53\u4f8b\u3068\u5171\u306b\u89e3\u8aac\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Level;\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\n\n$logger = new Logger('app');\n$logger-&gt;pushHandler(new StreamHandler(__DIR__.'\/logs\/app.log', Level::Debug));<\/pre>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>DEBUG<\/strong> (Level::Debug)<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ \u958b\u767a\u6642\u306e\u30c7\u30d0\u30c3\u30b0\u60c5\u5831\n   $logger-&gt;debug('SQL\u30af\u30a8\u30ea\u306e\u5b9f\u884c\u6642\u9593', [\n       'query' =&gt; 'SELECT * FROM users',\n       'execution_time' =&gt; 0.023\n   ]);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5909\u6570\u306e\u5024\u306e\u78ba\u8a8d<\/li>\n\n\n\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6e2c\u5b9a\u7d50\u679c<\/li>\n\n\n\n<li>\u958b\u767a\u74b0\u5883\u3067\u306e\u8a73\u7d30\u306a\u30c8\u30ec\u30fc\u30b9\u60c5\u5831<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>INFO<\/strong> (Level::Info)<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ \u6b63\u5e38\u7cfb\u306e\u51e6\u7406\u8a18\u9332\n   $logger-&gt;info('\u65b0\u898f\u30e6\u30fc\u30b6\u30fc\u767b\u9332\u5b8c\u4e86', [\n       'user_id' =&gt; $user-&gt;id,\n       'email' =&gt; $user-&gt;email\n   ]);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30e6\u30fc\u30b6\u30fc\u306e\u30a2\u30af\u30b7\u30e7\u30f3\u8a18\u9332<\/li>\n\n\n\n<li>\u30d0\u30c3\u30c1\u51e6\u7406\u306e\u958b\u59cb\/\u5b8c\u4e86<\/li>\n\n\n\n<li>\u91cd\u8981\u306a\u51e6\u7406\u306e\u30de\u30a4\u30eb\u30b9\u30c8\u30fc\u30f3<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>NOTICE<\/strong> (Level::Notice)<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ \u901a\u5e38\u3068\u306f\u7570\u306a\u308b\u6ce8\u76ee\u3059\u3079\u304d\u4e8b\u8c61\n   $logger-&gt;notice('API\u547c\u3073\u51fa\u3057\u306e\u9045\u5ef6\u3092\u691c\u77e5', [\n       'api' =&gt; 'payment_service',\n       'response_time' =&gt; 2.5\n   ]);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u4f4e\u4e0b\u306e\u5146\u5019<\/li>\n\n\n\n<li>\u8a2d\u5b9a\u5024\u306e\u81ea\u52d5\u5909\u66f4<\/li>\n\n\n\n<li>\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u81ea\u52d5\u66f4\u65b0<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>WARNING<\/strong> (Level::Warning)<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ \u6f5c\u5728\u7684\u306a\u554f\u984c\u306e\u8b66\u544a\n   $logger-&gt;warning('\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u6709\u52b9\u671f\u9650\u5207\u308c', [\n       'session_id' =&gt; $sessionId,\n       'user_ip' =&gt; $userIp\n   ]);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u975e\u63a8\u5968\u6a5f\u80fd\u306e\u4f7f\u7528<\/li>\n\n\n\n<li>\u30ea\u30bd\u30fc\u30b9\u4f7f\u7528\u91cf\u306e\u95be\u5024\u8d85\u904e<\/li>\n\n\n\n<li>\u518d\u8a66\u884c\u3092\u4f34\u3046\u51e6\u7406<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>ERROR<\/strong> (Level::Error)<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\n   $logger-&gt;error('\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u63a5\u7d9a\u30a8\u30e9\u30fc', [\n       'exception' =&gt; $e-&gt;getMessage(),\n       'trace' =&gt; $e-&gt;getTraceAsString()\n   ]);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4f8b\u5916\u306e\u767a\u751f<\/li>\n\n\n\n<li>API\u901a\u4fe1\u306e\u5931\u6557<\/li>\n\n\n\n<li>\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>CRITICAL<\/strong> (Level::Critical)<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ \u30b7\u30b9\u30c6\u30e0\u306e\u91cd\u5927\u306a\u554f\u984c\n   $logger-&gt;critical('\u30b9\u30c8\u30ec\u30fc\u30b8\u5bb9\u91cf\u304c\u5371\u6a5f\u7684\u72b6\u6cc1', [\n       'free_space' =&gt; $freeSpace,\n       'required_space' =&gt; $requiredSpace\n   ]);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b5\u30fc\u30d3\u30b9\u505c\u6b62\u306e\u53ef\u80fd\u6027\u304c\u3042\u308b\u554f\u984c<\/li>\n\n\n\n<li>\u6df1\u523b\u306a\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u554f\u984c<\/li>\n\n\n\n<li>\u30af\u30ea\u30c6\u30a3\u30ab\u30eb\u306a\u30ea\u30bd\u30fc\u30b9\u4e0d\u8db3<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>ALERT<\/strong> (Level::Alert)<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ \u5373\u6642\u5bfe\u5fdc\u304c\u5fc5\u8981\u306a\u554f\u984c\n   $logger-&gt;alert('\u8907\u6570\u306e\u30de\u30b9\u30bf\u30fc\u30c7\u30fc\u30bf\u66f4\u65b0\u304c\u5931\u6557', [\n       'failed_tables' =&gt; $failedTables,\n       'impact' =&gt; '\u30b5\u30fc\u30d3\u30b9\u5168\u4f53\u306b\u5f71\u97ff\u306e\u53ef\u80fd\u6027\u3042\u308a'\n   ]);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b5\u30fc\u30d3\u30b9\u306e\u4e3b\u8981\u6a5f\u80fd\u306e\u505c\u6b62<\/li>\n\n\n\n<li>\u30c7\u30fc\u30bf\u6574\u5408\u6027\u306e\u91cd\u5927\u306a\u7834\u640d<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30a4\u30f3\u30b7\u30c7\u30f3\u30c8<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>EMERGENCY<\/strong> (Level::Emergency)<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ \u30b7\u30b9\u30c6\u30e0\u505c\u6b62\u30ec\u30d9\u30eb\u306e\u81f4\u547d\u7684\u554f\u984c\n   $logger-&gt;emergency('\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u304c\u30c0\u30a6\u30f3', [\n       'last_error' =&gt; $lastError,\n       'system_status' =&gt; $systemStatus\n   ]);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u306e\u505c\u6b62<\/li>\n\n\n\n<li>\u91cd\u5927\u306a\u30c7\u30fc\u30bf\u640d\u5931<\/li>\n\n\n\n<li>\u81f4\u547d\u7684\u306a\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u4fb5\u5bb3<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-8\">\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u5fdc\u3058\u305f\u30ed\u30b0\u30ec\u30d9\u30eb\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba<\/h3>\n\n\n\n<p>\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u7279\u6027\u306b\u5fdc\u3058\u3066\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u30ed\u30b0\u30ec\u30d9\u30eb\u3092\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\/\/ \u30ab\u30b9\u30bf\u30e0\u30ed\u30b0\u30ec\u30d9\u30eb\u306e\u5b9a\u7fa9\nclass CustomLogger extends Logger\n{\n    \/\/ \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u56fa\u6709\u306e\u30ed\u30b0\u30ec\u30d9\u30eb\u5b9a\u6570\n    public const AUDIT = 250;\n    public const BUSINESS = 300;\n\n    public function audit(string $message, array $context = []): void\n    {\n        $this-&gt;addRecord(static::AUDIT, $message, $context);\n    }\n\n    public function business(string $message, array $context = []): void\n    {\n        $this-&gt;addRecord(static::BUSINESS, $message, $context);\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$logger = new CustomLogger('app');\n$logger-&gt;audit('\u30e6\u30fc\u30b6\u30fc\u304c\u6a5f\u5bc6\u30c7\u30fc\u30bf\u306b\u30a2\u30af\u30bb\u30b9', [\n    'user_id' =&gt; $userId,\n    'accessed_data' =&gt; $dataId\n]);<\/pre>\n\n\n\n<p>\u52b9\u679c\u7684\u306a\u30ed\u30b0\u30ec\u30d9\u30eb\u8a2d\u5b9a\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\uff1a<\/p>\n\n\n<div id=\"id-83a6e304-1112-452c-8ffe-3021a3eccad2\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u74b0\u5883<\/th><th>\u63a8\u5968\u6700\u5c0f\u30ed\u30b0\u30ec\u30d9\u30eb<\/th><th>\u7406\u7531<\/th><\/tr><\/thead><tbody><tr><td>\u958b\u767a<\/td><td>Debug<\/td><td>\u8a73\u7d30\u306a\u30c7\u30d0\u30c3\u30b0\u60c5\u5831\u304c\u5fc5\u8981<\/td><\/tr><tr><td>\u30c6\u30b9\u30c8<\/td><td>Info<\/td><td>\u6a5f\u80fd\u30c6\u30b9\u30c8\u306e\u691c\u8a3c\u306b\u5fc5\u8981\u306a\u60c5\u5831<\/td><\/tr><tr><td>\u30b9\u30c6\u30fc\u30b8\u30f3\u30b0<\/td><td>Notice<\/td><td>\u672c\u756a\u306b\u8fd1\u3044\u74b0\u5883\u3067\u306e\u7570\u5e38\u691c\u77e5<\/td><\/tr><tr><td>\u672c\u756a<\/td><td>Warning<\/td><td>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3068\u30b9\u30c8\u30ec\u30fc\u30b8\u306e\u6700\u9069\u5316<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<p>\u307e\u305f\u3001\u7279\u5b9a\u306e\u72b6\u6cc1\u306b\u5fdc\u3058\u3066\u8907\u6570\u306e\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u4f7f\u3044\u5206\u3051\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u67d4\u8edf\u306a\u30ed\u30b0\u7ba1\u7406\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\/\/ \u74b0\u5883\u306b\u5fdc\u3058\u305f\u30ed\u30b0\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8a2d\u5b9a\n$logger = new Logger('app');\n\n\/\/ \u5168\u3066\u306e\u30ed\u30b0\u3092\u30d5\u30a1\u30a4\u30eb\u306b\u51fa\u529b\n$logger-&gt;pushHandler(new StreamHandler(\n    __DIR__.'\/logs\/all.log',\n    Level::Debug\n));\n\n\/\/ \u30a8\u30e9\u30fc\u4ee5\u4e0a\u3092\u5225\u30d5\u30a1\u30a4\u30eb\u306b\u51fa\u529b\n$logger-&gt;pushHandler(new StreamHandler(\n    __DIR__.'\/logs\/error.log',\n    Level::Error\n));\n\n\/\/ \u30af\u30ea\u30c6\u30a3\u30ab\u30eb\u4ee5\u4e0a\u3092Slack\u306b\u901a\u77e5\n$logger-&gt;pushHandler(new SlackWebhookHandler(\n    'webhook_url',\n    '#alerts',\n    'MonologBot',\n    true,\n    null,\n    false,\n    true,\n    Level::Critical\n));<\/pre>\n\n\n\n<p>\u9069\u5207\u306a\u30ed\u30b0\u30ec\u30d9\u30eb\u306e\u4f7f\u3044\u5206\u3051\u306b\u3088\u308a\u3001\u30b7\u30b9\u30c6\u30e0\u306e\u76e3\u8996\u3068\u554f\u984c\u89e3\u6c7a\u304c\u52b9\u7387\u5316\u3055\u308c\u3001\u904b\u7528\u306e\u8cea\u304c\u5411\u4e0a\u3057\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u30ed\u30b0\u30ec\u30d9\u30eb\u3092\u6d3b\u7528\u3057\u305f\u5177\u4f53\u7684\u306a\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8a2d\u5b9a\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-9\">\u30ed\u30b0\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8ce2\u3044\u9078\u629e\u3068\u8a2d\u5b9a<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">\u76ee\u7684\u5225\u304a\u3059\u3059\u3081\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u6bd4\u8f03<\/h3>\n\n\n\n<p>Monolog\u306e\u5f37\u307f\u306e\u4e00\u3064\u306f\u3001\u591a\u69d8\u306a\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u63d0\u4f9b\u3057\u3066\u3044\u308b\u3053\u3068\u3067\u3059\u3002\u4e3b\u8981\u306a\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u7279\u5fb4\u3068\u4f7f\u7528\u4f8b\u3092\u89e3\u8aac\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>StreamHandler<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Level;\n\n\/\/ \u57fa\u672c\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30ed\u30b0\n$handler = new StreamHandler(\n    __DIR__.'\/logs\/app.log',\n    Level::Debug,\n    true,  \/\/ \u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u6709\u52b9\u5316\n    0666   \/\/ \u30d5\u30a1\u30a4\u30eb\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\n);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u4e00\u822c\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30ed\u30b0<\/li>\n\n\n\n<li>\u7279\u5fb4\uff1a\u30b7\u30f3\u30d7\u30eb\u3067\u78ba\u5b9f\u306a\u8a18\u9332<\/li>\n\n\n\n<li>\u6ce8\u610f\u70b9\uff1a\u30ed\u30fc\u30c6\u30fc\u30b7\u30e7\u30f3\u306a\u3057<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>RotatingFileHandler<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Handler\\RotatingFileHandler;\n\n\/\/ \u65e5\u5225\u306e\u30ed\u30b0\u30ed\u30fc\u30c6\u30fc\u30b7\u30e7\u30f3\n$handler = new RotatingFileHandler(\n    __DIR__.'\/logs\/app.log',\n    30,    \/\/ \u4fdd\u6301\u3059\u308b\u65e5\u6570\n    Level::Info,\n    true,  \/\/ \u30d5\u30a1\u30a4\u30eb\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\n    0666\n);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u9577\u671f\u904b\u7528\u3067\u306e\u8a18\u9332<\/li>\n\n\n\n<li>\u7279\u5fb4\uff1a\u81ea\u52d5\u7684\u306a\u30ed\u30b0\u30ed\u30fc\u30c6\u30fc\u30b7\u30e7\u30f3<\/li>\n\n\n\n<li>\u6ce8\u610f\u70b9\uff1a\u30c7\u30a3\u30b9\u30af\u5bb9\u91cf\u306e\u7ba1\u7406\u304c\u5fc5\u8981<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>ElasticsearchHandler<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Handler\\ElasticsearchHandler;\nuse Elasticsearch\\Client;\n\n\/\/ Elasticsearch\u3078\u306e\u8ee2\u9001\n$client = \\Elasticsearch\\ClientBuilder::create()\n    -&gt;setHosts(['localhost:9200'])\n    -&gt;build();\n\n$handler = new ElasticsearchHandler(\n    $client,\n    [\n        'index' =&gt; 'monolog',\n        'type' =&gt; '_doc',\n        'ignore_error' =&gt; false\n    ]\n);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u30ed\u30b0\u306e\u5206\u6790\u3068\u53ef\u8996\u5316<\/li>\n\n\n\n<li>\u7279\u5fb4\uff1a\u9ad8\u5ea6\u306a\u691c\u7d22\u3068\u5206\u6790\u304c\u53ef\u80fd<\/li>\n\n\n\n<li>\u6ce8\u610f\u70b9\uff1a\u30ea\u30bd\u30fc\u30b9\u6d88\u8cbb\u306b\u6ce8\u610f<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>SlackWebhookHandler<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Handler\\SlackWebhookHandler;\n\n\/\/ Slack\u3078\u306e\u901a\u77e5\n$handler = new SlackWebhookHandler(\n    'https:\/\/hooks.slack.com\/services\/YOUR\/WEBHOOK\/URL',\n    '#alerts',\n    'MonologBot',\n    true,   \/\/ \u30e1\u30f3\u30b7\u30e7\u30f3\u4ed8\u304d\n    null,   \/\/ \u30a8\u30e2\u30b8\n    false,  \/\/ \u8a73\u7d30\u8868\u793a\n    true,   \/\/ HTML\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\n    Level::Error\n);<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7528\u9014\uff1a\u5373\u6642\u901a\u77e5\u304c\u5fc5\u8981\u306a\u30a8\u30e9\u30fc<\/li>\n\n\n\n<li>\u7279\u5fb4\uff1a\u30c1\u30fc\u30e0\u5168\u4f53\u3067\u306e\u76e3\u8996\u304c\u5bb9\u6613<\/li>\n\n\n\n<li>\u6ce8\u610f\u70b9\uff1a\u901a\u77e5\u306e\u983b\u5ea6\u5236\u5fa1\u304c\u91cd\u8981<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-11\">\u8907\u6570\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u9023\u643a\u306b\u3088\u308b\u67d4\u8edf\u306a\u904b\u7528<\/h3>\n\n\n\n<p>\u5b9f\u8df5\u7684\u306a\u30ed\u30b0\u7ba1\u7406\u3067\u306f\u3001\u8907\u6570\u306e\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u52b9\u679c\u7684\u306a\u904b\u7528\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Handler\\RotatingFileHandler;\nuse Monolog\\Handler\\SlackWebhookHandler;\nuse Monolog\\Handler\\ElasticsearchHandler;\nuse Monolog\\Formatter\\JsonFormatter;\nuse Monolog\\Processor\\IntrospectionProcessor;\nuse Monolog\\Processor\\WebProcessor;\n\nclass LoggerFactory\n{\n    public static function createProductionLogger(): Logger\n    {\n        $logger = new Logger('production');\n\n        \/\/ 1. \u5168\u30ed\u30b0\u3092JSON\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3067\u8a18\u9332\n        $fileHandler = new RotatingFileHandler(\n            __DIR__.'\/logs\/app.log',\n            30,\n            Level::Debug\n        );\n        $fileHandler-&gt;setFormatter(new JsonFormatter());\n\n        \/\/ 2. \u30a8\u30e9\u30fc\u30ed\u30b0\u3092\u5225\u30d5\u30a1\u30a4\u30eb\u306b\u8a18\u9332\n        $errorHandler = new StreamHandler(\n            __DIR__.'\/logs\/error.log',\n            Level::Error\n        );\n\n        \/\/ 3. \u30af\u30ea\u30c6\u30a3\u30ab\u30eb\u30a8\u30e9\u30fc\u3092Slack\u306b\u901a\u77e5\n        $slackHandler = new SlackWebhookHandler(\n            'webhook_url',\n            '#alerts',\n            'MonologBot',\n            true,\n            null,\n            false,\n            true,\n            Level::Critical\n        );\n\n        \/\/ 4. \u5168\u30ed\u30b0\u3092Elasticsearch\u306b\u9001\u4fe1\n        $elasticsearchHandler = new ElasticsearchHandler(\n            \\Elasticsearch\\ClientBuilder::create()\n                -&gt;setHosts(['localhost:9200'])\n                -&gt;build(),\n            [\n                'index' =&gt; 'logs-'.date('Y.m.d'),\n                'type' =&gt; '_doc'\n            ]\n        );\n\n        \/\/ \u30d7\u30ed\u30bb\u30c3\u30b5\u30fc\u306e\u8ffd\u52a0\n        $logger-&gt;pushProcessor(new IntrospectionProcessor());\n        $logger-&gt;pushProcessor(new WebProcessor());\n\n        \/\/ \u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8ffd\u52a0\uff08\u512a\u5148\u9806\u4f4d\u9806\uff09\n        $logger-&gt;pushHandler($slackHandler);      \/\/ \u6700\u3082\u91cd\u8981\u306a\u901a\u77e5\n        $logger-&gt;pushHandler($errorHandler);      \/\/ \u30a8\u30e9\u30fc\u30ed\u30b0\n        $logger-&gt;pushHandler($elasticsearchHandler); \/\/ \u5206\u6790\u7528\n        $logger-&gt;pushHandler($fileHandler);       \/\/ \u5168\u30ed\u30b0\u4fdd\u5b58\n\n        return $logger;\n    }\n}<\/pre>\n\n\n\n<p>\u52b9\u679c\u7684\u306a\u30cf\u30f3\u30c9\u30e9\u30fc\u8a2d\u5b9a\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\uff1a<\/p>\n\n\n<div id=\"id-f4ee2caa-b570-4f7f-b795-9c24c1bd1b2e\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u76ee\u7684<\/th><th>\u63a8\u5968\u30cf\u30f3\u30c9\u30e9\u30fc<\/th><th>\u8a2d\u5b9a\u306e\u30dd\u30a4\u30f3\u30c8<\/th><\/tr><\/thead><tbody><tr><td>\u30c7\u30d0\u30c3\u30b0<\/td><td>StreamHandler<\/td><td>\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u6709\u52b9\u5316<\/td><\/tr><tr><td>\u76e3\u8996<\/td><td>SlackWebhookHandler<\/td><td>\u30ec\u30fc\u30c8\u5236\u9650\u306e\u8a2d\u5b9a<\/td><\/tr><tr><td>\u5206\u6790<\/td><td>ElasticsearchHandler<\/td><td>\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u8a2d\u8a08<\/td><\/tr><tr><td>\u30a2\u30fc\u30ab\u30a4\u30d6<\/td><td>RotatingFileHandler<\/td><td>\u4fdd\u6301\u671f\u9593\u306e\u6700\u9069\u5316<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<p>\u9ad8\u5ea6\u306a\u30ed\u30b0\u7ba1\u7406\u306e\u5b9f\u88c5\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\/\/ \u30ab\u30b9\u30bf\u30e0\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\u30fc\u306e\u4f5c\u6210\nclass CustomJsonFormatter extends JsonFormatter\n{\n    public function format(array $record): string\n    {\n        \/\/ \u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u8abf\u6574\n        $record['datetime'] = $record['datetime']-&gt;format('Y-m-d H:i:s.u');\n\n        \/\/ \u74b0\u5883\u60c5\u5831\u306e\u8ffd\u52a0\n        $record['environment'] = getenv('APP_ENV');\n        $record['server'] = gethostname();\n\n        return parent::format($record);\n    }\n}\n\n\/\/ \u30ab\u30b9\u30bf\u30e0\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc\u306e\u4f5c\u6210\nclass RequestContextProcessor\n{\n    public function __invoke(array $record): array\n    {\n        $record['extra']['url'] = $_SERVER['REQUEST_URI'] ?? null;\n        $record['extra']['method'] = $_SERVER['REQUEST_METHOD'] ?? null;\n        $record['extra']['client_ip'] = $_SERVER['REMOTE_ADDR'] ?? null;\n        $record['extra']['user_agent'] = $_SERVER['HTTP_USER_AGENT'] ?? null;\n\n        return $record;\n    }\n}\n\n\/\/ \u5b9f\u88c5\u4f8b\n$logger = new Logger('app');\n\n\/\/ \u30ab\u30b9\u30bf\u30e0\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\u30fc\u3068\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc\u306e\u9069\u7528\n$handler = new StreamHandler(__DIR__.'\/logs\/app.log');\n$handler-&gt;setFormatter(new CustomJsonFormatter());\n$logger-&gt;pushHandler($handler);\n$logger-&gt;pushProcessor(new RequestContextProcessor());\n\n\/\/ \u4f7f\u7528\u4f8b\ntry {\n    \/\/ \u4f55\u3089\u304b\u306e\u51e6\u7406\n    throw new \\Exception('\u30c6\u30b9\u30c8\u30a8\u30e9\u30fc');\n} catch (\\Exception $e) {\n    $logger-&gt;error('\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f', [\n        'exception' =&gt; [\n            'message' =&gt; $e-&gt;getMessage(),\n            'file' =&gt; $e-&gt;getFile(),\n            'line' =&gt; $e-&gt;getLine(),\n            'trace' =&gt; $e-&gt;getTraceAsString()\n        ]\n    ]);\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30cf\u30f3\u30c9\u30e9\u30fc\u8a2d\u5b9a\u306b\u3088\u308a\u3001\u52b9\u7387\u7684\u306a\u30ed\u30b0\u7ba1\u7406\u3068\u554f\u984c\u306e\u65e9\u671f\u767a\u898b\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u6d3b\u7528\u3057\u305f\u52b9\u679c\u7684\u306a\u30a8\u30e9\u30fc\u76e3\u8996\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-12\">Monolog\u306b\u3088\u308b\u52b9\u679c\u7684\u306a\u30a8\u30e9\u30fc\u76e3\u8996<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3<\/h3>\n\n\n\n<p>PHP\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u306e\u52b9\u679c\u7684\u306a\u30a8\u30e9\u30fc\u76e3\u8996\u3092\u5b9f\u73fe\u3059\u308b\u305f\u3081\u3001Monolog\u3092\u4f7f\u7528\u3057\u305f\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b0\u30ed\u30fc\u30d0\u30eb\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\ErrorHandler;\n\n\/\/ \u30a8\u30e9\u30fc\u30ed\u30b0\u5c02\u7528\u306e\u30ed\u30ac\u30fc\u3092\u4f5c\u6210\n$errorLogger = new Logger('error');\n$errorLogger-&gt;pushHandler(new StreamHandler(\n    __DIR__.'\/logs\/error.log',\n    Level::Debug\n));\n\n\/\/ \u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30e9\u30fc\u3092\u767b\u9332\nErrorHandler::register($errorLogger);\n\n\/\/ \u4f8b\u5916\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8a2d\u5b9a\nset_exception_handler(function (\\Throwable $e) use ($errorLogger) {\n    $errorLogger-&gt;error('\u672a\u6355\u6349\u306e\u4f8b\u5916\u304c\u767a\u751f\u3057\u307e\u3057\u305f', [\n        'exception' =&gt; get_class($e),\n        'message' =&gt; $e-&gt;getMessage(),\n        'file' =&gt; $e-&gt;getFile(),\n        'line' =&gt; $e-&gt;getLine(),\n        'trace' =&gt; $e-&gt;getTraceAsString()\n    ]);\n});<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30ab\u30b9\u30bf\u30e0\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nclass CustomErrorHandler\n{\n    private Logger $logger;\n    private array $errorTypesMap = [\n        E_ERROR =&gt; 'ERROR',\n        E_WARNING =&gt; 'WARNING',\n        E_PARSE =&gt; 'PARSE',\n        E_NOTICE =&gt; 'NOTICE',\n        E_CORE_ERROR =&gt; 'CORE_ERROR',\n        E_CORE_WARNING =&gt; 'CORE_WARNING',\n        E_COMPILE_ERROR =&gt; 'COMPILE_ERROR',\n        E_COMPILE_WARNING =&gt; 'COMPILE_WARNING',\n        E_USER_ERROR =&gt; 'USER_ERROR',\n        E_USER_WARNING =&gt; 'USER_WARNING',\n        E_USER_NOTICE =&gt; 'USER_NOTICE',\n        E_STRICT =&gt; 'STRICT',\n        E_RECOVERABLE_ERROR =&gt; 'RECOVERABLE_ERROR',\n        E_DEPRECATED =&gt; 'DEPRECATED',\n        E_USER_DEPRECATED =&gt; 'USER_DEPRECATED'\n    ];\n\n    public function __construct(Logger $logger)\n    {\n        $this-&gt;logger = $logger;\n    }\n\n    public function handle($level, $message, $file = '', $line = 0, $context = [])\n    {\n        $errorType = $this-&gt;errorTypesMap[$level] ?? 'UNKNOWN';\n\n        $this-&gt;logger-&gt;error('PHP\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f', [\n            'type' =&gt; $errorType,\n            'message' =&gt; $message,\n            'file' =&gt; $file,\n            'line' =&gt; $line,\n            'context' =&gt; $context\n        ]);\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">Slack\u3068\u30e1\u30fc\u30eb\u3068\u306e\u9023\u643a\u306b\u3088\u308b\u5373\u6642\u901a\u77e5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Slack\u901a\u77e5\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Handler\\SlackWebhookHandler;\nuse Monolog\\Formatter\\LineFormatter;\n\nclass ErrorNotifier\n{\n    private Logger $logger;\n\n    public function __construct()\n    {\n        $this-&gt;logger = new Logger('error_notifier');\n\n        \/\/ Slack\u901a\u77e5\u306e\u8a2d\u5b9a\n        $slackHandler = new SlackWebhookHandler(\n            'webhook_url',\n            '#errors',\n            'ErrorBot',\n            true,\n            null,\n            false,\n            true,\n            Level::Error\n        );\n\n        \/\/ \u30ab\u30b9\u30bf\u30e0\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306e\u8a2d\u5b9a\n        $formatter = new LineFormatter(\n            \"\u74b0\u5883: %extra.environment%\\n\u767a\u751f\u6642\u523b: %datetime%\\n%level_name%: %message%\\n\u5834\u6240: %extra.file%:%extra.line%\\n%context%\",\n            \"Y-m-d H:i:s\"\n        );\n        $slackHandler-&gt;setFormatter($formatter);\n\n        $this-&gt;logger-&gt;pushHandler($slackHandler);\n\n        \/\/ \u74b0\u5883\u60c5\u5831\u3092\u8ffd\u52a0\u3059\u308b\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc\n        $this-&gt;logger-&gt;pushProcessor(function ($record) {\n            $record['extra']['environment'] = getenv('APP_ENV');\n            $record['extra']['file'] = debug_backtrace()[1]['file'] ?? 'unknown';\n            $record['extra']['line'] = debug_backtrace()[1]['line'] ?? 0;\n            return $record;\n        });\n    }\n\n    public function notifyError(\\Throwable $e, array $context = [])\n    {\n        $this-&gt;logger-&gt;error($e-&gt;getMessage(), [\n            'exception' =&gt; [\n                'class' =&gt; get_class($e),\n                'trace' =&gt; $e-&gt;getTraceAsString()\n            ],\n            'context' =&gt; $context\n        ]);\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30e1\u30fc\u30eb\u901a\u77e5\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Handler\\NativeMailerHandler;\nuse Monolog\\Formatter\\HtmlFormatter;\n\n\/\/ \u30e1\u30fc\u30eb\u901a\u77e5\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8a2d\u5b9a\n$mailHandler = new NativeMailerHandler(\n    'alerts@example.com',\n    '[ERROR] \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc',\n    'monitoring@example.com',\n    Level::Critical\n);\n\n\/\/ HTML\u5f62\u5f0f\u306e\u30e1\u30fc\u30eb\u672c\u6587\n$mailHandler-&gt;setFormatter(new HtmlFormatter());\n\n\/\/ \u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u8ffd\u52a0\n$logger-&gt;pushHandler($mailHandler);<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u901a\u77e5\u306e\u7d71\u5408\u4f8b<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nclass IntegratedErrorMonitor\n{\n    private Logger $logger;\n    private ErrorNotifier $notifier;\n\n    public function __construct()\n    {\n        $this-&gt;logger = new Logger('error_monitor');\n        $this-&gt;notifier = new ErrorNotifier();\n\n        \/\/ \u30d5\u30a1\u30a4\u30eb\u30ed\u30b0\n        $this-&gt;logger-&gt;pushHandler(new StreamHandler(\n            __DIR__.'\/logs\/error.log',\n            Level::Error\n        ));\n\n        \/\/ Slack\u901a\u77e5\n        $this-&gt;logger-&gt;pushHandler(new SlackWebhookHandler(\n            'webhook_url',\n            '#errors',\n            'MonitorBot',\n            true,\n            null,\n            false,\n            true,\n            Level::Error\n        ));\n\n        \/\/ \u30e1\u30fc\u30eb\u901a\u77e5\uff08\u30af\u30ea\u30c6\u30a3\u30ab\u30eb\u30a8\u30e9\u30fc\u306e\u307f\uff09\n        $this-&gt;logger-&gt;pushHandler(new NativeMailerHandler(\n            'alerts@example.com',\n            '[CRITICAL] \u30b7\u30b9\u30c6\u30e0\u30a8\u30e9\u30fc',\n            'monitoring@example.com',\n            Level::Critical\n        ));\n    }\n\n    public function monitorException(\\Throwable $e, array $context = [])\n    {\n        \/\/ \u30a8\u30e9\u30fc\u30ec\u30d9\u30eb\u306e\u5224\u5b9a\n        $level = $this-&gt;determineErrorLevel($e);\n\n        \/\/ \u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u60c5\u5831\u306e\u53ce\u96c6\n        $contextData = array_merge($context, [\n            'exception' =&gt; [\n                'class' =&gt; get_class($e),\n                'message' =&gt; $e-&gt;getMessage(),\n                'code' =&gt; $e-&gt;getCode(),\n                'file' =&gt; $e-&gt;getFile(),\n                'line' =&gt; $e-&gt;getLine(),\n                'trace' =&gt; $e-&gt;getTraceAsString()\n            ],\n            'server' =&gt; [\n                'hostname' =&gt; gethostname(),\n                'ip' =&gt; $_SERVER['SERVER_ADDR'] ?? 'unknown',\n                'time' =&gt; date('Y-m-d H:i:s')\n            ]\n        ]);\n\n        \/\/ \u30ed\u30b0\u8a18\u9332\u3068\u901a\u77e5\n        $this-&gt;logger-&gt;log($level, $e-&gt;getMessage(), $contextData);\n\n        \/\/ \u30af\u30ea\u30c6\u30a3\u30ab\u30eb\u30a8\u30e9\u30fc\u306e\u5834\u5408\u306f\u8ffd\u52a0\u30a2\u30af\u30b7\u30e7\u30f3\n        if ($level === Level::Critical) {\n            $this-&gt;notifier-&gt;notifyError($e, $context);\n        }\n    }\n\n    private function determineErrorLevel(\\Throwable $e): Level\n    {\n        \/\/ \u30a8\u30e9\u30fc\u306e\u7a2e\u985e\u306b\u5fdc\u3058\u3066\u30ed\u30b0\u30ec\u30d9\u30eb\u3092\u6c7a\u5b9a\n        return match (true) {\n            $e instanceof \\Error =&gt; Level::Critical,\n            $e instanceof \\RuntimeException =&gt; Level::Error,\n            $e instanceof \\InvalidArgumentException =&gt; Level::Warning,\n            default =&gt; Level::Error,\n        };\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$monitor = new IntegratedErrorMonitor();\n\ntry {\n    \/\/ \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b3\u30fc\u30c9\n    throw new \\RuntimeException('\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u63a5\u7d9a\u30a8\u30e9\u30fc');\n} catch (\\Throwable $e) {\n    $monitor-&gt;monitorException($e, [\n        'database' =&gt; 'main',\n        'query' =&gt; 'SELECT * FROM users'\n    ]);\n}<\/pre>\n\n\n\n<p>\u30a8\u30e9\u30fc\u76e3\u8996\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\uff1a<\/p>\n\n\n<div id=\"id-bfc383c3-f486-4ea1-b6b0-f8e52d0b37db\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u9805\u76ee<\/th><th>\u63a8\u5968\u8a2d\u5b9a<\/th><th>\u7406\u7531<\/th><\/tr><\/thead><tbody><tr><td>\u30ed\u30b0\u30ec\u30d9\u30eb<\/td><td>\u30a8\u30e9\u30fc\u4ee5\u4e0a<\/td><td>\u91cd\u8981\u306a\u554f\u984c\u306e\u898b\u9003\u3057\u9632\u6b62<\/td><\/tr><tr><td>\u901a\u77e5\u983b\u5ea6<\/td><td>\u30ec\u30fc\u30c8\u5236\u9650\u3042\u308a<\/td><td>\u901a\u77e5\u75b2\u308c\u306e\u9632\u6b62<\/td><\/tr><tr><td>\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8<\/td><td>\u8a73\u7d30\u60c5\u5831\u3092\u542b\u3081\u308b<\/td><td>\u8fc5\u901f\u306a\u554f\u984c\u89e3\u6c7a<\/td><\/tr><tr><td>\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0<\/td><td>\u6709\u52b9<\/td><td>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<p>\u3053\u306e\u5b9f\u88c5\u306b\u3088\u308a\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u52b9\u679c\u7684\u306a\u30a8\u30e9\u30fc\u76e3\u8996\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5168\u3066\u306e\u30a8\u30e9\u30fc\u3092\u78ba\u5b9f\u306b\u8a18\u9332<\/li>\n\n\n\n<li>\u91cd\u8981\u306a\u30a8\u30e9\u30fc\u306e\u5373\u6642\u901a\u77e5<\/li>\n\n\n\n<li>\u8a73\u7d30\u306a\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u60c5\u5831\u306e\u53ce\u96c6<\/li>\n\n\n\n<li>\u74b0\u5883\u306b\u5fdc\u3058\u305f\u901a\u77e5\u30ec\u30d9\u30eb\u306e\u8abf\u6574<\/li>\n<\/ol>\n\n\n\n<p>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u76e3\u8996\u30b7\u30b9\u30c6\u30e0\u3092\u904b\u7528\u3059\u308b\u969b\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-15\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u30ed\u30b0\u8a2d\u5b9a<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-16\">\u975e\u540c\u671f\u30ed\u30b0\u51e6\u7406\u306b\u3088\u308b\u8ca0\u8377\u8efd\u6e1b<\/h3>\n\n\n\n<p>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u6700\u9069\u5316\u3059\u308b\u305f\u3081\u3001Monolog\u3067\u306e\u975e\u540c\u671f\u30ed\u30b0\u51e6\u7406\u3092\u5b9f\u88c5\u3059\u308b\u65b9\u6cd5\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>BufferHandler\u306e\u6d3b\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Handler\\BufferHandler;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Level;\n\nclass AsyncLogger\n{\n    private Logger $logger;\n\n    public function __construct()\n    {\n        $this-&gt;logger = new Logger('async_logger');\n\n        \/\/ \u57fa\u672c\u306eStreamHandler\n        $streamHandler = new StreamHandler(\n            __DIR__.'\/logs\/app.log',\n            Level::Debug\n        );\n\n        \/\/ BufferHandler\u3067\u30e9\u30c3\u30d7\n        $bufferHandler = new BufferHandler(\n            $streamHandler,\n            50,    \/\/ \u30d0\u30c3\u30d5\u30a1\u30b5\u30a4\u30ba\n            Level::Debug,\n            true,  \/\/ \u30d0\u30c3\u30d5\u30a1\u304c\u3044\u3063\u3071\u3044\u306b\u306a\u3063\u305f\u6642\u306b\u81ea\u52d5\u7684\u306b\u30d5\u30e9\u30c3\u30b7\u30e5\n            true   \/\/ \u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u6642\u306b\u30d5\u30e9\u30c3\u30b7\u30e5\n        );\n\n        $this-&gt;logger-&gt;pushHandler($bufferHandler);\n    }\n\n    public function __destruct()\n    {\n        \/\/ \u78ba\u5b9f\u306b\u30ed\u30b0\u3092\u66f8\u304d\u51fa\u3059\n        foreach ($this-&gt;logger-&gt;getHandlers() as $handler) {\n            if ($handler instanceof BufferHandler) {\n                $handler-&gt;flush();\n            }\n        }\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u975e\u540c\u671f\u30ad\u30e5\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Handler\\AbstractProcessingHandler;\nuse Monolog\\Level;\n\nclass AsyncQueueHandler extends AbstractProcessingHandler\n{\n    private $queue;\n    private $queueFile;\n\n    public function __construct(\n        string $queueFile = '\/tmp\/monolog_queue',\n        $level = Level::Debug,\n        bool $bubble = true\n    ) {\n        parent::__construct($level, $bubble);\n        $this-&gt;queueFile = $queueFile;\n        $this-&gt;openQueue();\n    }\n\n    protected function write(array $record): void\n    {\n        \/\/ \u30ec\u30b3\u30fc\u30c9\u3092\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u3057\u3066\u30ad\u30e5\u30fc\u306b\u8ffd\u52a0\n        $serialized = serialize($record) . PHP_EOL;\n        fwrite($this-&gt;queue, $serialized);\n    }\n\n    private function openQueue(): void\n    {\n        $this-&gt;queue = fopen($this-&gt;queueFile, 'a');\n    }\n\n    public function close(): void\n    {\n        if ($this-&gt;queue) {\n            fclose($this-&gt;queue);\n        }\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$logger = new Logger('async');\n$logger-&gt;pushHandler(new AsyncQueueHandler());\n\n\/\/ \u30ad\u30e5\u30fc\u51e6\u7406\u7528\u306e\u30b9\u30af\u30ea\u30d7\u30c8\uff08\u5225\u30d7\u30ed\u30bb\u30b9\u3067\u5b9f\u884c\uff09\nclass QueueProcessor\n{\n    public function processQueue(string $queueFile): void\n    {\n        $logger = new Logger('processor');\n        $logger-&gt;pushHandler(new StreamHandler(__DIR__.'\/logs\/app.log'));\n\n        while (true) {\n            $queue = @fopen($queueFile, 'r+');\n            if ($queue) {\n                while (($line = fgets($queue)) !== false) {\n                    $record = unserialize($line);\n                    if ($record) {\n                        $logger-&gt;log(\n                            $record['level'],\n                            $record['message'],\n                            $record['context']\n                        );\n                    }\n                }\n                ftruncate($queue, 0);\n                fclose($queue);\n            }\n            sleep(1);\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-17\">\u30ed\u30b0\u30ed\u30fc\u30c6\u30fc\u30b7\u30e7\u30f3\u306e\u6700\u9069\u306a\u8a2d\u5b9a\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>RotatingFileHandler\u306e\u9ad8\u5ea6\u306a\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Handler\\RotatingFileHandler;\nuse Monolog\\Formatter\\JsonFormatter;\n\nclass OptimizedLogger\n{\n    private Logger $logger;\n\n    public function __construct()\n    {\n        $this-&gt;logger = new Logger('optimized');\n\n        \/\/ \u9ad8\u5ea6\u306a\u30ed\u30fc\u30c6\u30fc\u30b7\u30e7\u30f3\u8a2d\u5b9a\n        $handler = new RotatingFileHandler(\n            __DIR__.'\/logs\/app.log',\n            30,        \/\/ \u4fdd\u6301\u3059\u308b\u65e5\u6570\n            Level::Info,\n            true,      \/\/ \u30d5\u30a1\u30a4\u30eb\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\n            0664,\n            true       \/\/ \u30d5\u30a1\u30a4\u30eb\u540d\u306b\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u3092\u4ed8\u52a0\n        );\n\n        \/\/ JSON\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306e\u4f7f\u7528\uff08\u30d1\u30fc\u30b9\u52b9\u7387\u306e\u5411\u4e0a\uff09\n        $handler-&gt;setFormatter(new JsonFormatter());\n\n        $this-&gt;logger-&gt;pushHandler($handler);\n    }\n\n    \/\/ \u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\n    public function cleanupOldLogs(int $daysToKeep = 30): void\n    {\n        $logDir = __DIR__.'\/logs';\n        $now = time();\n\n        foreach (glob($logDir.'\/*.log') as $file) {\n            if (is_file($file)) {\n                $fileTime = filemtime($file);\n                if (($now - $fileTime) &gt; ($daysToKeep * 86400)) {\n                    unlink($file);\n                }\n            }\n        }\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u5727\u7e2e\u6a5f\u80fd\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nclass LogCompressor\n{\n    public function compressOldLogs(string $logDir): void\n    {\n        foreach (glob($logDir.'\/*.log') as $file) {\n            if (is_file($file) &amp;&amp; !$this-&gt;isCurrentLog($file)) {\n                $gzFile = $file.'.gz';\n                $fp = gzopen($gzFile, 'w9');\n                gzwrite($fp, file_get_contents($file));\n                gzclose($fp);\n                unlink($file);\n            }\n        }\n    }\n\n    private function isCurrentLog(string $file): bool\n    {\n        return basename($file) === 'app.log';\n    }\n}<\/pre>\n\n\n\n<p>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\uff1a<\/p>\n\n\n<div id=\"id-ad9fd0d8-71ab-4a38-aa79-4d6b1dad0ff3\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u8a2d\u5b9a\u9805\u76ee<\/th><th>\u63a8\u5968\u5024<\/th><th>\u8aac\u660e<\/th><\/tr><\/thead><tbody><tr><td>\u30d0\u30c3\u30d5\u30a1\u30b5\u30a4\u30ba<\/td><td>50-100<\/td><td>\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u3068\u30c7\u30a3\u30b9\u30afI\/O\u306e\u30d0\u30e9\u30f3\u30b9<\/td><\/tr><tr><td>\u30ed\u30fc\u30c6\u30fc\u30b7\u30e7\u30f3\u671f\u9593<\/td><td>\u65e5\u6b21<\/td><td>\u30d5\u30a1\u30a4\u30eb\u7ba1\u7406\u306e\u52b9\u7387\u5316<\/td><\/tr><tr><td>\u4fdd\u6301\u671f\u9593<\/td><td>30\u65e5<\/td><td>\u30b9\u30c8\u30ec\u30fc\u30b8\u5bb9\u91cf\u306e\u6700\u9069\u5316<\/td><\/tr><tr><td>\u5727\u7e2e\u30bf\u30a4\u30df\u30f3\u30b0<\/td><td>7\u65e5\u4ee5\u4e0a\u7d4c\u904e<\/td><td>\u51e6\u7406\u8ca0\u8377\u306e\u5206\u6563<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<p>\u9ad8\u8ca0\u8377\u74b0\u5883\u3067\u306e\u6700\u9069\u5316\u5b9f\u88c5\u4f8b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nclass HighPerformanceLogger\n{\n    private Logger $logger;\n    private array $buffer = [];\n    private int $bufferSize;\n\n    public function __construct(int $bufferSize = 100)\n    {\n        $this-&gt;logger = new Logger('high_performance');\n        $this-&gt;bufferSize = $bufferSize;\n\n        \/\/ \u30e1\u30a4\u30f3\u306e\u30ed\u30b0\u30cf\u30f3\u30c9\u30e9\u30fc\n        $mainHandler = new RotatingFileHandler(\n            __DIR__.'\/logs\/app.log',\n            30,\n            Level::Info\n        );\n        $mainHandler-&gt;setFormatter(new JsonFormatter());\n\n        \/\/ \u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u8a2d\u5b9a\n        $bufferedHandler = new BufferHandler(\n            $mainHandler,\n            $this-&gt;bufferSize,\n            Level::Debug,\n            true,\n            true\n        );\n\n        \/\/ \u30a8\u30e9\u30fc\u30ec\u30d9\u30eb\u306e\u30ed\u30b0\u306f\u5373\u6642\u66f8\u304d\u8fbc\u307f\n        $errorHandler = new StreamHandler(\n            __DIR__.'\/logs\/error.log',\n            Level::Error,\n            false\n        );\n\n        $this-&gt;logger-&gt;pushHandler($bufferedHandler);\n        $this-&gt;logger-&gt;pushHandler($errorHandler);\n    }\n\n    public function log($level, string $message, array $context = []): void\n    {\n        \/\/ \u30a8\u30e9\u30fc\u30ec\u30d9\u30eb\u4ee5\u4e0a\u306f\u5373\u6642\u51e6\u7406\n        if ($level &gt;= Level::Error) {\n            $this-&gt;logger-&gt;log($level, $message, $context);\n            return;\n        }\n\n        \/\/ \u901a\u5e38\u306e\u30ed\u30b0\u306f\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\n        $this-&gt;buffer[] = [\n            'level' =&gt; $level,\n            'message' =&gt; $message,\n            'context' =&gt; $context,\n            'time' =&gt; microtime(true)\n        ];\n\n        \/\/ \u30d0\u30c3\u30d5\u30a1\u304c\u3044\u3063\u3071\u3044\u306b\u306a\u3063\u305f\u3089\u4e00\u62ec\u51e6\u7406\n        if (count($this-&gt;buffer) &gt;= $this-&gt;bufferSize) {\n            $this-&gt;flushBuffer();\n        }\n    }\n\n    private function flushBuffer(): void\n    {\n        foreach ($this-&gt;buffer as $record) {\n            $this-&gt;logger-&gt;log(\n                $record['level'],\n                $record['message'],\n                $record['context']\n            );\n        }\n\n        $this-&gt;buffer = [];\n    }\n\n    public function __destruct()\n    {\n        \/\/ \u6b8b\u3063\u3066\u3044\u308b\u30ed\u30b0\u3092\u78ba\u5b9f\u306b\u66f8\u304d\u8fbc\u307f\n        $this-&gt;flushBuffer();\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u6700\u9069\u5316\u306b\u3088\u308a\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u52b9\u679c\u304c\u671f\u5f85\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u30bf\u30a4\u30e0\u6539\u5584<\/li>\n\n\n\n<li>\u30c7\u30a3\u30b9\u30afI\/O\u64cd\u4f5c\u306e\u524a\u6e1b<\/li>\n\n\n\n<li>\u30ea\u30bd\u30fc\u30b9\u4f7f\u7528\u91cf\u306e\u6700\u9069\u5316<\/li>\n\n\n\n<li>\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u306e\u52b9\u7387\u7684\u306a\u7ba1\u7406<\/li>\n<\/ol>\n\n\n\n<p>\u6b21\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u8a2d\u5b9a\u3092\u6d3b\u7528\u3057\u305f\u5b9f\u969b\u306e\u904b\u7528\u306b\u304a\u3051\u308b\u30d2\u30f3\u30c8\u306b\u3064\u3044\u3066\u89e3\u8aac\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-18\">\u5b9f\u969b\u306e\u904b\u7528\u3067\u4f7f\u3048\u308bMonolog\u306e\u30d2\u30f3\u30c8\u96c6<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-19\">\u30c7\u30d0\u30c3\u30b0\u6642\u306b\u4f7f\u3048\u308b\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\u30fc\u306e\u6d3b\u7528<\/h3>\n\n\n\n<p>\u30c7\u30d0\u30c3\u30b0\u4f5c\u696d\u3092\u52b9\u7387\u5316\u3059\u308b\u305f\u3081\u306e\u5b9f\u8df5\u7684\u306a\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\u30fc\u6d3b\u7528\u65b9\u6cd5\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ab\u30e9\u30fc\u4ed8\u304dCLI\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\u30fc<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Formatter\\LineFormatter;\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\n\nclass ColoredDebugFormatter extends LineFormatter\n{\n    private const COLORS = [\n        'error' =&gt; \"\\033[31m\",      \/\/ \u8d64\n        'warning' =&gt; \"\\033[33m\",    \/\/ \u9ec4\n        'info' =&gt; \"\\033[36m\",       \/\/ \u30b7\u30a2\u30f3\n        'debug' =&gt; \"\\033[37m\",      \/\/ \u767d\n        'reset' =&gt; \"\\033[0m\"        \/\/ \u30ea\u30bb\u30c3\u30c8\n    ];\n\n    public function format(array $record): string\n    {\n        $level = strtolower($record['level_name']);\n        $color = self::COLORS[$level] ?? self::COLORS['debug'];\n\n        $output = parent::format($record);\n        return sprintf(\n            \"%s%s%s\",\n            $color,\n            $output,\n            self::COLORS['reset']\n        );\n    }\n}\n\n\/\/ \u4f7f\u7528\u4f8b\n$handler = new StreamHandler('php:\/\/stdout', Level::Debug);\n$handler-&gt;setFormatter(new ColoredDebugFormatter(\n    \"[%datetime%] %level_name%: %message% %context%\\n\"\n));<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c7\u30d0\u30c3\u30b0\u7528JSON\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\u30fc<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nuse Monolog\\Formatter\\JsonFormatter;\n\nclass DebugJsonFormatter extends JsonFormatter\n{\n    public function format(array $record): string\n    {\n        \/\/ \u30c7\u30d0\u30c3\u30b0\u306b\u6709\u7528\u306a\u60c5\u5831\u3092\u8ffd\u52a0\n        $record['debug_info'] = [\n            'memory_usage' =&gt; memory_get_usage(true),\n            'peak_memory' =&gt; memory_get_peak_usage(true),\n            'timing' =&gt; microtime(true),\n            'included_files' =&gt; get_included_files(),\n        ];\n\n        return parent::format($record);\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-20\">\u672c\u756a\u74b0\u5883\u3067\u306e\u5b89\u5168\u306a\u30ed\u30b0\u904b\u7528\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6a5f\u5bc6\u60c5\u5831\u306e\u30de\u30b9\u30ad\u30f3\u30b0\u51e6\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nclass SensitiveDataProcessor\n{\n    private array $sensitiveKeys = [\n        'password',\n        'credit_card',\n        'token',\n        'api_key',\n        'secret'\n    ];\n\n    public function __invoke(array $record): array\n    {\n        $record['context'] = $this-&gt;maskSensitiveData($record['context']);\n        if (isset($record['extra'])) {\n            $record['extra'] = $this-&gt;maskSensitiveData($record['extra']);\n        }\n\n        return $record;\n    }\n\n    private function maskSensitiveData($data): array\n    {\n        if (!is_array($data)) {\n            return $data;\n        }\n\n        foreach ($data as $key =&gt; $value) {\n            if (is_array($value)) {\n                $data[$key] = $this-&gt;maskSensitiveData($value);\n            } elseif ($this-&gt;isSensitiveKey($key)) {\n                $data[$key] = '********';\n            }\n        }\n\n        return $data;\n    }\n\n    private function isSensitiveKey(string $key): bool\n    {\n        $key = strtolower($key);\n        foreach ($this-&gt;sensitiveKeys as $sensitiveKey) {\n            if (str_contains($key, $sensitiveKey)) {\n                return true;\n            }\n        }\n        return false;\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u74b0\u5883\u5225\u30ed\u30b0\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nclass EnvironmentAwareLogger\n{\n    private Logger $logger;\n\n    public function __construct()\n    {\n        $this-&gt;logger = new Logger('production');\n\n        $environment = getenv('APP_ENV') ?: 'production';\n        $config = $this-&gt;getEnvironmentConfig($environment);\n\n        foreach ($config['handlers'] as $handler) {\n            $this-&gt;logger-&gt;pushHandler($handler);\n        }\n\n        \/\/ \u6a5f\u5bc6\u60c5\u5831\u306e\u30de\u30b9\u30ad\u30f3\u30b0\n        $this-&gt;logger-&gt;pushProcessor(new SensitiveDataProcessor());\n    }\n\n    private function getEnvironmentConfig(string $environment): array\n    {\n        return match($environment) {\n            'production' =&gt; [\n                'handlers' =&gt; [\n                    new RotatingFileHandler(\n                        __DIR__.'\/logs\/production.log',\n                        30,\n                        Level::Info\n                    ),\n                    new SlackWebhookHandler(\n                        'webhook_url',\n                        '#prod-alerts',\n                        'MonologBot',\n                        true,\n                        null,\n                        false,\n                        true,\n                        Level::Error\n                    )\n                ]\n            ],\n            'staging' =&gt; [\n                'handlers' =&gt; [\n                    new StreamHandler(\n                        __DIR__.'\/logs\/staging.log',\n                        Level::Debug\n                    )\n                ]\n            ],\n            default =&gt; [\n                'handlers' =&gt; [\n                    new StreamHandler('php:\/\/stdout', Level::Debug)\n                ]\n            ]\n        };\n    }\n}<\/pre>\n\n\n\n<p>\u5b9f\u8df5\u7684\u306a\u30ed\u30b0\u904b\u7528\u306eTips\uff1a<\/p>\n\n\n<div id=\"id-41037921-8a87-478f-81b3-2abac34e1b9a\">\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u30ab\u30c6\u30b4\u30ea<\/th><th>Tip<\/th><th>\u5b9f\u88c5\u4f8b<\/th><\/tr><\/thead><tbody><tr><td>\u30c7\u30d0\u30c3\u30b0<\/td><td>\u30b9\u30bf\u30c3\u30af\u30c8\u30ec\u30fc\u30b9\u306e\u8a73\u7d30\u5316<\/td><td>IntrospectionProcessor \u306e\u6d3b\u7528<\/td><\/tr><tr><td>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3<\/td><td>IP\u30a2\u30c9\u30ec\u30b9\u306e\u533f\u540d\u5316<\/td><td>WebProcessor \u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba<\/td><\/tr><tr><td>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9<\/td><td>\u6761\u4ef6\u4ed8\u304d\u30ed\u30b0\u8a18\u9332<\/td><td>ClosureHandler \u306e\u4f7f\u7528<\/td><\/tr><tr><td>\u904b\u7528\u7ba1\u7406<\/td><td>\u30ed\u30b0\u306e\u96c6\u4e2d\u7ba1\u7406<\/td><td>Fluentd\/ELK \u3068\u306e\u9023\u643a<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div>\n\n\n<p>\u904b\u7528\u6642\u306e\u5177\u4f53\u7684\u306a\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ed\u30b0\u30ec\u30d9\u30eb\u306e\u4f7f\u3044\u5206\u3051<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nclass ProductionLogger\n{\n    public function logUserAction(string $action, array $context = []): void\n    {\n        match($action) {\n            'login_success' =&gt; $this-&gt;logger-&gt;info('\u30ed\u30b0\u30a4\u30f3\u6210\u529f', $context),\n            'login_failure' =&gt; $this-&gt;logger-&gt;warning('\u30ed\u30b0\u30a4\u30f3\u5931\u6557', $context),\n            'password_reset' =&gt; $this-&gt;logger-&gt;notice('\u30d1\u30b9\u30ef\u30fc\u30c9\u30ea\u30bb\u30c3\u30c8', $context),\n            'account_locked' =&gt; $this-&gt;logger-&gt;error('\u30a2\u30ab\u30a6\u30f3\u30c8\u30ed\u30c3\u30af', $context),\n            default =&gt; $this-&gt;logger-&gt;debug('\u30e6\u30fc\u30b6\u30fc\u30a2\u30af\u30b7\u30e7\u30f3', [\n                'action' =&gt; $action,\n                'context' =&gt; $context\n            ])\n        };\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30a8\u30e9\u30fc\u30c8\u30e9\u30c3\u30ad\u30f3\u30b0<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nclass ErrorTracker\n{\n    private const ERROR_THRESHOLD = 5;\n    private array $errorCount = [];\n\n    public function trackError(string $errorType, \\Throwable $e): void\n    {\n        $key = $this-&gt;getErrorKey($errorType, $e);\n        $this-&gt;errorCount[$key] = ($this-&gt;errorCount[$key] ?? 0) + 1;\n\n        if ($this-&gt;errorCount[$key] &gt;= self::ERROR_THRESHOLD) {\n            $this-&gt;logger-&gt;critical('\u30a8\u30e9\u30fc\u306e\u591a\u767a\u3092\u691c\u77e5', [\n                'error_type' =&gt; $errorType,\n                'error_message' =&gt; $e-&gt;getMessage(),\n                'occurrence_count' =&gt; $this-&gt;errorCount[$key]\n            ]);\n\n            \/\/ \u30ab\u30a6\u30f3\u30c8\u3092\u30ea\u30bb\u30c3\u30c8\n            $this-&gt;errorCount[$key] = 0;\n        }\n    }\n\n    private function getErrorKey(string $type, \\Throwable $e): string\n    {\n        return md5($type . $e-&gt;getMessage() . $e-&gt;getFile() . $e-&gt;getLine());\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30ed\u30b0\u306e\u5206\u6790\u3068\u53ef\u8996\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\nclass LogAnalyzer\n{\n    public function analyzeErrorPatterns(string $logFile): array\n    {\n        $patterns = [];\n        $handle = fopen($logFile, 'r');\n\n        while (($line = fgets($handle)) !== false) {\n            $log = json_decode($line, true);\n            if ($log &amp;&amp; isset($log['level_name']) &amp;&amp; $log['level_name'] === 'ERROR') {\n                $key = $log['message'] ?? 'unknown';\n                $patterns[$key] = ($patterns[$key] ?? 0) + 1;\n            }\n        }\n\n        fclose($handle);\n        arsort($patterns);\n\n        return array_slice($patterns, 0, 10); \/\/ Top 10 \u30a8\u30e9\u30fc\u30d1\u30bf\u30fc\u30f3\n    }\n}<\/pre>\n\n\n\n<p>\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u30c1\u30a7\u30c3\u30af\u30ea\u30b9\u30c8\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u306e\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u78ba\u8a8d<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ed\u30b0\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u78ba\u8a8d\nls -la \/path\/to\/logs\n\n# \u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u306e\u4fee\u6b63\nchmod 755 \/path\/to\/logs\nchmod 644 \/path\/to\/logs\/*.log<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>\u30ed\u30b0\u30ed\u30fc\u30c6\u30fc\u30b7\u30e7\u30f3\u306e\u78ba\u8a8d<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u306e\u30b5\u30a4\u30ba\u3068\u6570\u306e\u78ba\u8a8d\ndu -sh \/path\/to\/logs\/*\nls -l \/path\/to\/logs | wc -l\n\n# \u53e4\u3044\u30ed\u30b0\u306e\u5727\u7e2e\nfind \/path\/to\/logs -name \"*.log\" -mtime +7 -exec gzip {} \\;<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u30e1\u30e2\u30ea\u4f7f\u7528\u91cf\u306e\u76e3\u8996<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n$logger-&gt;pushProcessor(function ($record) {\n    $record['extra']['memory_usage'] = memory_get_usage(true);\n    $record['extra']['memory_peak'] = memory_get_peak_usage(true);\n    return $record;\n});<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30d2\u30f3\u30c8\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001Monolog\u3092\u3088\u308a\u52b9\u679c\u7684\u306b\u904b\u7528\u3057\u3001\u30b7\u30b9\u30c6\u30e0\u306e\u5b89\u5b9a\u6027\u3068\u53ef\u89b3\u6e2c\u6027\u3092\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Warning: Undefined array key &#8220;is_admin&#8221; in \/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/ &#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"class_list":{"0":"post-2445","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-php","7":"nothumb"},"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2445","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2445"}],"version-history":[{"count":2,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2445\/revisions"}],"predecessor-version":[{"id":2447,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2445\/revisions\/2447"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2445"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}