library/log4php/appenders/LoggerAppenderMongoDB.php
changeset 46 f11c31f7fa3e
parent 45 a56e7f9a0463
child 47 03388ec805b4
equal deleted inserted replaced
45:a56e7f9a0463 46:f11c31f7fa3e
     1 <?php
       
     2 /**
       
     3  * Licensed to the Apache Software Foundation (ASF) under one or more
       
     4  * contributor license agreements.  See the NOTICE file distributed with
       
     5  * this work for additional information regarding copyright ownership.
       
     6  * The ASF licenses this file to You under the Apache License, Version 2.0
       
     7  * (the "License"); you may not use this file except in compliance with
       
     8  * the License.  You may obtain a copy of the License at
       
     9  *
       
    10  *     http://www.apache.org/licenses/LICENSE-2.0
       
    11  *
       
    12  * Unless required by applicable law or agreed to in writing, software
       
    13  * distributed under the License is distributed on an "AS IS" BASIS,
       
    14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    15  * See the License for the specific language governing permissions and
       
    16  * limitations under the License.
       
    17  */
       
    18 
       
    19 /**
       
    20  * Appender for writing to MongoDB.
       
    21  *
       
    22  * This class was originally contributed by Vladimir Gorej.
       
    23  *
       
    24  * ## Configurable parameters: ##
       
    25  *
       
    26  * - **host** - Server on which mongodb instance is located.
       
    27  * - **port** - Port on which the instance is bound.
       
    28  * - **databaseName** - Name of the database to which to log.
       
    29  * - **collectionName** - Name of the target collection within the given database.
       
    30  * - **username** - Username used to connect to the database.
       
    31  * - **password** - Password used to connect to the database.
       
    32  * - **timeout** - For how long the driver should try to connect to the database (in milliseconds).
       
    33  *
       
    34  * @version $Revision: 1346363 $
       
    35  * @package log4php
       
    36  * @subpackage appenders
       
    37  * @since 2.1
       
    38  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
       
    39  * @link http://logging.apache.org/log4php/docs/appenders/mongodb.html Appender documentation
       
    40  * @link http://github.com/log4mongo/log4mongo-php Vladimir Gorej's original submission.
       
    41  * @link http://www.mongodb.org/ MongoDB website.
       
    42  */
       
    43 class LoggerAppenderMongoDB extends LoggerAppender {
       
    44 
       
    45     // ******************************************
       
    46     // ** Constants                            **
       
    47     // ******************************************
       
    48 
       
    49     /** Default prefix for the {@link $host}. */
       
    50     const DEFAULT_MONGO_URL_PREFIX = 'mongodb://';
       
    51 
       
    52     /** Default value for {@link $host}, without a prefix. */
       
    53     const DEFAULT_MONGO_HOST = 'localhost';
       
    54 
       
    55     /** Default value for {@link $port} */
       
    56     const DEFAULT_MONGO_PORT = 27017;
       
    57 
       
    58     /** Default value for {@link $databaseName} */
       
    59     const DEFAULT_DB_NAME = 'log4php_mongodb';
       
    60 
       
    61     /** Default value for {@link $collectionName} */
       
    62     const DEFAULT_COLLECTION_NAME = 'logs';
       
    63 
       
    64     /** Default value for {@link $timeout} */
       
    65     const DEFAULT_TIMEOUT_VALUE = 3000;
       
    66 
       
    67     // ******************************************
       
    68     // ** Configurable parameters              **
       
    69     // ******************************************
       
    70 
       
    71     /** Server on which mongodb instance is located. */
       
    72     protected $host;
       
    73 
       
    74     /** Port on which the instance is bound. */
       
    75     protected $port;
       
    76 
       
    77     /** Name of the database to which to log. */
       
    78     protected $databaseName;
       
    79 
       
    80     /** Name of the collection within the given database. */
       
    81     protected $collectionName;
       
    82 
       
    83     /** Username used to connect to the database. */
       
    84     protected $userName;
       
    85 
       
    86     /** Password used to connect to the database. */
       
    87     protected $password;
       
    88 
       
    89     /** Timeout value used when connecting to the database (in milliseconds). */
       
    90     protected $timeout;
       
    91 
       
    92     // ******************************************
       
    93     // ** Member variables                     **
       
    94     // ******************************************
       
    95 
       
    96     /**
       
    97      * Connection to the MongoDB instance.
       
    98      * @var Mongo
       
    99      */
       
   100     protected $connection;
       
   101 
       
   102     /**
       
   103      * The collection to which log is written.
       
   104      * @var MongoCollection
       
   105      */
       
   106     protected $collection;
       
   107 
       
   108     public function __construct($name = '') {
       
   109         parent::__construct($name);
       
   110         $this->host = self::DEFAULT_MONGO_URL_PREFIX . self::DEFAULT_MONGO_HOST;
       
   111         $this->port = self::DEFAULT_MONGO_PORT;
       
   112         $this->databaseName = self::DEFAULT_DB_NAME;
       
   113         $this->collectionName = self::DEFAULT_COLLECTION_NAME;
       
   114         $this->timeout = self::DEFAULT_TIMEOUT_VALUE;
       
   115         $this->requiresLayout = false;
       
   116     }
       
   117 
       
   118     /**
       
   119      * Setup db connection.
       
   120      * Based on defined options, this method connects to the database and
       
   121      * creates a {@link $collection}.
       
   122      */
       
   123     public function activateOptions() {
       
   124         try {
       
   125             $this->connection = new Mongo(sprintf('%s:%d', $this->host, $this->port), array('timeout' => $this->timeout));
       
   126             $db = $this->connection->selectDB($this->databaseName);
       
   127             if ($this->userName !== null && $this->password !== null) {
       
   128                 $authResult = $db->authenticate($this->userName, $this->password);
       
   129                 if ($authResult['ok'] == floatval(0)) {
       
   130                     throw new Exception($authResult['errmsg'], $authResult['ok']);
       
   131                 }
       
   132             }
       
   133             $this->collection = $db->selectCollection($this->collectionName);
       
   134         } catch (MongoConnectionException $ex) {
       
   135             $this->closed = true;
       
   136             $this->warn(sprintf('Failed to connect to mongo deamon: %s', $ex->getMessage()));
       
   137         } catch (InvalidArgumentException $ex) {
       
   138             $this->closed = true;
       
   139             $this->warn(sprintf('Error while selecting mongo database: %s', $ex->getMessage()));
       
   140         } catch (Exception $ex) {
       
   141             $this->closed = true;
       
   142             $this->warn('Invalid credentials for mongo database authentication');
       
   143         }
       
   144     }
       
   145 
       
   146     /**
       
   147      * Appends a new event to the mongo database.
       
   148      *
       
   149      * @param LoggerLoggingEvent $event
       
   150      */
       
   151     public function append(LoggerLoggingEvent $event) {
       
   152         try {
       
   153             if ($this->collection != null) {
       
   154                 $this->collection->insert($this->format($event));
       
   155             }
       
   156         } catch (MongoCursorException $ex) {
       
   157             $this->warn(sprintf('Error while writing to mongo collection: %s', $ex->getMessage()));
       
   158         }
       
   159     }
       
   160 
       
   161     /**
       
   162      * Converts the logging event into an array which can be logged to mongodb.
       
   163      *
       
   164      * @param LoggerLoggingEvent $event
       
   165      * @return array The array representation of the logging event.
       
   166      */
       
   167     protected function format(LoggerLoggingEvent $event) {
       
   168         $timestampSec = (int)$event->getTimestamp();
       
   169         $timestampUsec = (int)(($event->getTimestamp() - $timestampSec) * 1000000);
       
   170 
       
   171         $document = array(
       
   172             'timestamp' => new MongoDate($timestampSec, $timestampUsec),
       
   173             'level' => $event->getLevel()->toString(),
       
   174             'thread' => (int)$event->getThreadName(),
       
   175             'message' => $event->getMessage(),
       
   176             'loggerName' => $event->getLoggerName()
       
   177         );
       
   178 
       
   179         $locationInfo = $event->getLocationInformation();
       
   180         if ($locationInfo != null) {
       
   181             $document['fileName'] = $locationInfo->getFileName();
       
   182             $document['method'] = $locationInfo->getMethodName();
       
   183             $document['lineNumber'] = ($locationInfo->getLineNumber() == 'NA') ? 'NA' : (int)$locationInfo->getLineNumber();
       
   184             $document['className'] = $locationInfo->getClassName();
       
   185         }
       
   186 
       
   187         $throwableInfo = $event->getThrowableInformation();
       
   188         if ($throwableInfo != null) {
       
   189             $document['exception'] = $this->formatThrowable($throwableInfo->getThrowable());
       
   190         }
       
   191 
       
   192         return $document;
       
   193     }
       
   194 
       
   195     /**
       
   196      * Converts an Exception into an array which can be logged to mongodb.
       
   197      *
       
   198      * Supports innner exceptions (PHP >= 5.3)
       
   199      *
       
   200      * @param Exception $ex
       
   201      * @return array
       
   202      */
       
   203     protected function formatThrowable(Exception $ex) {
       
   204         $array = array(
       
   205             'message' => $ex->getMessage(),
       
   206             'code' => $ex->getCode(),
       
   207             'stackTrace' => $ex->getTraceAsString(),
       
   208         );
       
   209 
       
   210         if (method_exists($ex, 'getPrevious') && $ex->getPrevious() !== null) {
       
   211             $array['innerException'] = $this->formatThrowable($ex->getPrevious());
       
   212         }
       
   213 
       
   214         return $array;
       
   215     }
       
   216 
       
   217     /**
       
   218      * Closes the connection to the logging database
       
   219      */
       
   220     public function close() {
       
   221         if ($this->closed != true) {
       
   222             $this->collection = null;
       
   223             if ($this->connection !== null) {
       
   224                 $this->connection->close();
       
   225                 $this->connection = null;
       
   226             }
       
   227             $this->closed = true;
       
   228         }
       
   229     }
       
   230 
       
   231     /**
       
   232      * Sets the value of {@link $host} parameter.
       
   233      * @param string $host
       
   234      */
       
   235     public function setHost($host) {
       
   236         if (!preg_match('/^mongodb\:\/\//', $host)) {
       
   237             $host = self::DEFAULT_MONGO_URL_PREFIX . $host;
       
   238         }
       
   239         $this->host = $host;
       
   240     }
       
   241 
       
   242     /**
       
   243      * Returns the value of {@link $host} parameter.
       
   244      * @return string
       
   245      */
       
   246     public function getHost() {
       
   247         return $this->host;
       
   248     }
       
   249 
       
   250     /**
       
   251      * Sets the value of {@link $port} parameter.
       
   252      * @param int $port
       
   253      */
       
   254     public function setPort($port) {
       
   255         $this->setPositiveInteger('port', $port);
       
   256     }
       
   257 
       
   258     /**
       
   259      * Returns the value of {@link $port} parameter.
       
   260      * @return int
       
   261      */
       
   262     public function getPort() {
       
   263         return $this->port;
       
   264     }
       
   265 
       
   266     /**
       
   267      * Sets the value of {@link $databaseName} parameter.
       
   268      * @param string $databaseName
       
   269      */
       
   270     public function setDatabaseName($databaseName) {
       
   271         $this->setString('databaseName', $databaseName);
       
   272     }
       
   273 
       
   274     /**
       
   275      * Returns the value of {@link $databaseName} parameter.
       
   276      * @return string
       
   277      */
       
   278     public function getDatabaseName() {
       
   279         return $this->databaseName;
       
   280     }
       
   281 
       
   282     /**
       
   283      * Sets the value of {@link $collectionName} parameter.
       
   284      * @param string $collectionName
       
   285      */
       
   286     public function setCollectionName($collectionName) {
       
   287         $this->setString('collectionName', $collectionName);
       
   288     }
       
   289 
       
   290     /**
       
   291      * Returns the value of {@link $collectionName} parameter.
       
   292      * @return string
       
   293      */
       
   294     public function getCollectionName() {
       
   295         return $this->collectionName;
       
   296     }
       
   297 
       
   298     /**
       
   299      * Sets the value of {@link $userName} parameter.
       
   300      * @param string $userName
       
   301      */
       
   302     public function setUserName($userName) {
       
   303         $this->setString('userName', $userName, true);
       
   304     }
       
   305 
       
   306     /**
       
   307      * Returns the value of {@link $userName} parameter.
       
   308      * @return string
       
   309      */
       
   310     public function getUserName() {
       
   311         return $this->userName;
       
   312     }
       
   313 
       
   314     /**
       
   315      * Sets the value of {@link $password} parameter.
       
   316      * @param string $password
       
   317      */
       
   318     public function setPassword($password) {
       
   319         $this->setString('password', $password, true);
       
   320     }
       
   321 
       
   322     /**
       
   323      * Returns the value of {@link $password} parameter.
       
   324      * @return string
       
   325      */
       
   326     public function getPassword() {
       
   327         return $this->password;
       
   328     }
       
   329 
       
   330     /**
       
   331      * Sets the value of {@link $timeout} parameter.
       
   332      * @param int $timeout
       
   333      */
       
   334     public function setTimeout($timeout) {
       
   335         $this->setPositiveInteger('timeout', $timeout);
       
   336     }
       
   337 
       
   338     /**
       
   339      * Returns the value of {@link $timeout} parameter.
       
   340      * @return int
       
   341      */
       
   342     public function getTimeout() {
       
   343         return $this->timeout;
       
   344     }
       
   345 
       
   346     /**
       
   347      * Returns the mongodb connection.
       
   348      * @return Mongo
       
   349      */
       
   350     public function getConnection() {
       
   351         return $this->connection;
       
   352     }
       
   353 
       
   354     /**
       
   355      * Returns the active mongodb collection.
       
   356      * @return MongoCollection
       
   357      */
       
   358     public function getCollection() {
       
   359         return $this->collection;
       
   360     }
       
   361 }