Include klogger, enable for trackbacks and index

This commit is contained in:
onli 2014-05-12 20:03:34 +02:00
parent 3bde48937f
commit 09400814d2
30 changed files with 1276 additions and 61 deletions

View File

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14::getLoader();
return ComposerAutoloaderInitcbda25b16bb8365467298ce193f0f30c::getLoader();

View File

@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Katzgrau\\KLogger\\Logger' => $vendorDir . '/katzgrau/klogger/src/Logger.php',
);

View File

@ -7,4 +7,5 @@ $baseDir = dirname($vendorDir);
return array(
'Zend\\Db\\' => array($vendorDir . '/zendframework/zend-db'),
'Psr\\Log\\' => array($vendorDir . '/psr/log'),
);

View File

@ -2,7 +2,7 @@
// autoload_real.php generated by Composer
class ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14
class ComposerAutoloaderInitcbda25b16bb8365467298ce193f0f30c
{
private static $loader;
@ -19,9 +19,9 @@ class ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitcbda25b16bb8365467298ce193f0f30c', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit3146f05565d9c8136a7e59e2a511ce14', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitcbda25b16bb8365467298ce193f0f30c', 'loadClassLoader'));
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

View File

@ -46,5 +46,99 @@
"support": {
"source": "https://github.com/zendframework/Component_ZendDb/tree/release-2.2.2"
}
},
{
"name": "psr/log",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
"shasum": ""
},
"time": "2012-12-21 11:40:51",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Psr\\Log\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"keywords": [
"log",
"psr",
"psr-3"
]
},
{
"name": "katzgrau/klogger",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/katzgrau/klogger.git",
"reference": "46cdd92a9b4a8443120cc955bf831450cb274813"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/katzgrau/klogger/zipball/46cdd92a9b4a8443120cc955bf831450cb274813",
"reference": "46cdd92a9b4a8443120cc955bf831450cb274813",
"shasum": ""
},
"require": {
"php": ">=5.3",
"psr/log": "1.0.0"
},
"require-dev": {
"phpunit/phpunit": "4.0.*"
},
"time": "2014-03-20 02:36:36",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Katzgrau\\KLogger\\": "src/"
},
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dan Horrigan",
"email": "dan@dhorrigan.com",
"homepage": "http://dhorrigan.com",
"role": "Lead Developer"
},
{
"name": "Kenny Katzgrau",
"email": "katzgrau@gmail.com"
}
],
"description": "A Simple Logging Class",
"keywords": [
"logging"
]
}
]

View File

