Thunderbots Project
Loading...
Searching...
No Matches
logger.h
1#pragma once
2
3#include <g3sinks/LogRotate.h>
4#include <g3sinks/LogRotateWithFilter.h>
5
6#include <experimental/filesystem>
7#include <g3log/g3log.hpp>
8#include <g3log/loglevels.hpp>
9#include <g3log/logmessage.hpp>
10#include <g3log/logworker.hpp>
11
12#include "software/logger/coloured_cout_sink.h"
13#include "software/logger/csv_sink.h"
14#include "software/logger/custom_logging_levels.h"
15#include "software/logger/plotjuggler_sink.h"
16#include "software/logger/protobuf_sink.h"
17
18// This undefines LOG macro defined by g3log
19#undef LOG
20
21// These macros allows us to overload arguments.
22// https://stackoverflow.com/questions/11761703/overloading-macro-on-number-of-arguments
23#define LOG_SELECT(_1, _2, NAME, ...) NAME
24#define LOG(...) LOG_SELECT(__VA_ARGS__, LOG_2, LOG_1)(__VA_ARGS__)
25
26// Called when LOG() is called with 1 argument. This is a copy of g3log's LOG() macro
27// Note: curly braces are not used as we need to pipe log messages to the logger
28#define LOG_1(level) \
29 if (!g3::logLevel(level)) \
30 { \
31 } \
32 else \
33 INTERNAL_LOG_MESSAGE(level).stream()
34
35// Called when LOG() is called with 2 arguments
36#define LOG_2(level, filename) \
37 if (level != CSV && level != VISUALIZE) \
38 { \
39 } \
40 else \
41 LOG_1(level) << filename \
42
53{
54 public:
64 static void initializeLogger(const std::string& runtime_dir,
65 const std::shared_ptr<ProtoLogger>& proto_logger,
66 const bool reduce_repetition = true)
67 {
68 static std::shared_ptr<LoggerSingleton> s(
69 new LoggerSingleton(runtime_dir, proto_logger, reduce_repetition));
70 }
71
72 private:
73 LoggerSingleton(const std::string& runtime_dir,
74 const std::shared_ptr<ProtoLogger>& proto_logger,
75 const bool reduce_repetition)
76 {
77 logWorker = g3::LogWorker::createLogWorker();
78 // Default locations
79 // Full system: bazel-out/k8-fastbuild/bin/software/full_system.runfiles/__main__/
80 // Robot diagnostics:
81 // bazel-out/k8-fastbuild/bin/software/gui/robot_diagnostics/robot_diagnostics_main.runfiles/__main__/
82 // Standalone Simulator:
83 // bazel-out/k8-fastbuild/bin/software/simulation/standalone_simulator_main.runfiles/__main__/
84 // Simulated
85 // tests:bazel-out/k8-fastbuild/bin/software/simulated_tests/TEST_NAME.runfiles/__main__/
86 // where TEST_NAME is the name of the simulated test
87
88 // Log locations can also be defined by setting the --logging_dir command line
89 // arg. Note: log locations are defaulted to the bazel-out folder due to Bazel's
90 // hermetic build principles
91
92 // if log dir doesn't exist, create it
93 if (!std::experimental::filesystem::exists(runtime_dir))
94 {
95 std::experimental::filesystem::create_directories(runtime_dir);
96 }
97
98 auto csv_sink_handle = logWorker->addSink(std::make_unique<CSVSink>(runtime_dir),
100 // Sink for outputting logs to the terminal
101 auto colour_cout_sink_handle = logWorker->addSink(
102 std::make_unique<ColouredCoutSink>(true, reduce_repetition),
104
105 // Sink for storing a file of filtered logs
106 auto filtered_log_rotate_sink_handle = logWorker->addSink(
107 std::make_unique<LogRotateWithFilter>(
108 std::make_unique<LogRotate>(log_name + filter_suffix, runtime_dir),
109 filtered_level_filter),
110 &LogRotateWithFilter::save);
111 // Sink for storing a file of filtered logs (only the default log levels)
112 auto default_log_rotate_sink_handle = logWorker->addSink(
113 std::make_unique<LogRotateWithFilter>(
114 std::make_unique<LogRotate>(log_name, runtime_dir), default_level_filter),
115 &LogRotateWithFilter::save);
116
117 // Sink for visualization
118 auto visualization_handle =
119 logWorker->addSink(std::make_unique<ProtobufSink>(runtime_dir, proto_logger),
120 &ProtobufSink::sendProtobuf);
121
122 // Sink for PlotJuggler plotting
123 auto plotjuggler_handle = logWorker->addSink(std::make_unique<PlotJugglerSink>(),
125
126 g3::initializeLogging(logWorker.get());
127 }
128
129 // levels is this vector are filtered out of the filtered log rotate sink
130 std::vector<LEVELS> filtered_level_filter = {DEBUG, VISUALIZE, CSV, INFO,
131 PLOTJUGGLER};
132 std::vector<LEVELS> default_level_filter = {VISUALIZE, CSV, PLOTJUGGLER};
133 const std::string filter_suffix = "_filtered";
134 const std::string log_name = "thunderbots";
135 std::unique_ptr<g3::LogWorker> logWorker;
136};
void appendToFile(g3::LogMessageMover log_entry)
Definition csv_sink.cpp:11
void displayColouredLog(g3::LogMessageMover log_entry)
Definition coloured_cout_sink.cpp:56
Definition logger.h:44
static void initializeLogger(const std::string &runtime_dir, const std::shared_ptr< ProtoLogger > &proto_logger, const bool reduce_repetition=true)
Definition logger.h:55
void sendToPlotJuggler(g3::LogMessageMover log_entry)
Definition plotjuggler_sink.cpp:13