Files
thehub/libs/utils/LogChannels_p.h

140 lines
4.3 KiB
C++

/*
* This file is part of the Flowee project
* Copyright (C) 2017-2026 Tom Zander <tom@flowee.org>
*
* This program 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.
*
* 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/>.
*/
#ifndef FLOWEE_LOGCHANNELS_P_H
#define FLOWEE_LOGCHANNELS_P_H
#include "LogChannel.h"
/*
* WARNING USAGE OF THIS HEADER IS RESTRICTED.
* This Header file is part of the private API and is meant to be used solely by the Logger component.
*
* Usage of this API will likely mean your code will break in interesting ways in the future,
* or even stop to compile.
*
* YOU HAVE BEEN WARNED!!
*/
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem/path.hpp>
#include <thread>
class ConfigurableChannel : public Log::Channel
{
public:
ConfigurableChannel(TimeStampFormat formatTimestamp);
virtual void reopenLogFiles() {}
bool logSection() const;
void setLogSection(bool printSection);
bool logLineNumber() const;
void setLogLineNumber(bool printLineNumber);
bool logMethodName() const;
void setLogMethodName(bool printMethodName);
bool logFilename() const;
void setLogFilename(bool printFilename);
virtual void setPath(const std::string &path) {}
protected:
TimeStampFormat m_timeStampFormat;
bool m_logSection;
bool m_logLineNumber;
bool m_logMethodName;
bool m_logFilename;
};
class ConsoleLogChannel : public ConfigurableChannel
{
public:
ConsoleLogChannel();
void setPrefix(const char *prefix);
const char *prefix() const {
return m_prefix;
}
virtual void pushLog(int64_t timeMillis, std::string *timestamp, const std::string &line, const char *filename,
int lineNumber, const char *methodName, short logSection, short logLevel);
private:
const char *m_prefix = nullptr;
};
class FileLogChannel : public ConfigurableChannel
{
public:
FileLogChannel(const boost::filesystem::path &logFilename);
~FileLogChannel();
virtual void pushLog(int64_t timeMillis, std::string *timestamp, const std::string &line, const char *filename,
int lineNumber, const char *methodName, short logSection, short logLevel);
virtual void reopenLogFiles();
virtual void setPath(const std::string &path);
private:
FILE *m_fileout;
boost::filesystem::path m_logFilename;
};
/*
* Logging in the context of multi-threading is hard because we need a mutex
* and we serialize all thread's messages to one by one reach the file or console.
* Files or console block on write pretty quickly under heavy load. Making bursts
* of logging slow the application down to a single IO constrained mutex.
*
* As such the idea was born to keep the IO bound operation out of operational
* threads and use lock-less operations to just push to memory log lines and have
* a writer thread safe that to disk.
*
* Logging is generally speaking in Flowee not a firehose and thus storing it in
* memory while running is perfectly adequate for testing setups and benchmarkings.
*/
class FastLogChannel : public Log::Channel
{
public:
FastLogChannel(const boost::filesystem::path &logFilename);
~FastLogChannel();
public:
void pushLog(int64_t timeMillis, std::string *timestamp, const std::string &line, const char *filename, int lineNumber, const char *methodName, short logSection, short logLevel) override;
struct Item {
Item() : next(0) {}
std::atomic<Item*> next;
int64_t timeMillis;
std::string line;
const char *filename;
const char *methodname;
int lineNumber;
short logSection;
short logLevel;
std::thread::id callingThread;
};
private:
std::unique_ptr<std::thread> m_writeThread;
std::atomic<Item*> m_writePtr;
};
#endif