diff --git a/src/Util/Logger/StreamLogger.php b/src/Util/Logger/StreamLogger.php
index 7e52df80f..701d36d2b 100644
--- a/src/Util/Logger/StreamLogger.php
+++ b/src/Util/Logger/StreamLogger.php
@@ -115,7 +115,6 @@ class StreamLogger extends AbstractLogger
 
 		$this->checkStream();
 
-		$this->stream = fopen($this->url, 'a');
 		$formattedLog = $this->formatLog($level, $message, $context);
 		fwrite($this->stream, $formattedLog);
 	}
diff --git a/src/Util/Logger/SyslogLogger.php b/src/Util/Logger/SyslogLogger.php
index e21e953ac..b1abd5bd5 100644
--- a/src/Util/Logger/SyslogLogger.php
+++ b/src/Util/Logger/SyslogLogger.php
@@ -4,7 +4,6 @@ namespace Friendica\Util\Logger;
 
 use Friendica\Network\HTTPException\InternalServerErrorException;
 use Friendica\Util\Introspection;
-use Psr\Log\InvalidArgumentException;
 use Psr\Log\LogLevel;
 
 /**
@@ -117,7 +116,7 @@ class SyslogLogger extends AbstractLogger
 	public function mapLevelToPriority($level)
 	{
 		if (!array_key_exists($level, $this->logLevels)) {
-			throw new InvalidArgumentException('LogLevel \'' . $level . '\' isn\'t valid.');
+			throw new \InvalidArgumentException(sprintf('The level "%s" is not valid.', $level));
 		}
 
 		return $this->logLevels[$level];
@@ -146,7 +145,7 @@ class SyslogLogger extends AbstractLogger
 			throw new InternalServerErrorException('Can\'t open syslog for ident "' . $this->channel . '" and facility "' . $this->logFacility . '""');
 		}
 
-		syslog($priority, $message);
+		$this->syslogWrapper($priority, $message);
 	}
 
 	/**
@@ -172,4 +171,15 @@ class SyslogLogger extends AbstractLogger
 
 		return $logMessage;
 	}
+
+	/**
+	 * A syslog wrapper to make syslog functionality testable
+	 *
+	 * @param int    $level The syslog priority
+	 * @param string $entry The message to send to the syslog function
+	 */
+	protected function syslogWrapper($level, $entry)
+	{
+		syslog($level, $entry);
+	}
 }
