Skip to content

Commit a2cb331

Browse files
committed
Swift: remove hacky binlog interception
1 parent 9a555ae commit a2cb331

File tree

2 files changed

+32
-40
lines changed

2 files changed

+32
-40
lines changed

swift/logging/SwiftLogging.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,10 @@ void Log::flushImpl() {
170170
}
171171

172172
void Log::diagnoseImpl(const SwiftDiagnostic& source,
173-
const std::chrono::system_clock::time_point& time,
173+
const std::chrono::nanoseconds& elapsed,
174174
std::string_view message) {
175+
using Clock = std::chrono::system_clock;
176+
Clock::time_point time{std::chrono::duration_cast<Clock::duration>(elapsed)};
175177
if (diagnostics) {
176178
diagnostics << source.json(time, message) << '\n';
177179
}

swift/logging/SwiftLogging.h

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <chrono>
34
#include <fstream>
45
#include <iostream>
56
#include <regex>
@@ -30,31 +31,40 @@
3031
#define LOG_DEBUG(...) LOG_WITH_LEVEL(debug, __VA_ARGS__)
3132
#define LOG_TRACE(...) LOG_WITH_LEVEL(trace, __VA_ARGS__)
3233

34+
#define LOG_WITH_LEVEL(LEVEL, ...) LOG_WITH_LEVEL_AND_TIME(LEVEL, ::binlog::clockNow(), __VA_ARGS__)
3335
// only do the actual logging if the picked up `Logger` instance is configured to handle the
3436
// 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+
} \
4647
} while (false)
4748

4849
// 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.
5154
#define DIAGNOSE_ERROR(ID, ...) DIAGNOSE_WITH_LEVEL(error, ID, __VA_ARGS__)
55+
#define DIAGNOSE_CRITICAL(ID, ...) DIAGNOSE_WITH_LEVEL(critical, ID, __VA_ARGS__)
5256

5357
#define CODEQL_DIAGNOSTIC_LOG_FORMAT_PREFIX "[{}] "
5458
// 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)
5868

5969
// avoid calling into binlog's original macros
6070
#undef BINLOG_CRITICAL
@@ -124,9 +134,9 @@ class Log {
124134
}
125135

126136
static void diagnose(const SwiftDiagnostic& source,
127-
const std::chrono::system_clock::time_point& time,
137+
const std::chrono::nanoseconds& elapsed,
128138
std::string_view message) {
129-
instance().diagnoseImpl(source, time, message);
139+
instance().diagnoseImpl(source, elapsed, message);
130140
}
131141

132142
private:
@@ -145,7 +155,7 @@ class Log {
145155
void configure();
146156
void flushImpl();
147157
void diagnoseImpl(const SwiftDiagnostic& source,
148-
const std::chrono::system_clock::time_point& time,
158+
const std::chrono::nanoseconds& elapsed,
149159
std::string_view message);
150160

151161
LoggerConfiguration getLoggerConfigurationImpl(std::string_view name);
@@ -230,26 +240,6 @@ struct SwiftDiagnosticLogWrapper {
230240
} // namespace detail
231241
} // namespace codeql
232242

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-
253243
namespace mserialize {
254244
// log diagnostics wrapper using the abbreviation of the underlying diagnostic, using
255245
// binlog/mserialize internal plumbing

0 commit comments

Comments
 (0)