forked from KjellKod/g3log
-
Notifications
You must be signed in to change notification settings - Fork 0
/
loglevels.hpp
192 lines (148 loc) · 6.17 KB
/
loglevels.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/** ==========================================================================
* 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
* with no warranties. This code is yours to share, use and modify with no
* strings attached and no restrictions or obligations.
*
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
* ============================================================================*/
#pragma once
#include "g3log/generated_definitions.hpp"
// Users of Juce or other libraries might have a define DEBUG which clashes with
// the DEBUG logging level for G3log. In that case they can instead use the define
// "CHANGE_G3LOG_DEBUG_TO_DBUG" and G3log's logging level DEBUG is changed to be DBUG
#if (defined(CHANGE_G3LOG_DEBUG_TO_DBUG))
#if (defined(DBUG))
#error "DEBUG is already defined elsewhere which clashes with G3Log's log level DEBUG"
#endif
#else
#if (defined(DEBUG))
#error "DEBUG is already defined elsewhere which clashes with G3Log's log level DEBUG"
#endif
#endif
#include <string>
#include <algorithm>
#include <map>
#include <atomic>
#include <g3log/atomicbool.hpp>
// Levels for logging, made so that it would be easy to change, remove, add levels -- KjellKod
struct LEVELS {
// force internal copy of the const char*. This is a simple safeguard for when g3log is used in a
// "dynamic, runtime loading of shared libraries"
LEVELS(const LEVELS& other): value(other.value), text(other.text.c_str()) {}
LEVELS(int id, const std::string& idtext) : value(id), text(idtext) {}
bool operator==(const LEVELS& rhs) const {
return (value == rhs.value && text == rhs.text);
}
bool operator!=(const LEVELS& rhs) const {
return (value != rhs.value || text != rhs.text);
}
friend void swap(LEVELS& first, LEVELS& second) {
using std::swap;
swap(first.value, second.value);
swap(first.text, second.text);
}
LEVELS& operator=(LEVELS other) {
swap(*this, other);
return *this;
}
int value;
std::string text;
};
// If you want to add any extra logging level then please add to your own source file the logging level you need
// then insert it using g3::only_change_at_initialization::addLogLevel(...). Please note that this only works for dynamic logging levels.
//
// There should be NO reason for modifying this source file when adding custom levels
//
// When dynamic loggins levels are disabled then adding your own logging levels is not required as
// the new logging level by default will always be enabled.
//
// example: MyLoggingLevel.h
// #pragma once
// const LEVELS MYINFO {WARNING.value +1, "MyInfoLevel"};
// const LEVELS MYFATAL {FATAL.value +1, "MyFatalLevel"};
//
// ... somewhere else when G3_DYNAMIC_LOGGING is enabled
// addLogLevel(MYINFO, true);
// LOG(MYINFO) << "some text";
//
// ... another example, when G3_DYNAMIC_LOGGING is enabled
// 'addLogLevel' is NOT required
// LOG(MYFATL) << "this will just work, and it will be counted as a FATAL event";
namespace g3 {
static const int kDebugValue = 100;
static const int kInfoValue = 300;
static const int kWarningValue = 500;
static const int kFatalValue = 1000;
static const int kInternalFatalValue = 2000;
} // g3
const LEVELS G3LOG_DEBUG{g3::kDebugValue, {"DEBUG"}},
INFO {g3::kInfoValue, {"INFO"}},
WARNING {g3::kWarningValue, {"WARNING"}},
FATAL {g3::kFatalValue, {"FATAL"}};
namespace g3 {
// Logging level and atomic status collection struct
struct LoggingLevel {
atomicbool status;
LEVELS level;
// default operator needed for std::map compliance
LoggingLevel(): status(false), level(INFO) {};
LoggingLevel(const LoggingLevel& lvl) : status(lvl.status), level(lvl.level) {}
LoggingLevel(const LEVELS& lvl): status(true), level(lvl) {};
LoggingLevel(const LEVELS& lvl, bool enabled): status(enabled), level(lvl) {};
~LoggingLevel() = default;
LoggingLevel& operator=(const LoggingLevel& other) {
status = other.status;
level = other.level;
return *this;
}
bool operator==(const LoggingLevel& rhs) const {
return (status == rhs.status && level == rhs.level);
}
};
} // g3
namespace g3 {
namespace internal {
const LEVELS CONTRACT {g3::kInternalFatalValue, {"CONTRACT"}},
FATAL_SIGNAL {g3::kInternalFatalValue + 1, {"FATAL_SIGNAL"}},
FATAL_EXCEPTION {kInternalFatalValue + 2, {"FATAL_EXCEPTION"}};
/// helper function to tell the logger if a log message was fatal. If it is it will force
/// a shutdown after all log entries are saved to the sinks
bool wasFatal(const LEVELS& level);
}
#ifdef G3_DYNAMIC_LOGGING
// Only safe if done at initialization in a single-thread context
namespace only_change_at_initialization {
/// add a custom level - enabled or disabled
void addLogLevel(LEVELS level, bool enabled);
/// add a custom level - enabled
void addLogLevel(LEVELS level);
/// reset all default logging levels to enabled
/// remove any added logging levels so that the only ones left are
/// {DEBUG,INFO,WARNING,ERROR,FATAL}
void reset();
} // only_change_at_initialization
namespace log_levels {
/// Enable log level >= log_level.
/// log levels below will be disabled
/// log levels equal or higher will be enabled.
void setHighest(LEVELS level);
void set(LEVELS level, bool enabled);
void disable(LEVELS level);
void enable(LEVELS level);
/// WARNING: This will also disable FATAL events from being logged
void disableAll();
void enableAll();
/// print all levels with their disabled or enabled status
std::string to_string(std::map<int, g3::LoggingLevel> levelsToPrint);
/// print snapshot of system levels with their
/// disabled or enabled status
std::string to_string();
/// Snapshot view of the current logging levels' status
std::map<int, g3::LoggingLevel> getAll();
enum class status {Absent, Enabled, Disabled};
status getStatus(LEVELS level);
} // log_levels
#endif
/// Enabled status for the given logging level
bool logLevel(LEVELS level);
} // g3