Skip to content
Snippets Groups Projects
Commit 71fb8d36 authored by Olav Morken's avatar Olav Morken
Browse files

New statistics logging core.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@3053 44740490-163a-0410-bde0-09ae8108e29a
parent d6e793bd
No related branches found
No related tags found
No related merge requests found
......@@ -140,8 +140,29 @@ $config = array (
/* Logging: file - Logfilename in the loggingdir from above.
*/
'logging.logfile' => 'simplesamlphp.log',
/* (New) statistics output configuration.
*
* This is an array of outputs. Each output has at least a 'class' option, which
* selects the output.
*/
'statistics.out' => array(
// Log statistics to the normal log.
/*
array(
'class' => 'core:Log',
'level' => 'notice',
),
*/
// Log statistics to files in a directory. One file per day.
/*
array(
'class' => 'core:File',
'directory' => '/var/log/stats',
),
*/
),
/*
* Enable
......
<?php
/**
* Statistics handler class.
*
* This class is responsible for taking a statistics event and logging it.
*
* @package simpleSAMLphp
* @version $Id$
*/
class SimpleSAML_Stats {
/**
* Whether this class is initialized.
* @var boolean
*/
private static $initialized = FALSE;
/**
* The statistics output callbacks.
* @var array
*/
private static $outputs = NULL;
/**
* Create an output from a configuration object.
*
* @param SimpleSAML_Configuration $config The configuration object.
* @return
*/
private static function createOutput(SimpleSAML_Configuration $config) {
$cls = $config->getString('class');
$cls = SimpleSAML_Module::resolveClass($cls, 'Stats_Output', 'SimpleSAML_Stats_Output');
$output = new $cls($config);
return $output;
}
/**
* Initialize the outputs.
*/
private static function initOutputs() {
$config = SimpleSAML_Configuration::getInstance();
$outputCfgs = $config->getConfigList('statistics.out', array());
self::$outputs = array();
foreach ($outputCfgs as $cfg) {
self::$outputs[] = self::createOutput($cfg);
}
}
/**
* Notify about an event.
*
* @param string $event The event.
* @param array $data Event data. Optional.
*/
public static function log($event, array $data = array()) {
assert('is_string($event)');
assert('!isset($data["op"])');
assert('!isset($data["time"])');
assert('!isset($data["_id"])');
if (!self::$initialized) {
self::initOutputs();
self::$initialized = TRUE;
}
if (empty(self::$outputs)) {
/* Not enabled. */
return;
}
$data['op'] = $event;
$data['time'] = microtime(TRUE);
/* The ID generation is designed to cluster IDs related in time close together. */
$int_t = (int)$data['time'];
$hd = SimpleSAML_Utilities::generateRandomBytes(16);
$data['_id'] = sprintf('%016x%s', $int_t, bin2hex($hd));
foreach (self::$outputs as $out) {
$out->emit($data);
}
}
}
<?php
/**
* Interface for statistics outputs.
*
* @package simpleSAMLphp
* @version $Id$
*/
abstract class SimpleSAML_Stats_Output {
/**
* Initialize the output.
*
* @param SimpleSAML_Configuration $config The configuration for this output.
*/
public function __construct(SimpleSAML_Configuration $config) {
/* Do nothing by default. */
}
/**
* Write a stats event.
*
* @param array $data The event.
*/
abstract public function emit(array $data);
}
<?php
/**
* Statistics logger that writes to a set of log files
*
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_core_Stats_Output_File extends SimpleSAML_Stats_Output {
/**
* The log directory.
* @var string
*/
private $logDir;
/**
* The file handle for the current file.
* @var resource
*/
private $file = NULL;
/**
* The current file date.
* @var string
*/
private $fileDate = NULL;
/**
* Initialize the output.
*
* @param SimpleSAML_Configuration $config The configuration for this output.
*/
public function __construct(SimpleSAML_Configuration $config) {
$this->logDir = $config->getPathValue('directory');
if ($this->logDir === NULL) {
throw new Exception('Missing "directory" option for core:File');
}
if (!is_dir($this->logDir)) {
throw new Exception('Could not find log directory: ' . var_export($this->logDir, TRUE));
}
}
/**
* Open a log file.
*
* @param string $date The date for the log file.
*/
private function openLog($date) {
assert('is_string($date)');
if ($this->file !== NULL && $this->file !== FALSE) {
fclose($this->file);
$this->file = NULL;
}
$fileName = $this->logDir . '/' . $date . '.log';
$this->file = @fopen($fileName, 'a');
if ($this->file === FALSE) {
throw new SimpleSAML_Error_Exception('Error opening log file: ' . var_export($fileName, TRUE));
}
/* Disable output buffering. */
stream_set_write_buffer($this->file, 0);
$this->fileDate = $date;
}
/**
* Write a stats event.
*
* @param array $data The event.
*/
public function emit(array $data) {
assert('isset($data["time"])');
$time = $data['time'];
$frac_time = $time - (int)$time;
$timestamp = gmdate('Y-m-d\TH:i:s', $time) . sprintf('%.03fZ', $frac_time);
$outDate = substr($timestamp, 0, 10); /* The date-part of the timstamp. */
if ($outDate !== $this->fileDate) {
$this->openLog($outDate);
}
$line = $timestamp . ' ' . json_encode($data) . "\n";
fwrite($this->file, $line);
}
}
<?php
/**
* Statistics logger that writes to the default logging handler.
*
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_core_Stats_Output_Log extends SimpleSAML_Stats_Output {
/**
* The logging function we should call.
* @var callback
*/
private $logger;
/**
* Initialize the output.
*
* @param SimpleSAML_Configuration $config The configuration for this output.
*/
public function __construct(SimpleSAML_Configuration $config) {
$logLevel = $config->getString('level', 'notice');
$this->logger = array('SimpleSAML_Logger', $logLevel);
if (!is_callable($this->logger)) {
throw new Exception('Invalid log level: ' . var_export($logLevel, TRUE));
}
}
/**
* Write a stats event.
*
* @param string $data The event (as a JSON string).
*/
public function emit(array $data) {
$str_data = json_encode($data);
call_user_func($this->logger, 'EVENT ' . $str_data);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment