| 5 bootstrap.inc | watchdog($type, $message, $severity = WATCHDOG_NOTICE, $link = NULL) |
| 6 bootstrap.inc | watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) |
| 7 bootstrap.inc | watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) |
| 8 bootstrap.inc | watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) |
Log a system message.
Parameters
$type: The category to which this message belongs. Can be any string, but the general practice is to use the name of the module calling watchdog().
$message: The message to store in the log. See t() for documentation on how $message and $variables interact. Keep $message translatable by not concatenating dynamic values into it!
$variables: Array of variables to replace in the message on display or NULL if message is already translated or not possible to translate.
$severity: The severity of the message, as per RFC 3164. Possible values are WATCHDOG_ERROR, WATCHDOG_WARNING, etc.
$link: A link to associate with the message.
See also
File
- includes/
bootstrap.inc, line 950 - Functions that need to be loaded on every Drupal request.
Code
<?php
function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) {
global $user, $base_root;
// Prepare the fields to be logged
$log_message = array(
'type' => $type,
'message' => $message,
'variables' => $variables,
'severity' => $severity,
'link' => $link,
'user' => $user,
'request_uri' => $base_root . request_uri(),
'referer' => referer_uri(),
'ip' => ip_address(),
'timestamp' => time(),
);
// Call the logging hooks to log/process the message
foreach (module_implements('watchdog') as $module) {
module_invoke($module, 'watchdog', $log_message);
}
}
?> Login or register to post comments
Comments
Watchdog Security Levels
For your own module development:
http://api.drupal.org/api/function/watchdog_severity_levels/6
<?phpfunction watchdog_severity_levels() {
return array(
WATCHDOG_EMERG => t('emergency'),
WATCHDOG_ALERT => t('alert'),
WATCHDOG_CRITICAL => t('critical'),
WATCHDOG_ERROR => t('error'),
WATCHDOG_WARNING => t('warning'),
WATCHDOG_NOTICE => t('notice'),
WATCHDOG_INFO => t('info'),
WATCHDOG_DEBUG => t('debug'),
);
}
?>
This function is invaluable
This function is invaluable for debugging your own code.
In its simplest form, one might use the following code to insert new lines into the watchdog log.
<?phpwatchdog('error title', 'error message');
?>
An interesting quirk with
An interesting quirk with this function is the variables array and the text in the log message. If you have a $variables['user'] element for example and then attempt to put the word 'user' anywhere in the message, you will encounter one of these 2 errors:
warning: preg_match() expects parameter 2 to be string, array given in /yourInstallDir/includes/bootstrap.inc on line 842.
OR
warning: preg_match() expects parameter 2 to be string, object given in /yourInstallDir/includes/bootstrap.inc on line 842.
This isnt a bug. It is intended and thus you have to fix your msg or variable to use a different case such as $variables['User'] and then you can use 'user' in the message or vice versa.
If this happens your code is
If this happens your code is broken. Those variables are the same as the ones that are passed on to t() and they should start with an exclamation mark (!), an at sign (@) or a percent sign (%). Translatable string replacement variables should never start with another character for safety reasons.
$link should be an HTML link
Note that $link should be an actual HTML link generated via l() or some such function not a link array as used in theme_links().
Thanks for the heads-up :) I
Thanks for the heads-up :) I was just wondering if I should l() it.
no comprendo
It would be really helpful if someone could post an example of how to use watchdog with some text that includes a variable, like "user XXX has just created a node titled XXX" or something..
A more complete example
<?phpwatchdog('example', 'Example module is unable to find the file @filename.', array('@filename' => $filename), WATCHDOG_ERROR);
?>
Example
In user.module:
watchdog('user', 'New user: %name (%email).', array('%name' => $name, '%email' => $mail), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
Limitation of Watchdog
An unfortunate limitation of watchdog if you want to use it in custom applications that don't use all of drupal (ie, you want to use drupal's database and session layers so you do drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION)) is that it requires "module_implements" which means the "module.inc" file must be loaded, which means that it can't be used before the drupal phase of DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE (I also think this means that it'll fail with aggressive caching).
Drupal 7 fixes this by adding function_exists('module_implements') but drupal 6 doesn't have it
Beware of $type length limitation to 16 chars
"$type The category to which this message belongs. Can be any string, but the general practice is to use the name of the module calling watchdog()."
Calling watchdog with $type string greater than 16 chars will fail as it is stored in db as varchar(16).
Using module name as $type should therefore not be the recommended general practice as custom modules / sub-modules names may often exceed 16 chars...
Error in documentation: $variables MUST be array(), not NULL
The docs above state:
If your message does not contain any tokens or string replacements, and you want to specify the severity, the quote above would indicate you should do this:
<?phpwatchdog('mymodule', $message, NULL, WATCHDOG_WARNING);
?>
However, doing so will result in this dread error message (bedeviling many different threads and irc chats):
preg_match() expects parameter 2 to be string, array given in docroot/includes/bootstrap.inc one line XXXX
So, don't follow the API docs. Use an empty array as your third parameter instead of NULL. ie, do this:
<?phpwatchdog('mymodule', $message, array(), WATCHDOG_WARNING);
?>
Of course, if the default WATCHDOG_NOTICE is good enough or you don't need to supply a link, just pass the first two parameters and don't worry about the rest as the default on the watchdog() end is to receive an array as the third param.
Suggestion: The watchdog() writers should specify with php that the third param is to be an array, like this
function watchdog($type, $message, array $variables=array(), .....
Log a system message.
Log a system message. Do u think that's enough explanation for this function??
Write the log into another DB
If I connect to another Database and use watchdog, it won't work as I'd expect.
For example:
db_set_active('db2');
user_save($user, array('name' => 'test',
'pass' => 'test',
'mail' => 'test@example.com',
'status' => 1)
); // create a new user in db2
watchdog("example module", $user->uid . " uid created", array(), WATCHDOG_INFO, null); // log the action in the default db
db_set_active('default');
It will create a new user into db2 as expected. The log, however, will be written in the default database.