1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #pragma once
5 
6 #include "DateTime.h"
7 #include <fmt/format.h>
8 #include <sigc++/signal.h>
9 #include <string_view>
10 
11 namespace Log {
12 	enum class Severity : int8_t {
13 		Fatal = -3,
14 		Error = -2,
15 		Warning = -1,
16 		Info = 0,
17 		Debug = 1,
18 		Verbose = 2
19 	};
20 
21 	struct Logger {
22 		~Logger();
23 
24 		// Handle formatting, indentation, etc.
25 		// Prefer the Verbose, Info, Warning, etc. functions instead of directly using this one
26 		void LogLevel(Severity sv, std::string &message);
27 		void LogLevel(Severity sv, std::string_view message);
28 		void LogLevel(Severity sv, const char *message);
29 
30 		bool SetLogFile(std::string filename);
31 
32 		// Return the severity cutoff at which log messages will be printed to stderr.
GetSeverityLogger33 		Severity GetSeverity() { return m_maxSeverity; }
SetSeverityLogger34 		void SetSeverity(Severity sv) { m_maxSeverity = sv; }
35 
GetFileSeverityLogger36 		Severity GetFileSeverity() { return m_maxSeverity; }
SetFileSeverityLogger37 		void SetFileSeverity(Severity sv) { m_maxFileSeverity = sv; }
38 
IncreaseIndentLogger39 		void IncreaseIndent() { current_indent += 1; }
DecreaseIndentLogger40 		void DecreaseIndent()
41 		{
42 			if (current_indent) current_indent -= 1;
43 		}
44 
45 		sigc::signal<void, Time::DateTime, Severity, std::string_view> printCallback;
46 
47 	private:
48 		void WriteLog(Time::DateTime t, Severity sv, std::string_view msg);
49 
50 		FILE *file;
51 		Severity m_maxSeverity = Severity::Info;
52 		Severity m_maxFileSeverity = Severity::Verbose;
53 		uint8_t current_indent;
54 		std::string m_logName;
55 	};
56 
57 	void SetLog(Logger &log);
58 	Logger *GetLog();
59 
GetLogLevel()60 	inline Severity GetLogLevel() { return GetLog()->GetSeverity(); }
SetLogLevel(Severity sv)61 	inline void SetLogLevel(Severity sv) { GetLog()->SetSeverity(sv); }
62 
63 	void LogOld(Severity sv, std::string message);
64 	[[noreturn]] void LogFatalOld(std::string message);
65 
66 	void LogInternal(Severity sv, const char *message, fmt::format_args args);
67 	[[noreturn]] void LogFatalInternal(const char *message, fmt::format_args args);
68 
69 	void IncreaseIndent();
70 	void DecreaseIndent();
71 
72 	template <typename... Args>
Verbose(const char * message,Args...args)73 	inline void Verbose(const char *message, Args... args)
74 	{
75 		LogInternal(Severity::Verbose, message, fmt::make_format_args(args...));
76 	}
77 
78 	template <typename... Args>
Info(const char * message,Args...args)79 	inline void Info(const char *message, Args... args)
80 	{
81 		LogInternal(Severity::Info, message, fmt::make_format_args(args...));
82 	}
83 
84 	template <typename... Args>
Debug(const char * message,Args...args)85 	inline void Debug(const char *message, Args... args)
86 	{
87 		LogInternal(Severity::Debug, message, fmt::make_format_args(args...));
88 	}
89 
90 	template <typename... Args>
Warning(const char * message,Args...args)91 	inline void Warning(const char *message, Args... args)
92 	{
93 		LogInternal(Severity::Warning, message, fmt::make_format_args(args...));
94 	}
95 
96 	template <typename... Args>
Error(const char * message,Args...args)97 	inline void Error(const char *message, Args... args)
98 	{
99 		LogInternal(Severity::Error, message, fmt::make_format_args(args...));
100 	}
101 
102 	template <typename... Args>
Fatal(const char * message,Args...args)103 	[[noreturn]] inline void Fatal(const char *message, Args... args)
104 	{
105 		LogFatalInternal(message, fmt::make_format_args(args...));
106 	}
107 
108 } // namespace Log
109