From 972c5df4d221d24265efb859901c1969def011f3 Mon Sep 17 00:00:00 2001
From: Lasse Birnbaum Jensen <lasse@sdu.dk>
Date: Thu, 7 Feb 2008 20:54:21 +0000
Subject: [PATCH] Suggestion for new logger.

TrackID is always prepended to the logstring

New logging options in config-template.php

Possible to configure logging to use syslog or file

Please test the new logging function.

Logging handler has only been added. The old logging function is still uses in the code.

After test all logging calls should be rewritten to the new format.

Usage:

Required:

require_once('SimpleSAML/Logger.php');

Logging:

Logger::emergency("text to log");
Logger::critical("text to log");
Logger::alert("text to log");
Logger::error("text to log");
Logger::warning("text to log");
Logger::notice("text to log");
Logger::info("text to log");
Logger::debug("text to log");
Logger::emergency("text to log");

Logger::info(array("text","to","log"));

Statistics:
Stats are prepended with STAT in the logfile for easier analysis.

Logger::stats("SSO");

Example (syslog):
Feb  7 21:02:33 server_name simpleSAMLphp[pid]: [trackid] loglevel text to log

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@268 44740490-163a-0410-bde0-09ae8108e29a
---
 config/config-template.php                    |  24 ++++-
 lib/SimpleSAML/Logger.php                     | 102 ++++++++++++++++++
 lib/SimpleSAML/Logger/LoggingHandlerFile.php  |  34 ++++++
 .../Logger/LoggingHandlerSyslog.php           |  18 ++++
 log/_placeholder.php                          |   3 +
 5 files changed, 178 insertions(+), 3 deletions(-)
 create mode 100644 lib/SimpleSAML/Logger/LoggingHandlerFile.php
 create mode 100644 lib/SimpleSAML/Logger/LoggingHandlerSyslog.php
 create mode 100644 log/_placeholder.php

diff --git a/config/config-template.php b/config/config-template.php
index bf0397da7..845d55821 100644
--- a/config/config-template.php
+++ b/config/config-template.php
@@ -27,6 +27,7 @@ $config = array (
 	'attributenamemapdir'   => 'attributemap/',
 	'certdir'               => 'certs/',
 	'dictionarydir'         => 'dictionaries/',
+	'loggingdir'            => 'log/',
 	
 	
 	'version'				=>	'0.9.1',
@@ -57,17 +58,34 @@ $config = array (
 	/*
 	 * Logging.
 	 * 
-	 * Choose a syslog facility to use for logging.
-	 * And define the minimum log level to log
+	 * define the minimum log level to log
 	 *		LOG_ERR				No statistics, only errors
 	 *		LOG_WARNING			No statistics, only warnings/errors
 	 *		LOG_NOTICE			Statistics and errors 
 	 *		LOG_INFO			Verbose logs
 	 *		LOG_DEBUG			Full debug logs - not reccomended for production
+	 * 
+	 * Choose logging handler.
+	 * 
+	 * Options: [syslog,file]
+	 * 
 	 */
-	'logging.facility'		=> LOG_LOCAL5,
 	'logging.level'			=> LOG_NOTICE,
+	'logging.handler'		=> 'syslog',
+
+	/*
+	 * Logging: syslog
+	 * Choose a syslog facility to use for logging.
+	 */
+	'logging.facility'		=> LOG_LOCAL5,
 	
+	/*
+	 * Logging: file
+	 * 
+	 * Logfilename in the loggingdir from above.
+	 */
+	'logging.logfile'		=> 'simplesamlphp.log',
+
 
 	/*
 	 * Enable
diff --git a/lib/SimpleSAML/Logger.php b/lib/SimpleSAML/Logger.php
index 7f63214a7..318808f8c 100644
--- a/lib/SimpleSAML/Logger.php
+++ b/lib/SimpleSAML/Logger.php
@@ -53,9 +53,111 @@ class SimpleSAML_Logger {
 		syslog($priority, $logstring);
 	
 	}
+}
+
+interface SimpleSAML_Logger_LoggingHandler {
+    function log_internal($level,$string);
+}
+
+class Logger {
+	private static $loggingHandler = null;
+	private static $logLevel = null;
+	private static $trackid = null;
+
+	static function emergency($string) {
+		self::log_internal(LOG_EMERG,$string);
+	}
+
+	static function critical($string) {
+		self::log_internal(LOG_CRIT,$string);
+	}
+
+	static function alert($string) {
+		self::log_internal(LOG_ALERT,$string);
+	}
 
+	static function error($string) {
+		self::log_internal(LOG_ERR,$string);
+	}
+
+	static function warning($string) {
+		self::log_internal(LOG_WARNING,$string);
+	}
+
+	static function notice($string) {
+		self::log_internal(LOG_NOTICE,$string);
+	}
+
+	static function info($string) {
+		self::log_internal(LOG_INFO,$string);
+	}
+
+	static function debug($string) {
+		self::log_internal(LOG_DEBUG,$string);
+	}
 
+	static function stats($string) {
+		self::log_internal(LOG_INFO,$string,true);
+	}
+	public static function createLoggingHandler() {
+		/* Get the configuration. */
+		$config = SimpleSAML_Configuration::getInstance();
+		assert($config instanceof SimpleSAML_Configuration);
+
+		/* Get the metadata handler option from the configuration. */
+		$handler = $config->getValue('logging.handler','syslog');
+
+		/*
+		 * setting minimum log_level
+		 */
+		self::$logLevel = $config->getValue('logging.level',LOG_INFO);
+
+		/*
+		 * get trackid, prefixes all logstrings
+		 */
+		$session = SimpleSAML_Session::getInstance();
+		self::$trackid = $session->getTrackID();
+
+		/* If 'session.handler' is NULL or unset, then we want
+		 * to fall back to the default PHP session handler.
+		 */
+		if(is_null($handler)) {
+			$handler = 'syslog';
+		}
+
+
+		/* The session handler must be a string. */
+		if(!is_string($handler)) {
+			throw new Exception('Invalid setting for the [logging.handler] configuration option. This option should be set to a valid string.');
+		}
+
+		$handler = strtolower($handler);
+
+		if($handler === 'syslog') {
+			require_once('SimpleSAML/Logger/LoggingHandlerSyslog.php');
+			$sh = new SimpleSAML_Logger_LoggingHandlerSyslog();
+
+		} elseif ($handler === 'file')  {
+			require_once('SimpleSAML/Logger/LoggingHandlerFile.php');
+			$sh = new SimpleSAML_Logger_LoggingHandlerFile();
+		} else {
+			throw new Exception('Invalid value for the [logging.handler] configuration option. Unknown handler: ' . $handler);
+		}
+		/* Set the session handler. */
+		self::$loggingHandler = $sh;
+	}
 	
+	static function log_internal($level,$string,$statsLog = false) {
+		if (self::$loggingHandler == null)
+			self::createLoggingHandler();
+		
+		if (self::$logLevel >= $level || $statsLog) {
+			if (is_array($string)) $string = implode(",",$string);
+			$string = '['.self::$trackid.'] '.$string;
+			if ($statsLog) $string = 'STAT '.$string;  
+			self::$loggingHandler->log_internal($level,$string);
+		}
+	}
 }
 
 ?>
