diff --git a/lib/private/log.php b/lib/private/log.php
index e0b9fe3c696a85e72c2ae02e76251921703c9d69..98465ec40eae8f5b80b94ed9264d5fe678f5c597 100644
--- a/lib/private/log.php
+++ b/lib/private/log.php
@@ -8,6 +8,8 @@
 
 namespace OC;
 
+use \OCP\ILogger;
+
 /**
  * logging utilities
  *
@@ -18,8 +20,24 @@ namespace OC;
  * MonoLog is an example implementing this interface.
  */
 
-class Log {
-	private $logClass;
+class Log implements ILogger {
+
+	private $logger;
+
+	/**
+	 * @param string $logger The logger that should be used
+	 */
+	public function __construct($logger=null) {
+		// FIXME: Add this for backwards compatibility, should be fixed at some point probably
+		if($logger === null) {
+			$this->logger = 'OC_Log_'.ucfirst(\OC_Config::getValue('log_type', 'owncloud'));
+			call_user_func(array($this->logger, 'init'));
+		} else {
+			$this->logger = $logger;
+		}
+
+	}
+
 
 	/**
 	 * System is unusable.
@@ -112,10 +130,6 @@ class Log {
 		$this->log(\OC_Log::DEBUG, $message, $context);
 	}
 
-	public function __construct() {
-		$this->logClass = 'OC_Log_'.ucfirst(\OC_Config::getValue('log_type', 'owncloud'));
-		call_user_func(array($this->logClass, 'init'));
-	}
 
 	/**
 	 * Logs with an arbitrary level.
@@ -130,7 +144,16 @@ class Log {
 		} else {
 			$app = 'no app in context';
 		}
-		$logClass=$this->logClass;
-		$logClass::write($app, $message, $level);
+		// interpolate $message as defined in PSR-3
+		$replace = array();
+		foreach ($context as $key => $val) {
+			$replace['{' . $key . '}'] = $val;
+		}
+
+		// interpolate replacement values into the message and return
+		$message = strtr($message, $replace);
+
+		$logger = $this->logger;
+		$logger::write($app, $message, $level);
 	}
 }
diff --git a/lib/private/server.php b/lib/private/server.php
index 27763ea6477898931fd78967b26048283f3874f3..fd8c2c38ad0f07d4082b8b228f7ce00f3cdf5db4 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -31,9 +31,9 @@ class Server extends SimpleContainer implements IServerContainer {
 			}
 
 			if (\OC::$session->exists('requesttoken')) {
-				$requesttoken = \OC::$session->get('requesttoken');
+				$requestToken = \OC::$session->get('requesttoken');
 			} else {
-				$requesttoken = false;
+				$requestToken = false;
 			}
 
 			if (defined('PHPUNIT_RUN') && PHPUNIT_RUN
@@ -55,7 +55,7 @@ class Server extends SimpleContainer implements IServerContainer {
 						? $_SERVER['REQUEST_METHOD']
 						: null,
 					'urlParams' => $urlParams,
-					'requesttoken' => $requesttoken,
+					'requesttoken' => $requestToken,
 				), $stream
 			);
 		});
@@ -159,6 +159,14 @@ class Server extends SimpleContainer implements IServerContainer {
 		$this->registerService('AvatarManager', function($c) {
 			return new AvatarManager();
 		});
+		$this->registerService('Logger', function($c) {
+			/** @var $c SimpleContainer */
+			$logClass = $c->query('AllConfig')->getSystemValue('log_type', 'owncloud');
+			$logger = 'OC_Log_' . ucfirst($logClass);
+			call_user_func(array($logger, 'init'));
+
+			return new Log($logger);
+		});
 		$this->registerService('JobList', function ($c) {
 			/**
 			 * @var Server $c
@@ -329,14 +337,14 @@ class Server extends SimpleContainer implements IServerContainer {
 	}
 
 	/**
-	 * @return \OC\URLGenerator
+	 * @return \OCP\IURLGenerator
 	 */
 	function getURLGenerator() {
 		return $this->query('URLGenerator');
 	}
 
 	/**
-	 * @return \OC\Helper
+	 * @return \OCP\IHelper
 	 */
 	function getHelper() {
 		return $this->query('AppHelper');
@@ -396,6 +404,15 @@ class Server extends SimpleContainer implements IServerContainer {
 		return $this->query('JobList');
 	}
 
+	/**
+	 * Returns a logger instance
+	 *
+	 * @return \OCP\ILogger
+	 */
+	function getLogger() {
+		return $this->query('Logger');
+	}
+
 	/**
 	 * Returns a router for generating and matching urls
 	 *
diff --git a/lib/public/ilogger.php b/lib/public/ilogger.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad0fcd05a1deea665f1caad7cc5ee4eb625d12fa
--- /dev/null
+++ b/lib/public/ilogger.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Copyright (c) 2014 Bernhard Posselt <dev@bernhard-posselt.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP;
+
+/**
+ * Interface ILogger
+ * @package OCP
+ *
+ * This logger interface follows the design guidelines of PSR-3
+ * https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#3-psrlogloggerinterface
+ */
+interface ILogger {
+	/**
+	 * System is unusable.
+	 *
+	 * @param string $message
+	 * @param array $context
+	 * @return null
+	 */
+	function emergency($message, array $context = array());
+
+	/**
+	 * Action must be taken immediately.
+	 *
+	 * @param string $message
+	 * @param array $context
+	 * @return null
+	 */
+	function alert($message, array $context = array());
+
+	/**
+	 * Critical conditions.
+	 *
+	 * @param string $message
+	 * @param array $context
+	 * @return null
+	 */
+	function critical($message, array $context = array());
+
+	/**
+	 * Runtime errors that do not require immediate action but should typically
+	 * be logged and monitored.
+	 *
+	 * @param string $message
+	 * @param array $context
+	 * @return null
+	 */
+	function error($message, array $context = array());
+
+	/**
+	 * Exceptional occurrences that are not errors.
+	 *
+	 * @param string $message
+	 * @param array $context
+	 * @return null
+	 */
+	function warning($message, array $context = array());
+
+	/**
+	 * Normal but significant events.
+	 *
+	 * @param string $message
+	 * @param array $context
+	 * @return null
+	 */
+	function notice($message, array $context = array());
+
+	/**
+	 * Interesting events.
+	 *
+	 * @param string $message
+	 * @param array $context
+	 * @return null
+	 */
+	function info($message, array $context = array());
+
+	/**
+	 * Detailed debug information.
+	 *
+	 * @param string $message
+	 * @param array $context
+	 * @return null
+	 */
+	function debug($message, array $context = array());
+
+	/**
+	 * Logs with an arbitrary level.
+	 *
+	 * @param mixed $level
+	 * @param string $message
+	 * @param array $context
+	 * @return mixed
+	 */
+	function log($level, $message, array $context = array());
+}
diff --git a/tests/lib/logger.php b/tests/lib/logger.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d5d4049b289e24043d17ed5ae63a42c31b2a4a4
--- /dev/null
+++ b/tests/lib/logger.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright (c) 2014 Thomas Müller <thomas.mueller@tmit.eu>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test;
+
+use OC\Log;
+
+class Logger extends \PHPUnit_Framework_TestCase {
+	/**
+	 * @var \OCP\ILogger
+	 */
+	private $logger;
+	static private $logs = array();
+
+	public function setUp() {
+		self::$logs = array();
+		$this->logger = new Log($this);
+	}
+
+	public function testInterpolation() {
+		$logger = $this->logger;
+		$logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
+
+		$expected = array('1 {Message {nothing} Bob Bar a}');
+		$this->assertEquals($expected, $this->getLogs());
+	}
+
+	private function getLogs() {
+		return self::$logs;
+	}
+
+	public static function write($app, $message, $level) {
+		self::$logs[]= "$level $message";
+	}
+}