Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
jadb committed Feb 12, 2013
1 parent 03a8012 commit 7e58970
Show file tree
Hide file tree
Showing 7 changed files with 384 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
composer.phar
composer.lock
vendor/**
233 changes: 233 additions & 0 deletions Lib/Log/Engine/MonologLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
<?php
App::uses('CakeLogInterface', 'Log');
App::uses('String', 'Utility');

use Monolog\Logger;

use Monolog\Handler\AmqpHandler;
use Monolog\Handler\BufferHandler;
use Monolog\Handler\ChromePHPHandler;
use Monolog\Handler\CouchDBHandler;
use Monolog\Handler\CubeHandler;
use Monolog\Handler\DoctrineCouchDBHandler;
use Monolog\Handler\FingersCrossedHandler;
use Monolog\Handler\FirePHPHandler;
use Monolog\Handler\GelfHandler;
use Monolog\Handler\GroupHandler;
use Monolog\Handler\MongoDBHandler;
use Monolog\Handler\NativeMailerHandler;
use Monolog\Handler\NullHandler;
use Monolog\Handler\PushoverHandler;
use Monolog\Handler\RavenHandler;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\SocketHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SwiftMailHandler;
use Monolog\Handler\SyslogHandler;

use Monolog\Processor\IntrospectionProcessor;
use Monolog\Processor\MemoryPeakProcessor;
use Monolog\Processor\MemoryProcessor;
use Monolog\Processor\MemoryUsageProcessor;
use Monolog\Processor\PsrLogMessageProcessor;
use Monolog\Processor\WebProcessor;

class MonologLogger implements CakeLogInterface {

public $search = null;

private $__config = array(
'channel' => 'monolog',
'handlers' => array(),
'processors' => array()
);

public function __construct($options = array()) {
extract(array_merge($this->__config, $options));
if (!isset($search) || empty($search) || !is_dir($search)) {
$search = dirname(dirname(dirname(dirname(__FILE__)))) . DS . 'vendor' . DS;
}

include $search . 'autoload.php';

$this->log = new Logger($channel);
$this->__push($handlers);
$this->__push($processors, 'Processor');
}

public function write($level, $message) {
$levels = array(

This comment has been minimized.

Copy link
@ADmad

ADmad Feb 12, 2013

You could just use the static function CakeLog::defaultLevels() instead.

This comment has been minimized.

Copy link
@jadb

jadb Feb 12, 2013

Author Owner

Not sure if I understand what you mean but the result for CakeLog::defaultLevels() returns something like this:

Array ( [0] => emergency [1] => alert [2] => critical [3] => error [4] => warning [5] => notice [6] => info [7] => debug )

Not exactly what I am looking for here. I am trying to allow for CakeLog::write(Logger::DEBUG, $msg) to write to the correct level.

Let me know if I am missing something. Thanks!

This comment has been minimized.

Copy link
@ADmad

ADmad Feb 12, 2013

Aren't Logger::DEBUG etc. also integer values?

This comment has been minimized.

Copy link
@jadb

jadb Feb 12, 2013

Author Owner

They are but not 1,2,3,4,5... See http://git.io/wVVj5w

This comment has been minimized.

Copy link
@ADmad

ADmad Feb 12, 2013

I see, nvm then.

Logger::DEBUG => 'debug',
Logger::INFO => 'info',
Logger::NOTICE => 'notice',
Logger::WARNING => 'warning',
Logger::ERROR => 'error',
Logger::CRITICAL => 'critical',
Logger::ALERT => 'alert',
Logger::EMERGENCY => 'emergency'
);

if (is_numeric($level)) {
if (isset($levels[$level])) {
$level = $levels[$level];
} else {
$level = 'error'; // Cake's default level.

This comment has been minimized.

Copy link
@ADmad

ADmad Feb 12, 2013

Why not just use the LOG_DEBUG constant which is set in core instead of string?

This comment has been minimized.

Copy link
@ADmad

ADmad Feb 12, 2013

Sorry disregard that.

}
}

$this->log->$level($message);
}

private function __push($list, $type = 'Handler') {
if (empty($list)) {
if ('Handler' == $type) {
$list = array('Stream' => array(LOGS . 'monolog.log'));
}
}

foreach ($list as $name => $params) {
if (is_numeric($name)) {
$name = $params;
$params = array();
}

$class = $name;
if (strpos($class, $type) === false) {
$class .= $type;
}

switch(strtolower($name)) {
// HANDLERS
case 'amqp':
$params += array(null, 'log', Logger::DEBUG, true);
$this->log->pushHandler(new AmqpHandler($params[0], $params[1], $params[2], $params[3]));
break;

case 'buffer':
$params += array(null, 0, Logger::DEBUG, true);
$this->log->pushHandler(new BufferHandler($params[0], $params[1], $params[2], $params[3]));
break;

case 'chromephp':
$params += array(Logger::DEBUG, true);
$this->log->pushHandler(new ChromePHPHandler($params[0], $params[1]));
break;

case 'couchdb':
$params += array(array(), Logger::DEBUG, true);
$this->log->pushHandler(new CouchDBHandler($params[0], $params[1], $params[2]));
break;

case 'cube':
$params += array(null, Logger::DEBUG, true);
$this->log->pushHandler(new CubeHandler($params[0], $params[1], $params[2]));
break;

case 'doctrinecouchdb':
$params += array(null, Logger::DEBUG, true);
$this->log->pushHandler(new DoctrineCouchDBHandler($params[0], $params[1], $params[2]));
break;

case 'fingerscrossed':
$params += array(null, null, 0, true, true);
$this->log->pushHandler(new FingersCrossedHandler($params[0], $params[1], $params[2], $params[3], $params[4]));
break;

case 'firephp':
$this->log->pushHandler(new FirePHPHandler());
break;

case 'gelf':
$params += array(null, Logger::DEBUG, true);
$this->log->pushHandler(new GelfHandler($params[0], $params[1], $params[2]));
break;

case 'group':
$params += array(array(), true);
$this->log->pushHandler(new GroupHandler($params[0], $params[1], $params[2]));
break;

case 'mongodb':
$params += array(null, null, null, Logger::DEBUG, true);
$this->log->pushHandler(new MongoDBHandler($params[0], $params[1], $params[2], $params[3], $params[4]));
break;

case 'nativemailer':
$params += array(null, null, null, Logger::ERROR, true);
$this->log->pushHandler(new NativeMailerHandler($params[0], $params[1], $params[2], $params[3], $params[4]));
break;

case 'null':
$params += array(Logger::DEBUG);
$this->log->pushHandler(new NullHandler($params[0]));
break;

case 'pushover':
$params += array(null, null, null, Logger::DEBUG, true);
$this->log->pushHandler(new PushoverHandler($params[0], $params[1], $params[2], $params[3], $params[4]));
break;

case 'raven':
$params += array(null, Logger::DEBUG, true);
$this->log->pushHandler(new RavenHandler($params[0], $params[1], $params[2]));
break;

case 'rotatingfile':
$params += array(LOGS . 'monolog-rotate.log', 0, Logger::DEBUG, true);
$this->log->pushHandler(new RotatingFileHandler($params[0], $params[1], $params[2], $params[3]));
break;

case 'socket':
$params += array(null, Logger::DEBUG, true);
$this->log->pushHandler(new SocketHandler($params[0], $params[1], $params[2]));
break;

case 'stream':
debug($params);
$params += array(LOGS . 'monolog.log', Logger::DEBUG, true);
$this->log->pushHandler(new StreamHandler($params[0], $params[1], $params[2]));
break;

case 'swiftmailer':
$params += array(null, null, Logger::DEBUG, true);
$this->log->pushHandler(new SwiftMailerHandler($params[0], $params[1], $params[2], $params[3]));
break;

case 'syslog':
$params += array(null, LOG_USER, Logger::DEBUG, true, LOG_PID);
$this->log->pushHandler(new SyslogHandler($params[0], $params[1], $params[2], $params[3], $params[4]));
break;


// PROCESSORS
case 'introspection':
$this->log->pushProcessor(new IntrospectionProcessor());
break;

case 'memorypeakusage':
$this->log->pushProcessor(new MemoryPeakUsageProcessor((bool) $params));
break;

case 'memory':
$this->log->pushProcessor(new MemoryProcessor((bool) $params));
break;

case 'memoryusage':
$this->log->pushProcessor(new MemoryUsageProcessor());
break;

case 'psrlogmessage':
$this->log->pushProcessor(new PsrLogMessageProcessor());
break;

case 'web':
if (empty($params)) {
$params = null;
}
$this->log->pushProcessor(new WebProcessor($params));
break;

}
}
}
}
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
PLUGIN=Monolog

default:
@composer

composer: composer.json
@if [ ! -f "composer.phar" ]; then make composer_install; else make composer_update; fi

composer_install: composer.json
@echo "Installing composer"
@curl -s http://getcomposer.org/installer | php
@php composer.phar install

composer_update: composer.phar
@php composer.phar update

jenkins:
@make composer
@if [ ! -d "../workspace.build" ]; then \
git clone --depth=2 https://github.com/cakephp/cakephp.git ../workspace.build && \
ln -s ${WORKSPACE} ../workspace.build/app/Plugin/${PLUGIN}; \
fi
@cd ../workspace.build/app; Console/cake test Monolog Lib/Log/Engine/MonologLogger
@cd ${WORKSPACE}
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# CakePHP Monolog Plugin

Despite the very advanced logging system offered in CakePHP, I still would have had to write a lot more
code to be able to handle logs the way I needed. To write the least code possible, I chose to go with the
popular monolog library.

## Install

Because monolog is a composer package and to avoid having to manually write a lot of includes (vs. auto-
loading), I decided to release this also as a composer package and take advantage of the auto-loading
magic.

First, add this plugin as a requirement to your `composer.json`:

{
"require": {
"cakephp/monolog": "*"
}
}

And then update:

php composer.phar update

That's it!

## Setup

Now, here's the tricky part. You can either define to use all integrated handlers and processors at once:

CakePlugin::load('Monolog');

Ok, you should now be ready to start configuring your channels.
62 changes: 62 additions & 0 deletions Test/Case/Lib/Log/Engine/MonologLoggerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
App::uses('MonologLogger', 'Monolog.Log/Engine');

use Monolog\Logger;

class MonologLoggerTest extends CakeTestCase {

public $logs = null;

public function setUp() {
$this->logs = LOGS;
$this->rotate = sprintf('rotate-%s-%s-%s', date('Y'), date('m'), date('d'));
$this->tearDown();
}

public function tearDown() {
$files = array(
'error',
'monolog',
$this->rotate
);
foreach ($files as $file) {
if (file_exists($this->logs . $file . '.log')) {
unlink($this->logs . $file . '.log');
}
}
}

public function testWritingWithDefaultHandler() {
$filename = $this->logs . 'monolog.log';
$log = new MonologLogger();
$log->write('warning', 'Test warning');
$this->assertTrue(file_exists($filename));

$result = file_get_contents($filename);
$this->assertRegExp('/^\[2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+\] monolog\.WARNING: Test warning \[\] \[\]/', $result);
}

public function testWritingWithCustomHandlers() {
$options = array(
'channel' => 'database',
'handlers' => array(
'Stream' => array($this->logs . 'error.log'),
'RotatingFile' => array($this->logs . 'rotate.log', 0, 400, false),
),
'processors' => array('Web')
);

$log = new MonologLogger($options);

$log->write('warning', 'Test warning');
$this->assertTrue(file_exists($this->logs . 'error.log'));
$this->assertFalse(file_exists($this->logs . $this->rotate . '.log'));

$this->tearDown();

$log->write('critical', 'Test critical');
$this->assertFalse(file_exists($this->logs . 'error.log'));
$this->assertTrue(file_exists($this->logs . $this->rotate . '.log'));
}

}
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0
28 changes: 28 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "cakephp/monolog",
"description": "CakePHP Monolog Plugin",
"type": "cakephp-plugin",
"keywords": ["cakephp", "monolog", "plugin"],
"homepage": "https://github.com/jadb/cakephp-monolog",
"license": "MIT",
"authors": [
{
"name": "Jad Bitar",
"homepage": "http://jadb.io",
"role": "Author"
},
{
"name": "Others",
"homepage": "https://github.com/jadb/cakephp-monolog/graphs/contributors"
}
],
"support": {
"issues": "https://github.com/jadb/cakephp-monolog/issues",
"source": "https://github.com/jadb/cakephp-monolog"
},
"require": {
"php": ">=5.3.0",
"monolog/monolog": "1.3.1",
"composer/installers": "*"
}
}

0 comments on commit 7e58970

Please sign in to comment.