/** ** Supermodel ** A Sega Model 3 Arcade Emulator. ** Copyright 2011-2020 Bart Trzynadlowski, Nik Henson, Ian Curtis, ** Harry Tuttle, and Spindizzi ** ** This file is part of Supermodel. ** ** Supermodel is free software: you can redistribute it and/or modify it under ** the terms of the GNU General Public License as published by the Free ** Software Foundation, either version 3 of the License, or (at your option) ** any later version. ** ** Supermodel is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ** more details. ** ** You should have received a copy of the GNU General Public License along ** with Supermodel. If not, see . **/ /* * Logger.h * * Header file for message logging. The OSD code is expected to set up a * default logger (CFileLogger). */ #ifndef INCLUDED_LOGGER_H #define INCLUDED_LOGGER_H #include "Types.h" #include "Version.h" #include "Util/NewConfig.h" #include #include #include #include #include #include #include /****************************************************************************** Class Definitions ******************************************************************************/ /* * CLogger * * Abstract class that receives log messages from Supermodel's log functions. * The logger object handles actual output of messages. Use the function-based * message logging interface to generate messages. */ class CLogger { public: // Log level in ascending order enum LogLevel: int { All = 0, Debug, Info, Error }; virtual ~CLogger() { } /* * DebugLog(fmt, ...): * DebugLog(fmt, vl): * * Prints to debug log. If DEBUG is not defined, will end up doing nothing. * * Parameters: * fmt printf()-style format string. * ... Variable number of parameters, corresponding to format * string. * vl Variable arguments already stored in a list. */ void DebugLog(const char *fmt, ...) { va_list vl; va_start(vl, fmt); DebugLog(fmt, vl); va_end(vl); } virtual void DebugLog(const char *fmt, va_list vl) = 0; /* * InfoLog(fmt, ...): * InfoLog(fmt, vl): * * Prints to error log but does not output an error to stderr. This is * useful for printing session information to the error log. * * Parameters: * fmt printf()-style format string. * ... Variable number of parameters, corresponding to format * string. * vl Variable arguments already stored in a list. */ void InfoLog(const char *fmt, ...) { va_list vl; va_start(vl, fmt); InfoLog(fmt, vl); va_end(vl); } virtual void InfoLog(const char *fmt, va_list vl) = 0; /* * ErrorLog(fmt, ...): * ErrorLog(fmt, vl): * * Prints to error log and outputs an error message to stderr. * * Parameters: * fmt printf()-style format string. * ... Variable number of parameters, corresponding to format * string. * vl Variable arguments already stored in a list. */ void ErrorLog(const char *fmt, ...) { va_list vl; va_start(vl, fmt); ErrorLog(fmt, vl); va_end(vl); } virtual void ErrorLog(const char *fmt, va_list vl) = 0; }; /* * CMultiLogger: * * Redirects to multiple loggers. */ class CMultiLogger: public CLogger { public: void DebugLog(const char *fmt, va_list vl); void InfoLog(const char *fmt, va_list vl); void ErrorLog(const char *fmt, va_list vl); CMultiLogger(std::vector> loggers); private: std::vector> m_loggers; }; /* * CConsoleErrorLogger: * * Logger that prints only essential error messages, formatted appropriately, * to the console (stderr). * * In the future, logging and console output need to be separated. This is * intended to be an interrim solution. */ class CConsoleErrorLogger: public CLogger { void DebugLog(const char *fmt, va_list vl); void InfoLog(const char *fmt, va_list vl); void ErrorLog(const char *fmt, va_list vl); }; /* * CFileLogger: * * Default logger that logs to debug and error log files. Files are opened and * closed for each message in order to preserve contents in case of program * crash. */ class CFileLogger: public CLogger { public: void DebugLog(const char *fmt, va_list vl); void InfoLog(const char *fmt, va_list vl); void ErrorLog(const char *fmt, va_list vl); CFileLogger(LogLevel level, std::vector filenames); CFileLogger(LogLevel level, std::vector filenames, std::vector systemFiles); private: std::mutex m_mtx; // needed because we may close/reopen files and logging must be thread-safe LogLevel m_logLevel; const std::vector m_logFilenames; std::vector m_logFiles; std::vector m_systemFiles; void ReopenFiles(std::ios_base::openmode mode); void WriteToFiles(const char *str); }; /* * CSystemLogger: * * Logs to the system log. */ class CSystemLogger: public CLogger { public: void DebugLog(const char *fmt, va_list vl); void InfoLog(const char *fmt, va_list vl); void ErrorLog(const char *fmt, va_list vl); CSystemLogger(LogLevel level); private: LogLevel m_logLevel; }; /****************************************************************************** Log Functions Message logging interface. All messages are passed to the currently active logger object. ******************************************************************************/ /* * DebugLog(fmt, ...): * * Prints debugging information. The OSD layer may choose to print this to a * log file, the screen, neither, or both. Newlines and other formatting codes * must be explicitly included. * * Parameters: * fmt A format string (the same as printf()). * ... Variable number of arguments, as required by format string. */ extern void DebugLog(const char *fmt, ...); /* * ErrorLog(fmt, ...): * * Prints error information. Errors need not require program termination and * may simply be informative warnings to the user. Newlines should not be * included in the format string -- they are automatically added at the end of * a line. * * Parameters: * fmt A format string (the same as printf()). * ... Variable number of arguments, as required by format string. * * Returns: * Must always return FAIL. */ extern bool ErrorLog(const char *fmt, ...); /* * InfoLog(fmt, ...); * * Prints information to the error log file but does not print to stderr. This * is useful for logging non-error information. Newlines are automatically * appended. * * Parameters: * fmt Format string (same as printf()). * ... Variable number of arguments as required by format string. */ extern void InfoLog(const char *fmt, ...); /* * SetLogger(Logger): * * Sets the logger object to use. * * Parameters: * Logger Unique pointer to a new logger object. If null pointer, log * messages will not be output. */ extern void SetLogger(std::shared_ptr logger); /* * GetLogger(void): * * Returns: * Current logger object (null pointer if not set). */ extern std::shared_ptr GetLogger(void); /* * CreateLogger(config): * * Returns: * A logger object that satisfies the requirements specified in the passed * configuration or an empty pointer if an unrecoverable error occurred. */ std::shared_ptr CreateLogger(const Util::Config::Node &config); #endif // INCLUDED_LOGGER_H