pluf2

pluf2 Git Source Tree


Root/src/Pluf/Log.php

<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of Plume Framework, a simple PHP Application Framework.
# Copyright (C) 2001-2009 Loic d'Anterroches and contributors.
#
# Plume Framework is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Plume Framework is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# ***** END LICENSE BLOCK ***** */

/**
 * High performance logging infrastructure.
 *
 * Logging while keeping a high performance in production is hard, it
 * is even harder if we want to track the point in the code where the
 * log information is generated, for example the file name and line
 * number. PHP offers the assert statement which, used in a not so
 * conventional way can get everything in a very efficient way.
 *
 * Note that the messages do not need to be strings. You can log
 * whatever you want. How the message is then stored in your logs is
 * up to the writer you are using. This can be for example a JSON
 * fragment.
 *
 * The removal of constraints on the log message simplify the log
 * system as you can push into it categories or extra informations.
 *
 * In the log stack, each log message is microtimed together with the
 * log level as integer. You can convert the integer to string at
 * write time.
 *
 */
class Pluf_Log
{
    /**
     * The log stack.
     *
     * A logger function is just pushing the data in the log stack,
     * the writers are then called to write the data later.
     */
    public static $stack = array();
    
    /**
     * Different log levels.
     */
    const ALL = 1;
    const DEBUG = 5;
    const INFO = 6;
    const WARN = 7;
    const ERROR = 8;
    const FATAL = 9;
    const OFF = 10;
    
    /**
     * Used to reverse the log level to the string.
     */
    public static $reverse = array(1 => 'ALL',
                                   5 => 'DEBUG',
                                   6 => 'INFO',
                                   7 => 'WARN',
                                   8 => 'ERROR',
                                   9 => 'FATAL');

    /**
     * Current log level.
     *
     * By default, set to 6, which is the INFO level.
     */
    public static $level = 6;

    /**
     * Current message in the assert log.
     */
    public static $assert_mess = null;

    /**
     * Current level of the message in the assert log.
     */
    public static $assert_level = 6;

    /**
     * Log the information in the stack.
     *
     * Flush the information if needed.
     *
     * @param $level Level to log
     * @param $message Message to log
     */
    private static function _log($level, $message)
    {

        if (self::$level >= $level and self::$level != 10) {
            self::$stack[] = array(microtime(true), $level, $message);
            if (!Pluf::f('log_delayed', false)) {
                self::flush();
            }
        }
    }

    /**
     * Base assert logger.
     *
     * The assert logging is a two step process as one need to go
     * through the assertion callback.
     *
     * @param $level Level to log
     * @param $message Message to log
     * @return bool false
     */
    private static function _alog($level, $message)
    {
        self::$assert_level = $level;
        self::$assert_mess = $message;
        return false; // This will trigger the assert handler.
    }

    /**
     * Log at the ALL level.
     *
     * @param $message Message to log
     */
    public static function log($message)
    {
        return self::_log(self::ALL, $message);
    }

    /**
     * Log at the DEBUG level.
     *
     * @param $message Message to log
     */
    public static function debug($message)
    {
        self::_log(self::DEBUG, $message);
    }

    public static function info($message)
    {
        self::_log(self::INFO, $message);
    }

    public static function warn($message)
    {
        self::_log(self::WARN, $message);
    }

    public static function error($message)
    {
        self::_log(self::ERROR, $message);
    }

    public static function fatal($message)
    {
        self::_log(self::FATAL, $message);
    }

    /**
     * Assert log at the ALL level.
     *
     * @param $message Message to log
     */
    public static function alog($message)
    {
        return self::_alog(self::ALL, $message);
    }

    /**
     * Assert log at the DEBUG level.
     *
     * @param $message Message to log
     */
    public static function adebug($message)
    {
        self::_alog(self::DEBUG, $message);
    }

    public static function ainfo($message)
    {
        self::_alog(self::INFO, $message);
    }

    public static function awarn($message)
    {
        self::_alog(self::WARN, $message);
    }

    public static function aerror($message)
    {
        self::_alog(self::ERROR, $message);
    }

    public static function afatal($message)
    {
        self::_alog(self::FATAL, $message);
    }
 
    /**
     * Flush the data to the writer.
     *
     * This reset the stack.
     */
    public static function flush()
    {
        $writer = Pluf::f('log_handler', 'Pluf_Log_File');
        call_user_func(array($writer, 'write'), self::$stack);
        self::$stack = array();
    }

    /**
     * Signal handler to flush the log.
     *
     * The name of the signal and the parameters are not used.
     *
     * @param $signal Name of the signal
     * @param &$params Parameters
     */
    public static function flushHandler($signal, &$params)
    {
        self::flush();
    }

    /**
     * Activation of the low impact logging.
     *
     * When called, it enabled the assertions for debugging.
     */
    public static function activeAssert()
    {
        assert_options(ASSERT_ACTIVE, 1); 
        assert_options(ASSERT_WARNING, 0);
        assert_options(ASSERT_QUIET_EVAL, 1);
        assert_options(ASSERT_CALLBACK, 'Pluf_Log_assert');
    }
}

/**
 * Assertion handler.
 *
 * @param $file Name of the file where the assert is called
 * @param $line Line number of the file where the assert is called
 * @param $code Code evaluated by the assert call
 */
function Pluf_Log_assert($file, $line, $code)
{
    if (Pluf_Log::$level >= Pluf_Log::$assert_level and 
        Pluf_Log::$level != 10) {
        Pluf_Log::$stack[] = array(
                                   microtime(true),
                                   Pluf_Log::$assert_level,
                                   Pluf_Log::$assert_mess,
                                   $file, $line, $code);
        if (!Pluf::f('log_delayed', false)) {
            Pluf_Log::flush();
        }
                               
    }
    Pluf_Log::$assert_level = 6;
    Pluf_Log::$assert_mess = null;
}

Archive Download this file

Branches

Number of commits:
Page rendered in 0.11391s using 11 queries.