Skip to content

Instantly share code, notes, and snippets.

@craiga
Last active September 30, 2015 19:18
Show Gist options
  • Save craiga/1849563 to your computer and use it in GitHub Desktop.
Save craiga/1849563 to your computer and use it in GitHub Desktop.
printf-esque log method
<?php
trait Logging {
/**
* Write a log message.
*
* Write a log message to $this->_logCallback, $this->_logFile and/or
* syslog.
* Parameters are as for {@link http://php.net/sprintf sprintf}, except
* that a syslog priority (LOG_EMERG to LOG_DEBUG; see http://php.net/syslog)
* can be supplied as the first parameter.
*
* @author Craig Anderson <craiga@craiga.id.au>
* @link https://gist.github.com/1849563
*/
protected function _log() {
if(is_callable($this->_logCallback) || $this->_logFile || $this->_logToSyslog) {
$args = func_get_args();
// If present, record priority, then remove it from arguments.
$priority = $this->_defaultPriority;
if(count($args) > 1 && is_numeric($args[0]) && $args[0] >= LOG_EMERG && $args[0] <= LOG_DEBUG) {
$priority = (int)array_shift($args);
}
// Pass remaining arguments through sprintf
if(count($args) == 1) {
$message = $args[0];
}
else {
// TODO: Escape extra '%' characters in the format?
$message = call_user_func_array("sprintf", $args);
}
// Only show message if priority is less than or equal to the maximum priority
if ($priority <= $this->_maximumPriority) {
// Pass to log callback
if(is_callable($this->_logCallback)) {
if(call_user_func($this->_logCallback, $message) === false) {
throw new RuntimeException("Couldn't call logging callback");
}
}
// Write to log file
if($this->_logFile) {
if(!preg_match('/\n$/', $message)) {
$message .= "\n";
}
if(file_put_contents($this->_logFile, $message, FILE_APPEND) === false) {
if(!is_file($this->_logFile)) {
throw new RuntimeException("Couldn't create log file");
}
else {
throw new RuntimeException("Couldn't write to existing log file");
}
}
}
// Send to syslog
if($this->_logToSyslog) {
if(is_null($this->_syslogIdentity)) {
$this->_syslogIdentity = get_class($this);
}
if(is_null($this->_syslogOptions)) {
$this->_syslogOptions = LOG_NDELAY | LOG_PID;
}
if(is_null($this->_syslogFacility)) {
$this->_syslogFacility = LOG_USER;
}
try {
if(!openlog($this->_syslogIdentity, $this->_syslogOptions, $this->_syslogFacility)) {
throw new RuntimeException("Call to openlog failed");
}
if(!syslog($priority, $message)) {
throw new RuntimeException("Call to syslog failed");
}
if(!closelog()) {
throw new RuntimeException("Call to closelog failed");
}
}
catch(Exception $e) {
@closelog();
throw $e;
}
}
}
}
}
/**
* Where to write log messages.
*/
protected $_logCallback = null;
protected $_logFile = "php://output";
/**
* Default and maximum priority.
* Note that priorities run the opposite way to the way you might expect. Emergencies are very low, debug messages
* are very high. See http://php.net/syslog for a list of priorities.
*/
protected $_defaultPriority = LOG_INFO;
protected $_maximumPriority = LOG_DEBUG;
/**
* Syslog settings.
*/
protected $_logToSyslog = false;
protected $_syslogIdentity = null; // If null, it'll be set to the result of get_class($this)
protected $_syslogOptions = null;
protected $_syslogFacility = null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment