1
votes

I have a Symfony app hosted with Docker on AWS. For logging I use AWS CloudWatch.

For example: the database connection can not be established. If I use the default monolog configuration, I get the error in the file /project/var/log/prod.log. When I change the path to php://stderr, I expect the same message in CloudWatch, but it doesn't appear.

I have modified the index.php for test reasons:

<?php
echo ini_get('error_log');
error_log('error_log');
file_put_contents('php://stderr', 'file_put_contents', FILE_APPEND);

The output is: /proc/self/fd/2 (docker logs target)

In CloudWatch I get the message error_log, but not file_put_contents.

I have no idea where the problem is. Maybe the Symfony app is misconfigured. But since the message file_put_contents is missing - which runs without Symfony - I'm not sure.

This is the monolog configuration:

monolog:
    handlers:
        main:
            type: fingers_crossed
            action_level: error
            handler: nested
            excluded_404s:
                # regex: exclude all 404 errors from the logs
                - ^/
        nested:
            type: stream
#            path: "%kernel.logs_dir%/%kernel.environment%.log"
            path: "php://stderr"
            level: debug
        console:
            type: console
            process_psr_3_messages: false
            channels: ["!event", "!doctrine"]
        deprecation:
            type: stream
            path: "%kernel.logs_dir%/%kernel.environment%.deprecations.log"
        deprecation_filter:
            type: filter
            handler: deprecation
            max_level: info
            channels: ["php"]

This is the default configuration, except the line path: "php://stderr".

1

1 Answers

6
votes

I managed to get Symfony logging to CloudWatch by the following:

Use this package:

composer require maxbanton/cwh:^1.0

Then in my config/packages/prod/monolog.yaml

monolog:
    handlers:
        main:
            type: fingers_crossed
            action_level: error
            handler: grouped
            excluded_404s:
                # regex: exclude all 404 errors from the logs
                - ^/
        grouped:
            type: group
            members: [cloudwatch, nested]
        nested:
            type: stream
            path: "%kernel.logs_dir%/%kernel.environment%.log"
            level: debug
        console:
            type: console
            process_psr_3_messages: false
            channels: ["!event", "!doctrine"]
        cloudwatch:
            type: service
            id: cloudwatch_handler
            level: error

Then in my config/services.yaml

services:
    cloudwatch_client:
    class: Aws\CloudWatchLogs\CloudWatchLogsClient
    arguments:
        - credentials: { key: '%env(AWS_KEY)%', secret: '%env(AWS_SECRET)%' }
          region: '%env(AWS_REGION)%'
          version: "2014-03-28"

    cloudwatch_handler:
        class: Maxbanton\Cwh\Handler\CloudWatch
        arguments:
            - "@cloudwatch_client"
            - "symfony"              # groupName
            - "%kernel.environment%" # streamName
            - 30                     # retentionDays
            - 10000                  # logsInBatch
            - { mytag: "symfony" }   # tags
            - WARNING                # logLevel

I then had to make sure the API Key I had set up had permissions for CloudWatch in IAM but after that it logged perfectly