diff --git a/tests/src/Util/Logger/AbstractLoggerTest.php b/tests/src/Util/Logger/AbstractLoggerTest.php
new file mode 100644
index 000000000..e0c033583
--- /dev/null
+++ b/tests/src/Util/Logger/AbstractLoggerTest.php
@@ -0,0 +1,143 @@
+<?php
+
+namespace Friendica\Test\src\Util\Logger;
+
+use Friendica\Test\MockedTest;
+use Friendica\Util\Introspection;
+use Mockery\MockInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+
+abstract class AbstractLoggerTest extends MockedTest
+{
+	use LoggerDataTrait;
+
+	const LOGLINE = '/.* \[.*\]: .* \{.*\"file\":\".*\".*,.*\"line\":\d*,.*\"function\":\".*\".*,.*\"uid\":\".*\".*}/';
+
+	const FILE = 'test';
+	const LINE = 666;
+	const FUNC = 'myfunction';
+
+	/**
+	 * @var Introspection|MockInterface
+	 */
+	protected $introspection;
+
+	/**
+	 * Returns the content of the current logger instance
+	 *
+	 * @return string
+	 */
+	abstract protected function getContent();
+
+	/**
+	 * Returns the current logger instance
+	 *
+	 * @param string $level the default loglevel
+	 *
+	 * @return LoggerInterface
+	 */
+	abstract protected function getInstance($level = LogLevel::DEBUG);
+
+	protected function setUp()
+	{
+		parent::setUp();
+
+		$this->introspection = \Mockery::mock(Introspection::class);
+		$this->introspection->shouldReceive('getRecord')->andReturn([
+			'file'     => self::FILE,
+			'line'     => self::LINE,
+			'function' => self::FUNC
+		]);
+	}
+
+	public function assertLogline($string)
+	{
+		$this->assertRegExp(self::LOGLINE, $string);
+	}
+
+	public function assertLoglineNums($assertNum, $string)
+	{
+		$this->assertEquals($assertNum, preg_match_all(self::LOGLINE, $string));
+	}
+
+	/**
+	 * Test if the logger works correctly
+	 */
+	public function testNormal()
+	{
+		$logger = $this->getInstance();
+		$logger->emergency('working!');
+		$logger->alert('working too!');
+		$logger->debug('and now?');
+		$logger->notice('message', ['an' => 'context']);
+
+		$text = $this->getContent();
+		$this->assertLogline($text);
+		$this->assertLoglineNums(4, $text);
+	}
+
+	/**
+	 * Test if a log entry is correctly interpolated
+	 */
+	public function testPsrInterpolate()
+	{
+		$logger = $this->getInstance();
+
+		$logger->emergency('A {psr} test', ['psr' => 'working']);
+		$logger->alert('An {array} test', ['array' => ['it', 'is', 'working']]);
+		$text = $this->getContent();
+		$this->assertContains('A working test', $text);
+		$this->assertContains('An ["it","is","working"] test', $text);
+	}
+
+	/**
+	 * Test if a log entry contains all necessary information
+	 */
+	public function testContainsInformation()
+	{
+		$logger = $this->getInstance();
+		$logger->emergency('A test');
+
+		$text = $this->getContent();
+		$this->assertContains('"file":"' . self::FILE . '"', $text);
+		$this->assertContains('"line":' . self::LINE, $text);
+		$this->assertContains('"function":"' . self::FUNC . '"', $text);
+	}
+
+	/**
+	 * Test if the minimum level is working
+	 */
+	public function testMinimumLevel()
+	{
+		$logger = $this->getInstance(LogLevel::NOTICE);
+
+		$logger->emergency('working');
+		$logger->alert('working');
+		$logger->error('working');
+		$logger->warning('working');
+		$logger->notice('working');
+		$logger->info('not working');
+		$logger->debug('not working');
+
+		$text = $this->getContent();
+
+		$this->assertLoglineNums(5, $text);
+	}
+
+	/**
+	 * Test with different logging data
+	 * @dataProvider dataTests
+	 */
+	public function testDifferentTypes($function, $message, array $context)
+	{
+		$logger = $this->getInstance();
+		$logger->$function($message, $context);
+
+		$text = $this->getContent();
+
+		$this->assertLogline($text);
+
+		$this->assertContains(@json_encode($context), $text);
+	}
+}
diff --git a/tests/src/Util/Logger/LoggerDataTrait.php b/tests/src/Util/Logger/LoggerDataTrait.php
new file mode 100644
index 000000000..1267098a8
--- /dev/null
+++ b/tests/src/Util/Logger/LoggerDataTrait.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Friendica\Test\src\Util\Logger;
+
+trait LoggerDataTrait
+{
+	public function dataTests()
+	{
+		return [
+			'emergency' => [
+				'function' => 'emergency',
+				'message' => 'test',
+				'context' => ['a' => 'context'],
+			],
+			'alert' => [
+				'function' => 'alert',
+				'message' => 'test {test}',
+				'context' => ['a' => 'context', 2 => 'so', 'test' => 'works'],
+			],
+			'critical' => [
+				'function' => 'critical',
+				'message' => 'test crit 2345',
+				'context' => ['a' => 'context', 'wit' => ['more', 'array']],
+			],
+			'error' => [
+				'function' => 'error',
+				'message' => 2.554,
+				'context' => [],
+			],
+			'warning' => [
+				'function' => 'warning',
+				'message' => 'test warn',
+				'context' => ['a' => 'context'],
+			],
+			'notice' => [
+				'function' => 'notice',
+				'message' => 2346,
+				'context' => ['a' => 'context'],
+			],
+			'info' => [
+				'function' => 'info',
+				'message' => null,
+				'context' => ['a' => 'context'],
+			],
+			'debug' => [
+				'function' => 'debug',
+				'message' => true,
+				'context' => ['a' => false],
+			],
+		];
+	}
+}
diff --git a/tests/src/Util/Logger/ProfilerLoggerTest.php b/tests/src/Util/Logger/ProfilerLoggerTest.php
new file mode 100644
index 000000000..848191a4d
--- /dev/null
+++ b/tests/src/Util/Logger/ProfilerLoggerTest.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Friendica\Test\src\Util\Logger;
+
+use Friendica\Test\MockedTest;
+use Friendica\Util\Logger\ProfilerLogger;
+use Friendica\Util\Profiler;
+use Mockery\MockInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+
+class ProfilerLoggerTest extends MockedTest
+{
+	use LoggerDataTrait;
+
+	/**
+	 * @var LoggerInterface|MockInterface
+	 */
+	private $logger;
+	/**
+	 * @var Profiler|MockInterface
+	 */
+	private $profiler;
+
+	protected function setUp()
+	{
+		parent::setUp();
+
+		$this->logger = \Mockery::mock(LoggerInterface::class);
+		$this->profiler = \Mockery::mock(Profiler::class);
+	}
+
+	/**
+	 * Test if the profiler is profiling data
+	 * @dataProvider dataTests
+	 */
+	public function testProfiling($function, $message, array $context)
+	{
+		$logger = new ProfilerLogger($this->logger, $this->profiler);
+
+		$this->logger->shouldReceive($function)->with($message, $context)->once();
+		$this->profiler->shouldReceive('saveTimestamp')->with(\Mockery::any(), 'file', \Mockery::any())->once();
+		$logger->$function($message, $context);
+	}
+
+	/**
+	 * Test the log() function
+	 */
+	public function testProfilingLog()
+	{
+		$logger = new ProfilerLogger($this->logger, $this->profiler);
+
+		$this->logger->shouldReceive('log')->with(LogLevel::WARNING, 'test', ['a' => 'context'])->once();
+		$this->profiler->shouldReceive('saveTimestamp')->with(\Mockery::any(), 'file', \Mockery::any())->once();
+
+		$logger->log(LogLevel::WARNING, 'test', ['a' => 'context']);
+	}
+}
diff --git a/tests/src/Util/Logger/StreamLoggerTest.php b/tests/src/Util/Logger/StreamLoggerTest.php
index 38706231c..bbf94419a 100644
--- a/tests/src/Util/Logger/StreamLoggerTest.php
+++ b/tests/src/Util/Logger/StreamLoggerTest.php
@@ -2,126 +2,89 @@
 
 namespace Friendica\Test\src\Util\Logger;
 
