Files

140 lines
4.3 KiB
C++
Raw Permalink Normal View History

/*
2017-11-13 23:09:33 +01:00
* This file is part of the Flowee project
2026-04-10 23:10:58 +02:00
* 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/>.
*/
2024-01-22 19:32:15 +01:00
#ifndef FLOWEE_LOGCHANNELS_P_H
#define FLOWEE_LOGCHANNELS_P_H
2022-11-24 17:50:08 +01:00
#include "LogChannel.h"
2019-04-06 12:19:13 +02:00
/*
* 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>
2022-11-24 17:50:08 +01:00
#include <boost/filesystem/path.hpp>
2026-04-10 23:10:58 +02:00
#include <thread>
2022-11-24 17:50:08 +01:00
class ConfigurableChannel : public Log::Channel
{
public:
2022-11-24 17:50:08 +01:00
ConfigurableChannel(TimeStampFormat formatTimestamp);
virtual void reopenLogFiles() {}
2022-11-24 17:50:08 +01:00
bool logSection() const;
void setLogSection(bool printSection);
2022-11-24 17:50:08 +01:00
bool logLineNumber() const;
void setLogLineNumber(bool printLineNumber);
2022-11-24 17:50:08 +01:00
bool logMethodName() const;
void setLogMethodName(bool printMethodName);
2022-11-24 17:50:08 +01:00
bool logFilename() const;
void setLogFilename(bool printFilename);
2018-03-08 19:32:14 +01:00
virtual void setPath(const std::string &path) {}
2017-05-15 14:39:52 +02:00
protected:
TimeStampFormat m_timeStampFormat;
2022-11-24 17:50:08 +01:00
bool m_logSection;
bool m_logLineNumber;
bool m_logMethodName;
bool m_logFilename;
};
2022-11-24 17:50:08 +01:00
class ConsoleLogChannel : public ConfigurableChannel
2017-05-15 14:39:52 +02:00
{
public:
ConsoleLogChannel();
2018-08-14 09:27:07 +02:00
void setPrefix(const char *prefix);
const char *prefix() const {
2018-05-06 22:00:16 +02:00
return m_prefix;
}
2017-05-15 14:39:52 +02:00
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);
2018-05-06 22:00:16 +02:00
private:
2018-08-14 09:27:07 +02:00
const char *m_prefix = nullptr;
2017-05-15 14:39:52 +02:00
};
2022-11-24 17:50:08 +01:00
class FileLogChannel : public ConfigurableChannel
{
public:
FileLogChannel(const boost::filesystem::path &logFilename);
~FileLogChannel();
2017-05-15 14:39:52 +02:00
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();
2018-03-08 19:32:14 +01:00
virtual void setPath(const std::string &path);
private:
FILE *m_fileout;
boost::filesystem::path m_logFilename;
};
2026-04-10 23:10:58 +02:00
/*
* 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;
2026-04-10 23:10:58 +02:00
short logSection;
short logLevel;
2026-04-10 23:53:01 +02:00
std::thread::id callingThread;
2026-04-10 23:10:58 +02:00
};
private:
std::unique_ptr<std::thread> m_writeThread;
std::atomic<Item*> m_writePtr;
};
#endif