98 lines
3.4 KiB
C++
98 lines
3.4 KiB
C++
#pragma once
|
|
#include <stdio.h>
|
|
#include <streambuf>
|
|
#include <ostream>
|
|
#include <set>
|
|
#include <config.h>
|
|
#include <vector>
|
|
#include <variant>
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <stack>
|
|
#ifdef __ANDROID__
|
|
#include <android/log.h>
|
|
#endif
|
|
#include <functional>
|
|
namespace Looper::Log {
|
|
struct LogStream {
|
|
std::set<FILE *> outputs;
|
|
static std::set<FILE *> global_outputs;
|
|
int my_log_level;
|
|
std::set<LogStream*> streams;
|
|
bool nested;
|
|
bool need_prefix;
|
|
std::vector<std::string> names;
|
|
std::set<FILE*> get_used_outputs();
|
|
|
|
#ifdef __ANDROID__
|
|
std::set<android_LogPriority> android_outputs;
|
|
#endif
|
|
std::string line;
|
|
LogStream(std::initializer_list<std::string> names, int log_level, bool nested, void* discriminator);
|
|
|
|
public:
|
|
virtual void _writec(const char chr);
|
|
typedef std::lock_guard<std::recursive_mutex> log_mutex_guard;
|
|
static int log_level;
|
|
virtual void writeprefix();
|
|
void write_level_prefix(size_t level);
|
|
void write_level(size_t level, const char *msg);
|
|
void write_level(size_t level, std::string msg);
|
|
void writef_level(size_t level, const char *msg, ...);
|
|
void vwritef_level(size_t level, const char *msg, va_list args);
|
|
void writeln(const char *msg);
|
|
void writeln_n(const char *msg, size_t n);
|
|
void writeln(std::string msg);
|
|
void writes(const char *msg);
|
|
void writesn(const char *msg, size_t n);
|
|
void writes(std::string msg);
|
|
virtual void writec(const char chr);
|
|
inline virtual ~LogStream() { }
|
|
void vwritef(const char *fmt, va_list args);
|
|
void writef(const char *fmt, ...);
|
|
void vwritefln(const char *fmt, va_list args);
|
|
void writefln(const char *fmt, ...);
|
|
LogStream(std::initializer_list<std::string> names, std::initializer_list<LogStream*> streams, int log_level = 0);
|
|
|
|
#ifdef __ANDROID__
|
|
LogStream(std::initializer_list<std::string> names, std::initializer_list<std::variant<FILE*, android_LogPriority>> outputs, int log_level = 0);
|
|
#else
|
|
LogStream(std::initializer_list<std::string> names, std::initializer_list<FILE*> outputs, int log_level = 0);
|
|
#endif
|
|
protected:
|
|
};
|
|
std::string get_log_name_by_idx(int idx);
|
|
void init_logging();
|
|
void init_logging_subprocess();
|
|
typedef std::function<LogStream*(int)> log_stream_creation_function_t;
|
|
void init_logging_custom(log_stream_creation_function_t fn);
|
|
LogStream &get_log_stream_by_level(int level);
|
|
#define LOG(level) (Looper::Log::get_log_stream_by_level(level))
|
|
#define DEBUG LOG(-1)
|
|
#define INFO LOG(0)
|
|
#define WARNING LOG(1)
|
|
#define ERROR LOG(2)
|
|
void pop_log_streams();
|
|
class Context {
|
|
std::function<void()> end;
|
|
public:
|
|
inline Context(std::function<void()> start, std::function<void()> end) {
|
|
start();
|
|
this->end = end;
|
|
}
|
|
inline ~Context() {
|
|
end();
|
|
}
|
|
};
|
|
class LogContext : public Context {
|
|
public:
|
|
inline LogContext(std::function<void()> push_log_stream_fn) : Context(push_log_stream_fn, pop_log_streams) {
|
|
|
|
}
|
|
};
|
|
typedef std::map<int, std::stack<LogStream*>> LogStreamMap;
|
|
}
|
|
extern "C" {
|
|
void write_log(int level, const char *log);
|
|
void write_logln(int level, const char *log);
|
|
}
|