-
Notifications
You must be signed in to change notification settings - Fork 158
/
user_clock_source.cpp
83 lines (70 loc) · 2.75 KB
/
user_clock_source.cpp
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
#include "quill/Backend.h"
#include "quill/Frontend.h"
#include "quill/LogMacros.h"
#include "quill/Logger.h"
#include "quill/UserClockSource.h"
#include "quill/sinks/ConsoleSink.h"
#include <atomic>
#include <chrono>
#include <cstdint>
#include <utility>
/**
* Example demonstrating custom clock usage for logging. This is particularly useful
* when simulating events from a specific time period, allowing logs to align with
* the simulated time.
*/
/**
* This class needs to be thread-safe, unless only a single thread in the application calling
* LOG_ macros from the same logger
*/
class SimulatedClock : public quill::UserClockSource
{
public:
SimulatedClock() = default;
/**
* Required by TimestampClock
* @return current time now, in nanoseconds since epoch
*/
uint64_t now() const override { return _timestamp_ns.load(std::memory_order_relaxed); }
/**
* set custom timestamp
* @param time_since_epoch timestamp
*/
void set_timestamp(std::chrono::seconds time_since_epoch)
{
// always convert to nanos
_timestamp_ns.store(static_cast<uint64_t>(std::chrono::nanoseconds{time_since_epoch}.count()),
std::memory_order_relaxed);
}
private:
std::atomic<uint64_t> _timestamp_ns{0}; // time since epoch - must always be in nanoseconds
};
int main()
{
// Start the backend thread
quill::BackendOptions backend_options;
quill::Backend::start(backend_options);
// Create a simulated timestamp class. Quill takes a pointer to this class,
// and the user is responsible for its lifetime.
// Ensure that the instance of this class remains alive for as long as the logger
// object exists, until the logger is removed.
SimulatedClock simulated_clock;
// Get the console sink and also create a logger using the simulated clock
auto console_sink = quill::Frontend::create_or_get_sink<quill::ConsoleSink>("sink_id_1");
quill::Logger* logger = quill::Frontend::create_or_get_logger(
"root", std::move(console_sink),
quill::PatternFormatterOptions{
"%(time) %(short_source_location:<28) LOG_%(log_level:<9) %(logger:<12) %(message)",
"%D %H:%M:%S.%Qns", quill::Timezone::LocalTime, false},
quill::ClockSourceType::User, &simulated_clock);
// Change the LogLevel to print everything
logger->set_log_level(quill::LogLevel::TraceL3);
// Set our timestamp to Sunday 12 June 2022
simulated_clock.set_timestamp(std::chrono::seconds{1655007309});
LOG_TRACE_L3(logger, "This is a log trace l3 example {}", 1);
LOG_TRACE_L2(logger, "This is a log trace l2 example {} {}", 2, 2.3);
// update our timestamp
simulated_clock.set_timestamp(std::chrono::seconds{1655039000});
LOG_INFO(logger, "This is a log info {} example", "string");
LOG_DEBUG(logger, "This is a log debug example {}", 4);
}