\ No newline at end of file
diff --git a/lib/SimpleSAML/Logger/LoggingHandlerFile.php b/lib/SimpleSAML/Logger/LoggingHandlerFile.php
new file mode 100644
index 000000000..dd77cd6f1
--- /dev/null
+++ b/lib/SimpleSAML/Logger/LoggingHandlerFile.php
@@ -0,0 +1,34 @@
+<?php
+
+require_once('SimpleSAML/Configuration.php');
+require_once('SimpleSAML/Logger.php');
+
+class SimpleSAML_Logger_LoggingHandlerFile implements SimpleSAML_Logger_LoggingHandler {
+
+    private $logFile = null;
+
+    function __construct() {
+        $config = SimpleSAML_Configuration::getInstance();
+        assert($config instanceof SimpleSAML_Configuration);
+
+        /* Get the metadata handler option from the configuration. */
+        $this->logFile = $config->getBaseDir().'/'.$config->getValue('loggingdir').'/'.$config->getValue('logging.logfile');
+
+        if (@file_exists($this->logFile)) {
+            if (!@is_writeable($this->logFile)) throw new Exception("Could not write to logfile: ".$this->logFile);
+        }
+        else
+        {
+            if (!@touch($this->logFile))  throw new Exception("Could not create logfile: ".$this->logFile." Loggingdir is not writeable for the webserver user.");
+        }
+    }
+
+    function log_internal($level,$string) {
+        if ($this->logFile != null) {
+            $line = sprintf("%s ssp %d %s\n",strftime("%b %d %H:%M:%S"),$level,$string);
+            file_put_contents($this->logFile,$line,FILE_APPEND);
+        }
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/lib/SimpleSAML/Logger/LoggingHandlerSyslog.php b/lib/SimpleSAML/Logger/LoggingHandlerSyslog.php
new file mode 100644
index 000000000..4ad3130a5
--- /dev/null
+++ b/lib/SimpleSAML/Logger/LoggingHandlerSyslog.php
@@ -0,0 +1,18 @@
+<?php
+
+require_once('SimpleSAML/Configuration.php');
+require_once('SimpleSAML/Logger.php');
+
+class SimpleSAML_Logger_LoggingHandlerSyslog implements SimpleSAML_Logger_LoggingHandler {
+
+    function __construct() {
+        $config = SimpleSAML_Configuration::getInstance();
+        assert($config instanceof SimpleSAML_Configuration);
+        openlog("simpleSAMLphp", LOG_PID, $config->getValue('logging.facility') );
+    }
+
+    function log_internal($level,$string) {
+        syslog($level,$level.' '.$string);
+    }
+}
+?>
\ No newline at end of file
diff --git a/log/_placeholder.php b/log/_placeholder.php
new file mode 100644
index 000000000..3af98a1ab
--- /dev/null
+++ b/log/_placeholder.php
@@ -0,0 +1,3 @@
+<?php
+/* this file can be deleted */
+?>
\ No newline at end of file
-- 
GitLab