2022-01-18 03:10:47 +00:00
|
|
|
/*
|
|
|
|
* InspIRCd -- Internet Relay Chat Daemon
|
|
|
|
*
|
|
|
|
* Copyright (C) 2022 Sadie Powell <sadie@witchery.services>
|
|
|
|
*
|
|
|
|
* This file is part of InspIRCd. InspIRCd 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, version 2.
|
|
|
|
*
|
|
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2022-09-23 22:12:30 +01:00
|
|
|
#ifdef _WIN32
|
|
|
|
# undef ERROR // Defined by WinGDI.h
|
|
|
|
#endif
|
|
|
|
|
2022-01-18 03:10:47 +00:00
|
|
|
namespace Log
|
|
|
|
{
|
|
|
|
class Method;
|
|
|
|
class FileMethod;
|
|
|
|
|
|
|
|
class Engine;
|
|
|
|
class FileEngine;
|
|
|
|
class StreamEngine;
|
|
|
|
|
|
|
|
class Manager;
|
|
|
|
|
2022-05-02 12:43:30 +01:00
|
|
|
/** A shared pointer to a log method. */
|
2022-01-18 03:10:47 +00:00
|
|
|
typedef std::shared_ptr<Method> MethodPtr;
|
|
|
|
|
2022-05-02 12:43:30 +01:00
|
|
|
/** Levels at which messages can be logged. */
|
2022-01-18 03:10:47 +00:00
|
|
|
enum class Level
|
|
|
|
: uint8_t
|
|
|
|
{
|
|
|
|
/** A critical message which must be investigated. */
|
|
|
|
ERROR = 0,
|
|
|
|
|
|
|
|
/** An important message which should be investigated. */
|
|
|
|
WARNING = 1,
|
|
|
|
|
|
|
|
/** A general message which is useful to have on record. */
|
|
|
|
NORMAL = 2,
|
|
|
|
|
|
|
|
/** A debug message that we might want to store when testing. */
|
|
|
|
DEBUG = 3,
|
|
|
|
|
|
|
|
/** A sensitive message that we should not store lightly. */
|
|
|
|
RAWIO = 4,
|
|
|
|
};
|
2022-05-02 12:43:30 +01:00
|
|
|
|
|
|
|
/** Converts a log level to a string.
|
|
|
|
* @param level The log level to convert.
|
|
|
|
*/
|
|
|
|
CoreExport const char* LevelToString(Level level);
|
2022-01-18 03:10:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Base class for logging methods. */
|
|
|
|
class CoreExport Log::Method
|
|
|
|
{
|
2023-01-18 14:54:04 +00:00
|
|
|
protected:
|
|
|
|
Method() = default;
|
|
|
|
|
2022-01-18 03:10:47 +00:00
|
|
|
public:
|
2023-01-18 14:54:04 +00:00
|
|
|
virtual ~Method() = default;
|
|
|
|
|
2022-01-18 03:10:47 +00:00
|
|
|
/** Determines whether this logging method accepts cached messages. */
|
|
|
|
virtual bool AcceptsCachedMessages() const { return true; }
|
|
|
|
|
|
|
|
/** Writes a message to the logger.
|
2022-08-23 23:18:55 +01:00
|
|
|
* @param time The time at which the message was logged.
|
2022-01-18 03:10:47 +00:00
|
|
|
* @param level The level at which the log message was written.
|
|
|
|
* @param type The component which wrote the log message.
|
|
|
|
* @param message The message which was written to the log.
|
|
|
|
*/
|
2022-08-23 23:18:55 +01:00
|
|
|
virtual void OnLog(time_t time, Level level, const std::string& type, const std::string& message) = 0;
|
2022-01-18 03:10:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/** A logger that writes to a file stream. */
|
|
|
|
class CoreExport Log::FileMethod final
|
|
|
|
: public Method
|
2022-05-02 17:21:19 +01:00
|
|
|
, public Timer
|
2022-01-18 03:10:47 +00:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
/** Whether to autoclose the file on exit. */
|
|
|
|
bool autoclose;
|
|
|
|
|
|
|
|
/** The file to which the log is written. */
|
|
|
|
FILE* file;
|
|
|
|
|
|
|
|
/** How often the file stream should be flushed. */
|
|
|
|
const unsigned long flush;
|
|
|
|
|
|
|
|
/** The number of lines which have been written since the file stream was created. */
|
|
|
|
unsigned long lines = 0;
|
|
|
|
|
|
|
|
/** The name the underlying file. */
|
|
|
|
const std::string name;
|
|
|
|
|
|
|
|
public:
|
|
|
|
FileMethod(const std::string& n, FILE* fh, unsigned long fl, bool ac);
|
|
|
|
~FileMethod() override;
|
|
|
|
|
|
|
|
/** @copydoc Log::Method::AcceptsCachedMessages */
|
|
|
|
bool AcceptsCachedMessages() const override { return false; }
|
|
|
|
|
2022-05-02 17:21:19 +01:00
|
|
|
/** @copydoc Timer::Tick */
|
|
|
|
bool Tick() override;
|
|
|
|
|
2022-01-18 03:10:47 +00:00
|
|
|
/** @copydoc Log::Method::OnLog */
|
2022-08-23 23:18:55 +01:00
|
|
|
void OnLog(time_t time, Level level, const std::string& type, const std::string& message) override;
|
2022-01-18 03:10:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/** Base class for logging engines. */
|
|
|
|
class CoreExport Log::Engine
|
|
|
|
: public DataProvider
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
Engine(Module* Creator, const std::string& Name);
|
|
|
|
|
|
|
|
public:
|
2022-09-05 21:14:36 +01:00
|
|
|
virtual ~Engine() override;
|
2022-01-18 03:10:47 +00:00
|
|
|
|
|
|
|
/** Creates a new logger from the specified config.
|
|
|
|
* @param tag The config tag to configure the logger with.
|
|
|
|
*/
|
2023-01-10 20:57:56 +00:00
|
|
|
virtual MethodPtr Create(const std::shared_ptr<ConfigTag>& tag) = 0;
|
2022-01-18 03:10:47 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/** A logger which writes to a file. */
|
|
|
|
class CoreExport Log::FileEngine final
|
|
|
|
: public Engine
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
FileEngine(Module* Creator);
|
|
|
|
|
|
|
|
/** @copydoc Log::Engine::Create */
|
2023-01-10 20:57:56 +00:00
|
|
|
MethodPtr Create(const std::shared_ptr<ConfigTag>& tag) override;
|
2022-01-18 03:10:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/** A logger which writes to a stream. */
|
|
|
|
class CoreExport Log::StreamEngine final
|
|
|
|
: public Engine
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
FILE* file;
|
|
|
|
|
|
|
|
public:
|
|
|
|
StreamEngine(Module* Creator, const std::string& Name, FILE* fh);
|
|
|
|
|
|
|
|
/** @copydoc Log::Engine::Create */
|
2023-01-10 20:57:56 +00:00
|
|
|
MethodPtr Create(const std::shared_ptr<ConfigTag>& tag) override;
|
2022-01-18 03:10:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/** Manager for the logging system. */
|
|
|
|
class CoreExport Log::Manager final
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
/** A log message which has been cached until modules load. */
|
|
|
|
struct CachedMessage final
|
|
|
|
{
|
2022-08-23 23:18:55 +01:00
|
|
|
/** The time the message was logged at. */
|
|
|
|
time_t time;
|
|
|
|
|
2022-01-18 03:10:47 +00:00
|
|
|
/** The level the message was logged at. */
|
|
|
|
Level level;
|
|
|
|
|
|
|
|
/** The type of the message that was logged. */
|
|
|
|
std::string type;
|
|
|
|
|
|
|
|
/** The message that was logged. */
|
|
|
|
std::string message;
|
|
|
|
|
2022-08-23 23:18:55 +01:00
|
|
|
CachedMessage(time_t ts, Level l, const std::string& t, const std::string& m);
|
2022-01-18 03:10:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/** Encapsulates information about a logger. */
|
|
|
|
struct Info final
|
|
|
|
{
|
|
|
|
/** Whether the logger was read from the server config. */
|
|
|
|
bool config;
|
|
|
|
|
|
|
|
/** The minimum log level that this logger accepts. */
|
|
|
|
Level level;
|
|
|
|
|
|
|
|
/** The types of log message that this logger accepts. */
|
|
|
|
TokenList types;
|
|
|
|
|
|
|
|
/** The handler for this logger type. */
|
|
|
|
MethodPtr method;
|
|
|
|
|
|
|
|
/** The engine which created this logger. */
|
|
|
|
const Engine* engine;
|
|
|
|
|
2022-05-01 22:55:26 +01:00
|
|
|
Info(Level l, TokenList t, MethodPtr m, bool c, const Engine* e) ATTR_NOT_NULL(6);
|
2022-01-18 03:10:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/** The log messages we have cached for modules. */
|
|
|
|
std::vector<CachedMessage> cache;
|
|
|
|
|
|
|
|
/** Whether we have just started up and need to cache messages until modules are loaded. */
|
|
|
|
bool caching = true;
|
|
|
|
|
|
|
|
/** The logger engine that writes to a file. */
|
|
|
|
Log::FileEngine filelog;
|
|
|
|
|
|
|
|
/** A logger that writes to stderr. */
|
|
|
|
Log::StreamEngine stderrlog;
|
|
|
|
|
|
|
|
/** A logger that writes to stdout. */
|
|
|
|
Log::StreamEngine stdoutlog;
|
|
|
|
|
|
|
|
/** The currently registered loggers. */
|
|
|
|
std::vector<Info> loggers;
|
|
|
|
|
|
|
|
/** Whether we are currently logging to a file. */
|
|
|
|
bool logging = false;
|
|
|
|
|
|
|
|
/** Writes a message to the server log.
|
|
|
|
* @param level The level to log at.
|
|
|
|
* @param type The type of message that is being logged.
|
|
|
|
* @param message The message to log.
|
|
|
|
* */
|
|
|
|
void Write(Level level, const std::string& type, const std::string& message);
|
|
|
|
|
|
|
|
/** Writes a message to the server logs.
|
|
|
|
* @param level The level to log at.
|
|
|
|
* @param type The type of message that is being logged.
|
|
|
|
* @param format The message to format and then log.
|
|
|
|
* @param args The arguments to use when formatting the log message
|
|
|
|
* */
|
|
|
|
void Write(Level level, const std::string& type, const char* format, va_list& args) ATTR_NOT_NULL(4) ATTR_PRINTF(4, 0);
|
|
|
|
|
|
|
|
public:
|
|
|
|
Manager();
|
|
|
|
|
|
|
|
/** Closes all loggers which were opened from the config. */
|
|
|
|
void CloseLogs();
|
|
|
|
|
|
|
|
/** Enables writing rawio logs to the standard output stream. */
|
|
|
|
void EnableDebugMode();
|
|
|
|
|
2023-01-09 18:30:09 +00:00
|
|
|
/** Notify a user that raw I/O logging is enabled.
|
|
|
|
* @param user The user to notify.
|
|
|
|
* @param type The type of message to send.
|
|
|
|
*/
|
2023-01-11 00:45:04 +00:00
|
|
|
static void NotifyRawIO(LocalUser* user, MessageType type);
|
2023-01-09 18:30:09 +00:00
|
|
|
|
2022-01-18 03:10:47 +00:00
|
|
|
/** Opens loggers that are specified in the config. */
|
|
|
|
void OpenLogs(bool requiremethods);
|
|
|
|
|
|
|
|
/** Registers the core logging services with the event system. */
|
|
|
|
void RegisterServices();
|
|
|
|
|
|
|
|
/** Unloads all loggers that are provided by the specified engine.
|
|
|
|
* @param engine The engine to unload the loggers of.
|
|
|
|
*/
|
2022-05-01 22:55:26 +01:00
|
|
|
void UnloadEngine(const Engine* engine) ATTR_NOT_NULL(2);
|
2022-01-18 03:10:47 +00:00
|
|
|
|
|
|
|
/** Writes an error message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
2022-05-02 17:31:57 +01:00
|
|
|
* @param message The message to log.
|
|
|
|
*/
|
2022-01-18 03:10:47 +00:00
|
|
|
inline void Error(const std::string& type, const std::string& message)
|
|
|
|
{
|
|
|
|
Write(Level::ERROR, type, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Writes an error message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
|
|
|
* @param format A format string to format and then log.
|
|
|
|
* */
|
|
|
|
inline void Error(const std::string& type, const char* format, ...) ATTR_NOT_NULL(3) ATTR_PRINTF(3, 4)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
|
|
Write(Level::ERROR, type, format, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Writes a warning message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
2022-05-02 17:31:57 +01:00
|
|
|
* @param message The message to log.
|
2022-01-18 03:10:47 +00:00
|
|
|
* */
|
|
|
|
inline void Warning(const std::string& type, const std::string& message)
|
|
|
|
{
|
|
|
|
Write(Level::WARNING, type, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Writes a warning message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
|
|
|
* @param format A format string to format and then log.
|
|
|
|
* */
|
2022-09-29 12:01:29 +01:00
|
|
|
inline void Warning(const std::string& type, const char* format, ...) ATTR_NOT_NULL(3) ATTR_PRINTF(3, 4)
|
2022-01-18 03:10:47 +00:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
|
|
Write(Level::WARNING, type, format, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Writes a normal message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
2022-05-02 17:31:57 +01:00
|
|
|
* @param message The message to log.
|
2022-01-18 03:10:47 +00:00
|
|
|
* */
|
|
|
|
inline void Normal(const std::string& type, const std::string& message)
|
|
|
|
{
|
|
|
|
Write(Level::NORMAL, type, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Writes a normal message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
|
|
|
* @param format A format string to format and then log.
|
|
|
|
* */
|
2022-09-29 12:01:29 +01:00
|
|
|
inline void Normal(const std::string& type, const char* format, ...) ATTR_NOT_NULL(3) ATTR_PRINTF(3, 4)
|
2022-01-18 03:10:47 +00:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
|
|
Write(Level::NORMAL, type, format, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Writes a debug message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
2022-05-02 17:31:57 +01:00
|
|
|
* @param message The message to log.
|
2022-01-18 03:10:47 +00:00
|
|
|
* */
|
|
|
|
inline void Debug(const std::string& type, const std::string& message)
|
|
|
|
{
|
|
|
|
Write(Level::DEBUG, type, message);
|
|
|
|
}
|
|
|
|
/** Writes a debug message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
|
|
|
* @param format A format string to format and then log.
|
|
|
|
* */
|
2022-09-29 12:01:29 +01:00
|
|
|
inline void Debug(const std::string& type, const char* format, ...) ATTR_NOT_NULL(3) ATTR_PRINTF(3, 4)
|
2022-01-18 03:10:47 +00:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
|
|
Write(Level::DEBUG, type, format, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Writes a raw I/O message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
2022-05-02 17:31:57 +01:00
|
|
|
* @param message The message to log.
|
2022-01-18 03:10:47 +00:00
|
|
|
* */
|
|
|
|
inline void RawIO(const std::string& type, const std::string& message)
|
|
|
|
{
|
|
|
|
Write(Level::RAWIO, type, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Writes a raw I/O message to the server log.
|
|
|
|
* @param type The type of message that is being logged.
|
|
|
|
* @param format A format string to format and then log.
|
|
|
|
* */
|
2022-09-29 12:01:29 +01:00
|
|
|
inline void RawIO(const std::string& type, const char* format, ...) ATTR_NOT_NULL(3) ATTR_PRINTF(3, 4)
|
2022-01-18 03:10:47 +00:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
|
|
Write(Level::RAWIO, type, format, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
};
|