View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFPROP:Proposal Zone Template}

{zone-data:component-name}
Zend_Log_Writer_MongoDb
{zone-data}

{zone-data:proposer-list}
[Robert Allen|mailto:zircote@gmail.com]
{zone-data}

{zone-data:liaison}
TBD
{zone-data}

{zone-data:revision}
1.0 - 1 March 2012: Initial Draft.
{zone-data}

{zone-data:overview}
Zend_Log_Writer_MongoDb is a log writer for Zend_Log enabling centralized logging in distributed environments. It enables log aggregation, filtering and prevents the loss of log information in cloud instances that auto-scale down and are not able to copy log files to outside storage. When utilized with 'capped' collections tailing cursors may be implemented for realtime log observations by utilizing the Zend_Tool_Project_Provider_MongoLog project provider.
{zone-data}

{zone-data:references}
* [Zend_Log_Writer_MongoDb|https://github.com/zircote/Zend_Log_Writer_Mongo]
* [MongoDb.org|http://www.mongodb.org/]
* [Mongo docs on php.net|http://www.php.net/manual/en/book.mongo.php]
{zone-data}

{zone-data:requirements}
* This component *will* require installation of the Mongo extension.
* This component *will* require logging collections to be capped for tailing.
* This component *will* support mapping of document members via configuration.
* This component *will* track origination hostnames as part of the document saved.
{zone-data}

{zone-data:dependencies}
* MongoDb pecl extension
* Zend_Log_Writer_Abstract
* Zend_Tool_Project_Provider_Abstract
* Zend_Tool_Project_Provider_Exception
{zone-data}

{zone-data:operation}
The Zend_Log_Writer_MongoDb component may be instantiated explicitly as a writer and attached to an existing Zend_Log instance, via the Zend_Log_Writer_MongoDb::factory() method, or the Zend_Log::factory().

The Zend_Tool_Project_Provider_MongoLog if elected to be included would examine the project resources for a MongoDb writer type for determination of configuration or throw an Zend_Tool_Project_Provider_Exception. This tool will watch the logs of all servers in the cluster and tail them in realtime. The three options are:
{code}
zf tail mongo-log ?
-h hostname -- This is a server hostname allowing you to watch the logs of a specific server in the operational cluster.
-f filter -- This is a regex filter that the logs are gathered against
-p priority -- The log priority to filter the tail on
-e environment -- The server environment you are interested in tailing [development|testing|production]
{code}
{zone-data}

{zone-data:milestones}
Describe some intermediate state of this component in terms of design notes, additional material added to this page, and / code. Note any significant dependencies here, such as, "Milestone #3 can not be completed until feature Foo has been added to ZF component XYZ." Milestones will be required for acceptance of future proposals. They are not hard, and many times you will only need to think of the first three below.
* Milestone 1: Complete review and incorporate feedback into design.
* Milestone 2: Complete Unit tests.
* Milestone 3: Complete prototypical code and passing all unit tests.
* Milestone 5: Complete documentation.

{zone-data}

{zone-data:class-list}
* Zend_Log_Writer_MongoDb
* Zend_Tool_Project_Provider_MongoLog
{zone-data}

{zone-data:use-cases}
||UC-01||
{code}
<?php
$logger = Zend_Log::factory(
array(
'timestampFormat' => 'Y-m-d',
array(
'writerName' => 'MongoDb',
'writerParams' => array(
'server' => 'mongodb://somehost.mongolab.com:27017',
'collection' => 'logging',
'database' => 'zend_log',
'options' => array(
'username' => 'zircote-dev',
'password' => 'somepassword',
'connect' => true,
'timeout' => 200,
'replicaSet' => 'repset1',
'db' => 'zend_log'
)
)
)
)
);
$logger->crit(__METHOD__);
{code}

||UC-02||
{code}
<?php
$config = array(
'server' => 'mongodb://somehost.mongolab.com:27017',
'collection' => 'logging',
'database' => 'zend_log',
'options' => array(
'username' => 'zircote-dev',
'password' => 'somepassword',
'connect' => true,
'timeout' => 200,
'replicaSet' => 'repset1',
'db' => 'zend_log')
);
$log = new Zend_log();
$log->addWriter(Zend_Log_Writer_MongoDb::factory($config));
$log->info('this is a test ' . __METHOD__);
{code}

||UC-03||
{code}
<?php
$config = array(
'collection' => 'log',
'database' => 'pincrowd'
);
$writer = Zend_Log_Writer_MongoDb::factory($config);
$log = new Zend_log();
$log->addWriter($writer);
$log->info('this is a test');
{code}

||UC-04||
{code}
<?php
$mongo = new MongoDb();
$collection = $mongo->selectDB('logging')
->selectCollection('logCollection');
$log = new Zend_log();
$writer = new Zend_Log_Writer_MongoDb($collection);
$log->addWriter($writer);
$log->err(__METHOD__);
{code}

||UC-05||
Tailing Cursor Example:
{code}
<?php
$mongo = new Mongo();
$db = $mongo->selectDB('logging');
$collection = $db->selectCollection('logCollection');
$cursor = $collection->find()->tailable(true);
while (true) {
if ($cursor->hasNext()) {
$doc = $cursor->getNext();
echo date(DATE_ISO8601, $doc['timestamp']->sec), ' ',$doc['priorityName'],' ', $doc['message'], PHP_EOL;
} else {
usleep(500);
}
}
{code}

||UC-06||
{code}
;;; application.ini ;;;
resources.log.mongo.writerName = "MongoDb"
resources.log.mongo.writerParams.database = "pincrowd"
resources.log.mongo.writerParams.collection = "logging"
resources.log.mongo.writerParams.documentMap.timestamp = 'timestamp'
resources.log.mongo.writerParams.documentMap.message = 'message'
resources.log.mongo.writerParams.documentMap.priority = 'priority'
resources.log.mongo.writerParams.documentMap.priorityName = 'priorityName'
resources.log.mongo.writerParams.documentMap.hostname = 'hostname'
resources.log.mongo.filterName = "Priority"
resources.log.mongo.filterParams.priority = 5

<?php
if($bootstrap->hasResource('log')){
$log = $bootstrap->getResource('log');
$log->info('log me');
}
{code}
|||UC-07||
Example Document
{code}
{
"_id" : ObjectId("4f5fa1546be132029900009e"),
"timestamp" : ISODate("2012-03-13T19:34:44Z"),
"message" : "this is a test 27",
"priority" : 3,
"priorityName" : "ERR",
"hostname" : "zircote-mbp-4.local"
}
{code}
{zone-data}

{zone-data:skeletons}
{code}
<?php
/**
* @category Zend
* @package Zend_Log
* @subpackage Writer
*/
/**
* @see Zend_Log_Writer_Abstract
*/
require_once ('Zend/Log/Writer/Abstract.php');
/**
* @category Zend
* @package Zend_Log
* @subpackage Writer
*
*/
class Zend_Log_Writer_MongoDb extends Zend_Log_Writer_Abstract
{
/**
*
*
* @var MongoCollection
*/
protected $_collection;
/**
* Defines the mapping of data to the collection members.
*
* @var array
*/
protected $_documentMap = array(
'timestamp' => 'timestamp',
'message' => 'message',
'priority' => 'priority',
'priorityName' => 'priorityName',
'hostname' => 'hostname'
);
/**
* Originating hostname of the log entry.
*
* @var string
*/
protected $_hostname;
/**
*
*
* @param MongoCollection $collection
* @param array $documentMap
*/
public function __construct(MongoCollection $collection, $documentMap = null)
{
}
/**
* (non-PHPdoc)
* @see Zend_Log_Writer_Abstract::_write()
*/
protected function _write ($event)
{
}
/**
*
* @param array $config
* @return Zend_Log_Writer_MongoDb
*/
static public function factory ($config)
{
}
/**
* Create the MongoCollection Object.
*
* @param array $config
* @return MongoCollection
*/
static protected function _createMongoCollection($config)
{
}
/**
* Determine the hostname of the server executing the code. This allows for
* demarcation of entries in a cluster.
*/
protected function _setHostname()
{
}
}

/**
*
* @category Zend
* @package Zend_Tool
* @subpackage Framework
*/
/**
* @see Zend_Tool_Project_Provider_AbstractProvider
*/
require_once 'Zend/Tool/Project/Provider/AbstractProvider.php';
/**
*
*
* @category Zend
* @package Zend_Tool
* @subpackage Framework
*
*
*/
class Zend_Tool_Project_Provider_MongoLog extends Zend_Tool_Project_Provider_Abstract
{
/**
*
* @var array
*/
protected $_config;
/**
*
* @var array
*/
protected $_mongoParams;
/**
*
* @var MongoCollection
*/
protected $_mongoCollection;
/**
* @see Zend_Tool_Project_Provider_AbstractProvider::initialize()
*/
public function initialize()
{
}

/**
* Loads the config into the self::_config property.
* @return Zend_Tool_Project_Provider_MongoLog
* @throws Zend_Tool_Project_Exception
*/
protected function _loadConfig()
{
}
/**
*
* @param array|Zend_Config $config
* @return Zend_Tool_Project_Provider_MongoLog
*/
protected function _setConfig($config)
{
}
/**
* <b>Example Usage:</b>
*
* <code>
* zf tail log -h 'some-host.cloud.com' -f 'somebad thing happened' -e production
* </code>
*
* @param string $filter text to filter the logs by
* @param server $hostname comma seperated lists of servers to return logs for
* @param int $priority The log priority to filter the tail on
* @param string $env project environment by which the configs are loaded
*/
public function tail($filter = null, $hostname = null, $priority = null, $env = 'development')
{
}
/**
* Handles the creation of the MongoCollection
*/
protected function _setMongo()
{
}

/**
*
*
* @param array $config
* @return MongoCollection
*/
protected function _createMongoCollection($config)
{
}
}
{code}
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>