Make cron watchdog more granular and informative

kbahey - March 27, 2007 - 18:39
Project:Drupal
Version:7.x-dev
Component:cron system
Category:feature request
Priority:normal
Assigned:Unassigned
Status:active
Issue tags:cron
Description

Often times, one sees cron runs being slow, but can't easily tell which module is causing the slowness.

This patch makes cron's watchdog messages more granular. It reports each module that is run by cron, and the number of milliseconds it takes for each to complete.

This makes the information automatically collected and available at a glance in the watchdog, without the need to install devel, ...etc.

Here are sample results:

select message from watchdog where type = 'cron' order by wid;
+-----------------------------------------------+
| message                                       |
+-----------------------------------------------+
| cron time elapsed for aggregator is 39.72 ms. |
| cron time elapsed for drupal is 1.27 ms.      |
| cron time elapsed for filter is 1.77 ms.      |
| cron time elapsed for node is 1.57 ms.        |
| cron time elapsed for ping is 1.26 ms.        |
| cron time elapsed for poll is 8.77 ms.        |
| cron time elapsed for search is 6.94 ms.      |
| cron time elapsed for statistics is 3.47 ms.  |
| cron time elapsed for watchdog is 2.99 ms.    |
| Cron run completed.                           |
+-----------------------------------------------+
10 rows in set (0.00 sec)

AttachmentSizeStatusTest resultOperations
cron-timings.patch945 bytesIgnoredNoneNone

#1

yched - March 28, 2007 - 15:02

+1 - it's quite difficult right now to find out where a cron messes up.

#2

ChrisKennedy - March 30, 2007 - 18:25

Won't this seriously fill up the watchdog table with cron messages and make it harder to quickly see other error logs? It would be nice if there were a way to get verbose cron error messages in cases of an error, but short ones if everything works correctly.

#3

yched - March 30, 2007 - 18:44

Isn't the 'filter' dropdown on the log page precisely here for that ?

