diff --git a/config/config-template.php b/config/config-template.php
index bf0397da7372501ef2dede4e05c9d39557e31453..845d558219a205177e43b5e42186aae2fcf22777 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 7f63214a7035cf76889aa8c6faeeb25b9fbebc50..318808f8ced5343e638b6796e050b0d4ca91e73b 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 0000000000000000000000000000000000000000..dd77cd6f10c4b562fd7f76b28fd6f2c5dcc4d374
--- /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 0000000000000000000000000000000000000000..4ad3130a5b830d454eb390dad863c995752c0043
--- /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 0000000000000000000000000000000000000000..3af98a1abfa352ff904245ffd67e96c06b741ad1
--- /dev/null
+++ b/log/_placeholder.php
@@ -0,0 +1,3 @@
+<?php
+/* this file can be deleted */
+?>
\ No newline at end of file