bounty还有3天到期。回答此问题可获得+300声望奖励。Zeth希望引起更多的注意这个问题。
几个docker-container,在Kubernetes集群中运行:
PHP
Nginx
MySQL
Redis
有一个Graylog-instance(版本3),它监听来自这些容器的stdout
和stderr
。
在PHP容器中,有一个Symfony应用程序,它使用Monolog来记录错误,信息,警告和通知等等。Monolog通常记录到一个文件,在/config/packages/prod/monolog.yaml
中定义如下:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
nested:
type: rotating_file
path: "%kernel.logs_dir%/%kernel.environment%.log" # <-- Here
level: debug
我的运营部门说:
Graylog看不到容器中的任何文件。就是这样
* 我的问题 *
我如何设置它,所以我所有的错误,警告,通知,信息等,是在Graylog中找到?
解决方案尝试1:获取Monolog-logger以打印到控制台
我尝试在/config/packages/prod/monolog.yaml
中执行各种后空翻,以获得如下代码:
// src/Controller/YourController.php
namespace App\Controller;
use Psr\Log\LoggerInterface;
...
class YourController extends AbstractController
{
public function yourAction(LoggerInterface $logger): Response
{
$logger->info('This is an informational log');
return new Response('Check the logs!');
}
}
将日志写入stdout
或stderr
。但是在标准输出中没有任何输出。
我的(最佳)尝试:
console:
type: console
process_psr_3_messages: false
channels: ['!event', '!doctrine', '!console']
syslog_handler:
type: syslog
level: debug
解决方案二:使用error_log()
error_log('my message')
-函数将输出到控制台。耶!虽然感觉很傻,我有这个巨大的日志库(Monolog
),但我最终还是使用了error_log()
。
另外,我希望所有的错误和警告都是caught
并发送到Graylog -而不仅仅是我自己插入的error_log
-语句。
另一部分是,这是我使用error_log()
时的输出示例:
projectname-php-1 | NOTICE: PHP message: ZZZ ErrorLogStatement: Error.log().
projectname-nginx-1 | 2023/09/22 12:56:17 [error] 10#10: *20 FastCGI sent in stderr: "PHP message: ZZZ ErrorLogStatement: Error.log()" while reading response header from upstream, client: 172.20.0.1, server: symfony.local, request: "GET /my-custom-endpoint?test_case=all_logs HTTP/1.1", upstream: "fastcgi://172.20.0.5:9000", host: "127.0.0.1:8200"
projectname-nginx-1 | 172.20.0.1 - - [22/Sep/2023:12:56:17 +0000] "GET /my-custom-endpoint?test_case=all_logs HTTP/1.1" 200 35 "-" "PostmanRuntime/7.32.3" "-"
projectname-php-1 | 172.20.0.6 - 22/Sep/2023:12:56:02 +0000 "GET /index.php" 200
这意味着我的Nginx容器和PHP容器都输出了错误,这在我的Graylog中增加了很多冗余行。我可以过滤这些,但仍然!太乱了
解决方案三:将我的错误日志“链接”到stdout
我在这里找到了这个建议:Make a Docker application write to stdout。
也就是将循环错误日志文件“链接”到stdout
(然后可能删除该文件的循环)。
所以我试着运行这个:
ln -sf /dev/stdout /var/www/docroot/var/log/my-log-file.log
但我犯了这个错误:
流或文件:无法在追加模式下打开“/var/www/docroot/var/log/prod-2023-09-22.log”:无法打开流:没有这样的文件或目录。
即使我成功了...这看起来很古怪,不像是正确的方法。所以我就不想让这件事继续下去了。
解决方案4:通过它的API将错误从Monolog发送到Graylog
这将是理想的解决方案。我只是希望有一个更简单的解决方案。
但这就是我现在在摆弄的东西。
2条答案
按热度按时间fivyi3re1#
为了将日志消息从运行在Kubernetes集群内Docker容器中的Symfony应用程序发送到Graylog示例,您可以通过Monolog library的GELF(Graylog Extended Log Format)消息格式测试对Graylog的支持。
通过在Monolog中使用GELF处理程序,您应该能够直接将日志消息发送到Graylog示例。
在Symfony应用程序的代码库中添加所需的软件包:
这将更新您的
composer.json
和composer.lock
文件,添加新的依赖项。我假设你的Dockerfile包含像
RUN composer install --no-progress --no-interaction --optimize-autoloader
这样的行:当Docker镜像被重建时,composer install
命令将安装graylog2/gelf-php
包沿着其他依赖项。然后,修改Symfony
monolog.yaml
配置文件以包含Gelf处理程序:在
.env
或Kubernetes ConfigMap中,您可以指定GRAYLOG_HOSTNAME
和GRAYLOG_PORT
值:Symfony应用程序使用Monolog和GELF处理程序将日志直接发送到Graylog示例的组件和数据流如下所示:
在这个设置中,Monolog直接与Graylog通信,避免了将日志写入Docker容器内的文件或控制台的需要。这应该解决了操作部门提到的限制,因为Graylog不需要访问容器内的文件。
yftpprvb2#
根据你的问题,PHP SAPI容器(PHP-FPM)已经配置了基于Graylog的监听器,正如你用
error_log()
演示的那样,默认情况下,它会进入PHP SAPI错误日志通道,这就是你想要的地方(特别是对于容器化的Symfony应用程序)。要使Monolog使用该配置,请使用标准处理程序之一**ErrorLogHandler**。
也就是说,您不会用
error_log()
调用来粘贴代码,而是使用更多的PSR-3 Logger Interface专用等价物,这些等价物在方法名称中附带日志级别,并在Symfony-App中提供更多专用配置选项,同时保留最后的error_log()
退出舱口,仍然集成并(相对地)开箱即用(即在Graylog中)。我无法想象为什么你想在一个容器中旋转日志,但是因为这是Monolog,你有所有的选择,包括使用多个目标等。.