Logger
Loading...
Searching...
No Matches
Logger.hpp
Go to the documentation of this file.
1/*
2 MIT License
3
4 Copyright(c) 2023 George Fotopoulos
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files(the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions :
12
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23*/
24
25#pragma once
26
27#ifdef _MSC_VER
28#pragma warning(disable : 4996)
29#endif
30
31#include <array>
32#include <cstdarg>
33#include <cstdio>
34#include <ctime>
35#include <mutex>
36#include <string>
37#include <vector>
38
39class Logger {
40public:
41 enum class Level {
42 Trace,
43 Debug,
44 Info,
45 Warn,
46 Error,
48 };
49
50 Logger(const Logger &) = delete;
51
52 Logger(Logger &&) = delete;
53
54 Logger &operator=(const Logger &) = delete;
55
56 Logger &operator=(Logger &&) = delete;
57
58 static Logger &GetInstance() {
59 static Logger instance;
60 return instance;
61 }
62
63 static void SetLevel(const Level level) {
64 Logger &instance = GetInstance();
65 instance.mLevel = level;
66 }
67
68 static void EnableFileOutput() {
69 Logger &instance = GetInstance();
70 instance.mFileOutputEnabled = true;
71 }
72
73 static void DisableFileOutput() {
74 Logger &instance = GetInstance();
75 instance.mFileOutputEnabled = false;
76 }
77
78 static void SetFileOutput(const char *output) {
79 Logger &instance = GetInstance();
80 instance.mFileOutput = output;
81 }
82
83 template<typename... Args>
84 static void Trace(const char *format, Args... args) {
85 Log(Level::Trace, "trace", format, args...);
86 }
87
88 template<typename... Args>
89 static void Debug(const char *format, Args... args) {
90 Log(Level::Debug, "debug", format, args...);
91 }
92
93 template<typename... Args>
94 static void Info(const char *format, Args... args) {
95 Log(Level::Info, "info", format, args...);
96 }
97
98 template<typename... Args>
99 static void Warn(const char *format, Args... args) {
100 Log(Level::Warn, "warn", format, args...);
101 }
102
103 template<typename... Args>
104 static void Error(const char *format, Args... args) {
105 Log(Level::Error, "error", format, args...);
106 }
107
108 template<typename... Args>
109 static void Critical(const char *format, Args... args) {
110 Log(Level::Critical, "critical", format, args...);
111 }
112
113 static void Trace(const char *str) {
114 Log(Level::Trace, "trace", str);
115 }
116
117 static void Debug(const char *str) {
118 Log(Level::Debug, "debug", str);
119 }
120
121 static void Info(const char *str) {
122 Log(Level::Info, "info", str);
123 }
124
125 static void Warn(const char *str) {
126 Log(Level::Warn, "warn", str);
127 }
128
129 static void Error(const char *str) {
130 Log(Level::Error, "error", str);
131 }
132
133 static void Critical(const char *str) {
134 Log(Level::Critical, "critical", str);
135 }
136
137private:
138 Logger() = default;
139
140 ~Logger() = default;
141
142 template<typename... Args>
143 static void Log(const Level level, const char *tag, const char *format, Args... args) {
144 Logger &instance = GetInstance();
145 std::lock_guard<std::mutex> lock(instance.mMutex);
146 if (instance.mLevel <= level) {
147 std::time_t t = std::time(nullptr);
148 std::array<char, 100> time_buf{};
149 std::strftime(time_buf.data(), sizeof time_buf, "%Y-%m-%d %H:%M:%S", std::gmtime(&t));
150 std::printf("[%s] [%s] ", time_buf.data(), tag);
151 std::printf(format, args...);
152 std::printf("\n");
153 if (instance.mFileOutputEnabled) {
154 std::FILE *file = std::fopen(instance.mFileOutput.c_str(), "a");
155 std::fprintf(file, "[%s] [%s] ", time_buf.data(), tag);
156 std::fprintf(file, format, args...);
157 std::fprintf(file, "\n");
158 std::fclose(file);
159 }
160 }
161 }
162
163 static void Log(const Level level, const char *tag, const char *str) {
164 Logger &instance = GetInstance();
165 std::lock_guard<std::mutex> lock(instance.mMutex);
166 if (instance.mLevel <= level) {
167 std::time_t t = std::time(nullptr);
168 std::array<char, 100> time_buf{};
169 std::strftime(time_buf.data(), sizeof time_buf, "%Y-%m-%d %H:%M:%S", std::gmtime(&t));
170 std::printf("[%s] [%s] %s\n", time_buf.data(), tag, str);
171 if (instance.mFileOutputEnabled) {
172 std::FILE *file = std::fopen(instance.mFileOutput.c_str(), "a");
173 std::fprintf(file, "[%s] [%s] %s\n", time_buf.data(), tag, str);
174 std::fclose(file);
175 }
176 }
177 }
178
179 Level mLevel{Level::Info};
180 bool mFileOutputEnabled{false};
181 std::string mFileOutput{"default.log"};
182 std::mutex mMutex;
183};
Definition: Logger.hpp:39
static void SetFileOutput(const char *output)
Definition: Logger.hpp:78
static void Info(const char *str)
Definition: Logger.hpp:121
static void Trace(const char *format, Args... args)
Definition: Logger.hpp:84
static Logger & GetInstance()
Definition: Logger.hpp:58
static void SetLevel(const Level level)
Definition: Logger.hpp:63
static void Debug(const char *str)
Definition: Logger.hpp:117
static void DisableFileOutput()
Definition: Logger.hpp:73
static void Warn(const char *format, Args... args)
Definition: Logger.hpp:99
static void Critical(const char *format, Args... args)
Definition: Logger.hpp:109
Logger & operator=(const Logger &)=delete
static void Error(const char *format, Args... args)
Definition: Logger.hpp:104
static void Trace(const char *str)
Definition: Logger.hpp:113
static void Info(const char *format, Args... args)
Definition: Logger.hpp:94
Logger(Logger &&)=delete
static void EnableFileOutput()
Definition: Logger.hpp:68
static void Warn(const char *str)
Definition: Logger.hpp:125
static void Critical(const char *str)
Definition: Logger.hpp:133
Level
Definition: Logger.hpp:41
Logger(const Logger &)=delete
static void Debug(const char *format, Args... args)
Definition: Logger.hpp:89
Logger & operator=(Logger &&)=delete
static void Error(const char *str)
Definition: Logger.hpp:129