您的应用程序保持沉默——这是一个不好的信号
\n\n您是否曾经从愤怒的用户那里得知生产环境中的 Bug?如果是——您知道这有多痛苦。如果不是——您很幸运(暂时)。
\n\nPHP 是一种运行在全球 78% 网站上的语言。但它有一个特点:它太“安静”了。默认情况下,PHP 会直接吞掉错误,显示一个白屏,或者更糟糕的是,继续使用错误的数据运行。没有监控和日志记录系统,您就是盲人。
\n\n在本文中,我们将探讨如何将您的 PHP 应用程序从一个“黑箱”转变为一个透明的系统,其中每个错误、每个慢速请求和每个可疑操作都会被记录下来。开始吧!
\n\n为什么“echo $error”不是日志记录?
\n\n许多初级开发人员会这样写:
\n\ntry {\n // 一些代码\n} catch (Exception $e) {\n echo $e->getMessage();\n}\n\n\n这不是日志记录。这是对空呐喊。输出到浏览器不会被保存、不会被结构化,也不会给您任何分析。真正的日志记录是当您可以:
\n\n- \n
- 在错误发生后 5 分钟内看到它 \n
- 了解它发生在哪个服务器和哪个环境中 \n
- 过滤数千条记录并找到那一条特定的记录 \n
- 如果出现问题,通过 Telegram/Slack 收到通知 \n
让我们来看看能够做到这一点的工具。
\n\nMonolog——PHP 的事实标准
\n\n如果您用 PHP 编程并且不使用 Monolog,您很可能是在重复造轮子。这是一个已成为 PHP 日志记录标准的库(是的,Laravel 和 Symfony 在底层都使用它)。
\n\n安装和最简单的示例
\n\ncomposer require monolog/monolog\n\n\n<?php\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\n\n// 创建日志通道\n$log = new Logger('my_app');\n// 写入文件 /var/log/my_app.log\n$log->pushHandler(new StreamHandler('/var/log/my_app.log', Logger::WARNING));\n\n// 使用\n$log->warning('这是一个警告');\n$log->error('严重错误:数据库不可用');\n\n\n这已经好多了。但 Monolog 能做的远不止这些。您可以同时将日志发送到不同的地方:
\n\n- \n
- 到文件——用于本地调试 \n
- 到 Elasticsearch——用于全面的搜索 \n
- 到 Telegram/Slack——用于紧急通知 \n
- 到 Syslog——用于系统管理 \n
包含多个处理程序的高级示例
\n\n<?php\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Handler\\TelegramBotHandler;\nuse Monolog\\Handler\\ElasticsearchHandler;\nuse Monolog\\Formatter\\LineFormatter;\n\n$log = new Logger('production');\n\n// 所有错误写入文件\n$fileHandler = new StreamHandler('/var/log/app.log', Logger::DEBUG);\n$log->pushHandler($fileHandler);\n\n// 严重错误——立即发送到 Telegram\n$telegramHandler = new TelegramBotHandler(\n 'YOUR_BOT_TOKEN', \n 'YOUR_CHAT_ID', \n Logger::CRITICAL\n);\n$telegramHandler->setFormatter(new LineFormatter(\n "[%datetime%] %channel%.%level_name%: %message% %context%\\n"\n));\n$log->pushHandler($telegramHandler);\n\n// 记录日志\n$log->critical('数据库宕机', ['server' => gethostname()]);\n\n\n现在,如果数据库在夜间宕机,您会通过手机上的通知得知。而不是在早上从客户那里得知。
\n\nSentry——带有上下文的错误监控
\n\nMonolog 擅长写入日志,但当错误数量增多时,仅仅阅读文件就是一场噩梦。这时 Sentry 就派上用场了——这是一个带有 Web 界面的错误收集系统。
\n\nSentry 会自动收集:
\n- \n
- 调用栈(stack trace) \n
- 请求数据(URL、标头、正文) \n
- 用户信息(如果已传递) \n
- 变量状态