How can I output the date with ConsoleLogger? - php

I have a console command and I'm initializing ConsoleLogger in the initialize method:
$this->logger = new ConsoleLogger($output);
But the date is not outputted in the console. Is it possible to prefix the output with the datetime?

I know this is an old topic, but it's the first result when you google for "symfony console log date", that's why I'd like to share what I found when trying to solve this.
According to the Symfony docs, you can specify a custom formatter (found in old Symfony 2.6 docs)
https://symfony.com/doc/2.6//cookbook/logging/monolog_console.html
# app/config/services.yml
services:
my_formatter:
class: Symfony\Bridge\Monolog\Formatter\ConsoleFormatter
arguments:
# NOTE
# The placeholder to use in the `format` is enclosed in single `%` (ex.: `%datetime%`)
# However, here we escape `%` characters so Symfony will not interpret them as service parameters.
# https://symfony.com/doc/current/configuration.html#configuration-parameters
- "[%%datetime%%] %%start_tag%%%%message%%%%end_tag%% (%%level_name%%) %%context%% %%extra%%\n"
But that's not doing the trick already.
Taking a look at the source of ConsoleFormatter, I found this:
const SIMPLE_FORMAT = "%datetime% %start_tag%%level_name%%end_tag% <comment>[%channel%]</> %message%%context%%extra%\n";
const SIMPLE_DATE = 'H:i:s';
So there date is set as H:i:s here.
Luckily this date can be overwritten with the date_format option.
This is how I solved it now:
In my monolog.yaml I added the formatter
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]
verbosity_levels:
VERBOSITY_NORMAL: DEBUG
formatter: console_log_formatter
And in services.yml I added the custom formatter with my date_format set
console_log_formatter:
class: Symfony\Bridge\Monolog\Formatter\ConsoleFormatter
arguments:
- date_format: 'Y-m-d H:i:s'

maybe you need to define the verbosity level
$this->consoleLogger = new ConsoleLogger($output, [LogLevel::INFO => OutputInterface::VERBOSITY_NORMAL]);
Hope this is what you are looking for

Related

Workflow in Symfony doesn't work with "multiple_state"

In one of the configuration files of Symfony 5.2.8 with Workflow 5.2.7 I have:
framework:
workflows:
register_participation:
type: 'workflow' # or 'state_machine'
audit_trail:
enabled: true
marking_store:
type: 'multiple_state'
arguments:
- complexState
# [...]
When I execute bin/console I have error:
Unrecognized option "arguments" under framework.workflows.workflows.register_participation.marking_store". Available options are "property", "service", "type".
When I change the configuration to:
framework:
workflows:
register_participation:
type: 'workflow' # or 'state_machine'
audit_trail:
enabled: true
marking_store:
type: 'multiple_state'
property: state
# [...]
I get the error:
The value "multiple_state" is not allowed for path framework.workflows.workflows.register_participation.marking_store.type". Permissible values: "method"
It works when I change to this:
marking_store:
type: 'method'
property: main_state
Anybody have idea what can I do to works with multiple_state? Thanks in advance.
From the symfony workflow documentation:
The marking store type could be “multiple_state” or “single_state”. A
single state marking store does not support a model being on multiple
places at the same time. This means a “workflow” must use a
“multiple_state” marking store and a “state_machine” must use a
“single_state” marking store. Symfony configures the marking store
according to the “type” by default, so it’s preferable to not
configure it.
A single state marking store uses a string to store the data. A
multiple state marking store uses an array to store the data.
So if you configure type "workflow" it should automatically be "multiple_state". You could dump your entity and the state property should be of type array

How define some PHP constant in the Symfony configuration?

this is my first post, so i will try to be clear
So i need to define some constants in the Symfony configuration (in a .yaml file, i guess)
I know i could define them throw public const MY_CONST but that is not what I want.
I guess this is what i need (the second part, i am not using Abstract controller as i am not in a controller)
https://symfony.com/doc/current/configuration.html#accessing-configuration-parameters
But I just can't get it to work. Could anyone help me, by giving me an exemple, or maybe an other way to do ?
Thanks guys.
The parameters you described can be used in the configuration defined as eg;
parameters:
the_answer: 42
You can then use these values in further configuration things (see below for example). Or if you want to handle these values in a controller you can (not recommended anymore) use $this->getParameter('the_answer') to get the value.
Binding arguments (recommended):
This approach wil bind values which you can then get (auto-magically injected) in a controller function/service by referencing the argument.
The values can range from simple scalar values to services, .env variables, php constants and all of the other things the configuration can parse.
# config/services.yaml
services:
_defaults:
bind:
string $helloWorld: 'Hello world!' # simple string
int $theAnswer: '%the_answer%' # reference an already defined parameter.
string $apiKey: '%env(REMOTE_API)%' # env variable.
Then these get injected in a service/controller function when we do something like:
public function hello(string $apiKey, int $theAnswer, string $helloWorld) {
// do things with $apiKey, $theAnswer and $helloWorld
}
More details and examples can be found in the symfony docs https://symfony.com/doc/current/service_container.html#binding-arguments-by-name-or-type
Inject into service (alternative)
You can also directly inject it into the defined service using arguments.
# config/services.yaml
services:
# explicitly configure the service
App\Updates\SiteUpdateManager:
arguments:
$adminEmail: 'manager#example.com'

Change filename on custom monolog file

