35
35
#define LOG_DEBUG (...) LOG_WITH_LEVEL(debug, __VA_ARGS__)
36
36
#define LOG_TRACE (...) LOG_WITH_LEVEL(trace, __VA_ARGS__)
37
37
38
- #define CODEQL_GET_SECOND (...) CODEQL_GET_SECOND_I(__VA_ARGS__, 0 , 0 )
39
- #define CODEQL_GET_SECOND_I (X, Y, ...) Y
40
-
41
38
// only do the actual logging if the picked up `Logger` instance is configured to handle the
42
39
// provided log level. `LEVEL` must be a compile-time constant. `logger()` is evaluated once
43
- // TODO(C++20) replace non-standard ##__VA_ARGS__ with __VA_OPT__(,) __VA_ARGS__
44
- #define LOG_WITH_LEVEL_AND_CATEGORY (LEVEL, CATEGORY, ...) \
45
- do { \
46
- static_assert (::codeql::detail::checkLogArgs<decltype (CODEQL_GET_SECOND (__VA_ARGS__))>( \
47
- MSERIALIZE_FIRST (__VA_ARGS__)), \
48
- " diagnostics logs must have format starting with \" [{}]\" " ); \
49
- constexpr auto _level = ::codeql::Log::Level::LEVEL; \
50
- ::codeql::Logger& _logger = logger (); \
51
- if (_level >= _logger.level ()) { \
52
- BINLOG_CREATE_SOURCE_AND_EVENT (_logger.writer (), _level, CATEGORY, ::binlog::clockNow (), \
53
- __VA_ARGS__); \
54
- } \
55
- if (_level >= ::codeql::Log::Level::error) { \
56
- ::codeql::Log::flush (); \
57
- } \
40
+ #define LOG_WITH_LEVEL (LEVEL, ...) \
41
+ do { \
42
+ constexpr auto _level = ::codeql::Log::Level::LEVEL; \
43
+ ::codeql::Logger& _logger = logger (); \
44
+ if (_level >= _logger.level ()) { \
45
+ BINLOG_CREATE_SOURCE_AND_EVENT (_logger.writer (), _level, /* category*/ , ::binlog::clockNow (), \
46
+ __VA_ARGS__); \
47
+ } \
48
+ if (_level >= ::codeql::Log::Level::error) { \
49
+ ::codeql::Log::flush (); \
50
+ } \
58
51
} while (false )
59
52
60
- #define LOG_WITH_LEVEL (LEVEL, ...) LOG_WITH_LEVEL_AND_CATEGORY(LEVEL, , __VA_ARGS__)
53
+ // Emit errors with a specified SwiftDiagnostic object. These will be both logged and outputted as
54
+ // JSON DB diagnostics
55
+ #define DIAGNOSE_CRITICAL (ID, ...) DIAGNOSE_WITH_LEVEL(critical, ID, __VA_ARGS__)
56
+ #define DIAGNOSE_ERROR (ID, ...) DIAGNOSE_WITH_LEVEL(error, ID, __VA_ARGS__)
57
+
58
+ #define CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX " [{}] "
59
+ // TODO(C++20) replace non-standard , ##__VA_ARGS__ with __VA_OPT__(,) __VA_ARGS__
60
+ #define DIAGNOSE_WITH_LEVEL (LEVEL, ID, FORMAT, ...) \
61
+ LOG_WITH_LEVEL (LEVEL, CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX FORMAT, \
62
+ ::codeql::detail::SwiftDiagnosticLogWrapper{ID}, ##__VA_ARGS__);
61
63
62
64
// avoid calling into binlog's original macros
63
65
#undef BINLOG_CRITICAL
@@ -126,8 +128,7 @@ class Log {
126
128
return instance ().getLoggerConfigurationImpl (name);
127
129
}
128
130
129
- template <typename Source>
130
- static void diagnose (const Source& source,
131
+ static void diagnose (const SwiftDiagnostic& source,
131
132
const std::chrono::system_clock::time_point& time,
132
133
std::string_view message) {
133
134
instance ().diagnostics .write (source, time, message);
@@ -224,31 +225,9 @@ class Logger {
224
225
};
225
226
226
227
namespace detail {
227
- constexpr std::string_view diagnosticsFormatPrefix = " [{}] " ;
228
-
229
- template <typename T>
230
- constexpr bool checkLogArgs (std::string_view format) {
231
- using Type = std::remove_cv_t <std::remove_reference_t <T>>;
232
- constexpr bool isDiagnostic = std::is_same_v<Type, SwiftDiagnosticsSource> ||
233
- std::is_same_v<Type, SwiftDiagnosticsSourceWithLocation>;
234
- return !isDiagnostic ||
235
- format.substr (0 , diagnosticsFormatPrefix.size ()) == diagnosticsFormatPrefix;
236
- }
237
-
238
- template <typename Writer, typename Source, typename ... T>
239
- void binlogAddEventIgnoreFirstOverload (Writer& writer,
240
- std::uint64_t eventSourceId,
241
- std::uint64_t clock,
242
- const char * format,
243
- const Source& source,
244
- T&&... t) {
245
- std::chrono::system_clock::time_point point{
246
- std::chrono::duration_cast<std::chrono::system_clock::duration>(
247
- std::chrono::nanoseconds{clock})};
248
- constexpr auto offset = ::codeql::detail::diagnosticsFormatPrefix.size ();
249
- ::codeql::Log::diagnose (source, point, fmt::format(format + offset, t...));
250
- writer.addEvent (eventSourceId, clock, source, std::forward<T>(t)...);
251
- }
228
+ struct SwiftDiagnosticLogWrapper {
229
+ const SwiftDiagnostic& value;
230
+ };
252
231
253
232
} // namespace detail
254
233
} // namespace codeql
@@ -262,32 +241,37 @@ void addEventIgnoreFirst(Writer& writer,
262
241
std::uint64_t eventSourceId,
263
242
std::uint64_t clock,
264
243
const char (&format)[N],
265
- const codeql::SwiftDiagnosticsSource & source,
244
+ codeql::detail::SwiftDiagnosticLogWrapper& & source,
266
245
T&&... t) {
267
- codeql::detail::binlogAddEventIgnoreFirstOverload (writer, eventSourceId, clock, format, source,
268
- std::forward<T>(t)...);
246
+ std::chrono::system_clock::time_point point{
247
+ std::chrono::duration_cast<std::chrono::system_clock::duration>(
248
+ std::chrono::nanoseconds{clock})};
249
+ constexpr std::string_view prefix = CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX;
250
+ ::codeql::Log::diagnose (source.value, point, fmt::format(format + prefix.size(), t...));
251
+ writer.addEvent (eventSourceId, clock, source, std::forward<T>(t)...);
269
252
}
253
+ } // namespace binlog::detail
270
254
271
- template <typename Writer, size_t N, typename ... T>
272
- void addEventIgnoreFirst (Writer& writer,
273
- std::uint64_t eventSourceId,
274
- std::uint64_t clock,
275
- const char (&format)[N],
276
- codeql::SwiftDiagnosticsSourceWithLocation&& source,
277
- T&&... t) {
278
- codeql::detail::binlogAddEventIgnoreFirstOverload (writer, eventSourceId, clock, format, source,
279
- std::forward<T>(t)...);
280
- }
255
+ namespace mserialize {
256
+ // log diagnostics wrapper using the abbreviation of the underlying diagnostic, using
257
+ // binlog/mserialize internal plumbing
258
+ template <>
259
+ struct CustomTag <codeql::detail::SwiftDiagnosticLogWrapper, void >
260
+ : detail::BuiltinTag<std::string> {
261
+ using T = codeql::detail::SwiftDiagnosticLogWrapper;
262
+ };
281
263
282
- template <typename Writer, size_t N, typename ... T>
283
- void addEventIgnoreFirst (Writer& writer,
284
- std::uint64_t eventSourceId,
285
- std::uint64_t clock,
286
- const char (&format)[N],
287
- const codeql::SwiftDiagnosticsSourceWithLocation& source,
288
- T&&... t) {
289
- codeql::detail::binlogAddEventIgnoreFirstOverload (writer, eventSourceId, clock, format, source,
290
- std::forward<T>(t)...);
291
- }
264
+ template <>
265
+ struct CustomSerializer <codeql::detail::SwiftDiagnosticLogWrapper, void > {
266
+ template <typename OutputStream>
267
+ static void serialize (const codeql::detail::SwiftDiagnosticLogWrapper& source,
268
+ OutputStream& out) {
269
+ mserialize::serialize (source.value .abbreviation (), out);
270
+ }
292
271
293
- } // namespace binlog::detail
272
+ static size_t serialized_size (const codeql::detail::SwiftDiagnosticLogWrapper& source) {
273
+ return mserialize::serialized_size (source.value .abbreviation ());
274
+ }
275
+ };
276
+
277
+ } // namespace mserialize
0 commit comments