I am using monolog with this configuration:
monolog:
channels:
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
when#dev:
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event"]
# uncomment to get logging in your browser
# you may have to allow bigger header sizes in your Web server configuration
#firephp:
# type: firephp
# level: info
#chromephp:
# type: chromephp
# level: info
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]
when#test:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
channels: ["!event"]
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
when#prod:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
nested:
type: stream
path: "%kernel.logs_dir%/prod.log"
level: debug
formatter: monolog.formatter.json
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
deprecation:
type: stream
channels: [deprecation]
path: php://stderr
The only thing I actually changed from the default is:
path: "%kernel.logs_dir%/prod.log"
for the production environment. Have prod.log file but after getting 500 errors the file is empty. Nothing is logged there.
APP_ENV is set to prod in .env.
Could you please check the web engine error log, what gets logged there on 5xx errors? Also, you could try removing the following when#prod.monolog.handlers.nested.formatted so it looks like this:
...
when#prod:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
nested:
type: stream
path: "%kernel.logs_dir%/prod.log"
level: debug
formatter: monolog.formatter.json
console:
type: console
process_psr_3_messages: false
...
Related
While upgrading to php8.1 I had to upgrade several modules of my current project, including gesdinet's refresh-token. A ghost method was present in my controller so I could document this api with annotations but it's not possible anymore. I managed to define the refreshtoken api method in nelmio_api_doc.yaml so I can still use it and test it from my sandbox page.
The problem here is that I have 5 areas in my api's documentation (and so, 5 sandbox pages) but the refresh_token method appear in every single one of them instead of only one.
I tried to insert various flavors and syntax of
areas:
- front
in the configuration file but it doesn't seems to work.
Does anyone know how to restrict it the same way it was done with annotations but with the yaml file ? (nelmio's documentation is clearly lacking on the subject)
the "packages/nelmio_api_do.yaml" file
nelmio_api_doc:
documentation:
info:
title: "API documentation"
version: '%version%'
sandbox:
request_format:
method: accept_header
accept_type: application/json
body_format:
formats: [ form, json ]
default_format: form
paths:
/api/front/token/refresh:
post:
tags:
- Authentication
summary: Refresh token mechanism
parameters:
refresh_token:
in: formData
name: refresh_token
type: string
responses:
'200':
description: OK
schema:
type: object
properties:
token:
type: string
refresh_token:
type: string
'401':
description: An authentication exception occurred.
security: [ ]
areas:
default:
path_patterns: [ ^/api/test/default ]
front:
path_patterns: [ ^/api/front ]
in advance thanks for your ideas.
(php 8.1 / symfony 5.4 / nelmio 3.10.1)
Nevermind guys, I eventually found the solution.
I was trying to follow what I saw for defining paths in the yaml file but while I tried to insert it in
nelmio_api_doc->documentation->paths->[the_method_path] (which works)
the right way to do this and condition the method to an area is:
nelmio_api_doc->documentation->areas->[your_area_name]->paths->[the_method_path]
so now the file looks like:
nelmio_api_doc:
documentation:
info:
title: "API documentation"
version: '%version%'
sandbox:
request_format:
method: accept_header
accept_type: application/json
body_format:
formats: [ form, json ]
default_format: form
areas:
default:
path_patterns: [ ^/api/test/default ]
front:
path_patterns: [ ^/api/front ]
paths:
/api/front/token/refresh:
post:
tags:
- Authentication
summary: Refresh token mechanism
parameters:
refresh_token:
in: formData
name: refresh_token
type: string
responses:
'200':
description: OK
schema:
type: object
properties:
token:
type: string
refresh_token:
type: string
'401':
description: An authentication exception occurred.
security: [ ]
This work for me
nelmio_api_doc:
areas:
oauth:
path_patterns:
- /oauth
documentation:
basePath: /
info:
title: oauth api
description: oauth documentation
paths:
/oauth/v2/token:
post:
tags:
- Authentication
produces:
- application/json
parameters:
- name: client_id
in: formData
required: true
type: string
- name: username
in: formData
required: true
type: string
example: 'test#test.fr'
- name: password
in: formData
required: true
type: string
example: 'password'
- name: grant_type
in: formData
required: true
type: string
example: 'password'
responses:
200:
description: Login successful
schema:
type: object
properties:
access_token:
type: string
expires_in:
type: integer
token_type:
type: string
example: 'bearer'
scope:
type: string
example: null
refresh_token:
type: string
403:
description: Login failed
schema:
type: array
properties:
error:
type: string
error_description:
type: string
default:
path_patterns:
- /address
documentation:
basePath: /
info:
title: default API
description: default API documentation
paths:
/address:
get:
tags:
- address
summary: OK - List address types
produces:
- application/json
parameters:
- name: access_token
type: string
in: query
required: true
description: API access token
responses:
200:
description: Returned when successful
schema:
items:
$ref: "#definitions/AddressEntity"
type: array
examples:
application/json:
data:
- type: adress type
id: M
attributes:
id: M
label: Main Address
401:
description: Bad access token
I'm using symfony 6.0 and i configured my monolog to send errors via email in prod.
How ever, it is using the async messenger transport (doctrine) instead of the configured gmail DSN.
I'm not sure how to use one config or the other, messenger being by default configured, but i don't use it (yet).
Here are my config files:
mailer.yaml
monolog:
channels:
- grouped # Deprecations are logged in the dedicated "deprecation" channel when it exists
-
when#prod:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: grouped
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
grouped:
type: group
members: [ streamed, deduplicated ]
streamed:
type: stream
path: '%kernel.logs_dir%/%kernel.environment%.log'
level: debug
deduplicated:
type: deduplication
handler: symfony_mailer
symfony_mailer:
type: symfony_mailer
from_email: 'email#email.com'
to_email: 'email#email.com'
subject: 'Company- An Error Occurred! %%message%%'
level: debug
formatter: monolog.formatter.html
content_type: text/html
My mailer.yaml config:
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
And my messenger.yaml config:
framework:
messenger:
failure_transport: failed
transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
use_notify: true
check_delayed_interval: 60000
retry_strategy:
max_retries: 3
multiplier: 2
failed: 'doctrine://default?queue_name=failed'
# sync: 'sync://'
routing:
Symfony\Component\Mailer\Messenger\SendEmailMessage: async
Symfony\Component\Notifier\Message\ChatMessage: async
Symfony\Component\Notifier\Message\SmsMessage: async
# Route your messages to the transports
# 'App\Message\YourMessage': async
In my .env file:
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
MAILER_DSN=gmail://email#email.com:password#localhost
So for now it just save the mail in database, but i want it to be just send by mail.
I am trying to print a custom channel in production. It works great in the dev environment. I want it to log at all times and not just on error.
Below is my config for production:
monolog:
channels: ["always"]
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
channels: ["!always"]
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
always:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ['always']
This is my config for development:
monolog:
channels: ["always"]
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!always"]
console:
type: console
bubble: false
verbosity_levels:
VERBOSITY_VERBOSE: INFO
VERBOSITY_VERY_VERBOSE: DEBUG
channels: ["!doctrine"]
console_very_verbose:
type: console
bubble: false
verbosity_levels:
VERBOSITY_VERBOSE: NOTICE
VERBOSITY_VERY_VERBOSE: NOTICE
VERBOSITY_DEBUG: DEBUG
channels: ["doctrine"]
always:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: always
here is an example from the log:
[2017-01-23 14:17:39] always.INFO: STAR REMOTE CONTROL FROM DEFAULT CONTROLLER [] []
and Here is how I call it:
/**
* #param Request $request
* #return Response
* #throws \Exception
* #Route("/star-remote-control")
*
*/
public function starRemoteControlAction(Request $request)
{
$this->container->get('monolog.logger.always')->info('STAR REMOTE CONTROL FROM DEFAULT CONTROLLER');
...
Can you help me troubleshoot why it is not showing up in the prod.log?
So the answer to my problem was really all about the order of the handlers. All I has to do was move the "Always" handler to the top before the "fingers_crossed" handler and the logs were written exactly as I wanted them.
Here is the config_prod.yml
monolog:
channels: ["always"]
handlers:
always:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["always"]
main:
type: fingers_crossed
action_level: error
handler: nested
channels: ["!always"]
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
check out the official documentation about the fingers_crossed handler:
It stores all log messages during a request but only passes them to a second handler if one of the messages reaches an action_level.
Your action level in prod environment is error, but you are actually logging a info message. Try changing the action level or log and error or critical message and the entry should show up in the prod log file.
I have a symfony2 application, which has a bunch of monolog handlers in place. The logging for the dev environment works fine, yet I want one monolog handler to be always be logging, naming transmission_recorder, also on prod. Yet for the prod, the logging is inactive.
I am assuming that the finger_crossed might prevent logging on prod, yet I do not want to enable logging of all the things for all the monolog handlers, only for a specific one.
How do I achieve that?
Here's my relevant configuration:
config.yml:
monolog:
handlers:
console:
type: console
transmission_recorder:
type: service
id: dba.handler.transmission.recorder
config_dev.yml:
imports:
- { resource: config.yml }
monolog:
handlers:
main:
type: rotating_file
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
max_files: 14
channels:
- "!event"
console:
type: console
bubble: false
config_prod.yml:
imports:
- { resource: config.yml }
monolog:
handlers:
main:
type: fingers_crossed
action_level: WARNING
handler: grouped_warning
grouped_warning:
type: group
members:
- file_debug
file_debug:
type: rotating_file
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
max_files: 14
console:
type: console
Im working on a project using symfony2, I uploaded it on the web, and turn it from the dev mode to the prod mode, I've done some testing, and when I got an exception, it sent me 3O email on my inbox, there is my config_prod code :
NOTE: Im using monolog for logging
imports:
- { resource: config.yml }
#framework:
# validation:
# cache: apc
doctrine:
orm:
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: grouped
grouped:
type: group
members: [streamed, swift]
streamed:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: debug
swift:
type: swift_mailer
from_email: FQN#foo.com
to_email: a.krachli#improvia-maroc.com
subject: "GESTIBAT::Error_Exception"
level: debug
login:
type: stream
path: "%kernel.logs_dir%/auth.log"
level: info
channels: security
If someone has an idea, Thanks for help!
You should buffer logger messages before sending them as it is described in symfony2 documentation
buffered:
type: buffer
handler: swift