4.6.x bootstrap.inc watchdog($type, $message, $severity = WATCHDOG_NOTICE, $link = NULL)
4.7.x bootstrap.inc watchdog($type, $message, $severity = WATCHDOG_NOTICE, $link = NULL)
5.x bootstrap.inc watchdog($type, $message, $severity = WATCHDOG_NOTICE, $link = NULL)
6.x bootstrap.inc watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL)
7.x bootstrap.inc watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL)

Logs a system message.


$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. Keep $message translatable by not concatenating dynamic values into it! Variables in the message should be added by using placeholder strings alongside the variables argument to declare the value of the placeholders. See t() for documentation on how $message and $variables interact.

$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; one of the following values as defined in RFC 3164:

$link: A link to associate with the message.

See also



105 calls to watchdog()
actions_do in includes/actions.inc
Performs a given list of actions by executing their callback functions.
actions_save in includes/actions.inc
Saves an action and its user-supplied parameter values to the database.
actions_synchronize in includes/actions.inc
Synchronizes actions that are provided by modules in hook_action_info().
aggregator_parse_feed in modules/aggregator/aggregator.parser.inc
Parses a feed and stores its items.
aggregator_refresh in modules/aggregator/aggregator.module
Checks a news feed for new items.

... See full list

10 string references to 'watchdog'
actions_loop_test_watchdog in modules/simpletest/tests/actions_loop_test.module
Implements hook_watchdog().
bootstrap_hooks in includes/bootstrap.inc
Defines the critical hooks that force modules to always be loaded.
dblog_top in modules/dblog/dblog.admin.inc
Page callback: Shows the most frequent log messages of a given event type.
dblog_update_7001 in modules/dblog/dblog.install
Update the {watchdog} table.
dblog_update_7002 in modules/dblog/dblog.install
Add an index to the severity column in the watchdog database table.

... See full list


includes/bootstrap.inc, line 1981
Functions that need to be loaded on every Drupal request.


function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) {
  global $user, $base_root;
  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')) {
    $in_error_state = TRUE;

    // The user object may not exist in all conditions, so 0 is substituted if needed.
    $user_uid = isset($user->uid) ? $user->uid : 0;

    // Prepare the fields to be logged
    $log_entry = array(
      'type' => $type,
      'message' => $message,
      'variables' => $variables,
      'severity' => $severity,
      'link' => $link,
      'user' => $user,
      'uid' => $user_uid,
      'request_uri' => $base_root . request_uri(),
      'referer' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '',
      'ip' => ip_address(),
      // Request time isn't accurate for long processes, use time() instead.
      'timestamp' => time(),

    // Call the logging hooks to log/process the message
    foreach (module_implements('watchdog') as $module) {
      module_invoke($module, 'watchdog', $log_entry);

    // It is critical that the semaphore is only cleared here, in the parent
    // watchdog() call (not outside the loop), to prevent recursive execution.
    $in_error_state = FALSE;


geerlingguy’s picture


function watchdog_severity_levels() {
  return array(
    WATCHDOG_EMERGENCY => 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'),
timofey’s picture

To output form id, insert the following into hooks_form_alter function:

watchdog('cg_volunteer', 'cg in form_alter %formly', array('%formly' => $form['#id']), WATCHDOG_NOTICE, $link = NULL);

check /admin/reports/dblog for the output

jhr’s picture

For debugging use dpm().
Requires the develmodule, but the output is a lot prettier and it goes to the page and not back in the log.

peterx’s picture

The comment about t() is confusing because it does not say where the translation should occur. watchdog() invokes dblog_watchdog() in modules/dblog/dblog.module and dblog_watchdog() does not translate anything. The translation has to occur before watchdog() processes the data; You could, in theory, have the following complex code when the message is logged on behalf of another module.
watchdog(t('Name @x', array('@x' => 'A')), t('Message @y @z', array('@y' => 'BBBB')), array('@z' => 'CCCCCCCCCC'));

SaV’s picture

Well it is true that dblog_watchdog is not translating anything before writing into the db...
It is translating when reading and outputing the log message.
So please just stay with the core documentation and use the watchdog function without the t().
(see function theme_dblog_message() in dblog.admin.inc at line 254)

dxvargas’s picture

I totally agree with you, don't use t() with the watchdog function. Strings should be untranslated in DB in watchdog table, they'll be translated when outputing the log message.
The documentation is misleading here, should be fixed.

paulsheldrake’s picture

Here is an example for how to use watchdog with translation and replacements

$replacements = array('!term' => $search_term);
$message = 'Query for "!term" returned 200 response but with no data';
watchdog('instagram_pane', $message, $replacements, WATCHDOG_ERROR);
kenorb’s picture

I found this function useful for reporting the errors on the site.

 * Log and display the error
 * @param string $error Error to report
 * @param object/array $object Object to include with the log
 * @param bool $backtrace TRUE if watchdog log should include full backtrace of the error
function _watchdog_log($error, $object = NULL, $backtrace = TRUE) {
  $object_msg = $object ? 'Object: ' . var_export($object, TRUE) : '';
  $bt = $backtrace ? 'Backtrace: ' . var_export(debug_backtrace(), TRUE) : '';
  watchdog('PHP', "Error message: %error
\n%bt", array('%error' => $error, '%object' => $object_msg, '%bt' => $bt), WATCHDOG_ERROR); $last_id = db_query("SELECT 1", array(), array('return' => Database::RETURN_INSERT_ID)); $msg = t("Error: !id", array('!id' => $last_id)); $err_msg = user_access('access site reports') ? l($msg, 'admin/reports/event/' . $last_id) : $msg; drupal_set_message($err_msg, 'error'); }

Especially in some try/catch areas:

      try {
// some code
      } catch (Exception $e) {
Silicon.Valet’s picture

Using hook_watchdog to spit out the dsm means that you can catch errors thrown elsewhere and filter per your own requirements.

sebby’s picture

Nice Silicon.

For example, you can have email notifications for the watchdog error, very useful.

Jverg’s picture

How i can choose from the variables only the type of the severity?

jonhattan’s picture

MD3’s picture

Link should be a valid HTML anchor tag. Use l() or url().

cleaver’s picture

aaronbauman’s picture

Example from Logging API documentation:

D7 watchdog:

watchdog('my_module', $message);
watchdog('my_module', $message, array(), WATCHDOG_ERROR);

D8 equivalent:

nafassait’s picture


japo32’s picture

Does the D8 version have translate or variables?