Skip to content

Instantly share code, notes, and snippets.

@mishterk
Last active May 6, 2025 02:22
Show Gist options
  • Save mishterk/2d437afd3630348dd449057eccf42041 to your computer and use it in GitHub Desktop.
Save mishterk/2d437afd3630348dd449057eccf42041 to your computer and use it in GitHub Desktop.
Wolf Digital file logging helper class and function
<?php
namespace WolfDigital;
use DateTime;
use DateTimeZone;
use Exception;
class FileLogger {
/** @var FileLogger */
private $parent_logger;
/** @var string */
private $log_dir;
/** @var string */
private $file_name;
/** @var string */
private $namespace;
/** @var int */
private $depth;
private $timezone;
/** @var array */
private static $namespace_stack = [];
/**
* @param string $log_dir
* @param string $file_name
* @param FileLogger|null $parent_logger An optional additional FileLogger to pass messages through to.
* @param string $namespace
*/
public function __construct( $log_dir, $file_name, FileLogger $parent_logger = null, $namespace = '', $timezone = '' ) {
$this->log_dir = untrailingslashit( $log_dir );
$this->file_name = trim( $file_name, '/' );
$this->parent_logger = $parent_logger;
$this->namespace = $namespace;
$this->depth = 0;
$this->timezone = $timezone ?: date_default_timezone_get();
$this->createLogDir();
}
/**
* @param string $message
*/
public function log( $message ) {
$stamp = '[' . $this->getTimestamp() . ']';
if ( is_array( $message ) || is_object( $message ) ) {
$message = print_r( $message, true );
}
if ( $this->depth > 0 ) {
$multiplier = $this->depth == 1 ? 1 : 2;
$message = str_repeat( ' ', $this->depth * $multiplier ) . '– ' . $message;
}
if ( $this->namespace ) {
$message = "{$this->namespace} $message";
}
error_log( "$stamp $message \n", 3, $this->getPathToLogFile() );
if ( $this->parent_logger ) {
$this->parent_logger->log( $message );
}
}
/**
* Add a blank line to the log file.
*/
public function logBlankLine() {
error_log( "\n", 3, $this->getPathToLogFile() );
if ( $this->parent_logger ) {
$this->parent_logger->logBlankLine();
}
}
/**
* Set the depth for the log message indentation.
*
* @param int $depth
*/
public function setDepth( $depth ) {
$this->depth = $depth;
}
/**
* Set the namespace for log messages and push it onto the stack.
*
* @param string $namespace
*/
public function setNamespace( $namespace ) {
self::$namespace_stack[] = $this->namespace;
$this->namespace = $namespace;
}
/**
* Revert the namespace to the previous one in the stack.
*/
public function revertNamespace() {
if ( ! empty( self::$namespace_stack ) ) {
$this->namespace = array_pop( self::$namespace_stack );
} else {
$this->namespace = '';
}
}
/**
* Get the current namespace stack.
*
* @return array
*/
public function getNamespaceStack() {
return self::$namespace_stack;
}
/**
* @return string
*/
private function getPathToLogFile() {
$dir = $this->log_dir;
$name = $this->file_name;
$extension = '.log';
return "{$dir}/{$name}{$extension}";
}
private function getTimestamp() {
try {
$dt = new DateTime( "now", new DateTimeZone( $this->timezone ) );
$dt->setTimestamp( time() );
return $dt->format( 'Y-m-d h:i:sa' ) . ' ' . $this->timezone;
} catch ( Exception $e ) {
return date( 'Y-m-d h:i:sa' ) . ' ' . date_default_timezone_get();
}
}
private function createLogDir() {
if ( ! file_exists( $this->log_dir ) ) {
wp_mkdir_p( $this->log_dir );
}
}
}
<?php
namespace WolfDigital;
use DateTime;
use DateTimeZone;
use WolfDigital\FileLogger;
defined( 'WOLFD_CORE_LOG_DIR' ) or define( 'WOLFD_CORE_LOG_DIR', wp_get_upload_dir()['basedir'] . '/wolfdigital' );
defined( 'WOLFD_CORE_LOG_TZ' ) or define( 'WOLFD_CORE_LOG_TZ', 'Australia/Melbourne' );
/**
* @param string $basename Base name for the log file (e.g. 'jobfile-import')
* @param string $date_prefix 'daily', 'monthly', 'none', or a custom DateTime format (e.g. 'Y-m')
* @return FileLogger
*/
function logger( $basename = 'log', $date_prefix = 'monthly' ) {
static $loggers = [];
$key = "{$basename}|{$date_prefix}";
if ( ! isset( $loggers[ $key ] ) ) {
$prefix = '';
try {
$tz = new DateTimeZone( WOLFD_CORE_LOG_TZ );
$now = new DateTime( 'now', $tz );
switch ( $date_prefix ) {
case 'daily':
$prefix = $now->format( 'Ymd' );
break;
case 'monthly':
$prefix = $now->format( 'Ym' );
break;
case 'none':
$prefix = '';
break;
default:
$prefix = $now->format( $date_prefix );
break;
}
} catch ( \Exception $e ) {
// fail silently
}
$filename = join( '-', array_filter( [ $prefix, $basename ] ) );
$loggers[ $key ] = new FileLogger(
WOLFD_CORE_LOG_DIR,
$filename,
null,
'',
WOLFD_CORE_LOG_TZ
);
}
return $loggers[ $key ];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment