Revision: 3053
Author: olavmrk
Date: Wed Mar 21 05:28:39 2012
Log: New statistics logging core.
http://code.google.com/p/simplesamlphp/source/detail?r=3053
Added:
/trunk/lib/SimpleSAML/Stats
/trunk/lib/SimpleSAML/Stats/Output.php
/trunk/lib/SimpleSAML/Stats.php
/trunk/modules/core/lib/Stats
/trunk/modules/core/lib/Stats/Output
/trunk/modules/core/lib/Stats/Output/File.php
/trunk/modules/core/lib/Stats/Output/Log.php
Modified:
/trunk/config-templates/config.php
=======================================
--- /dev/null
+++ /trunk/lib/SimpleSAML/Stats/Output.php Wed Mar 21 05:28:39 2012
@@ -0,0 +1,28 @@
+<?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);
+
+}
=======================================
--- /dev/null
+++ /trunk/lib/SimpleSAML/Stats.php Wed Mar 21 05:28:39 2012
@@ -0,0 +1,92 @@
+<?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);
+ }
+ }
+
+}
=======================================
--- /dev/null
+++ /trunk/modules/core/lib/Stats/Output/File.php Wed Mar 21 05:28:39 2012
@@ -0,0 +1,98 @@
+<?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);
+ }
+
+}
=======================================
--- /dev/null
+++ /trunk/modules/core/lib/Stats/Output/Log.php Wed Mar 21 05:28:39 2012
@@ -0,0 +1,43 @@
+<?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);
+ }
+
+}
=======================================
--- /trunk/config-templates/config.php Mon Jan 23 03:54:03 2012
+++ /trunk/config-templates/config.php Wed Mar 21 05:28:39 2012
@@ -140,8 +140,29 @@
/* 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
--
You received this message because you are subscribed to the Google Groups
"simpleSAMLphp commits" group.
To post to this group, send email to simplesamlphp-commits@googlegroups.com.
To unsubscribe from this group, send email to
simplesamlphp-commits+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/simplesamlphp-commits?hl=en.