Logging¶
In your code you may wish to record events for debuggers or system admins.
CiviCRM has a logging interface that implements psr3.
By default, these will log to files in the ConfigAndLog directory. However, sites can implement alternative logging using listeners (see further down).
Best practice when logging in your code looks like this
\Civi::log('smarty')->debug('smarty escaping original {original}, escaped {escaped} type {type} charset {charset}', [
'original' => $string,
'escaped' => $value,
'type' => $esc_type,
'charset' => $char_set,
]);
Note that
1) The priority in this example is debug
priority level. There are 8 levels in the psr3
specification and the calls to them just use the error level as the method (e.g Civi::log()->error()
).
Here is a useful explainer on the levels
2) Use words, not abbreviations for variable names and use underscores (not camel case). Even if
the variable is something weird & wonderful like $cType
the
string should be {contact_type}
3)The optional channel
is defined. If you just use \Civi::log()
it will use the default
channel. The impact of specifying the channel is that
a) extensions (such as monolog)
can implement per-channel logging configuration and b) absent any non
core handling each channel is logged to a separate file. It is recommended
that in your own code you use one or more channels to segment the logging
output. Channels do not need to be pre-defined
4) The use of parameterisation - you should put each variable in curly braces ({}
) and
then put the expanded version in an array. (Also note that a psr3)
requirement is that the key name is exception
if it holds an exception).
5) Core does not use separate channels extensively - this is historical & perhaps on the basis of not wanting to change the behaviour pro-actively in case changes site-specific concerns of some sort.
6) There are other logging methods used in core like
CRM_Core_Error::debug_log_message
and
CRM_Core_Error::debug_var
. These are old methods and should be swapped out over time.
Customising logging output¶
It is possible to change how logging output is handled with listeners.
For example the monolog extension allows different logging channels to be logged in different ways and to use features such as browser logging and command line verbosity.
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
function monolog_civicrm_container(ContainerBuilder $container) {
$container->setDefinition('psr_log_manager', new Definition('\Civi\MonoLog\MonologManager', []))->setPublic(TRUE);
}