redis = $redis; if (!isset($settings)) { $settings = new Settings(); } $this->settings = $settings; } /** * Clear all data in the logger database. */ public function clear() { $this->templateCache = NULL; $this->redis->flushDB(); } /** * Load and cache the list of templates in the instance for this page cycle. * * Note that the templates are in Redis storage format, including the prefix, * to link directly to the results. */ protected function ensureTemplateCache() { if (!isset($this->templateCache)) { $this->templateCache = $this->scan($this->settings->getRedisPattern(), 0, $this->settings->getScanBatchSize()); } } /** * Return the list of channels. Assumed to be constant for a given page cycle. * * @return string[int] */ public function getChannels() { $this->ensureTemplateCache(); $channels = array(); foreach ($this->templateCache as $key) { preg_match($this->settings->getChannelRegex(), $key, $matches); $channel = $matches[1]; $channels[$channel] = $channel; } ksort($channels); return $channels; } /** * @param $template * The Redis key for a template. * @param int $skip * The number of pages to skip. * @param int $entries_per_page * The maximum number of entries in a page. */ public function getEntries($template, $skip = 0, $entries_per_page = 0) { $entries_per_page = $this->settings->getEntriesPerPage($entries_per_page); // Redis expect actual number of entries in the RANGE parameters. $start = $skip * $entries_per_page; $end = $start + $entries_per_page; $entries = $this->redis->lRange($template, $start, $end); return $entries; } /** * @param mixed $criterium * Filter will always pass if criterium is not set, but be checked otherwise. * @param string $regex * The regex against which to match to pass the filter. * @param $string * The string to match against the regex. * * @return bool */ protected function passesFilter($criterium, $regex, $string) { if (!isset($criterium)) { $ret = TRUE; } else { $sts = preg_match($regex, $string, $matches); $ret = $sts && ($matches[1] == $criterium); } return $ret; } /** * @return \Redis\Logger\Settings */ public function getSettings() { return $this->settings; } public static function getTemplateChannel($template) { } /** * @param null $channel * @param int $severity * WATCHDOG_* : 0 to 7 * @param int $skip * Number of pages to skip. * @param int $entries_per_page * Maximum number of entries per page. */ public function getTemplates($channel = NULL, $severity = NULL, $skip = 0, $entries_per_page = 0) { $this->ensureTemplateCache(); $matches = array(); $count = 0; $channelRegex = $this->settings->getChannelRegex(); $severityRegex = $this->settings->getSeverityRegex(); $entries_per_page = $this->settings->getEntriesPerPage($entries_per_page); $start = $skip * $entries_per_page; $end = $start + $entries_per_page; foreach ($this->templateCache as $template) { if (!$this->passesFilter($channel, $channelRegex, $template)) { continue; } if (!$this->passesFilter($severity, $severityRegex, $template)) { continue; } $count++; if ($count >= $skip) { if ($count >= $end) { break; } $matches[] = $template; } } return $matches; } /** * Perform a complete Redis SCAN series. * * @param string $pattern * The Redis SCAN MATCH optional argument. * @param int $max * Maximum number of matches to be returned. Cursor is left dangling if $max * is lower than the maximum number of available results: only the minimum * number of SCAN iterations needed to reach $max results will be performed. * @param int $batch_suggestion * The Redis SCAN COUNT optional argument. * * @return string[] */ public function scan($pattern = '*', $max = 0, $batch_suggestion = 10) { $redis = $this->redis; $saved_scan_option = $redis->getOption(\Redis::OPT_SCAN); $redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY); $ret = array(); // Initialize our iterator to NULL. $scan_it = NULL; $count = 0; $request_count = 1; // Retry when we get no keys back. while ($arr_keys = $redis->scan($scan_it, $pattern, $batch_suggestion)) { $request_count++; foreach ($arr_keys as $str_key) { $ret[] = $str_key; if ($max) { $count++; if ($count >= $max) { break 2; // Break out of foreach + while. } } } } if ($saved_scan_option != \Redis::SCAN_RETRY) { $redis->setOption(\Redis::OPT_SCAN, $saved_scan_option); } return $ret; } }