Log a system message.

Log a system message.


r.aubin’s picture

For your own module development:


function 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'),
joshmiller’s picture

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.

watchdog('error title', 'error message');
crystaldawn’s picture

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.
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.

Xano’s picture

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.

rszrama’s picture

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().

nightlife2008’s picture

Thanks for the heads-up :) I was just wondering if I should l() it.

armanschwarz’s picture

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..

agerson’s picture

  watchdog('example', 'Example module is unable to find the file @filename.', array('@filename' => $filename), WATCHDOG_ERROR);
SeanA’s picture

In user.module:

watchdog('user', 'New user: %name (%email).', array('%name' => $name, '%email' => $mail), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));

Jztinfinity’s picture

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

pmunch’s picture

"$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...

apotek’s picture

The docs above state:

$variables Array of variables to replace in the message on display or NULL if message is already translated or not possible to translate.

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:

watchdog('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:

watchdog('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(), .....

m4r71n’s picture

Log a system message. Do u think that's enough explanation for this function??

mcarrera’s picture

If I connect to another Database and use watchdog, it won't work as I'd expect.
For example:

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

It will create a new user into db2 as expected. The log, however, will be written in the default database.

fuzzy76’s picture

This is done explicitly in dblog_watchdog(). I guess the reasoning is that a system message should always be recorded in the system that did the operation, not the target system.

Harry Slaughter’s picture

Valid, but long, links may get truncated in watchdog() somewhere.

I tried using a perfectly legit link in watchdog() that was over 200 characters. The end of the URL and a bunch of markup got lopped off, leaving the log messages page all messed up and making my link invalid.


vomitHatSteve’s picture

Looking through the coding of the D7 version of this function vs. the D6 version, they basically wrap the entire function in an if switch:

  static $in_error_state = FALSE;

  // It is possible that the error handling will itself trigger an error. In that case, we could
  // end up in an infinite loop. To avoid that, we implement a simple static semaphore.
  if (!$in_error_state && function_exists('module_implements')) {
    /* SNIP */
    $in_error_state = FALSE;

Does this mean that D6 is susceptible to an infinite loop if there's an error on watchdog? Are bug fixes like this not getting send back to D6?

apotek’s picture

While the error level (WATCHDOG_NOTICE, WATCHDOG_WARNING etc ) makes a difference in a console where you are reading the current system messages based in a logging level, it, unfortunately does NOT make a difference in the text generated to the file itself.

So, for example, the entry you find in /var/log/messages for this:
$ drush php-eval 'watchdog("MyModule", "My message !var %var2", array("!var" => "variable1", "%var2" => "variable2"), WATCHDOG_NOTICE,"http://mylink.com");'

Is this:

tail -1 /var/log/messages
Nov 28 18:15:49 myhostname drupal: http://default|1354144549|MyModule||http://default/index.php||0|http://mylink.com|My message variable1 variable2

If I "up" the message level to WATCHDOG_ERROR, the entry in the log file remains the same!
$ drush php-eval 'watchdog("MyModule", "My message !var %var2", array("!var" => "variable1", "%var2" => "variable2"), WATCHDOG_ERROR,"http://mylink.com");'

$ tail -1 /var/log/messages
Nov 28 18:15:49 myhostname drupal: http://default|1354144549|MyModule||http://default/index.php||0|http://mylink.com|My message variable1 variable2

In other words, the actual log entry in the log file has exactly the same info for an error as it does for a notice.

Thus, if you need to filter your logs only for warnings or errors, you can't, unless you use a console application or use the system service, which is not always possible with every host.

Suggestion: Put ERROR, WARNING, NOTICE at the start of your actual message text.
watchdog('MyModule', 'ERROR: My message !var %var2', array('!var' => 'variable1', '%var2' => 'variable2'), WATCHDOG_ERROR, 'http://mylink.com');

jaychenmyself’s picture

I want to know what the user enters into the view search ? watchdog can do it ?