如何为Docker配置PHP日志,及在Symfony、laravel框架中配置案例

2023-06-01 00:00:00 框架 配置 何为

如果您使用 docker 和云服务来实时运行您的应用程序,您应该管理您的日志。

存储它们的最常用方法是将它们放入文本文件中。这是大多数后端框架的默认配置。如果您在本地或在 VPS 服务器上运行您的应用程序进行测试,则此选项是可以的。


当您在生产环境中运行您的应用程序时,您应该选择一个更好的选项来管理您的日志。

几乎每个云都有一个用于旋转日志的工具,如果没有,您可以使用例如 Grafana Loki 或 ELK 堆栈。

这些解决方案更好,因为为您提供了轮换和搜索日志的界面。

此外,您可以轻松访问它们,无需连接到服务器即可查看它们。


如果您使用 Docker 容器,并且您在云服务中运行您的应用程序,它们通常会自动将您的容器日志写入 AWS CloudWatch 或 GCloud Stackdriver 等工具。


但首先,您需要将日志流重定向到 Docker 容器的输出才能使用它们。


Linux

Docker 容器正在运行 Linux 进程。在 linux 中,每个正在运行的进程都有 3 个流,STDIN、STDOUT、STDERR。 

STDIN 它是命令输入流,您可以为 ex 提供。

通过你的键盘。 

STDOUT 是运行命令可以打印输出的流。 

STDERR 是标准错误流,但是我觉得这个名字有点混乱,因为它基本上是用于诊断输出的。

当您在终端中运行 

docker logs [container]

命令时,您将看到 STDOUT 和 STDERR 流的输出。

所以我们的目标是将我们的日志重定向到这些流之一。


官方 docker 文档页面:

https://docs.docker.com/config/containers/logging/


PHP-FPM

在 PHP 中,我们经常使用 PHP-FPM(进程管理器)运行我们的应用程序。如果您在 docker 容器内使用 FPM 运行 docker,并运行 docker logs 命令,您应该会看到包含已处理请求或错误的输出。

所以 PHP-FPM 已经将其输出写入 STDOUT。

PHP-FPM 允许我们捕获 worker 输出并将它们转发到 STDOUT。

为此,我们需要确保 FPM 配置正确。您可以创建新的配置文件,并将其推送到例如 /usr/local/etc/php-fpm.d/logging.conf 文件:

[global]
error_log = /proc/self/fd/2
[www]
access.log = /proc/self/fd/2
catch_workers_output = yes
decorate_workers_output = no

error_log 和 access.log 参数是对日志输出流的配置。


catch_workers_output 选项正在打开工作人员的输出缓存。 

decorate_workers_output 是关闭输出装饰的选项。

如果您将此选项保持打开状态,FPM 将像这样装饰您的应用程序输出:

[21-Mar-2016 14:10:02] WARNING: [pool www] child 12 said into stdout: "[your log line]"

请记住,decorate_workers_output 选项仅适用于 PHP 7.3.0 及更高版本。


如果你使用的是官方的docker php-fpm镜像,这个配置已经在

/usr/local/etc/php-fpm.d/docker.conf

文件中设置了,所以你不需要再做任何事情了


PHP应用配置

现在,将从 PHP 工作人员放入标准输出的所有内容都将显示在我们的 docker 日志中。但是当日志被转发到 PHP 中的那个流时呢?

要在 PHP 级别向 STDIN 写入内容,我们只需要写入 php://stdout 流。

以最简单的方式,您可以这样做:

<?php
file_put_contents('php://stdout', 'Hello world');

当您在 php cli 中执行此代码时,您将在输出中获得 Hello world 文本。


但这不是将日志推送到 STDOUT 的最佳方式。

每个现代框架都应该有一个 PSR-3 Logger。

我认为现在最流行的是monolog,所以我将向您展示如何在Symfony、Laravel和纯用法中配置它。


Monolog

Monolog 是一个很棒的库,可以处理应用程序中的日志。它的配置简单且富有弹性。

基本的 Monolog 配置

如果您在项目中使用 monolog 进行手动配置,则需要以这种方式配置处理程序:

(修改后的文档示例)

<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('stdout');
$log->pushHandler(new StreamHandler('php://stdout', Logger::DEBUG));
$log->debug('Foo');

您只需要配置 StreamHandler,以写入 php://stdout 文件。


Symfony

Symfony 内核自 Flex 提供以来,使用极简的 PSR-3 记录器,默认情况下将所有内容记录到 php://stderr。

在 Symfony 中,monolog 和其他组件一样是在 YAML 文件中配置的。 

所以相同的配置看起来像这样:

# config/packages/monolog.yaml
monolog:
    handlers:
        stdout:
            type: stream
            path: "php://stdout"
            level: debug

Laravel

Laravel 使用数组进行配置,所以同样的事情看起来像这样:

# config/logging.php
<?php
use Monolog\Handler\StreamHandler;
return [
    'channels' =>
        'stdout' => [
            'driver' => 'monolog',
            'handler' => StreamHandler::class,
            'level' => env('LOG_LEVEL', 'debug'),
            'with' => [
                'stream' => 'php://stdout',
            ],
        ],
];


STDERR 或标准输出

在互联网上的一些文章中,您可以看到有人使用 stderr,有人使用 stdout 流在那里写入日志。 现在我找不到任何理由选择其中一个更好。

我在这个主题上找到的唯一信息就是那个帖子。


我认为 stderr 在某些示例中更受欢迎,Fabien Potencier 也在他的简约记录器中将其设置为默认值,所以我认为我们可以假设这个更好。


就我个人而言,我总是使用标准输出,所以这就是我在这篇文章的示例中使用它的原因。 如果我能找到一个很好的理由来使用其中一个而不是另一个,我会更新这篇文章。


转:

https://mateuszcholewka.com

相关文章