I have the following configuration in my monolog.yaml file:
monolog:
handlers:
main:
type: stream
path: "php://stdout"
level: debug
channels: ["!event"]
gelf:
type: gelf
publisher:
hostname: mygelfhost.com
port: 12201
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]
But it only sends messages to mygelfhost.com using UDP. When I tried to put:
hostname: tcp://mygelfhost.com
I receive the following error:
Failed to create socket-client for udp://tcp://log-dev.hpa.lis-dev.net:12201: php_network_getaddresses: getaddrinfo failed: Name or service not known (0)
My goal is to send the logs via TCP to the same host, I have checked the configuration here: https://github.com/symfony/monolog-bundle/blob/master/DependencyInjection/Configuration.php#L25 with no possible solution.
Building off of #Chase's answer:
monolog:
handlers:
gelf:
type: gelf
publisher: my_tcp_gelf_publisher
The difference above is my_tcp_gelf_publisher is a Publisher object, not a Handler object. You want to tell the handler, which publisher to use "my_tcp_gelf_publisher", since that's what's being defined in services.yaml
In services.yaml:
services:
my_tcp_gelf_publisher:
class: Gelf\Publisher
arguments: ["#gelf.tcp_transport"]
gelf.tcp_transport:
class: Gelf\Transport\TcpTransport
arguments:
- "mygelfhost.com" # Hostname
- 12201 #port
This is pretty much the same, except you'll need to put the #gelf.tcp_transport service reference in quotes, otherwise you'll get a scaler error.
A bonus tip, if by chance you decide to configure your transport to use port 12202 (Gelf\Transport\TcpTransport's SSL port) be sure to ensure your endpoint supports ssl and you provide the correctly configured SslOptions object, otherwise use standard port 12201 (or any other port).
You need to specify the transport for Gelf. By default it uses UDP.
monolog:
handlers:
gelf:
type: gelf
id: my_tcp_gelf_publisher
In your services:
services:
my_tcp_gelf_publisher:
class: Gelf\Publisher
arguments: [#gelf.tcp_transport]
gelf.tcp_transport:
class: Gelf\Transport\TcpTransport
arguments:
- "mygelfhost.com" # Hostname
- 12201 #port
Something like this should work, I havent tested the code though. Based on the defining a publisher and the config example from: https://github.com/bzikarsky/gelf-php
Related
We have a new Symfony setup with Redis as cache mechanism. We want to connect to a specific host, not the default localhost. On production, the ./bin/console debug:dotenv gives the correct REDIS_HOST. This is configured in our .env and .env.local.php.
The error we get is:
Connection refused: tcp:127.0.0.1/6379
This is our config:
services.yml
services:
Redis:
# you can also use \RedisArray, \RedisCluster or \Predis\Client classes
class: \Predis\Client
calls:
- connect:
- '%env(REDIS_HOST)%'
- '%env(int:REDIS_PORT)%'
Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler:
arguments:
- '#Redis'
- prefix: sp_ss_
- ttl: 1800
cache.yml
framework:
cache:
app: cache.adapter.redis
default_redis_provider: 'Redis'
pools:
site.cache:
adapter: cache.app
And our .env file:
APP_ENV=prod
APP_SECRET=****
MESSENGER_TRANSPORT_DSN=redis://redis.local:6379/messages
REDIS_HOST=redis.local
REDIS_PORT=6379
REDIS_URL=redis://redis.local:6379
The Symfony's documentation suggest to use "calls -> connect", but it's used only when you was defined the class as 'Redis'. When you use '\Predis\Client', you need to use the settings bellow:
"config/services.yaml"
Redis:
# you can also use \RedisArray, \RedisCluster or \Predis\Client classes
class: \Predis\Client
# See all parameters here: https://github.com/predis/predis/wiki/Connection-Parameters#list-of-connection-parameters
arguments:
- host: '%env(REDIS_HOST)%'
- port: '%env(int:REDIS_PORT)%'
# uncomment the following if your Redis server requires a password
# - password: '%env(REDIS_PASSWORD)%'
I'm also using the '\Predis\Client' and after to change to 'arguments' the connection was worked here.
For more parameters references, please check this link (List of connection parameters).
There might be hidden other .env files. May you check out the files list with the following code at the root of your projects? Are there other env files such as .env.prod, .env.local?
ls -lah
I'm on Symfony 4 and I want to create a dedicated channel for many log types:
this is my configuration for channels and handlers:
monolog:
channels: ["channel1", "channel2"]
handlers:
channel1:
level: debug
type: stream
path: "%kernel.logs_dir%/channel1.log"
channels: ["channel"]
channel2:
level: debug
type: stream
path: "%kernel.logs_dir%/channel2.log"
channels: ["channel2"]
Then, in my service to write log, I inject the custom
services:
_defaults:
autowire: true
autoconfigure: true
Infrastructure\Logger\Channel1Logger:
arguments:
- '#monolog.logger.channel1'
Infrastructure\Logger\Channel2Logger:
arguments:
- '#monolog.logger.channel2'
But, all my logs are directly written to the channel "app",
When I debug the container, I see my services listed
What I'm doing wrong?
I found the error. By default, the config/services.yaml will override all configuration from external files. That's why my log continues to be on the default channel (autowiring). To avoid this, you have to exclude the loggers custom files from autowiring
I am working on a web app built using Symfony 2.6 and there are different configuration inside app/config folder. How do I know which one is being used.
Inside app/config I see config.yml config_dev.yml config_prod.yml and the monolog entry I see in config_dev.yml and also in monolog_prod.yml. It is as below.
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
Now I want to use monolog to input some logs in a controller and put those logs separate form other logs. How can this be done?.
You know which one is used on your environment.
If you are in dev mode you are using config_dev.yml merged with config.yml
You can check it into your virtual host if the file is on app.php you are in prod mode, if the file points to app_dev.php you are in dev mode usually
To log into other files you can create a channel like this:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
your_handler:
level: debug
type: stream
path: '%kernel.logs_dir%/custom.log'
channels: ['your_channel']
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
And into your controller you can call it in this way:
$logger = $this->get('monolog.logger.your_handler');
$logger->debug('your custom message into your custom log file');
I'm trying to stream logs from a symfony 2 app to a graylog 2 server using the gelf format.
My monolog configuration looks as follows:
monolog:
handlers:
# --- 8< ---
# ...
# --- >8 ---
graylog:
type: gelf
publisher:
hostname: my-graylog-server.com
port: 12201
level: debug
formatter: app.gelf_formatter
When the graylog server is not available, I get (understandably) a connection refused error
[2017-07-28 16:03:25] app.ERROR: Failed to write to socket: fwrite(): send of 153 bytes failed with errno=111 Connection refused (8) [] []
which results in an internal server error (500 response code to the request causing the log).
(See also this question: Prevent Internal Server Error with Symfony 2 / Monolog on failed gelf connection)
gelf-php provides an IngoreErrorTransportLogger, which seems to be build for this exact purpose.
How can I configure this in Symfony's monolog config?
It turns out that Symfony has WhatFailureGroup handler wrapper a handler which ignores errors from the logs of all logging handlers that it wraps.
Our config now looks like this, it just drops errors during logging (probably not ideal, but better than failing outright due to an error during logging).
monolog:
handlers:
main:
type: fingers_crossed
action_level: warning
handler: grouped
grouped:
type: whatfailuregroup
members: [file, graylog]
file:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
graylog:
type: gelf
publisher:
hostname: my-graylog-server.com
port: 12201
level: debug
formatter: app.gelf_formatter
Essentially we replaced type: group with type: whatfailuregroup.
You can additionally use UDP transport in Graylog.
First you'd need to configure GELF UDP input in Graylog, then configure it like this:
monolog:
handlers:
# ...
graylog:
type: gelf
publisher:
id: gelf_publisher
nested: true
services:
gelf_publisher:
class: Gelf\Publisher
arguments:
- '#gelf_transport'
gelf_transport:
class: Gelf\Transport\UdpTransport
arguments:
- '%env(GRAYLOG_HOSTNAME)%'
- '%env(GRAYLOG_PORT)%'
I want to use sentry to evaluate possible errors, exceptions, etc.
I tried to use the KunstmaanSentryBundle and it's great to catch all kind of errors like undefined functions and so on, but I want to define my own Monolog channel with it's own handler, but unfortunately I haven't found documentation about it.
config.yml would be something like:
monolog:
handlers:
sentry:
type: stream
level: error
//Log to database parameter (raven for sentry)
Does anybody knows the right configuration?
This is part of config_prod.yml:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: grouped_main
sentry:
type: raven
dsn: 'http://user:pass#url/1'
level: notice
# Groups
grouped_main:
type: group
members: [sentry, streamed_main]
# Streams
streamed_main:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: error
Enjoy! :)
Wanted to add this as a comment on the accepted answer, but not enough rep, so:
From \Symfony\Bundle\MonologBundle\DependencyInjection\Configuration :
"Possible handler types and related configurations (brackets indicate optional params):
raven:
dsn: connection string
client_id: Raven client custom service id (optional)
[level]: level name or int value, defaults to DEBUG
[bubble]: bool, defaults to true
"
Example config would be:
monolog:
handlers:
sentry:
type: raven
dsn: '%sentry_api_key%'
client_id: 'your.raven.client.custom.service.id'
level: notice
bubble: false