@ -0,0 +1,3 @@
/tests/logs/*.txt
/vendor/
composer.lock

View File

@ -0,0 +1,163 @@
# KLogger: Simple Logging for PHP
A project written by [Kenny Katzgrau](http://twitter.com/katzgrau) and [Dan Horrigan](http://twitter.com/dhrrgn).
## About
KLogger is an easy-to-use [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
compliant logging class for PHP. It isn't naive about
file permissions (which is expected). It was meant to be a class that you could
quickly include into a project and have working right away.
## Installation
### Composer
From the Command Line:
```
composer require katzgrau/klogger:1.0.*
```
In your `composer.json`:
``` json
{
"require": {
"katzgrau/klogger": "1.0.*"
}
}
```
## Basic Usage
``` php
<?php
require 'vendor/autoload.php';
$users = [
[
'name' => 'Kenny Katzgrau',
'username' => 'katzgrau',
],
[
'name' => 'Dan Horrigan',
'username' => 'dhrrgn',
],
];
$logger = new Katzgrau\KLogger\Logger(__DIR__.'/logs');
$logger->info('Returned a million search results');
$logger->error('Oh dear.');
$logger->debug('Got these users from the Database.', $users);
```
### Output
```
[2014-03-20 3:35:43.762437] [INFO] Returned a million search results
[2014-03-20 3:35:43.762578] [ERROR] Oh dear.
[2014-03-20 3:35:43.762795] [DEBUG] Got these users from the Database.
0: array(
'name' => 'Kenny Katzgrau',
'username' => 'katzgrau',
)
1: array(
'name' => 'Dan Horrigan',
'username' => 'dhrrgn',
)
```
## PSR-3 Compliant
KLogger is [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
compliant. This means it implements the `Psr\Log\LoggerInterface`.
[See Here for the interface definition.](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#3-psrlogloggerinterface)
## Setting the Log Level Threshold
You can use the `Psr\Log\LogLevel` constants to set Log Level Threshold, so that
any messages below that level, will not be logged.
### Default Level
The default level is `DEBUG`, which means everything will be logged.
### Available Levels
``` php
<?php
use Psr\Log\LogLevel;
// These are in order of highest priority to lowest.
LogLevel::EMERGENCY;
LogLevel::ALERT;
LogLevel::CRITICAL;
LogLevel::ERROR;
LogLevel::WARNING;
LogLevel::NOTICE;
LogLevel::INFO;
LogLevel::DEBUG;
```
### Example
``` php
<?php
// The
$logger = new Katzgrau\KLogger\Logger('/var/log/', Psr\Log\LogLevel::WARNING);
$logger->error('Uh Oh!'); // Will be logged
$logger->info('Something Happened Here'); // Will be NOT logged
```
## Why use KLogger?
Why not? Just drop it in and go. If it saves you time and does what you need,
go for it! Take a line from the book of our C-code fathers: "`build` upon the
work of others".
## Who uses KLogger?
Klogger has been used in projects at:
* The University of Iowa
* The University of Laverne
* The New Jersey Institute of Technology
* Middlesex Hospital in NJ
Additionally, it's been used in numerous projects, both commercial and personal.
## Special Thanks
Special thanks to all contributors:
* [Dan Horrigan](http://twitter.com/dhrrgn)
* [Tim Kinnane](http://twitter.com/etherealtim)
* [Brian Fenton](http://github.com/fentie)
* [Cameron Will](https://github.com/cwill747)
## License
The MIT License
Copyright (c) 2008-2014 Kenny Katzgrau <katzgrau@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,30 @@
{
"name": "katzgrau/klogger",
"version": "1.0.0",
"description": "A Simple Logging Class",
"keywords": ["logging"],
"require": {
"php": ">=5.3",
"psr/log": "1.0.0"
},
"require-dev": {
"phpunit/phpunit": "4.0.*"
},
"license": "MIT",
"authors": [
{
"name": "Kenny Katzgrau",
"email": "katzgrau@gmail.com"
},
{
"name": "Dan Horrigan",
"email": "dan@dhorrigan.com"
}
],
"autoload": {
"psr-4": {
"Katzgrau\\KLogger\\": "src/"
},
"classmap": ["src/"]
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true"
stopOnFailure="false"
bootstrap="./vendor/autoload.php"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true">
<testsuites>
<testsuite name="common">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<directory>./vendor</directory>
</blacklist>
</filter>
</phpunit>

View File

@ -0,0 +1,231 @@
<?php
namespace Katzgrau\KLogger;
use DateTime;
use RuntimeException;
use Psr\Log\AbstractLogger;
use Psr\Log\LogLevel;
/**
* Finally, a light, permissions-checking logging class.
*
* Originally written for use with wpSearch
*
* Usage:
* $log = new Katzgrau\KLogger\Logger('/var/log/', Psr\Log\LogLevel::INFO);
* $log->info('Returned a million search results'); //Prints to the log file
* $log->error('Oh dear.'); //Prints to the log file
* $log->debug('x = 5'); //Prints nothing due to current severity threshhold
*
* @author Kenny Katzgrau <katzgrau@gmail.com>
* @since July 26, 2008 Last update July 1, 2012
* @link http://codefury.net
* @version 0.2.0
*/
/**
* Class documentation
*/
class Logger extends AbstractLogger
{
/**
* Path to the log file
* @var string
*/
private $logFilePath = null;
/**
* Current minimum logging threshold
* @var integer
*/
private $logLevelThreshold = LogLevel::DEBUG;
private $logLevels = array(
LogLevel::EMERGENCY => 0,
LogLevel::ALERT => 1,
LogLevel::CRITICAL => 2,
LogLevel::ERROR => 3,
LogLevel::WARNING => 4,
LogLevel::NOTICE => 5,
LogLevel::INFO => 6,
LogLevel::DEBUG => 7,
);
/**
* This holds the file handle for this instance's log file
* @var resource
*/
private $fileHandle = null;
/**
* Valid PHP date() format string for log timestamps
* @var string
*/
private $dateFormat = 'Y-m-d G:i:s.u';
/**
* Octal notation for default permissions of the log file
* @var integer
*/
private $defaultPermissions = 0777;
/**
* Class constructor
*
* @param string $logDirectory File path to the logging directory
* @param integer $logLevelThreshold The LogLevel Threshold
* @return void
*/
public function __construct($logDirectory, $logLevelThreshold = LogLevel::DEBUG)
{
$this->logLevelThreshold = $logLevelThreshold;
$logDirectory = rtrim($logDirectory, '\\/');
if (! file_exists($logDirectory)) {
mkdir($logDirectory, $this->defaultPermissions, true);
}
$this->logFilePath = $logDirectory.DIRECTORY_SEPARATOR.'log_'.date('Y-m-d').'.txt';
if (file_exists($this->logFilePath) && !is_writable($this->logFilePath)) {
throw new RuntimeException('The file could not be written to. Check that appropriate permissions have been set.');
}
$this->fileHandle = fopen($this->logFilePath, 'a');
if ( ! $this->fileHandle) {
throw new RuntimeException('The file could not be opened. Check permissions.');
}
}
/**
* Class destructor
*/
public function __destruct()
{
if ($this->fileHandle) {
fclose($this->fileHandle);
}
}
/**
* Sets the date format used by all instances of KLogger
*
* @param string $dateFormat Valid format string for date()
*/
public function setDateFormat($dateFormat)
{
$this->dateFormat = $dateFormat;
}
/**
* Sets the Log Level Threshold
*
* @param string $dateFormat Valid format string for date()
*/
public function setLogLevelThreshold($logLevelThreshold)
{
$this->logLevelThreshold = $logLevelThreshold;
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
*/
public function log($level, $message, array $context = array())
{
if ($this->logLevels[$this->logLevelThreshold] < $this->logLevels[$level]) {
return;
}
$message = $this->formatMessage($level, $message, $context);
$this->write($message);
}
/**
* Writes a line to the log without prepending a status or timestamp
*
* @param string $line Line to write to the log
* @return void
*/
public function write($message)
{
if (! is_null($this->fileHandle)) {
if (fwrite($this->fileHandle, $message) === false) {
throw new RuntimeException('The file could not be written to. Check that appropriate permissions have been set.');
}
}
}
/**
* Formats the message for logging.
*
* @param string $level The Log Level of the message
* @param string $message The message to log
* @param array $context The context
* @return string
*/
private function formatMessage($level, $message, $context)
{
$level = strtoupper($level);
if (! empty($context)) {
$message .= PHP_EOL.$this->indent($this->contextToString($context));
}
return "[{$this->getTimestamp()}] [{$level}] {$message}".PHP_EOL;
}
/**
* Gets the correctly formatted Date/Time for the log entry.
*
* PHP DateTime is dump, and you have to resort to trickery to get microseconds
* to work correctly, so here it is.
*
* @return string
*/
private function getTimestamp()
{
$originalTime = microtime(true);
$micro = sprintf("%06d", ($originalTime - floor($originalTime)) * 1000000);
$date = new DateTime(date('Y-m-d H:i:s.'.$micro, $originalTime));
return $date->format($this->dateFormat);
}
/**
* Takes the given context and coverts it to a string.
*
* @param array $context The Context
* @return string
*/
private function contextToString($context)
{
$export = '';
foreach ($context as $key => $value) {
$export .= "{$key}: ";
$export .= preg_replace(array(
'/=>\s+([a-zA-Z])/im',
'/array\(\s+\)/im',
'/^ |\G /m',
), array(
'=> $1',
'array()',
' ',
), str_replace('array (', 'array(', var_export($value, true)));
$export .= PHP_EOL;
}
return str_replace(array('\\\\', '\\\''), array('\\', '\''), rtrim($export));
}
/**
* Indents the given string with the given indent.
*
* @param string $string The string to indent
* @param string $indent What to use as the indent.
* @return string
*/
private function indent($string, $indent = ' ')
{
return $indent.str_replace("\n", "\n".$indent, $string);
}
}

View File

@ -0,0 +1,20 @@
<?php
use Katzgrau\KLogger\Logger;
class LoggerTest extends PHPUnit_Framework_TestCase
{
private $logPath;
private $logger;
public function setUp()
{
$this->logPath = __DIR__.'/logs';
$this->logger = new Logger($this->logPath);
}
public function testImplementsPsr3LoggerInterface()
{
$this->assertInstanceOf('Psr\Log\LoggerInterface', $this->logger);
}
}

1
bundled-libs/psr/log/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
vendor

View File

@ -0,0 +1,19 @@
Copyright (c) 2012 PHP Framework Interoperability Group
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,120 @@
<?php
namespace Psr\Log;
/**
* This is a simple Logger implementation that other Loggers can inherit from.
*
* It simply delegates all log-level-specific methods to the `log` method to
* reduce boilerplate code that a simple Logger that does the same thing with
* messages regardless of the error level has to implement.
*/
abstract class AbstractLogger implements LoggerInterface
{
/**
* System is unusable.
*
* @param string $message
* @param array $context
* @return null
*/
public function emergency($message, array $context = array())
{
$this->log(LogLevel::EMERGENCY, $message, $context);
}
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
* @return null
*/
public function alert($message, array $context = array())
{
$this->log(LogLevel::ALERT, $message, $context);
}
/**
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string $message
* @param array $context
* @return null
*/
public function critical($message, array $context = array())
{
$this->log(LogLevel::CRITICAL, $message, $context);
}
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string $message
* @param array $context
* @return null
*/
public function error($message, array $context = array())
{
$this->log(LogLevel::ERROR, $message, $context);
}
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
* @return null
*/
public function warning($message, array $context = array())
{
$this->log(LogLevel::WARNING, $message, $context);
}
/**
* Normal but significant events.
*
* @param string $message
* @param array $context
* @return null
*/
public function notice($message, array $context = array())
{
$this->log(LogLevel::NOTICE, $message, $context);
}
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
* @return null
*/
public function info($message, array $context = array())
{
$this->log(LogLevel::INFO, $message, $context);
}
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
* @return null
*/
public function debug($message, array $context = array())
{
$this->log(LogLevel::DEBUG, $message, $context);
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace Psr\Log;
class InvalidArgumentException extends \InvalidArgumentException
{
}

View File

@ -0,0 +1,18 @@
<?php
namespace Psr\Log;
/**
* Describes log levels
*/
class LogLevel
{
const EMERGENCY = 'emergency';
const ALERT = 'alert';
const CRITICAL = 'critical';
const ERROR = 'error';
const WARNING = 'warning';
const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';
}

View File

@ -0,0 +1,17 @@
<?php
namespace Psr\Log;
/**
* Describes a logger-aware instance
*/
interface LoggerAwareInterface
{
/**
* Sets a logger instance on the object
*
* @param LoggerInterface $logger
* @return null
*/
public function setLogger(LoggerInterface $logger);
}

View File

@ -0,0 +1,22 @@
<?php
namespace Psr\Log;
/**
* Basic Implementation of LoggerAwareInterface.
*/
trait LoggerAwareTrait
{
/** @var LoggerInterface */
protected $logger;
/**
* Sets a logger.
*
* @param LoggerInterface $logger
*/
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}
}

View File

@ -0,0 +1,114 @@
<?php
namespace Psr\Log;
/**
* Describes a logger instance
*
* The message MUST be a string or object implementing __toString().
*
* The message MAY contain placeholders in the form: {foo} where foo
* will be replaced by the context data in key "foo".
*
* The context array can contain arbitrary data, the only assumption that
* can be made by implementors is that if an Exception instance is given
* to produce a stack trace, it MUST be in a key named "exception".
*
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
* for the full interface specification.
*/
interface LoggerInterface
{
/**
* System is unusable.
*
* @param string $message
* @param array $context
* @return null
*/
public function emergency($message, array $context = array());
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
* @return null
*/
public function alert($message, array $context = array());
/**
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string $message
* @param array $context
* @return null
*/
public function critical($message, array $context = array());
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string $message
* @param array $context
* @return null
*/
public function error($message, array $context = array());
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
* @return null
*/
public function warning($message, array $context = array());
/**
* Normal but significant events.
*
* @param string $message
* @param array $context
* @return null
*/
public function notice($message, array $context = array());
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
* @return null
*/
public function info($message, array $context = array());
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
* @return null
*/
public function debug($message, array $context = array());
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
*/
public function log($level, $message, array $context = array());
}

View File

@ -0,0 +1,131 @@
<?php
namespace Psr\Log;
/**
* This is a simple Logger trait that classes unable to extend AbstractLogger
* (because they extend another class, etc) can include.
*
* It simply delegates all log-level-specific methods to the `log` method to
* reduce boilerplate code that a simple Logger that does the same thing with
* messages regardless of the error level has to implement.
*/
trait LoggerTrait
{
/**
* System is unusable.
*
* @param string $message
* @param array $context
* @return null
*/
public function emergency($message, array $context = array())
{
$this->log(LogLevel::EMERGENCY, $message, $context);
}
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
* @return null
*/
public function alert($message, array $context = array())
{
$this->log(LogLevel::ALERT, $message, $context);
}
/**
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string $message
* @param array $context
* @return null
*/
public function critical($message, array $context = array())
{
$this->log(LogLevel::CRITICAL, $message, $context);
}
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string $message
* @param array $context
* @return null
*/
public function error($message, array $context = array())
{
$this->log(LogLevel::ERROR, $message, $context);
}
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
* @return null
*/
public function warning($message, array $context = array())
{
$this->log(LogLevel::WARNING, $message, $context);
}
/**
* Normal but significant events.
*
* @param string $message
* @param array $context
* @return null
*/
public function notice($message, array $context = array())
{
$this->log(LogLevel::NOTICE, $message, $context);
}
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
* @return null
*/
public function info($message, array $context = array())
{
$this->log(LogLevel::INFO, $message, $context);
}
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
* @return null
*/
public function debug($message, array $context = array())
{
$this->log(LogLevel::DEBUG, $message, $context);
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
*/
abstract public function log($level, $message, array $context = array());
}

View File

@ -0,0 +1,27 @@
<?php
namespace Psr\Log;
/**
* This Logger can be used to avoid conditional log calls
*
* Logging should always be optional, and if no logger is provided to your
* library creating a NullLogger instance to have something to throw logs at
* is a good way to avoid littering your code with `if ($this->logger) { }`
* blocks.
*/
class NullLogger extends AbstractLogger
{
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
*/
public function log($level, $message, array $context = array())
{
// noop
}
}

View File

@ -0,0 +1,116 @@
<?php
namespace Psr\Log\Test;
use Psr\Log\LogLevel;
/**
* Provides a base test class for ensuring compliance with the LoggerInterface
*
* Implementors can extend the class and implement abstract methods to run this as part of their test suite
*/
abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase
{
/**
* @return LoggerInterface
*/
abstract function getLogger();
/**
* This must return the log messages in order with a simple formatting: "<LOG LEVEL> <MESSAGE>"
*
* Example ->error('Foo') would yield "error Foo"
*
* @return string[]
*/
abstract function getLogs();
public function testImplements()
{
$this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
}
/**
* @dataProvider provideLevelsAndMessages
*/
public function testLogsAtAllLevels($level, $message)
{
$logger = $this->getLogger();
$logger->{$level}($message, array('user' => 'Bob'));
$logger->log($level, $message, array('user' => 'Bob'));
$expected = array(
$level.' message of level '.$level.' with context: Bob',
$level.' message of level '.$level.' with context: Bob',
);
$this->assertEquals($expected, $this->getLogs());
}
public function provideLevelsAndMessages()
{
return array(
LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
);
}
/**
* @expectedException Psr\Log\InvalidArgumentException
*/
public function testThrowsOnInvalidLevel()
{
$logger = $this->getLogger();
$logger->log('invalid level', 'Foo');
}
public function testContextReplacement()
{
$logger = $this->getLogger();
$logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
$expected = array('info {Message {nothing} Bob Bar a}');
$this->assertEquals($expected, $this->getLogs());
}
public function testObjectCastToString()
{
$dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
$dummy->expects($this->once())
->method('__toString')
->will($this->returnValue('DUMMY'));
$this->getLogger()->warning($dummy);
}
public function testContextCanContainAnything()
{
$context = array(
'bool' => true,
'null' => null,
'string' => 'Foo',
'int' => 0,
'float' => 0.5,
'nested' => array('with object' => new DummyTest),
'object' => new \DateTime,
'resource' => fopen('php://memory', 'r'),
);
$this->getLogger()->warning('Crazy context data', $context);
}
public function testContextExceptionKeyCanBeExceptionOrOtherValues()
{
$this->getLogger()->warning('Random message', array('exception' => 'oops'));
$this->getLogger()->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));
}
}
class DummyTest
{
}

View File

@ -0,0 +1,45 @@
PSR Log
=======
This repository holds all interfaces/classes/traits related to
[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md).
Note that this is not a logger of its own. It is merely an interface that
describes a logger. See the specification for more details.
Usage
-----
If you need a logger, you can use the interface like this:
```php
<?php
use Psr\Log\LoggerInterface;
class Foo
{
private $logger;
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
public function doSomething()
{
if ($this->logger) {
$this->logger->info('Doing work');
}
// do something useful
}
}
```
You can then pick one of the implementations of the interface to get a logger.
If you want to implement the interface, you can require this package and
implement `Psr\Log\LoggerInterface` in your code. Please read the
[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
for details.

View File

@ -0,0 +1,17 @@
{
"name": "psr/log",
"description": "Common interface for logging libraries",
"keywords": ["psr", "psr-3", "log"],
"license": "MIT",
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"autoload": {
"psr-0": {
"Psr\\Log\\": ""
}
}
}

View File

@ -7,8 +7,9 @@
],
"require": {
"php": ">=5.3.3",
"zendframework/zend-db": "2.*"
}
"zendframework/zend-db": "2.*",
"katzgrau/klogger": "1.0.*"
},
"config": {
"vendor-dir": "bundled-libs"
}

