Skip to content

Commit

Permalink
Merge branch 'release/1.1.3'
Browse files Browse the repository at this point in the history
frqnck committed Sep 10, 2015
2 parents 191143d + 64d8f38 commit e352307
Showing 7 changed files with 151 additions and 34 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# APIx Log changelog

#### Version 1.1.3 (10-Sep-2015)
- Added `setDeferred` so processing of logs happen at destruction time on a bucket and/or logger level.
- Updated the README.md accordingly.

#### Version 1.1.2 (28-Aug-2015)
- Updated the README.md
- Added HHVM support.
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -10,17 +10,18 @@ Minimalist **PSR-3** compliant logger.

Feel free to comment, send pull requests and patches...

:new: *Log dispatch can be postponed/accumulated using `setDeferred()`.*

Basic usage (*standalone*)
-----------
```php
use Apix\Log;

// Bucket for log superior or equal to `critical`
$urgent_logger = new Logger\Mail('franck@foo.bar');
$urgent_logger->setMinLevel('critical'); // set the minimal level
$urgent_logger->setMinLevel('critical'); // catch logs >= to `critical`
```

This logger/bucket will intercept `critical`, `alert` and `emergency` logs.
This logger/bucket will intercept `critical`, `alert` and `emergency` logs (see [Log levels](#Log-levels)).

To log an event, use:

@@ -33,20 +34,20 @@ Advanced usage (*multi-logs dispatcher*)
Okay. Lets create some additional loggers/buckets -- one generic, another one for development.

```php
// Bucket for log >= to `notice`
$app_logger = new Logger\File('/var/log/apix_app.log');
$app_logger->setMinLevel('notice')
->setCascading(False); // stop the log here if intercepted
$app_logger->setMinLevel('notice') // intercept logs that are >= `notice`,
->setDeferred(True) // postpone/accumulate logs processing,
->setCascading(False); // don't propagate to further buckets.

// The main logger object (injecting the buckets)
// The main logger object (injecting the previous buckets)
$logger = new Logger( array($urgent_logger, $app_logger) );

if(DEBUG) {
// Bucket log just for `info` and `debug`
// Bucket for the remaining logs -- i.e. `info` and `debug`
$debug_logger = new Logger\File('/tmp/apix_develop.log');
$debug_logger->setMinLevel('debug');
$debug_logger->setMinLevel('debug'); // Note: `debug` is the default!

$logger->add($debug_logger); // another way to inject a bucket
$logger->add($debug_logger); // another way to inject a bucket
}
```

@@ -76,7 +77,7 @@ error | Runtime errors, used to log unhandled exceptions
warning | May indicate that an error will occur if action is not taken
notice | Events that are unusual but not error conditions
info | Normal operational messages (no action required)
debug | Verbose info useful to developers for debugging purposes
debug | Verbose info useful to developers for debugging purposes (default)

[PSR-3]: http://tools.ietf.org/html/rfc5424
[RFC 5424]: http://tools.ietf.org/html/rfc5424
11 changes: 11 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -18,6 +18,17 @@
</testsuite>
</testsuites>

<filter>
<whitelist>
<directory>./</directory>
<exclude>
<directory>build</directory>
<directory>tests</directory>
<directory>vendor</directory>
</exclude>
</whitelist>
</filter>

</phpunit>

<!-- vim: set tabstop=4 shiftwidth=4 expandtab: -->
2 changes: 1 addition & 1 deletion src/Logger.php
Original file line number Diff line number Diff line change
@@ -140,7 +140,7 @@ protected function sortBuckets()
}

/**
* Returns all the registered log buckets.
* Returns all the registered log buckets.
*
* @return array
*/
54 changes: 52 additions & 2 deletions src/Logger/AbstractLogger.php
Original file line number Diff line number Diff line change
@@ -49,6 +49,18 @@ abstract class AbstractLogger extends AbsPsrLogger
*/
protected $cascading = true;

/**
* Whether this logger will be deferred (push the logs at destruct time).
* @var bool
*/
protected $deferred = false;

/**
* Holds the deferred logs.
* @var array
*/
protected $deferred_logs = array();

/**
* Gets the named level code.
*
@@ -104,7 +116,11 @@ public function process(array $log)
$this->interpolate($log['msg'], $log['ctx'])
);

$this->write($log);
if ($this->deferred) {
$this->deferred_logs[] = $log;
} else {
$this->write($log);
}

return $this->cascading;
}
@@ -122,7 +138,6 @@ public function isHandling($level_code)

/**
* Sets the minimal level at which this logger will be triggered.
* NOTE: considering wether to rename this to `interceptAt`
*
* @param string $name
* @param boolean $cascading Should the logs continue pass that level (default to true)
@@ -191,4 +206,39 @@ public static function interpolate($message, array $context = array())
return strtr($message, $replaces);
}

/**
* Sets wether to enable/disable log deferring.
*
* @param bool $bool
* @return self
*/
public function setDeferred($bool)
{
$this->deferred = (boolean) $bool;

return $this;
}

/**
* Returns all the deferred logs.
*
* @return array
*/
public function getDeferredLogs()
{
return $this->deferred_logs;
}

/**
* Process any accumulated deferred log if there are any.
*/
final public function __destruct()
{
if ($this->deferred && !empty($this->deferred_logs)) {
foreach($this->deferred_logs as $log) {
$this->write($log);
}
}
}

}
4 changes: 3 additions & 1 deletion src/Logger/ErrorLog.php
Original file line number Diff line number Diff line change
@@ -63,7 +63,9 @@ public function __construct($file = null, $type = self::PHP)
*/
public function write(array $log)
{
$msg = $this->type == self::FILE ? $log['msg'] . PHP_EOL : $log['msg'];
$msg = $this->deferred || $this->type == self::FILE
? $log['msg'] . PHP_EOL
: $log['msg'];

return error_log($msg, $this->type, $this->destination, $this->headers);
}
87 changes: 68 additions & 19 deletions tests/LoggerTest.php
Original file line number Diff line number Diff line change
@@ -45,20 +45,19 @@ public function testConstructorThrowsInvalidArgumentException()

