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.

Reply via email to