You are here

function performance_update_7200 in Performance Logging and Monitoring 7.2

Move summary data from old performance_summary table to new cache bin. Note that we now cache per language and separate anonymous users from logged in users! During this migration, we do BASIC separation between anonymous and logged in users based on admin paths. Back up your data if you want to keep the original logs! DRUSH NOTE: make sure to set a proper $base_url using the --uri parameter or by means of a drushrc.php config file! Alternatively you can setup a $conf['performance_key'] = 'my_unique_key'; in settings.php when using multiple domains for one site.

File

./performance.install, line 241
Install and update for Performance Logging

Code

function performance_update_7200() {
  global $language;

  // Abort when improperly invoked when using drush. See DRUSH NOTE above.
  if (drupal_is_cli() && variable_get('performance_key', FALSE) === FALSE && $GLOBALS['base_url'] == 'http://default') {

    // Throw an exception to make this update fail. Found no other way. Better
    // suggestion anyone? Tried various drush functions, such as
    // drush_set_error(), to no avail. Update was always marked as 'completed'
    // and was not re-executed when re-running drush updb.
    throw new Exception(dt("Please run drush with the --uri parameter or setup a drushrc.php file to successfully migrate the summary data! The site's domain name will be used in the cache key! Use \$conf['performance_key'] = 'my_unique_key'; in settings.php when using multiple domains on one site."));
    return;
  }

  // Create new cache bin, see http://drupal.org/node/150220.
  $table = array(
    'description' => 'Table that holds summary performance data.',
    'fields' => array(
      'cid' => array(
        'description' => 'Primary Key: Unique cache ID.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'data' => array(
        'description' => 'A collection of data to cache.',
        'type' => 'blob',
        'not null' => FALSE,
        'size' => 'big',
      ),
      'expire' => array(
        'description' => 'A Unix timestamp indicating when the cache entry should expire, or 0 for never.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'created' => array(
        'description' => 'A Unix timestamp indicating when the cache entry was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'serialized' => array(
        'description' => 'A flag to indicate whether content is serialized (1) or not (0).',
        'type' => 'int',
        'size' => 'small',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'expire' => array(
        'expire',
      ),
    ),
    'primary key' => array(
      'cid',
    ),
  );
  $keys_cache = array();

  // Keep records for 1 day.
  $expire = REQUEST_TIME + 24 * 60 * 60;

  // Extra check to prevent errors when running this update multiple times.
  if (db_table_exists('performance_summary') && !db_table_exists('cache_performance')) {
    db_create_table('cache_performance', $table);
    $result = db_select('performance_summary', 'ps')
      ->fields('ps')
      ->execute();
    foreach ($result as $row) {

      // Make some BASIC separation between anonymous users and logged in users.
      $anonymous = 1;
      if (preg_match('/^(admin|admin\\/.*|node\\/add.*)$/i', $row->path) || preg_match('/^(node|user)\\/\\d+\\/(edit|translate|delete|revisions.*)$/i', $row->path)) {
        $anonymous = 0;
      }
      $data = array(
        'path' => $row->path,
        'bytes_max' => $row->bytes_max,
        'bytes_sum' => $row->bytes_avg * $row->num_accesses,
        'ms_max' => $row->ms_max,
        'ms_sum' => $row->ms_avg * $row->num_accesses,
        'query_timer_max' => $row->query_timer_max,
        'query_timer_sum' => $row->query_timer_avg * $row->num_accesses,
        'query_count_max' => $row->query_count_max,
        'query_count_sum' => $row->query_count_avg * $row->num_accesses,
        'num_accesses' => $row->num_accesses,
        'last_access' => $row->last_access,
        'anon' => $anonymous,
        'language' => $language->language,
      );

      // We now cache per language and distinguish between anonymous users and
      // logged in users. As usual, we keep logs for one day!
      $key = PERFORMANCE_KEY . $row->path . ':' . $language->language . ':' . $anonymous;
      cache_set($key, $data, 'cache_performance', $expire);

      // Keep the key for the key cache store. We do it this way so that keys
      // will replace eachother which would not happen when using
      // $keys_cache[] = $key;
      $keys_cache[$key] = 1;
    }

    // This will allow easy retrieval of data as we cannot use SQL queries since
    // the cache store can by anything!
    cache_set(PERFORMANCE_KEY, $keys_cache, 'cache_performance');

    // No longer needed!
    db_drop_table('performance_summary');

    // Preserve summary logging setting if enabled.
    // There can, in theory, be unlimited variables named performance_summary_%
    // where we do not know what % is, hence this approach.
    $result = db_select('variable', 'v')
      ->fields('v', array(
      'value',
    ))
      ->condition('name', 'performance_summary\\_%', 'LIKE')
      ->execute();
    foreach ($result as $row) {
      if (unserialize($row->value)) {
        variable_set('performance_summary', 1);
        break;
      }
    }

    // Delete old performance summary variables!
    db_delete('variable')
      ->condition('name', 'performance_summary\\_%', 'LIKE')
      ->execute();
    return t('Migrated all data from old performance_summary table to new cache bin.');
  }
}