Skip to content

Instantly share code, notes, and snippets.

@samayo
Last active October 4, 2015 13:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samayo/d83ae3b88cbcbb845b81 to your computer and use it in GitHub Desktop.
Save samayo/d83ae3b88cbcbb845b81 to your computer and use it in GitHub Desktop.
<?php
/**
* Autolog
*
* @author Simon D <eritr3a@gmail.com>
* @link https://github.com/samayo/autolog
* @copyright Copyright (c) 2013
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
namespace Logger;
class LoggerException extends \Exception{}
/**
* An Autolog Class
*
* @category Fastpress
* @package Autolog
* @version 0.1.0
*/
class Autolog implements \ArrayAccess
{
const INFO = 1;
const ALERT = 2;
const ERROR = 3;
const SMS = 6; /* todo or not todo*/
const FILE = 7;
const EMAIL = 8;
const DATABASE = 9;
const SIMPLE = 10;
const VERBOSE = 11;
const AUTOLOG = true;
protected $levels = [
self::INFO => "INFO",
self::ALERT => "ALERT",
self::ERROR => "ERROR",
];
protected $verbosity = [
self::SIMPLE => "SIMPLE",
self::VERBOSE => "VERBOSE",
];
protected $option = [
'email' => 'foo@bar.com',
'log.file' => '',
'log.access' => '',
'system.files' => [
"nginx" => "/var/log/nginx/error.log",
"php-fpm" => "/var/log/php-fpm/error.log",
"mariadb" => "/var/log/mariadb/mariadb.log",
]
];
private $db = true;
private $dateFormat = "Y-m-d H:i:s";
public function __construct(){}
public function database(\PDO $db){
$this->db = $db;
}
protected function toSMS(){
// @TODO
}
protected function toEmail($msg, $level, $subject = "Autolog\Log .. "){
$email = $this->option["email"];
$headers = "From: " . $email . " \r\n";
$headers .= "Reply-To: " . $email . " \r\n";
$headers .= "MIME-Version: 1.0 \r\n";
$headers .= "Content-Type: text/html; charset=UTF8 \r\n";
mail($email, $subject, $msg, $headers);
}
protected function toFile($time, $level, $message){
$path = $this->option["log.file"];
if(is_file($path) && is_readable($path)){
file_put_contents($path, $time . $level . $message, FILE_APPEND);
}
}
protected function toDatabase($level, $subject, $message){
if (!$this->conn) {
throw new LoggerException("Database connection not found");
}
$log = $this->conn->prepare("INSERT INTO logs (time, level, subject, message) VALUES (NOW(),?,?,?)");
$log->execute([$level, $subject, $message]);
}
protected function formatter($data, $level, $verbosity){
$log = is_array($data) ? $data : array();
$log["time"] = "'time':'" . date($this->dateFormat) . "', ";
$log["level"] = "'level':'" . $this->levels[$level] . "', ";
if(is_object($data) && count($data) == 1){
$log["msg"] = "'log':'" . $data . "', \r\n";
$log["title"] = "'title':'" . substr($data, 0, 100). "' ";
}
if(is_string($data)){
$log["msg"] = "'log':'" . $data . "', \r\n";
}
if(is_array($log) && isset($log["msg"])){
$log["msg"] = "'log':'" . $log["msg"] . "', \r\n";
}
if(!isset($log["title"])){
$log["title"] = "Logger: " . $log["level"];
}
return (object) $log;
}
public function log($msg, $level = self::INFO, $handler = self::EMAIL, $verbosity = self::SIMPLE){
$log = $this->formatter($msg, $level, $verbosity);
switch ($handler) {
case self::FILE:
$this->toFile($log->time, $log->level, $log->msg);
break;
case self::EMAIL:
$this->toEmail($log->msg, $log->level, $log->title);
break;
case self::DATABASE:
$this->toDatabase($log->level, $log->title, $log->msg);
break;
case self::SMS:
$this->toSMS($log->title, $log->msg); // TODO :
break;
default:
throw new Exception(sprintf(
"Unknown handler argument: %s, please choose appropriate log handler", $handler
));
break;
}
}
private function isFile($filename){
if (is_file($filename) && is_readable($filename)) {
return $filename;
}
}
public function trigger($option, $handler = self::EMAIL){
switch ($option) {
case self::AUTOLOG:
$this->Autologger($handler);
break;
default:
# code...
break;
}
}
protected function Autologger($handler){
$systemLogFiles = $this->option['system.files'];
if (!$accessLog = $this->isFile($this->option["log.access"])) {
return;
}
$logTime = json_decode(file_get_contents($accessLog), true);
foreach ($systemLogFiles as $system => $logFile) {
if (!$this->isFile($logFile)) {
return;
}
if (!in_array($system, array_keys($logTime))) {
return;
}
if (substr($logTime[$system], 0, 9) === substr(filemtime($logFile), 0, 9)) {
return;
}
$logTime[$system] = time();
touch($logFile);
file_put_contents($accessLog, json_encode($logTime));
$log = array();
$log["msg"] = exec("tail " . $logFile);
$log["title"] = "New " . $system . " error log found";
$this->log($log, self::ERROR, $handler);
}
}
public function offsetGet($offset){
if(array_key_exists($offset, $this->option)){
return $this->option[$offset];
}
}
public function offsetSet($offset, $value){
$this->option[$offset] = $value;
}
public function offsetUnset($offset){}
public function offsetExists($offset){}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment