symfony2 exceptions without logging - symfony

There are several places in my application where I throw an exception as part of the business logic, but I don't need Symfony2 to generate and log an exception.
For example, when the user attempts an action he can't do temporarily, I call $this->createAccessDeniedException() with a nice error message. This is not an application failure and I don't need it logged. Mostly it's a message to the user saying "try again later, or after you completed this other step first".
Can I teach it to not log certain cases or am I using exceptions badly and if so, what should I do instead?
update: My config:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: grouped
grouped:
type: group
members: [streamed, buffered]
streamed:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: debug
buffered:
type: buffer
handler: swift
swift:
type: swift_mailer
from_email: xxx#xxx.xxx
to_email: xxx#xxx.xxx
subject: "Error"
level: info

As you can see in the ExceptionListener, the AccessDeniedException should not be logged as a normal exception, but as a special message on the DEBUG level.
If you are seeing these messages in your production log files, you should check the minimal level configured for Monolog. I recommend to set it NOTICE.

Related

How to configure sending errors by e-mail with Symfony 5.1, Monolog and Mailer component?

Do you have an example configuration to send logs by email with the Mailer component of Symfony 5.1.
In the Symfony blog we announce this feature, but I can't put the right config in monolog.yaml
https://symfony.com/blog/new-in-symfony-5-1-misc-improvements-part-3 :
That's why in Symfony 5.1 we added a new Monolog log handler which uses the Mailer component to send the logs via email.
Unfortunately this addition only covers the actuall MailerHandler class in the monolog-bridge. This does not cover the possibility to configure it in the monolog-bundle (that's the drawback if those components are distributed over multiple packages).
The PR for the change in the monolog-bundle is still open, and can be found here: Add Symfony Mailer support #354.
If you don't want to wait for the change in the monolog-bundle you could already use it by defining the handler as a service and then using it with the service type in the monolog configuration.
So define your service:
services:
# this configures the "mail" as a prototype, so you can
# define the sender and recipient mail addresses here
symfony_mailer_service_template:
class: Symfony\Component\Mime\Email
calls:
- ['from', ['webapp#example.com']]
- ['to', ['ops#example.com']]
- ['subject', ['Logs']]
symfony_mailer_service:
class: Symfony\Bridge\Monolog\Handler\MailerHandler
arguments:
- '#mailer.mailer'
- '#symfony_mailer_service_template'
- !php/const Monolog\Logger::DEBUG # log level
- true # bubble
And then in your mailer configuration you could use it like this:
monolog:
handlers:
main:
type: fingers_crossed
handler: deduplicated
deduplicated:
type: deduplication
handler: symfony_mailer
symfony_mailer:
type: service
id: symfony_mailer_service

How to configure Symfony Messenger to work with topic exchange?

We have a project that partially uses DDD. When changing / creating an entity, we throw an event inside the entity. Next, the Doctrine Event Subscriber takes all the events and forwards them to the EventBus.
Let's say we have a MissionCreatedEvent event. I want to make routing key mission.event.created for it and tie it into 2 queues: new_mission_notification_to_part_time_employee and new_mission_area_notification_to_manager.
This is what the config looks like:
transports:
async_new_mission_notification_to_part_time_employee:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
exchange:
name: mission
type: topic
queues:
new_mission_notification_to_part_time_employee:
binding_keys: ['mission.event.created']
retry_strategy:
max_retries: 0
async_new_mission_area_notification_to_manager:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
exchange:
name: mission
type: topic
queues:
new_mission_area_notification_to_manager:
binding_keys: ['mission.event.created']
retry_strategy:
max_retries: 0
routing:
'App\Domain\Mission\Event\MissionCreatedEvent':
- async_new_mission_notification_to_part_time_employee
- async_new_mission_area_notification_to_manager
The problem is that Symfony Messenger first runs on transports and only then pushes the message into exchange. Since we have 2 transports, it turns out that the event with routing key mission.event.created is triggered twice. Because of this, my Message handlers run 2 times.
There is an option not to use routing key mission.event.created. But use similar to mission.cmd.notify_part_time_employee_about_new_mission
and mission.cmd.notify_manager_about_new_mission_in_area for each transport with direct exchange.
This will help solve duplication problems, but I can’t use all the features that RabbitMQ gives me :(

How do I log to different files with Monolog in Symfony2?

I want to log messages to separate files depending on the context. Currently everything is going into the environment's log file. How can this be accomplished with Monolog in Symfony2?
In your config files (config.yml or config_dev.yml and config_prod.yml) under monolog: register new handlers for each file you want to log to.
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
the environment's log file will receive everything from debug level up, but the main logger service will only log with action level error and up.
Add your own handlers for the files you want to log to in your config files.
cron_logger:
type: stream
path: "%kernel.logs_dir%/cron.log"
level: notice
channels: "cronchan"
You can choose which level of messages will be logged in the file. You should specify which channel will log to this handler. In this case the channel name chosen was "cronchan". At the same level as handlers, register your new channel (you need MonologBundle 2.4 for this).
monolog:
handlers:
...
cron_logger: ...
channels: ["cronchan"]
You can now log specifically to the cron.log file by getting the correct channel's service in a controller: $logger = $this->get('monolog.logger.cronchan');
Now everything from notice level and up will be logged in the cron.log file. The messages will possibly also be logged in the environment's log file, but you can remove the channel from the file's handler's channels.

Symfony2 authenticate user through an API on integration testing

I would like to authenticate the user through an API (external user provider) running my integration tests.
my config_test.yml
imports:
- { resource: config.yml }
- { resource: parameters_test.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
monolog:
handlers:
main:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: info
After the login (SUCCEED) the next step is ask for user information and I got:
"Full authentication is required to access this resource."
I guess something is happening with the stored session.
I am using Redis on dev and prod to store sessions.
Mocking sessions on the test environment because of
"Failed to start the session because headers have already been sent by "/path/to/bin/phpunit" at line 2."
Doing it manually is working like a charm.
session.storage.mock_file uses by default %kernel.cache_dir%/sessions for a storing of session's file. Check if this folder is writable for both server user and cli user.
'Setting up Permissions' http://symfony.com/doc/current/book/installation.html#configuration-and-setup
Another 2 possible reasons of error:
stateless: true on your firewall in firewalls section. The ContextListener is not created and Token is not saved to the session. AnonymousToken is assigned to next request.
stateless: true you also can have RememberMeToken instead of AnonymousToken if remember_me feature enabled. This token is also not full fledged.
UPDATE
Ensure that intercept_redirects is false in config_test.yml as it may break all redirects.
web_profiler:
toolbar: false
intercept_redirects: false

Disable log in Symfony2

This question may have been asked before. I have searched for answers, but I haven't found what I was looking for.
In Symfony 2.3, is there a way to disable the logger for specific requests? I mean, I am using a SOAP service for my project. When I send a request to login, the username and password are dumped straight as plain text into the log file. Is there a way to stop logging this kind of specific requests?
For example, when I send a request for login, the logger should be disabled, but for all other request it works again. Is this possible?
depending if your are in Prod or Dev environement but everything is in config.yml or config_dev.yml :
to disable logging just remove monolog configuration like this :
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
bubble: false
# 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
but in my opinion , you shouln't do this because logging allows you to improve significantly your code !
Logging except for a specific service :
You need to create a specific log channel for your service as described there :
http://symfony.com/doc/current/cookbook/logging/channels_handlers.html
and there :
http://symfony.com/doc/current/reference/dic_tags.html#dic-tags-monolog
you ll be able to separate your soap log from others and eventually send it to null

Resources