Skip to main content

Blog Post

How to Get a Summary of Watchdog (dblog) Messages

While working on a site audit, I wanted to be able to see what errors were currently happening on the site. I checked and they had dblog enabled already with a few days of errors, but going to admin/reports/dblog showed me pages full of the same error. This can happen when there is an error that occurs on a popular page or happens on every page load and it makes the logs difficult to read. In addition to that, the overview page truncates the error message and so you need to click through to the detail page to see the entire thing.

There are contributed modules for viewing and interacting with the error log such as Better Watchdog UI and Views Watchdog, plus built into drush is drush watchdog-show. However, I was looking for something simple that 1) didn't require me to install and learn a module, and 2) got rid of the message duplication. Finding nothing that fit my needs exactly, I ended up writing a small script. This is just a simple PHP file that you run with drush scr and it spits out an HTML file.

To use it:

  • Copy the script into a text file.
  • Save it as watchdog-view.php (or whatever you’d like to call it).
  • Run it with drush scr watchdog-view.php > site-errors.html
  • Open up the site-errors.html file in your browser.
<?php

// To skip over types of messages, add them to this array.
// Example: $skip_types = array('cron', 'user');
$skip_types = array();

// Get the list of names that go with the severity levels.
$severity_levels = watchdog_severity_levels();

drush_print("<html>");
drush_print("<body>");
drush_print("<h1>WATCHDOG MESSAGES</h1>");

// Get all the message types.
$query = db_select('watchdog', 'wd')
 ->fields('wd', array('type'))
 ->distinct();

$types = $query->execute();

// Build a table for each message type.
foreach ($types as $typeobj) {
 $type = $typeobj->type;

 // If this type is one we want to skip, go to the top of the loop.
 if (in_array($type, $skip_types)) {
   continue;
 }

 // Get messages for this type, one for each location/message combo, ignoring
 // the timestamp. If you have errors that are occurring on every page load
 // and want to condense it further, omit the "location" throughout the script.
 $query = db_select('watchdog', 'wd')
   ->fields('wd', array('variables', 'location', 'message', 'severity'))
   ->condition('type', $type)
   ->orderBy('message', 'location')
   ->groupby('location', 'message', 'variables');

 $result = $query->execute();

 // Print out the messages for this type in a table.
 drush_print("<h2>Type: $type</h2>");
 drush_print('<table border="1">');
 drush_print('<tr><th>Severity</th><th>Message</th><th>Location</th></tr>');

 foreach ($result as $row) {
   if (isset($row->message) && isset($row->variables)) {
     if ($row->variables === 'N;') {
       $message = $row->message;
     }
     else {
       $message = t($row->message, unserialize($row->variables));
     }

     // Make the location clickable.
     $location = '<a href="' . $row->location . '">' . $row->location . '</a>';

     // Get the name of the severity level.
     $severity = $severity_levels[$row->severity];

     // Print out the row.
     drush_print('<tr>');
     drush_print("<td>$severity</td>");
     drush_print("<td>$message</td>");
     drush_print("<td>$location</td>");
     drush_print('</tr>');
   }
 }

 drush_print("</table>");
}

drush_print("</body>");
drush_print("</html>");

The resulting HTML page looks like a flashback to the 90s web (minus the animated gifs and blinky tags) but it’s a simple and clean overview of everything your site is currently logging.

Additional Resources
Getting Your Drupal 6 Site Ready to Run on PHP 5.6 | Blog
How to Prettify The Output From Your Remote Drush Commands | Blog 
Conditionally Open a Link in a New Tab in Views Without the PHP Filter | Blog

Headshot

Meet team member, Michelle Cox

Michelle started using Drupal in 2005 with the 4.6 release. She spent the next seven years actively participating in the community by writing and maintaining three contributed modules, assisting in the forums and on IRC, and performing webmaster duties on the *.drupal.org sites. After a two year break to focus on photography, she came back to Drupal and contributes to the community by helping with webmaster tasks and working with her co-maintainers on her contributed modules.

Michelle first discovered her love of programming by writing BASIC programs on her Commodore 64 as a teen. While working toward her BS in computer science at University of Wisconsin - La Crosse
, she started work as a Visual Foxpro developer and continued to work in VFP until 2004. She kept programming as a hobby when she left the professional world to take care of her two boys. Michelle  discovered Drupal while working on her family website and quickly fell in love with both the software and the community. Prior to Mediacurrent, she developed a local community social networking site and wrote the Advanced Forum, Author Pane, and Advanced Profile Kit modules.

In addition to being a coder, Michelle is a mom, photographer, and Whovian. Percentages vary.

Learn more about Michelle >

Related Insights