1
1
#pragma once
2
2
3
+ #include < chrono>
3
4
#include < fstream>
4
5
#include < iostream>
5
6
#include < regex>
30
31
#define LOG_DEBUG (...) LOG_WITH_LEVEL(debug, __VA_ARGS__)
31
32
#define LOG_TRACE (...) LOG_WITH_LEVEL(trace, __VA_ARGS__)
32
33
34
+ #define LOG_WITH_LEVEL (LEVEL, ...) LOG_WITH_LEVEL_AND_TIME(LEVEL, ::binlog::clockNow(), __VA_ARGS__)
33
35
// only do the actual logging if the picked up `Logger` instance is configured to handle the
34
36
// provided log level. `LEVEL` must be a compile-time constant. `logger()` is evaluated once
35
- #define LOG_WITH_LEVEL (LEVEL, ...) \
36
- do { \
37
- constexpr auto _level = ::codeql::Log::Level::LEVEL; \
38
- ::codeql::Logger& _logger = logger (); \
39
- if (_level >= _logger.level ()) { \
40
- BINLOG_CREATE_SOURCE_AND_EVENT (_logger.writer (), _level, /* category*/ , ::binlog::clockNow (), \
41
- __VA_ARGS__); \
42
- } \
43
- if (_level >= ::codeql::Log::Level::error) { \
44
- ::codeql::Log::flush (); \
45
- } \
37
+ #define LOG_WITH_LEVEL_AND_TIME (LEVEL, TIME, ...) \
38
+ do { \
39
+ constexpr auto _level = ::codeql::Log::Level::LEVEL; \
40
+ ::codeql::Logger& _logger = logger (); \
41
+ if (_level >= _logger.level ()) { \
42
+ BINLOG_CREATE_SOURCE_AND_EVENT (_logger.writer (), _level, /* category*/ , TIME, __VA_ARGS__); \
43
+ } \
44
+ if (_level >= ::codeql::Log::Level::error) { \
45
+ ::codeql::Log::flush (); \
46
+ } \
46
47
} while (false )
47
48
48
49
// Emit errors with a specified SwiftDiagnostic object. These will be both logged and outputted as
49
- // JSON DB diagnostics
50
- #define DIAGNOSE_CRITICAL (ID, ...) DIAGNOSE_WITH_LEVEL(critical, ID, __VA_ARGS__)
50
+ // JSON DB diagnostics. The format must be appliable to the following arguments both as binlog and
51
+ // as fmt::format formatting.
52
+ // Beware that contrary to LOG_* macros, arguments right of the format will be evaluated twice. ID
53
+ // is evaluated once though.
51
54
#define DIAGNOSE_ERROR (ID, ...) DIAGNOSE_WITH_LEVEL(error, ID, __VA_ARGS__)
55
+ #define DIAGNOSE_CRITICAL (ID, ...) DIAGNOSE_WITH_LEVEL(critical, ID, __VA_ARGS__)
52
56
53
57
#define CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX " [{}] "
54
58
// TODO(C++20) replace non-standard , ##__VA_ARGS__ with __VA_OPT__(,) __VA_ARGS__
55
- #define DIAGNOSE_WITH_LEVEL (LEVEL, ID, FORMAT, ...) \
56
- LOG_WITH_LEVEL (LEVEL, CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX FORMAT, \
57
- ::codeql::detail::SwiftDiagnosticLogWrapper{ID}, ##__VA_ARGS__);
59
+ #define DIAGNOSE_WITH_LEVEL (LEVEL, ID, FORMAT, ...) \
60
+ do { \
61
+ auto _now = ::binlog::clockNow (); \
62
+ const ::codeql::SwiftDiagnostic& _id = ID; \
63
+ ::codeql::Log::diagnose (_id, std::chrono::nanoseconds{_now}, \
64
+ fmt::format (FORMAT, ##__VA_ARGS__)); \
65
+ LOG_WITH_LEVEL_AND_TIME (LEVEL, _now, CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX FORMAT, \
66
+ ::codeql::detail::SwiftDiagnosticLogWrapper{_id}, ##__VA_ARGS__); \
67
+ } while (false )
58
68
59
69
// avoid calling into binlog's original macros
60
70
#undef BINLOG_CRITICAL
@@ -124,9 +134,9 @@ class Log {
124
134
}
125
135
126
136
static void diagnose (const SwiftDiagnostic& source,
127
- const std::chrono::system_clock::time_point& time ,
137
+ const std::chrono::nanoseconds& elapsed ,
128
138
std::string_view message) {
129
- instance ().diagnoseImpl (source, time , message);
139
+ instance ().diagnoseImpl (source, elapsed , message);
130
140
}
131
141
132
142
private:
@@ -145,7 +155,7 @@ class Log {
145
155
void configure ();
146
156
void flushImpl ();
147
157
void diagnoseImpl (const SwiftDiagnostic& source,
148
- const std::chrono::system_clock::time_point& time ,
158
+ const std::chrono::nanoseconds& elapsed ,
149
159
std::string_view message);
150
160
151
161
LoggerConfiguration getLoggerConfigurationImpl (std::string_view name);
@@ -230,26 +240,6 @@ struct SwiftDiagnosticLogWrapper {
230
240
} // namespace detail
231
241
} // namespace codeql
232
242
233
- // we intercept this binlog plumbing function providing better overload resolution matches in
234
- // case the first non-format argument is a diagnostic source, and emit it in that case with the
235
- // same timestamp
236
- namespace binlog ::detail {
237
- template <typename Writer, size_t N, typename ... T>
238
- void addEventIgnoreFirst (Writer& writer,
239
- std::uint64_t eventSourceId,
240
- std::uint64_t clock,
241
- const char (&format)[N],
242
- codeql::detail::SwiftDiagnosticLogWrapper&& source,
243
- T&&... t) {
244
- std::chrono::system_clock::time_point point{
245
- std::chrono::duration_cast<std::chrono::system_clock::duration>(
246
- std::chrono::nanoseconds{clock})};
247
- constexpr std::string_view prefix = CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX;
248
- ::codeql::Log::diagnose (source.value, point, fmt::format(format + prefix.size(), t...));
249
- writer.addEvent (eventSourceId, clock, source, std::forward<T>(t)...);
250
- }
251
- } // namespace binlog::detail
252
-
253
243
namespace mserialize {
254
244
// log diagnostics wrapper using the abbreviation of the underlying diagnostic, using
255
245
// binlog/mserialize internal plumbing
0 commit comments