I just had to debug a dysfunctionnal cron, and found this really useful.
In fact there should even be an addition message on cron start for each module IMO, in order to point out the offending module easily (you get in but don't get out)

#4

ChrisKennedy - March 30, 2007 - 18:51

I don't think it would be a good idea if every admin had to continually filter out dozens of pages of cron messages in order to find out if anything important has happened to their site.

As you said, this helped you debug a dysfunctional cron. But the other 364 days of the year when cron works you're just spamming the watchdog table in a way that obscures other important information.

You don't think there's a way to help people debug dysfunctional cron jobs while not generating huge numbers of log messages when its working properly?

#5

kbahey - March 30, 2007 - 19:20

How about if I combine all the messages in one message, so the number of entries is no longer a concern?

#6

FiReaNG3L - March 30, 2007 - 20:19

ChrisKennedy: The same remark could be done for user logins and other somehow useful cron messages. Watchdog is more often than not a flood of not really useful information if you have no problems. Its whole point is to provide information in case of problems.

Of course, if we could choose which level of cron to run (basic, advanced, debug? see http://drupal.org/node/77875) we could avoid this kind of problem.

The suggestion is good for debug purposes. I dont think it could be implemented in devel?

#7

kbahey - March 30, 2007 - 20:29

I don't think I would want it to be a devel thing, or an option.

The reason is, if it goes wrong once and the problem never recurrs you have no chance of knowing what happened. If it is always on, then you can go back and see which module is the culprit without the need for installing something new, and the chance that it will not happen again.

I can collapse all the messages in one so the "too much messages in the log" complaint is resolved.

If this has a chance to get in core, I will do that. Otherwise, if it gets shot early, or new direction/features are requested, there is no point.

#8

yched - March 30, 2007 - 21:41

collapse all messages into one : why not - but if cron execution breaks in the middle, then nothing gets logged at all ?

#9

kbahey - March 30, 2007 - 23:43

So far, we have a +2 (yched and myself) and a -1 (Chris Johnson).

Anyone else wants to comment on this?

#10

scor - May 15, 2007 - 20:28

I agree with yched and kbahey, it can come handy when a module tends to be too greedy. having an all-in-one message seems necessary.
Worst case scenario, how about an option in the status report page: 'Activate detailed cron watchdog'

#11

keith.smith - June 23, 2007 - 20:03
Status:needs review» needs work

This patch applied successfully, and did log cron activities and their respective completion times. This is a useful patch, and may become more so as Update Status gets into core (US queries to drupal.org for module information may vary depending on the responsiveness, or lack thereof, of drupal.org, and this type of information may be helpful in staving off extra support requests in the forums due to 'failed' cron runs.)

That said, this patch does throw some notices on an undefined $args variable so am setting to cnw.

#12

kbahey - June 23, 2007 - 20:40
Status:needs work» needs review

Here is a version that just calls the function.

I also made this optional, so those who need it can add a variable to settings.php, documented in a comment.

The default behavior is not to log, and hence no one sees anything new.

To enable it, just add this to settings.php:

<?php
$conf
= array(
 
'cron_log_times' => 1,
);
?>

AttachmentSizeStatusTest resultOperations
cron-timings-2.patch1.13 KBIgnoredNoneNone

#13

meba - July 1, 2007 - 20:22

this seems ok. i agree it's now difficult to see what messed up the cron. applied succesfully

#14

webchick - July 1, 2007 - 20:51
Status:needs review» needs work

It seems like we don't need to do the timer business unless that flag is enabled, correct? So it should surround the entire logic, not just the output of the message.

#15

Gábor Hojtsy - July 1, 2007 - 21:05

And watchdog() should not have t() in it anymore.

#16

kbahey - July 1, 2007 - 21:14
Status:needs work» needs review

I think the timing overhead is negligible. We already do it for the database layer.

Anyway, here is a patch that addresses both comments.

AttachmentSizeStatusTest resultOperations
cron-timings-3.patch1.26 KBIgnoredNoneNone

#17

douggreen - September 4, 2007 - 12:32

As a compromise to the two possibilities (a) have it always on, or (b) turn it on with a settings.php setting, I'd like to propose that this automatically enable itself when it self-detects that it's running too long. This can be easily done by adding a variable_set in drupal_cron_cleanup. However, if such an option happens automatically, then I think that we'd also need to add a user setting to disable it, rather than rely on the admin to edit settings.php.

I also suggest that this be added to the commented out values in settings.php, otherwise, the option will be little known. There doesn't appear to be any precedence for this (very few variables are listed, and none that are entirely core based settings without a UI), so I don't know if the idea will be accepted.

I rolled a new patch that removes a couple extraneous lines of code. I tested with and without the option and confirm that it works.

Since the suggestions above need discussion, I didn't roll them into the patch

AttachmentSizeStatusTest resultOperations
131536.patch1.19 KBIgnoredNoneNone

#18

catch - October 26, 2007 - 23:33

This would be nice to have, it's hard to work out what makes cron run slow at the moment. #17 still applies with offset.

#19

Dries - October 28, 2007 - 14:38

It's too verbose, IMO. I'm OK with showing a timestamp, but it shouldn't generate that many messages.

#20

catch - October 31, 2007 - 11:29
Status:needs review» needs work

ok then.

#21

kbahey - October 31, 2007 - 14:43

Dries

Per your comment on verbosity? Would you accept it if it just had the module name and number of milliseconds?

#22

Pancho - February 8, 2008 - 00:05
Version:6.x-dev» 7.x-dev

Moving feature requests to D7 queue.

#23

kbahey - February 18, 2008 - 18:38
Status:needs work» needs review

@douggreen

Your idea is good, but sometimes cron does not complete, so it may not turn itself on.

Here is an updated patch, rerolled for 7.x.

It also has a commented out $conf in settings.php saying what it will do when enabled.

I tested it and it works. Zero impact by default, but gives useful info when needed.

AttachmentSizeStatusTest resultOperations
cron-timing-4.patch2.2 KBIdlePassed: 8991 passes, 0 fails, 0 exceptionsView details | Re-test

#24

coltrane - February 20, 2008 - 18:54

#23 applies with offset, code looks good and it works correctly.

I like this feature and I'm used to visually parsing through many lines of log code so my vote is the output stays as-is and doesn't get lumped into a single watchdog message.

#25

aexl_konzepto.net - March 19, 2008 - 01:26

thank you for this great patch. it helped me a lot when debuging a nasty lockup of my cron.
i (imho) improved this in some ways, as i do development on 5.7 find my code in #236077: Verbose cron backport.
start/stop helped me in finding my lockup, cron got killed before finishing.
a re-backport should be easy, i just changed the signature of the watchdog function.

from #236077: Verbose cron backport:

With this patch of includes/common.inc cron tells you something like this:

Cron run completed: 452.03 ms. (filter:16, node:8, search:4, statistics:0, watchdog:28, backup_migrate:0, cram:8, eventrepeat:32, image:16, job_queue:184.01, persistent_login:8, simplenews:40, subscriptions_mail:84.01, update_status:0, workflow:4, cclinks:16, states:0, calendar_ical:4, subscriptions_content:0, notify:0)

also,
// If you want to log start/stop messages for each module to the watchdog,
// then add the following line to your settings.php
//
// $conf = array ('cron_debug' => 1);

This is a backport of a patch in #131536: Make cron watchdog more granular and informative with (imho) significant improvements.
The only change is the different signature of the watchdog function.
The settings.php changes are not included in this patch.

#26

flobruit - March 21, 2008 - 19:30

+1. The optional verbose cron run is definitely the way to go.

re-rolled patch from #23

AttachmentSizeStatusTest resultOperations
cron-timing-131536-26.patch2.29 KBIdleFailed: 9172 passes, 3 fails, 3 exceptionsView details | Re-test

#27

aexl_konzepto.net - March 22, 2008 - 21:22

let me advertise my improvements:

- cron is always verbose, but output is collected on one watchdog line.
if my cron gets stuck, i have the advantage to have debug information at hand.
timer calls are cheap, and no extra log lines are wasted. so why not collect information always???

- start/stop messages:
sometimes my cron gets stuck (eg by a backup module), and i wont see a 'cron finished' line in watchdog.
then i turn on cron-debug and now i can see which module is started but never stopped.
as this clutters up log messages, it is an option.

#28

keith.smith - March 22, 2008 - 21:36
Status:needs review» needs work

+ * Enable the following settings to make cron logs the time, in milliseconds
+ * taken for each hook_cron in all modules that implement it. This is helpful
+ * when you want to narrow down which module bogs down cron runs. The messages
+ * are logged to the watchdog, so you can see it in dblog or syslog, depending
+ * on which one you have configured.

- Note that "logs" should be "log".
- Comma after "in milliseconds"
- "narrow down which module bogs down cron runs" -> "narrow down" and "bogs down" are both very colloquial uses of that may be hard for some non-native English speakers to parse.

#29

andreiashu - March 23, 2008 - 01:59

Is there any chance that i could apply this patch for a D5 site ?

#30

kbahey - March 23, 2008 - 02:40

@andreiashu

The patch in #16 (cron-timings-3.patch) applies to Drupal 5 (with offset that you can ignore).

#31

andreiashu - March 23, 2008 - 02:55

@kbahey 10x for quick response. I applied the patch successfully with one little adjustment:
- watchdog('cron', 'Cron time elapsed for @module is @millisecs ms.', array('@module' => $module, '@millisecs' => $timer['time']));
+ watchdog('cron', 'Cron time elapsed for '.$module.' is '.$timer['time'].' ms.');

#32

Steven Jones - April 8, 2008 - 09:18
Status:needs work» needs review

Patch from #26, updated with comments from #28 and re-rolled against HEAD.

AttachmentSizeStatusTest resultOperations
cron-timing-131536.patch2.2 KBIdleFailed: 9191 passes, 3 fails, 3 exceptionsView details | Re-test

#33

csevb10 - April 8, 2008 - 21:36

If this had existed before, it would have been tremendously helpful to debug performance issues on pretty much every large site I've worked on.
+1 to this so that I don't have to do it manually every time moving forward.

#34

flobruit - April 8, 2008 - 22:27

Works as expected (only verbose when specified).

Style change for default.settings.php: add a title to the comment, and use

# $conf['cron_log_times'] = 1;

instead of

# $conf = array(
  ...
#   'cron_log_times' => 1, // Leave the comma here.
  ...
#);

so that it is easier to enable/disable one setting independently from the others.

AttachmentSizeStatusTest resultOperations
cron-timing-131536-34.patch2.21 KBIdleFailed: 9020 passes, 3 fails, 3 exceptionsView details | Re-test

#35

EvanDonovan - August 6, 2008 - 22:01

+1 for this patch.

Subscribing...

#36

lilou - August 23, 2008 - 20:20

Patch still applied against CVS HEAD.

#37

Arancaytar - November 16, 2008 - 13:05
Status:needs review» needs work

+    // If you want to log cron timings for each module to the watchdog,
+    // then add the following line to your settings.php:
+    //
+    // $conf = array ('cron_log_times' => 1);

Isn't this what we have configuration pages for? Just because I'm a hardcore coder who needs to debug cron now and then, it doesn't mean I'm allergic to GUIs. ;)

My suggestion is to put this on the error reporting settings page, or something...

#38

catch - November 16, 2008 - 16:32

I'm all for obscure variables which don't get exposed in the core UI - can we put the interface for this in the devel module?

#39

kbahey - November 17, 2008 - 22:20
Status:needs work» needs review

Here is a reroll for offsets with better wording.

AttachmentSizeStatusTest resultOperations
cron-timing-131536-39.patch2.18 KBIdleFailed: 8990 passes, 1 fail, 0 exceptionsView details | Re-test

#40

Squigee - November 20, 2008 - 02:53

This is a great patch and the functionality is very useful when debugging cron failures. I was experiencing a cron failure that presented as a timeout (but the amount of time that elapsed was not enough to actually be a timeout). I applied the patch and was able to see the modules that succeeded, but I needed to know the module that cron was choking on.

By changing:
if ($log_timing) {
timer_start($function);
}

to
if ($log_timing) {
timer_start($function);
watchdog('cron', 'Cron process for @module module initiated', array('@module' => $module));
}

I was able to see which module started cron but never completed. This allowed me to isolate the module causing the problem (disabling it allowed subsequent cron jobs to complete properly). I suggest you consider adding this feature to the verbose output... if not explicitly defined but then available through another config setting. I found this functionality crucial in debugging.

Best regards,
-Mike

#41

kbahey - November 20, 2008 - 03:07

Here is a patch that does that.

If you set the variable to 'info', only timings are logged. If you set it to 'debug', it will log timing and start of processing for each module.

AttachmentSizeStatusTest resultOperations
cron-timing-131536-41.patch2.88 KBIdleFailed: 9191 passes, 3 fails, 3 exceptionsView details | Re-test

#42

gpk - November 27, 2008 - 18:39

#43

wwwoliondorcom - January 10, 2009 - 07:13

Cron job problem on FILTER - Cron has been running for more than an hour and is most likely stuck.

Hi,

I have found that my Cron problem might be caused by the core FILTER module, but as I cannot disable it I wonder what to do now ?

Thanks a lot.

#44

rkdesantos - January 15, 2009 - 06:14

I've been using the patch in #23 for awhile and re-applying as Drupal versions changed. After the upgrade to v5.15 was done and the patch reapplied it no longer works properly and I get:

Cron time elapsed for @module is @millisecs ms

in my log instead of the module timings. Any ideas? Anyone else have this issue or did I miss something in the upgrade?

#45

momper - January 15, 2009 - 18:13

+1 for this functionality after hours of debugging (crontab was o.k. - problem has to do something with a module)

i would be interested (like #44) in an solution for 5.x and 6.x

thanks a lot

#46

gpk - January 17, 2009 - 20:32

@43: unlikely, all http://api.drupal.org/api/function/filter_cron/6 does is to clear a cache.

@44: that's not surprising. #23 uses the Drupal 6.x/7.x watchdog API in which the 3rd argument is an array of variables for substituting into the $message. In 5.x you would need to change that line in drupal_cron_run() to

<?php
watchdog
('cron', t('Cron time elapsed for @module is @millisecs ms.', array('@module' => $module, '@millisecs' => $timer['time'])));
?>

#47

rkdesantos - January 18, 2009 - 02:06

Thanks gpk, that worked. I was able to take the latest version of the patch, make the necessary change and it is working great now in v5.15.

#48

System Message - January 22, 2009 - 10:20
Status:needs review» needs work

The last submitted patch failed testing.

#49

tstoeckler - February 13, 2009 - 22:42

#50

rkdesantos - May 27, 2009 - 02:07

It would be great if this can get into D7. I've patched versions of D5 and D6 manually and found it to be immensely valuable in finding problems in cron as well as giving me a clear indication of which modules are consuming the most resources on cron runs.

#51

Dave Reid - July 7, 2009 - 21:01

I have a feeling that this is creeping fast towards debugging info. Something like this would be great in contrib (cron_debug). Since it could provide as useful as information as needed. As much as this problem has bitten me already, I don't think it's appropriate for core.

#52

EvanDonovan - July 7, 2009 - 22:24

Personally, I've stopped using this patch, useful as it was, in favor of SuperCron (http://drupal.org/project/supercron), which is vastly more powerful.

I suppose there's no chance that a cron implementation with some of the features of SuperCron (individual hook invocation, individual hook disabling, cron statistics) could make it into 7.x core is there?

SuperCron has a great deal of debugging info available but requires that you replace the default cron.php with supercron.php in your crontab. I think it would be great if SuperCron was worked on to the point where it was core-worthy, since that way you could have as much or as little debugging information as possible. But as it is, I'm fairly satisfied with having it in contrib, as long as it gets more widely known as a valuable resource.

#53

gpk - July 7, 2009 - 22:24

For cron_debug... see http://drupal.org/project/supercron.

Note that there is no real way of hooking into the cron run (to output debugging info etc.), and supercron gets round this by essentially replacing the default cron.php with its own supercron.php. Maybe that's the best way of doing it, or maybe cron.php should allow other (cron) modules to alter its behavior?

(Also note that versions of poormanscron that output similar debugging info are able to so by bypassing cron.php/drupal_cron_run.)

#54

EvanDonovan - July 7, 2009 - 22:24

gpk & I cross-posted, in case anyone's confused :)

#55

Dave Reid - July 7, 2009 - 22:54
Status:needs work» won't fix

If other modules want to bypass the cron system, it's easy to do so using module_implements() and module_invoke(). IAs this hasn't had much traction lately, this isn't really appropriate for core, and there are better alternative methods in contrib, I'm going to mark this won't fix.

#56

gpk - July 8, 2009 - 08:24

>If other modules want to bypass the cron system, it's easy to do so using module_implements() and module_invoke().
Well yes, that's what supercron does.

The point I was trying to get at is that you have to manually bypass cron.php / drupal_cron_run(), e.g. by putting a new supercron.php file in the root of your Drupal install in this case (and you then have to put it back every time you upgrade core). So my question was more to do with whether Drupal's cron.php / http://api.drupal.org/api/function/drupal_cron_run/6 should let you skip the core code for invoking cron hooks and use your own custom routine instead (à la supercron). Perhaps like the custom smtp library you can define in 5.x/6.x, for bypassing Drupal's default mail sending.

If anyone thinks this would be a good idea then this issue could be repurposed, or a new one opened.

#57

EvanDonovan - July 9, 2009 - 20:21
Status:won't fix» active

I think making the cron system pluggable, like the cache system or the SMTP mail system, is a great idea. Reopening just long enough to discuss whether we should make that a new issue :)

#58

Dave Reid - September 27, 2009 - 23:12
Component:base system» cron system

Moving to new cron system component.

 
 

Drupal is a registered trademark of Dries Buytaert.