I would like to propose a modification to to the Drupal v6+ core modules common.inc and modules.inc that will make it possible to easily trace and "unstick" cron execution by simply setting two new variables in the variable table.

This is a problem that seems to crop up from time to time, often (usually?) due to module misconfiguration or defective data. It is however, somewhat problematic to track down which module is misbehaving.

I have tested the core hack detailed below under Drupal 6.14 and it seems to work well so I am submitting it for review and possible inclusion in Drupal Core.

If this proposed modification is accepted, perhaps someone more familiar than I with Drupal user interface coding can put together an interface to set and unset these two added variables at a suitable spot in the admin interface, and create an update script to add the variables to the database automatically.

Firstly, in function drupal_cron_run() (line 2662 in common.inc for Drupal 6.14)
Following the line

	$semaphore = variable_get('cron_semaphore', FALSE);

add the lines

	global $conf;
	$result = db_query('SELECT * FROM {variable} WHERE {name} LIKE \'cron%\'');
	while ($variable = db_fetch_object($result)) {
	  $conf[$variable->name] = unserialize($variable->value);
	}
	$crontrace = isset($conf['cron_trace']) ? $conf['cron_trace'] : FALSE;
	$cronreset = isset($conf['cron_reset']) ? $conf['cron_reset'] : FALSE;
	if ($crontrace) {
	  watchdog('cron', "Cron invoked", array(), WATCHDOG_NOTICE);
	  if ($cronreset) $semaphore = FALSE;
	  variable_set('cron_reset', FALSE);
	}

Reading in from the data table directly ensures that the intended values for the two new variables 'cron_trace' and 'cron_reset' will be read no matter what else is happening in the system. This will take considerably longer than reading the cached variable value using the variable_get() function but as cron is normally invoked daily or, worst case typically hourly, the additional overhead is negligible.

Now, if the variable 'cron_trace' is true (non-zero), a watchdog notice will be issued indicating the invocation of cron. In addition, if 'cron_reset' is true (non-zero), the cron semaphore will be forced to zero, ensuring that cron will actually run.

Secondly, in function module_invoke_all (at the end of modules.inc - (line 464 in modules.inc for Drupal 6.14), modify the lines

	  foreach (module_implements($hook) as $module) {
	    $function = $module .'_'. $hook;
	    $result = call_user_func_array($function, $args);

to the following...

	  foreach (module_implements($hook) as $module) {
	    $function = $module .'_'. $hook;

	    $crontrace = variable_get('cron_trace', FALSE);
	    if ($crontrace && $hook == 'cron')
	      watchdog('cron', "$function invoked.", array(), WATCHDOG_NOTICE);
	    $t1 = gettimeofday();
	    $result = call_user_func_array($function, $args);
	    $t2 = gettimeofday();
	    if ($crontrace && $hook == 'cron') {
	      $secs = $t2['sec'] - $t1['sec'];
	      $usec = $t2['usec']- $t1['usec'];
	      if ($usec < 0) { $usec += 1000000; $secs -= 1; }
	      $msg = sprintf("%s ran for %d.%06d seconds.", $function, $secs, $usec);
	        watchdog('cron', $msg, array(), WATCHDOG_NOTICE);
	    }

This will then log to the watchdog table each and every cron hook invocation, and upon return from the hook function, the execution time for that hook will also be recorded.

Now add to the variable table in the database the following rows (using phpMyAdmin or other suitable database tool) ...

name value
cron_reset i:0;
cron_trace i:0;

Now the detailed per-hook trace of a cron invocation can be enabled by setting the cron_trace variable to 'i:1;' (php serialized representation of integer value 1) and after invoking cron the results can be viewed in the watchdog log.

If cron is actually stuck - reporting that it is already running or has run for too long in the watchdog log, you will need to also set the variable 'cron_reset' to 'i:1;'

This will now force cron to run and examination of the watchdog log entries generated by the run will help localise which module's cron hook is misbehaving.

The additional watchdog logging calls will only occur when the trace is turned on, and then only if cron hooks are being invoked, so the additional overhead in module_invoke_all is minimal - one cached variable_get, two if statements and two calls to system function gettimeofday().

If anyone borrows this patch and applies it themselves, please remember that in its current form, this is a core hack. As such, it will be overwritten and need to be reapplied whenever you update Drupal.

Comments

Dr Jay’s picture

Thanks for this - works like a peach! +1 to add this to the core.

tryitonce’s picture

subscribing

neokrish’s picture

subscribing

VM’s picture

feature requests should be filed against the newest version of Drupal. New features don't directly go into older versions of Drupal core. This should have been marked D7 originally, but now it may likely have to be moved to D8 for others to take a serious look at it.

marcingy’s picture

Version: 6.x-dev » 8.x-dev

Bumping version

kscheirer’s picture

Status: Needs review » Needs work

This might still be a good idea, but cron has changed somewhat since D6, this patch will need a reroll at minimum.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Issue summary: View changes
Status: Needs work » Closed (outdated)

This seems like it was open for D6. Which obviously is no longer supported. If still valid for D10 and up please reopen updating issue summary

Thanks.