I use a rotating monolog handler
monolog:
channels: ['import']
handlers:
import_client:
level: debug
type: rotating_file
max_files: 10
path: '%kernel.logs_dir%/import.log'
channels: [import_client]
All works fine except I don't like the filename. I get import-2018-02-22.log.
Does it exist a way to change this format?
I would like the filename to be like import-"date(YmdHis)".log.
Is possible to rewrite the filename format? Did you have any solutions ?
I found the solution, need to add in config handler a new parameter :
date_format: 'YmdHms'
The RotatingFileHandler Logs records to a file and creates one logfile per day. It will also delete files older than $maxFiles. You should use logrotate for high profile setups though, this is just meant as a quick and dirty solution.
As you can see in the original RotatingFileHandler: you could possibly change the rotate dateformat
public function setFilenameFormat($filenameFormat, $dateFormat)
But I don't see any configuration option in the symfony monolog reference.
You could call a service using
services:
app.custom_rotating_service:
# ...
calls:
- method: setFilenameFormat
arguments:
- 'yourFilenameFormat'
- 'Ymd'
It seems to me you would get into soemthing complex for no added value of a date format.
TLDR
It's not possible to have a logfile By Hour/Minute with monolog
Changing Date format or the rotation frequency to months/year of the handler seems (to me) doable but not supported by the symfony monolog configuration. you could create a service and try to call the method automatically on service isntance creation
You should use logrotate if you have a custom need of rotating log

How to disable output for a command in Symfony Console?

I writing a module, actually a custom command in Magento 2. Magento 2 console application is proudly powered by Symfony Console, obviously. And my concernation is how to disable output from $output for specified command?
For example:
$setupUpgradeCommand = $this->getApplication()->find('setup:upgrade');
$setupUpgradeArguments = array(
'command' => 'setup:upgrade',
'--quiet' => true,
);
$setupUpgradeInput = new ArrayInput($setupUpgradeArguments);
$start = microtime(true);
$output->writeln('<info>Start upgrading module schemas...</info>');
$setupUpgradeCommand->run($setupUpgradeInput, $output);
$output->writeln('...............................<info>OK</info>');
// My long logic-code start from here....
Unfortunately, even I set --quiet to true, output of this command setup:upgrade still there.
Any ideas?
As answered in a comment.. although almost exactly the same as the answer by #toooni.
You can insert the NullOutput rather than inserting the actual output object supplied by the command.
use Symfony\Component\Console\Output\NullOutput;
$setupUpgradeCommand->run($setupUpgradeInput, new NullOutput());
You can use BufferedOutput:
use Symfony\Component\Console\Output\BufferedOutput;
...
$setupUpgradeCommand->run($setupUpgradeInput, new BufferedOutput());
The usage is described here:
http://symfony.com/doc/current/cookbook/console/command_in_controller.html
Another option would be to use the logger and have this spewed on your CLI if you ask for it. You can read more about it in this (by now old) news post: http://symfony.com/blog/new-in-symfony-2-4-show-logs-in-console
A full example where you can even format the output taken from the post:
services:
my_formatter:
class: Symfony\Bridge\Monolog\Formatter\ConsoleFormatter
arguments:
- "[%%datetime%%] %%start_tag%%%%message%%%%end_tag%% (%%level_name%%) %%context%% %%extra%%\n"
monolog:
handlers:
console:
type: console
verbosity_levels:
VERBOSITY_NORMAL: NOTICE
channels: my_channel
formatter: my_formatter
You can find the documentation here: http://symfony.com/doc/current/cookbook/logging/monolog.html

How do I set a MysQL variable (time_zone) from within doctrine / symfony?

I would like to know how I can set the MySQL time zone to UTC (SET time_zone = 'UTC') from within Symfony/Doctrine, so when I call a UNIX_TIMESTAMP() function on a DATETIME field in my query, it returns the UTC unix time and not unix time in the server's time zone.
How can I do this, either automatically upon every connection, or manually before these types of queries where the timezone makes a difference?
BTW, I need to do this conversion within the MySQL query and not the app so I can GROUP BY an interval that requires epoch time.
You can do this via the configureDoctrineConnection callbacks that gets called in ProjectConfiguration`:
public function configureDoctrineConnection(Doctrine_Connection $connection)
{
$connection->exec('SET time_zone = "UTC"');
}
There may be issues with this if you're using multiple connections.
(Answer edited to remove additonal method that was flawed.)
I would try editing the projectConfiguration, and add something like (untested and unverified):
$databaseManager = new sfDatabaseManager($this->configuration);
$connection = $databaseManager->getDatabase($options['connection'])->getConnection();
$diff = $connection->execute("SET time_zone = 'UTC'");
Note, $options and $this->configuration is only available in a task, so maybe this should be hardcoded (I believe default is 'doctrine').
If you want to do this at the Symfony application level, the way is adding this to the config/settings.yml
all:
.settings:
default_culture: en_US
default_timezone: Asia/Kolkata
Sorry for the answer not on MySQL, but on Oracle DB.
I searched for data on Oracle DB for a long time, but found nothing.
This is the only topic that also discusses the problem, but only in MySQL.
Perhaps, someone will help, for Oracle DB:
In file config/services.yaml
For Symofony 4:
services:
Doctrine\DBAL\Event\Listeners\OracleSessionInit:
arguments:
- TIME_ZONE: 'UTC'
tags:
- { name: doctrine.event_listener, event: postConnect }
For Symfony 2 and 3:
services:
oci8.listener:
class: Doctrine\DBAL\Event\Listeners\OracleSessionInit
arguments:
- TIME_ZONE: 'UTC'
tags:
- { name: doctrine.event_listener, event: postConnect }
Or, you can write the arguments object to yaml as:
arguments: { TIME_ZONE: 'UTC' }
For MySQL 8 and Symfony 5, you can add the following to config/services.yaml
services:
Doctrine\DBAL\Event\Listeners\SQLSessionInit:
arguments:
- 'SET TIME_ZONE="+04:00"'
tags:
- { name: doctrine.event_listener, event: postConnect }

Categories