-use Friendica\Test\MockedTest;
 use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\Introspection;
 use Friendica\Util\Logger\StreamLogger;
-use Mockery\MockInterface;
 use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamFile;
 use Psr\Log\LogLevel;
 
-class StreamLoggerTest extends MockedTest
+class StreamLoggerTest extends AbstractLoggerTest
 {
-	const LOGLINE = '/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} .* \[.*\]: .* \{.*\"file\":\".*\".*,.*\"line\":\d*,.*\"function\":\".*\".*,.*\"uid\":\".*\".*,.*\"process_id\":\d*.*\}/';
-
-	const FILE = 'test';
-	const LINE = 666;
-	const FUNC = 'myfunction';
-
 	use VFSTrait;
 
 	/**
-	 * @var Introspection|MockInterface
+	 * @var StreamLogger
 	 */
-	private $introspection;
+	private $logger;
+
+	/**
+	 * @var vfsStreamFile
+	 */
+	private $logfile;
 
 	protected function setUp()
 	{
 		parent::setUp();
 
 		$this->setUpVfsDir();
-
-		$this->introspection = \Mockery::mock(Introspection::class);
-		$this->introspection->shouldReceive('getRecord')->andReturn([
-			'file'     => self::FILE,
-			'line'     => self::LINE,
-			'function' => self::FUNC
-		]);
-	}
-
-	public function assertLogline($string)
-	{
-		$this->assertRegExp(self::LOGLINE, $string);
-	}
-
-	public function assertLoglineNums($assertNum, $string)
-	{
-		$this->assertEquals($assertNum, preg_match_all(self::LOGLINE, $string));
-	}
-
-	public function testNormal()
-	{
-		$logfile = vfsStream::newFile('friendica.log')
-			->at($this->root);
-
-		$logger = new StreamLogger('test', $logfile->url(), $this->introspection);
-		$logger->emergency('working!');
-		$logger->alert('working too!');
-		$logger->debug('and now?');
-		$logger->notice('message', ['an' => 'context']);
-
-		$text = $logfile->getContent();
-		$this->assertLogline($text);
-		$this->assertLoglineNums(4, $text);
 	}
 
 	/**
-	 * Test if a log entry is correctly interpolated
+	 * {@@inheritdoc}
 	 */
-	public function testPsrInterpolate()
+	protected function getInstance($level = LogLevel::DEBUG)
 	{
-		$logfile = vfsStream::newFile('friendica.log')
+		$this->logfile = vfsStream::newFile('friendica.log')
 			->at($this->root);
 
-		$logger = new StreamLogger('test', $logfile->url(), $this->introspection);
+		$this->logger = new StreamLogger('test', $this->logfile->url(), $this->introspection, $level);
 
-		$logger->emergency('A {psr} test', ['psr' => 'working']);
-		$logger->alert('An {array} test', ['array' => ['it', 'is', 'working']]);
-		$text = $logfile->getContent();
-		$this->assertContains('A working test', $text);
-		$this->assertContains('An ["it","is","working"] test', $text);
+		return $this->logger;
 	}
 
 	/**
-	 * Test if a log entry contains all necessary information
+	 * {@inheritdoc}
 	 */
-	public function testContainsInformation()
+	protected function getContent()
 	{
-		$logfile = vfsStream::newFile('friendica.log')
-			->at($this->root);
-
-		$logger = new StreamLogger('test', $logfile->url(), $this->introspection);
-
-		$logger->emergency('A test');
-
-		$text = $logfile->getContent();
-		$this->assertContains('"process_id":' . getmypid(), $text);
-		$this->assertContains('"file":"' . self::FILE . '"', $text);
-		$this->assertContains('"line":' . self::LINE, $text);
-		$this->assertContains('"function":"' . self::FUNC . '"', $text);
+		return $this->logfile->getContent();
 	}
 
 	/**
-	 * Test if the minimum level is working
+	 * Test if a stream is working
 	 */
-	public function testMinimumLevel()
+	public function testStream()
 	{
 		$logfile = vfsStream::newFile('friendica.log')
 			->at($this->root);
 
-		$logger = new StreamLogger('test', $logfile->url(), $this->introspection, LogLevel::NOTICE);
+		$filehandler = fopen($logfile->url(), 'ab');
 
+		$logger = new StreamLogger('test', $filehandler, $this->introspection);
 		$logger->emergency('working');
-		$logger->alert('working');
-		$logger->error('working');
-		$logger->warning('working');
-		$logger->notice('working');
-		$logger->info('not working');
-		$logger->debug('not working');
 
 		$text = $logfile->getContent();
 
-		$this->assertLoglineNums(5, $text);
+		$this->assertLogline($text);
+	}
+
+	/**
+	 * Test if the close statement is working
+	 */
+	public function testClose()
+	{
+		$logfile = vfsStream::newFile('friendica.log')
+			->at($this->root);
+
+		$logger = new StreamLogger('test', $logfile->url(), $this->introspection);
+		$logger->emergency('working');
+		$logger->close();
+		// close doesn't affect
+		$logger->emergency('working too');
+
+		$text = $logfile->getContent();
+
+		$this->assertLoglineNums(2, $text);
 	}
 
 	/**
@@ -187,4 +150,14 @@ class StreamLoggerTest extends MockedTest
 
 		$logger->log('NOPE', 'a test');
 	}
+
+	/**
+	 * Test when the file is null
+	 * @expectedException \InvalidArgumentException
+	 * @expectedExceptionMessage A stream must either be a resource or a string.
+	 */
+	public function testWrongFile()
+	{
+		$logger = new StreamLogger('test', null, $this->introspection);
+	}
 }
diff --git a/tests/src/Util/Logger/SyslogLoggerTest.php b/tests/src/Util/Logger/SyslogLoggerTest.php
new file mode 100644
index 000000000..545f76b32
--- /dev/null
+++ b/tests/src/Util/Logger/SyslogLoggerTest.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Friendica\Test\src\Util\Logger;
+
+use Friendica\Util\Logger\SyslogLogger;
+use Psr\Log\LogLevel;
+
+class SyslogLoggerTest extends AbstractLoggerTest
+{
+	/**
+	 * @var SyslogLoggerWrapper
+	 */
+	private $logger;
+
+	protected function setUp()
+	{
+		parent::setUp();
+
+		$this->introspection->shouldReceive('addClasses')->with([SyslogLogger::class]);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	protected function getContent()
+	{
+		return $this->logger->getContent();
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	protected function getInstance($level = LogLevel::DEBUG)
+	{
+		$this->logger = new SyslogLoggerWrapper('test', $this->introspection, $level);
+
+		return $this->logger;
+	}
+
+
+	/**
+	 * Test when the minimum level is not valid
+	 * @expectedException \InvalidArgumentException
+	 * @expectedExceptionMessageRegExp /The level ".*" is not valid./
+	 */
+	public function testWrongMinimumLevel()
+	{
+		$logger = new SyslogLoggerWrapper('test', $this->introspection, 'NOPE');
+	}
+
+	/**
+	 * Test when the minimum level is not valid
+	 * @expectedException \InvalidArgumentException
+	 * @expectedExceptionMessageRegExp /The level ".*" is not valid./
+	 */
+	public function testWrongLogLevel()
+	{
+		$logger = new SyslogLoggerWrapper('test', $this->introspection);
+
+		$logger->log('NOPE', 'a test');
+	}
+}
diff --git a/tests/src/Util/Logger/SyslogLoggerWrapper.php b/tests/src/Util/Logger/SyslogLoggerWrapper.php
new file mode 100644
index 000000000..63ad53690
--- /dev/null
+++ b/tests/src/Util/Logger/SyslogLoggerWrapper.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Friendica\Test\src\Util\Logger;
+
+use Friendica\Util\Introspection;
+use Friendica\Util\Logger\SyslogLogger;
+use Psr\Log\LogLevel;
+
+class SyslogLoggerWrapper extends SyslogLogger
+{
+	private $content;
+
+	public function __construct($channel, Introspection $introspection, $level = LogLevel::NOTICE, $logOpts = LOG_PID, $logFacility = LOG_USER)
+	{
+		parent::__construct($channel, $introspection, $level, $logOpts, $logFacility);
+
+		$this->content = '';
+	}
+
+	/**
+	 * Gets the content from the wrapped Syslog
+	 *
+	 * @return string
+	 */
+	public function getContent()
+	{
+		return $this->content;
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	protected function syslogWrapper($level, $entry)
+	{
+		$this->content .= $entry . PHP_EOL;
+	}
+}
diff --git a/tests/src/Util/Logger/VoidLoggerTest.php b/tests/src/Util/Logger/VoidLoggerTest.php
new file mode 100644
index 000000000..4c436d697
--- /dev/null
+++ b/tests/src/Util/Logger/VoidLoggerTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Friendica\Test\src\Util\Logger;
+
+use Friendica\Test\MockedTest;
+use Friendica\Util\Logger\VoidLogger;
+use Psr\Log\LogLevel;
+
+class VoidLoggerTest extends MockedTest
+{
+	use LoggerDataTrait;
+
+	/**
+	 * Test if the profiler is profiling data
+	 * @dataProvider dataTests
+	 */
+	public function testNormal($function, $message, array $context)
+	{
+		$logger = new VoidLogger();
+		$logger->$function($message, $context);
+	}
+
+	/**
+	 * Test the log() function
+	 */
+	public function testProfilingLog()
+	{
+		$logger = new VoidLogger();
+		$logger->log(LogLevel::WARNING, 'test', ['a' => 'context']);
+	}
+}