View File

@ -3,7 +3,9 @@
Version 2.0-beta2 ()
------------------------------------------------------------------------
* Include klogger, call it as $serendipity['logger']->debug/error
* Add HTTP_Request2 and dependencies as bundled libraries and
update PEAR library to version 1.9.4

View File

@ -668,14 +668,14 @@ function serendipity_handle_references($id, $author, $title, $text, $dry_run = f
static $old_references = array();
static $saved_references = array();
static $saved_urls = array();
static $debug = false;
$serendipity['logger']->debug("serendipity_handle_references");
if ($dry_run) {
// Store the current list of references. We might need to restore them for later user.
$old_references = serendipity_db_query("SELECT * FROM {$serendipity['dbPrefix']}references WHERE (type = '' OR type IS NULL) AND entry_id = " . (int)$id, false, 'assoc');
if ($debug && is_string($old_references)) {
echo '<span class="block_level">' . $old_references . "</span>";
if (is_string($old_references)) {
$serendipity['logger']->debug($old_references);
}
if (is_array($old_references) && count($old_references) > 0) {
@ -686,15 +686,14 @@ function serendipity_handle_references($id, $author, $title, $text, $dry_run = f
$saved_urls[$old_reference['link']] = true;
}
}
if ($debug) echo "Got references in dry run: <pre>" . print_r($current_references, true) . "</pre>\n";
$serendipity['logger']->debug("Got references in dry run: " . print_r($current_references, true));
} else {
// A dry-run was called previously and restorable references are found. Restore them now.
$del = serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}references WHERE (type = '' OR type IS NULL) AND entry_id = " . (int)$id);
if ($debug && is_string($del)) {
echo '<span class="block_level">' . $del . "</span>";
if (is_string($del)) {
$serendipity['logger']->debug($del);
}
if ($debug) echo "<span class='block_level'>Deleted references.</span>";
$serendipity['logger']->debug("Deleted references");
if (is_array($old_references) && count($old_references) > 0) {
$current_references = array();
@ -703,13 +702,13 @@ function serendipity_handle_references($id, $author, $title, $text, $dry_run = f
$current_references[$old_reference['link'] . $old_reference['name']] = $old_reference;
$q = serendipity_db_insert('references', $old_reference, 'show');
$cr = serendipity_db_query($q);
if ($debug && is_string($cr)) {
echo '<span class="block_level">' . $cr . "</span>";
if (is_string($cr)) {
$serendipity['logger']->debug($cr);
}
}
}
if ($debug) echo "Got references in final run: <pre>" . print_r($current_references, true) . "</pre>\n";
$serendipity['logger']->debug("Got references in final run:" . print_r($current_references, true));
}
if (!preg_match_all('@<a[^>]+?href\s*=\s*["\']?([^\'" >]+?)[ \'"][^>]*>(.+?)</a>@i', $text, $matches)) {
@ -731,13 +730,13 @@ function serendipity_handle_references($id, $author, $title, $text, $dry_run = f
$checked_locations = array();
serendipity_plugin_api::hook_event('backend_trackbacks', $locations);
for ($i = 0, $j = count($locations); $i < $j; ++$i) {
if ($debug) echo "<span class='block_level'>Checking {$locations[$i]}...</span>";
$serendipity['logger']->debug("Checking {$locations[$i]}...");
if ($locations[$i][0] == '/') {
$locations[$i] = 'http' . (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off' ? 's' : '') . '://' . $_SERVER['HTTP_HOST'] . $locations[$i];
}
if (isset($checked_locations[$locations[$i]])) {
if ($debug) echo "<span class='block_level'>Already checked.</span>";
$serendipity['logger']->debug("Already checked");
continue;
}
@ -757,42 +756,42 @@ function serendipity_handle_references($id, $author, $title, $text, $dry_run = f
AND (type = '' OR type IS NULL)";
$row = serendipity_db_query($query, true, 'num');
if ($debug && is_string($row)) {
echo '<span class="block_level">' . $row . "</span>";
if (is_string($row)) {
$serendipity['logger']->debug($row);
}
$names[$i] = strip_tags($names[$i]);
if (empty($names[$i])) {
if ($debug) echo "Found reference $locations[$i] w/o name. Adding location as name.";
$serendipity['logger']->debug("Found reference $locations[$i] w/o name. Adding location as name");
$names[$i] = $locations[$i];
}
if ($row[0] > 0 && isset($saved_references[$locations[$i] . $names[$i]])) {
if ($debug) echo "<span class='block_level'>Found references for $id, skipping rest</span>";
$serendipity['logger']->debug("Found references for $id, skipping rest");
continue;
}
if (!isset($serendipity['noautodiscovery']) || !$serendipity['noautodiscovery']) {
if (!$dry_run) {
if (!isset($saved_urls[$locations[$i]])){
if ($debug) echo "<span class='block_level'>Enabling autodiscovery.</span>";
$serendipity['logger']->debug("Enabling autodiscovery");
serendipity_reference_autodiscover($locations[$i], $url, $author, $title, serendipity_trackback_excerpt($text));
} else {
$serendipity['logger']->debug("This reference was already used before in $id and therefore will not be trackbacked again");
}
elseif ($debug) echo "<span class='block_level'>This reference was already used before in $id and therefore will not be trackbacked again.</span>";
} elseif ($debug) {
echo "<span class='block_level'>Dry run: Skipping autodiscovery</span>";
} else {
$serendipity['logger']->debug("Dry run: Skipping autodiscovery");
}
$checked_locations[$locations[$i]] = true; // Store trackbacked link so that no further trackbacks will be sent to the same link
} elseif ($debug) {
echo "<span class='block_level'>Skipping full autodiscovery</span>";
} else {
$serendipity['logger']->debug("Skipping full autodiscovery");
}
}
$del = serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}references WHERE entry_id=" . (int)$id . " AND (type = '' OR type IS NULL)");
if ($debug && is_string($del)) {
echo '<span class="block_level">' . $del . "</span>";
if (is_string($del)) {
$serendipity['logger']->debug($del);
}
if ($debug) echo "<span class='block_level'>Deleted references again.</span>";
$serendipity['logger']->debug("Deleted references again");
if (!is_array($old_references)) {
$old_references = array();
@ -812,16 +811,16 @@ function serendipity_handle_references($id, $author, $title, $text, $dry_run = f
$query = "INSERT INTO {$serendipity['dbPrefix']}references (id, entry_id, name, link) VALUES(";
$query .= (int)$current_references[$locations[$i] . $names[$i]]['id'] . ", " . (int)$id . ", '" . $i_link . "', '" . $i_location . "')";
$ins = serendipity_db_query($query);
if ($debug && is_string($ins)) {
echo '<span class="block_level">' . $ins . "</span>";
if (is_string($ins)) {
$serendipity['logger']->debug($ins);
}
$duplicate_check[$locations[$i] . $names[$i]] = true;
} else {
$query = "INSERT INTO {$serendipity['dbPrefix']}references (entry_id, name, link) VALUES(";
$query .= (int)$id . ", '" . $i_link . "', '" . $i_location . "')";
$ins = serendipity_db_query($query);
if ($debug && is_string($ins)) {
echo '<span class="block_level">' . $ins . "</span>";
if (is_string($ins)) {
$serendipity['logger']->debug($ins);
}
$old_references[] = array(
@ -833,15 +832,11 @@ function serendipity_handle_references($id, $author, $title, $text, $dry_run = f
$duplicate_check[$i_location . $i_link] = true;
}
if ($debug) {
echo "Current lookup for {$locations[$i]}{$names[$i]} is <pre>" . print_r($current_references[$locations[$i] . $names[$i]], true) . "</pre>\n";
echo '<span class="block_level">' . $query . "</span>";
}
$serendipity['logger']->debug("Current lookup for {$locations[$i]}{$names[$i]} is" . print_r($current_references[$locations[$i] . $names[$i]], true));
$serendipity['logger']->debug($query);
}
if ($debug) {
echo "Old/Saved locations: <pre>" . print_r($old_references, true) . "</pre>\n";
}
$serendipity['logger']->debug(print_r($old_references, true));
// Add citations
preg_match_all('@<cite[^>]*>([^<]+)</cite>@i', $text, $matches);
@ -851,8 +846,8 @@ function serendipity_handle_references($id, $author, $title, $text, $dry_run = f
$query .= (int)$id . ", '" . serendipity_db_escape_string($citation) . "')";
$cite = serendipity_db_query($query);
if ($debug && is_string($cite)) {
echo '<span class="block_level">' . $cite . "</span>";
if (is_string($cite)) {
$serendipity['logger']->debug($cite);
}
}
}

View File

@ -2,19 +2,17 @@
# Copyright (c) 2003-2005, Jannis Hermanns (on behalf the Serendipity Developer Team)
# All rights reserved. See LICENSE file for licensing details
$global_debug = false;
if ($global_debug) {
#apd_set_pprof_trace();
#apd_set_pprof_trace();
function microtime_float() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();
function microtime_float() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();
// We need to set this to return a 200 since we use .htaccess ErrorDocument
// rules to handle archives.
header('HTTP/1.0 200');
@ -674,10 +672,6 @@ if (!defined('NO_EXIT')) {
$serendipity['smarty']->display(serendipity_getTemplateFile($serendipity['smarty_file'], 'serendipityPath'));
}
if ($global_debug) {
/* TODO: Remove (hide) this debug */
echo '<div id="s9y_debug" style="text-align: center; color: red; font-size: 10pt; font-weight: bold; padding: 10px">Page delivered in '. round(microtime_float()-$time_start,6) .' seconds, '. sizeof(get_included_files()) .' files included</div>';
echo '</div>';
}
$serendipity['logger']->debug('Page delivered in '. round(microtime_float()-$time_start,6) .' seconds, '. sizeof(get_included_files()) .' files included');
/* vim: set sts=4 ts=4 expandtab : */

View File

@ -257,8 +257,13 @@ include($local_config);
if ($serendipity['production'] === 'debug') {
error_reporting(E_ALL &~E_NOTICE | E_STRICT);
$serendipity['log_level'] = Psr\Log\LogLevel::DEBUG;
} else {
$serendipity['log_level'] = Psr\Log\LogLevel::ERROR;
}
$serendipity['logger'] = new Katzgrau\KLogger\Logger($serendipity['serendipityPath'] . '/templates_c/logs', $serendipity['log_level']);
//[internal callback function]: errorToExceptionHandler()
if(is_callable($serendipity['errorhandler'], false, $callable_name)) {
// set serendipity global error to exeption handler
@ -281,6 +286,7 @@ include(S9Y_INCLUDE_PATH . 'include/functions.inc.php');
if (serendipity_FUNCTIONS_LOADED !== true) {
$serendipity['lang'] = 'en';
include(S9Y_INCLUDE_PATH . 'include/lang.inc.php');
$serendipity['logger']->critical(sprintf(INCLUDE_ERROR . '<br />' . FILE_CREATE_YOURSELF, 'include/functions.inc.php'));
serendipity_die(sprintf(INCLUDE_ERROR . '<br />' . FILE_CREATE_YOURSELF, 'include/functions.inc.php'));
}
@ -290,6 +296,7 @@ if (serendipity_FUNCTIONS_LOADED !== true) {
if (!serendipity_db_connect()) {
$serendipity['lang'] = 'en';
include(S9Y_INCLUDE_PATH . 'include/lang.inc.php');
$serendipity['logger']->critical(DATABASE_ERROR);
serendipity_die(DATABASE_ERROR);
}
@ -429,5 +436,6 @@ if (isset($_SESSION['serendipityUser'])) {
if (isset($_SESSION['serendipityEmail'])) {
$serendipity['email'] = $_SESSION['serendipityEmail'];
}
serendipity_plugin_api::hook_event('frontend_configure', $serendipity);
/* vim: set sts=4 ts=4 expandtab : */