diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a70bbd..7ed1f3d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
* Fixed psr-3 processing being applied to all handlers, only leaf ones are now processing
* Fixed regression when `app` channel is defined explicitly
* Fixed handlers marked as nested not being ignored properly from the stack
+* Added support for Redis configuration
## 3.3.1 (2018-11-04)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index ff02317..4eea7fe 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -88,6 +88,21 @@
* - [level]: level name or int value, defaults to DEBUG
* - [bubble]: bool, defaults to true
*
+ * - redis:
+ * - redis:
+ * - id: optional if host is given
+ * - host: 127.0.0.1
+ * - password: null
+ * - port: 6379
+ * - database: 0
+ * - key_name: monolog_redis
+ *
+ * - predis:
+ * - redis:
+ * - id: optional if host is given
+ * - host: tcp://10.0.0.1:6379
+ * - key_name: monolog_redis
+ *
* - fingers_crossed:
* - handler: the wrapped handler's name
* - [action_level|activation_strategy]: minimum level or service id to activate the handler, defaults to WARNING
@@ -522,6 +537,44 @@ public function getConfigTreeBuilder()
->scalarNode('index')->defaultValue('monolog')->end() // elasticsearch
->scalarNode('document_type')->defaultValue('logs')->end() // elasticsearch
->scalarNode('ignore_error')->defaultValue(false)->end() // elasticsearch
+ ->arrayNode('redis')
+ ->canBeUnset()
+ ->beforeNormalization()
+ ->ifString()
+ ->then(function ($v) { return array('id' => $v); })
+ ->end()
+ ->children()
+ ->scalarNode('id')->end()
+ ->scalarNode('host')->end()
+ ->scalarNode('password')->defaultNull()->end()
+ ->scalarNode('port')->defaultValue(6379)->end()
+ ->scalarNode('database')->defaultValue(0)->end()
+ ->scalarNode('key_name')->defaultValue('monolog_redis')->end()
+ ->end()
+ ->validate()
+ ->ifTrue(function ($v) {
+ return !isset($v['id']) && !isset($v['host']);
+ })
+ ->thenInvalid('What must be set is either the host or the service id of the Redis client.')
+ ->end()
+ ->end() // redis
+ ->arrayNode('predis')
+ ->canBeUnset()
+ ->beforeNormalization()
+ ->ifString()
+ ->then(function ($v) { return array('id' => $v); })
+ ->end()
+ ->children()
+ ->scalarNode('id')->end()
+ ->scalarNode('host')->end()
+ ->end()
+ ->validate()
+ ->ifTrue(function ($v) {
+ return !isset($v['id']) && !isset($v['host']);
+ })
+ ->thenInvalid('What must be set is either the host or the service id of the Predis client.')
+ ->end()
+ ->end() // predis
->arrayNode('config')
->canBeUnset()
->prototype('scalar')->end()
@@ -849,6 +902,14 @@ public function getConfigTreeBuilder()
->ifTrue(function ($v) { return 'server_log' === $v['type'] && empty($v['host']); })
->thenInvalid('The host has to be specified to use a ServerLogHandler')
->end()
+ ->validate()
+ ->ifTrue(function ($v) { return 'redis' === $v['type'] && empty($v['redis']); })
+ ->thenInvalid('The host has to be specified to use a RedisLogHandler')
+ ->end()
+ ->validate()
+ ->ifTrue(function ($v) { return 'predis' === $v['type'] && empty($v['redis']); })
+ ->thenInvalid('The host has to be specified to use a RedisLogHandler')
+ ->end()
->end()
->validate()
->ifTrue(function ($v) { return isset($v['debug']); })
diff --git a/DependencyInjection/MonologExtension.php b/DependencyInjection/MonologExtension.php
index 14b0066..ab8ca55 100644
--- a/DependencyInjection/MonologExtension.php
+++ b/DependencyInjection/MonologExtension.php
@@ -311,6 +311,43 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
$handler['bubble'],
));
break;
+ case 'redis':
+ case 'predis':
+ if (isset($handler['redis']['id'])) {
+ $clientId = $handler['redis']['id'];
+ } elseif ('redis' === $handler['type']) {
+ if (!class_exists(\Redis::class)) {
+ throw new \RuntimeException('The \Redis class is not available.');
+ }
+
+ $client = new Definition(\Redis::class);
+ $client->addMethodCall('connect', array($handler['redis']['host'], $handler['redis']['port']));
+ $client->addMethodCall('auth', array($handler['redis']['password']));
+ $client->addMethodCall('select', array($handler['redis']['database']));
+ $client->setPublic(false);
+ $clientId = uniqid('monolog.redis.client.', true);
+ $container->setDefinition($clientId, $client);
+ } else {
+ if (!class_exists(\Predis\Client::class)) {
+ throw new \RuntimeException('The \Predis\Client class is not available.');
+ }
+
+ $client = new Definition(\Predis\Client::class);
+ $client->setArguments(array(
+ $handler['redis']['host'],
+ ));
+ $client->setPublic(false);
+
+ $clientId = uniqid('monolog.predis.client.', true);
+ $container->setDefinition($clientId, $client);
+ }
+ $definition->setArguments(array(
+ new Reference($clientId),
+ $handler['redis']['key_name'],
+ $handler['level'],
+ $handler['bubble'],
+ ));
+ break;
case 'chromephp':
$definition->setArguments(array(
@@ -835,6 +872,8 @@ private function getHandlerClassByType($handlerType)
'mongo' => 'Monolog\Handler\MongoDBHandler',
'elasticsearch' => 'Monolog\Handler\ElasticSearchHandler',
'server_log' => 'Symfony\Bridge\Monolog\Handler\ServerLogHandler',
+ 'redis' => 'Monolog\Handler\RedisHandler',
+ 'predis' => 'Monolog\Handler\RedisHandler',
);
if (!isset($typeToClassMapping[$handlerType])) {
diff --git a/Resources/config/schema/monolog-1.0.xsd b/Resources/config/schema/monolog-1.0.xsd
index 137df65..cf0eac8 100644
--- a/Resources/config/schema/monolog-1.0.xsd
+++ b/Resources/config/schema/monolog-1.0.xsd
@@ -157,6 +157,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index a59c75d..aa7a5b3 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -362,6 +362,50 @@ public function testWithNestedHandler()
$this->assertTrue($config['handlers']['foobar']['nested']);
}
+ public function testWithRedisHandler()
+ {
+ $configs = array(
+ array(
+ 'handlers' => array(
+ 'redis' => array(
+ 'type' => 'redis',
+ 'redis' => array(
+ 'host' => '127.0.1.1',
+ 'password' => 'pa$$w0rd',
+ 'port' => 1234,
+ 'database' => 1,
+ 'key_name' => 'monolog_redis_test'
+ )
+ )
+ )
+ )
+ );
+ $config = $this->process($configs);
+
+ $this->assertEquals('127.0.1.1', $config['handlers']['redis']['redis']['host']);
+ $this->assertEquals('pa$$w0rd', $config['handlers']['redis']['redis']['password']);
+ $this->assertEquals(1234, $config['handlers']['redis']['redis']['port']);
+ $this->assertEquals(1, $config['handlers']['redis']['redis']['database']);
+ $this->assertEquals('monolog_redis_test', $config['handlers']['redis']['redis']['key_name']);
+
+ $configs = array(
+ array(
+ 'handlers' => array(
+ 'redis' => array(
+ 'type' => 'predis',
+ 'redis' => array(
+ 'host' => '127.0.1.1',
+ 'key_name' => 'monolog_redis_test'
+ )
+ )
+ )
+ )
+ );
+ $config = $this->process($configs);
+
+ $this->assertEquals('127.0.1.1', $config['handlers']['redis']['redis']['host']);
+ $this->assertEquals('monolog_redis_test', $config['handlers']['redis']['redis']['key_name']);
+ }
/**
* Processes an array of configurations and returns a compiled version.