Files
libsst/Include/ZUtil/ZLog.hpp
2026-04-03 00:22:39 -05:00

270 lines
7.4 KiB
C++

/*
ZLog.hpp
Author: James Russell
Purpose:
Logging utility. The logging class cannot be instantiated, but instead is utilized through
static public method calls. The logging system must be initialized before use and can be
shutdown at any time. Any logging calls placed after the system has been shutdown amount
to a no-op.
The logging system is thread-safe.
License:
TODO
*/
#ifndef _ZLOG_HPP
#define _ZLOG_HPP
#include <ZSTL/ZPair.hpp>
#include <ZSTL/ZString.hpp>
#include <ZUtil/ZMutex.hpp>
#include <ZUtil/ZSmartPointer.hpp>
#include <iostream>
#include <fstream>
//Typedef to define a log file handle
typedef size_t ZLogFile;
//Logging type enumeration used to specify which level of log is being performed
enum ZLogType
{
LOG_ERROR, //Used when an error condition has occurred
LOG_WARNING, //Used when a recoverable error condition has occurred
LOG_INFO, //Used when significant events have occurred
LOG_SPAM, //Used for insignificant events and process flow notification
LOG_SIZE
};
//Overall Logging Levels
#define ZLOG_LEVEL_NONE 0
#define ZLOG_LEVEL_ERROR 1
#define ZLOG_LEVEL_WARNING 2
#define ZLOG_LEVEL_INFO 3
#define ZLOG_LEVEL_SPAM 4
//If the log level is not defined by the user, then ensure all logging is handled
#ifndef ZLOG_LEVEL
#define ZLOG_LEVEL ZLOG_LEVEL_SPAM
#endif
//Define used to enumerate the default log file
#define ZLOGFILE_DEFAULT 0
#if defined(_MSC_VER) || defined(__GNUC__) || defined(__SUNPRO_CC) //C99 style variadic macros
#define SystemLogError(...) ZLog::Printf(LOG_ERROR, ZLOGFILE_DEFAULT, 0, 0, __FUNCTION__, __VA_ARGS__)
#define SystemLogWarning(...) ZLog::Printf(LOG_WARNING, ZLOGFILE_DEFAULT, 0, 0, __FUNCTION__, __VA_ARGS__)
#define SystemLogInfo(...) ZLog::Printf(LOG_INFO, ZLOGFILE_DEFAULT, 0, 0, __FUNCTION__, __VA_ARGS__)
#define SystemLogSpam(...) ZLog::Printf(LOG_SPAM, ZLOGFILE_DEFAULT, 0, 0, __FUNCTION__, __VA_ARGS__)
#if ZLOG_LEVEL < ZLOG_LEVEL_SPAM
#undef SystemLogSpam
#define SystemLogSpam(...)
#endif
#if ZLOG_LEVEL < ZLOG_LEVEL_INFO
#undef SystemLogInfo
#define SystemLogInfo(...)
#endif
#if ZLOG_LEVEL < ZLOG_LEVEL_WARNING
#undef SystemLogWarning
#define SystemLogWarning(...)
#endif
#if ZLOG_LEVEL < ZLOG_LEVEL_ERROR
#undef SystemLogError
#define SystemLogError(...)
#endif
#if (ZLOG_LEVEL < ZLOG_LEVEL_NONE) || (ZLOG_LEVEL > ZLOG_LEVEL_SPAM)
#error ZLOG_LEVEL Set to Invalid Value!
#endif
#else //Not C99-style variadic macro
#error Define variadic macro flavor for your compiler in ZLog.hpp
#endif
/*
Logging delegate. Called when a log entry has been made.
*/
class ZLogDelegate
{
public:
virtual ~ZLogDelegate() { }
/*
virtual public ZLogDelegate::Execute
Delegate execute method. This is called whenever a logging entry has been made.
@param _type - the type of logging entry
@param _file - the log file written to
@param _logEntry - the logging entry made
@return (void)
*/
virtual void Execute(ZLogType _type, ZLogFile _file, const ZString& _logEntry) = 0;
};
/*
ZEngine logging class.
*/
class ZLog
{
private:
//Mutex for logging system
static ZMutex LogLock;
//Boolean indicating the logging system is activated
static bool bIsInitialized;
//Array of logging output streams (second pair parameter indicates active / suspended)
static ZArray< ZPair<std::ofstream*, bool> > LogFiles;
//Array of logging delegates
static ZArray< ZPtr<ZLogDelegate> > Delegates;
//Root path for logging
static ZString LogFileRoot;
//Maintained Tick Count
static uint64_t *UserTick;
//Maintained Update Frame Count
static uint64_t *UserUpdate;
//Tick Estimate when NULL is passed in as Tick
static uint64_t TickEstimate;
//Update Frame estimate when NULL is passed in as Update tick
static uint64_t UpdateFrameEstimate;
//Private Constructor
ZLog() { }
//Private Copy Constructor
ZLog(const ZLog& _other) { URFP(_other); }
//Private Destructor
~ZLog() { }
public:
/////////////////////////////////
/* Initialization and Shutdown */
/////////////////////////////////
/*
static public ZFileSystem::Init
Initialization method for ZLog. Until this is called, all logging calls return immediately.
@param _logFileRoot - the directory to place log files in
@param _defaultLogFile - log file name for the 'default' log file (NULL log file)
@param _ticks - pointer to a value that will be updated with tick count (NULL to use parameter value only)
@param _update - pointer to a value that will be updated with update frame count (NULL to use parameter value only)
@return (void)
*/
static void Init(const ZString& _logFileRoot, const ZString& _defaultLogFile, uint64_t* _ticks = NULL, uint64_t* _update = NULL);
/*
static public ZFileSystem::Shutdown
Shutdown method for ZLog. Closes out the opened log files and flushes the output buffers. After
this is called, all logging operations return immediately.
@return (void)
*/
static void Shutdown();
///////////////////////////////
/* Logging System Operations */
///////////////////////////////
/*
static public ZFileSystem::AddLoggingDelegate
Adds a logging delegate to the system which is called whenever logging takes
place.
@param _delegate - the logging delegate to call when logging takes place
@return (void)
*/
static void AddLoggingDelegate(ZPtr<ZLogDelegate> _delegate);
/*
static public ZFileSystem::CreateLogFile
Creates a log file for use in the system.
@param _fileName - the name to use for the log file
@return (ZLOG_FILE) - the created log file (will be NULL if could not create)
*/
static ZLogFile CreateLogFile(const ZString& _fileName);
/*
public static ZLog::Resume
Resumes logging operations on a given log file.
@param _logFile - the file to suspend logging operations on
@return (void)
*/
static void Resume(ZLogFile _logFile);
/*
public static ZLog::SuspendLogging
Suspends logging operations on a given log file.
@param _logFile - the file to suspend logging operations on
@return (void)
*/
static void Suspend(ZLogFile _logFile);
/////////////////////
/* Logging Methods */
/////////////////////
/*
static public ZFileSystem::Printf
Varardic logging function, which writes the given string out to the log file. This version takes varargs in the
same way as printf. This logging function has a limit on the length of the output string of 4096 characters - excess
characters will be truncated.
@param _type - the logging type
@param _file - the file to write to (if ZLOG_DEFAULT, uses the default file)
@param _ticks - the tick count at which the log file is written
@param _updateFrame - the update 'frame' during which the log is written
@param _str - the string to write to the log file
@param ... - the variable arguments to provide to format _str
@param args - parsed va_list
@return (void)
*/
static void Printf(ZLogType _type, ZLogFile _file, uint64_t _ticks, uint32_t _updateFrame, const char *_function, const char *_str, ...);
/*
static public ZFileSystem::WriteLine
Writes a string out to the given log file.
@param _type - the logging type
@param _file - the file to write to (if ZLOG_DEFAULT, uses the default file)
@param _ticks - the tick count at which the log file is written
@param _updateFrame - the update 'frame' during which the log is written
@param _renderFrame - the render 'frame' during which the log is written
@param _str - the string to write to the log file
@return (void)
*/
static void WriteLine(ZLogType _type, ZLogFile _file, uint64_t _ticks, uint32_t _updateFrame, const char* _str);
};
#endif