public function testConstructor()
{
$e = $this->_getMocklogger(array('process'));
$e->setMinLevel( LogLevel::ERROR );
$err_logger = $this->_getMocklogger(array('process'));
$err_logger->setMinLevel( LogLevel::ERROR );

$e->expects($this->once())->method('process');
$crit_logger = $this->_getMocklogger(array('process'));
$crit_logger->setMinLevel( LogLevel::CRITICAL );

$c = $this->_getMocklogger(array('process'));
$c->setMinLevel( LogLevel::CRITICAL );
$this->logger = new Logger( array($err_logger, $crit_logger) );

$c->expects($this->once())->method('process');
$err_logger->expects($this->once())->method('process');
$crit_logger->expects($this->once())->method('process');

$this->logger = new Logger( array($c, $e) );

$this->logger->error('test');
$this->logger->critical('test');
$this->logger->error('test err');
$this->logger->critical('test crit');
}

/**
@@ -124,7 +123,7 @@ public function testLogWillNotProcess()

protected function _getFilledInLogBuckets($cascading=true)
{
// the log bucket for everything (starts at 0 Debug level).
// The log bucket for everything (starts at 0 Debug level).
$dev_log = new Logger\Runtime();
$dev_log->setMinLevel('debug', $cascading);

@@ -197,26 +196,76 @@ public function testLogEntriesAreNotCascasding()
}

public function testSetCascading()
{
$logger = new Logger\Runtime();
$this->assertTrue(
\PHPUnit_Framework_Assert::readAttribute($logger, "cascading"),
"The 'cascading' propertie should be True by default"
);
$logger->setCascading(false);
$this->assertFalse(
\PHPUnit_Framework_Assert::readAttribute($logger, "cascading")
);
}

public function testCascading()
{
$dev_log = new Logger\Runtime();
$dev_log->setMinLevel('debug');
$this->logger->add($dev_log);

$app_log = new Logger\Runtime();

$app_log = new Logger\Runtime();
$app_log->setMinLevel('alert');

$this->logger->add($dev_log);
$this->logger->add($app_log);

$buckets = $this->logger->getBuckets();

$this->logger->alert('test 1');
$this->logger->alert('cascading');
$this->assertCount(1, $buckets[0]->getItems());
$this->assertCount(1, $buckets[1]->getItems());

$app_log->setCascading(false);
$this->logger->alert('test 2');
$app_log->setCascading(false)->alert('not-cascading');

$this->assertCount(2, $buckets[0]->getItems(), 'app_log count = 2');
$this->assertCount(1, $buckets[1]->getItems(), 'dev_log count = 1');
}

public function testSetDeferred()
{
$logger = new Logger\Runtime();
$this->assertFalse(
\PHPUnit_Framework_Assert::readAttribute($logger, "deferred"),
"The 'deferred' propertie should be False by default"
);
$logger->setDeferred(true);
$this->assertTrue(
\PHPUnit_Framework_Assert::readAttribute($logger, "deferred")
);
}

public function testDeferring()
{
$logger = new Logger\Runtime();
$logger->alert('not-deferred');

$this->assertCount(1, $logger->getItems());

$logger->setDeferred(true)->alert('deferred');

$this->assertCount(1, $logger->getItems());
$this->assertCount(1, $logger->getDeferredLogs());
}

public function testDestructIsNotDeferring()
{
$logger = new Logger\Runtime();
$logger->setDeferred(true)->alert('deferred');
$logger->setDeferred(false)->alert('not-deferred');

$logger->__destruct();

$this->assertCount(2, $buckets[0]->getItems(), 'app_log should now have 2');
$this->assertCount(1, $buckets[1]->getItems(), 'dev_log should still have 1');
$this->assertCount(1, $logger->getDeferredLogs());
}

}

0 comments on commit e352307

Please sign in to comment.