Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for Redis configuration #305

Merged
merged 2 commits into from Jun 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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)

Expand Down
61 changes: 61 additions & 0 deletions DependencyInjection/Configuration.php
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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']); })
Expand Down
39 changes: 39 additions & 0 deletions DependencyInjection/MonologExtension.php
Expand Up @@ -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(
Expand Down Expand Up @@ -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])) {
Expand Down
14 changes: 14 additions & 0 deletions Resources/config/schema/monolog-1.0.xsd
Expand Up @@ -157,6 +157,20 @@
<xsd:attribute name="collection" type="xsd:string" />
</xsd:complexType>

<xsd:complexType name="redis">
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="host" type="xsd:string" />
<xsd:attribute name="password" type="xsd:string" />
<xsd:attribute name="port" type="xsd:integer" />
<xsd:attribute name="database" type="xsd:integer" />
<xsd:attribute name="key_name" type="xsd:string" />
</xsd:complexType>

<xsd:complexType name="predis">
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="host" type="xsd:string" />
</xsd:complexType>

<xsd:complexType name="elasticsearch">
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="host" type="xsd:string" />
Expand Down
44 changes: 44 additions & 0 deletions Tests/DependencyInjection/ConfigurationTest.php
Expand Up @@ -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.
Expand Down