Send Symfony logs to Slack with Symfony Notifier (as a Monolog handler)

Configure Slack App

Create a Slack App

Slack's admin panel is too complicated!

First, you need to create an app in Slack and install it into your workspace.

The home of managing apps is in the Slack API (But not the Slack App Directory...)

Get bot token and configure permission

The bot token (starts with xoxb-) shows up after you installed the app to your workspace and you can confirm it later in "Slack API > Your Apps > Your App > Features > OAuth Permissions".

bot_token.png

Then add chat:write to the "Bot Token Scopes" below.

You can also restrict the IP that accessing the API.

Configure Symfony

Install Symfony Notifier

composer req notifier symfony/slack-notifier

Configure Slack Transport

# config/packages/notifier.yaml
framework:
    notifier:
        chatter_transports:
            slack: '%env(SLACK_DSN)%'
        #    telegram: '%env(TELEGRAM_DSN)%'
        #texter_transports:
        #    twilio: '%env(TWILIO_DSN)%'
        #    nexmo: '%env(NEXMO_DSN)%'
        channel_policy:
            # use chat/slack, chat/telegram, sms/twilio or sms/nexmo
            urgent: ['chat/slack']
            high: ['chat/slack']
            medium: ['chat/slack']
            low: ['chat/slack']

Add bot token and channel to environment variable

# .env
SLACK_DSN=slack://XOXB-TOKEN@default?channel=CHANNEL
# OR: slack://XOXB-TOKEN@default?channel=@USER

Remember to add your app to the channel! (if you are sending to a channel rather than a user)

More DSN examples

Configure Monolog

Add NotifierHandler as service

# config/services.yaml
Symfony\Bridge\Monolog\Handler\NotifierHandler: ~

Add handler to chain

# config/packages/monolog.yaml
when@dev:
    monolog:
        handlers:
            main:
                type: group
                members: ['nested', 'notifier']
            nested:
                type: stream
                path: "%kernel.logs_dir%/%kernel.environment%.log"
                level: debug
                channels: ["!event"]
            notifier:
                type: service
                id: Symfony\Bridge\Monolog\Handler\NotifierHandler
when@prod:
    monolog:
        handlers:
            main:
                type: fingers_crossed
                action_level: notice
                handler: grouped
                excluded_http_codes: [404, 405]
                buffer_size: 50 # How many messages should be saved? Prevent memory leaks
            grouped:
                type: group
                members: ['nested', 'notifier']
            nested:
                type: stream
                path: "%env(resolve:LOGGER_PATH)%"
                level: debug
            notifier:
                type: service
                id: Symfony\Bridge\Monolog\Handler\NotifierHandler