Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
logging Namespace Reference

Namespace containing all global type/structs that will be used project wide for logging. More...

Namespaces

namespace  graphing
 Namespace containing all global type/structs that will be used project wide for graphing and plotting data with matplotlib. These graphing functions are built to be as feature rich as possible while still being easy to use.
 

Classes

class  LoggingFilter
 This class serves as a container class for handling log filtering of loggers. This must be used if you want each handler to have a different logging level since adding multiple handlers to the same logger will apply the loggers logging level to each handler. More...
 
class  MRDTConsoleSink
 A custom console sink for logging messages with specific formatting and timestamping. This class extends quill::ConsoleSink and provides the capability to format log messages using a specified pattern and time format, allowing for customizable and colorized console outputs. More...
 
class  MRDTRotatingFileSink
 A custom rotating file sink that formats and logs messages to a file with automatic rotation based on file size or time interval. This class extends quill::RotatingFileSink and provides the ability to format log messages using a pattern and time format, ensuring that logs are written to a rotating file system. More...
 
class  MRDTRoveCommSink
 A custom logger sink designed to send formatted log messages over the RoveComm protocol. This class extends quill::Sink and is tailored for use in the Autonomy system, where log messages need to be transmitted as packets over a network to a BaseStation via UDP. More...
 

Functions

void InitializeLoggers (std::string szLoggingOutputPath, std::string szProgramTimeLogsDir)
 Logger Initializer - Sets Up all the logging handlers required for having the above loggers.
 

Variables

quill::Logger * g_qFileLogger
 
quill::Logger * g_qConsoleLogger
 
quill::Logger * g_qRoveCommLogger
 
quill::Logger * g_qSharedLogger
 
quill::LogLevel g_eConsoleLogLevel
 
quill::LogLevel g_eFileLogLevel
 
quill::LogLevel g_eRoveCommLogLevel
 
std::string g_szProgramStartTimeString
 
std::string g_szLoggingOutputPath
 
const std::function< void(const rovecomm::RoveCommPacket< uint8_t > &, const sockaddr_in &)> SetLoggingLevelsCallback
 

Detailed Description

Namespace containing all global type/structs that will be used project wide for logging.

Logging Levels:

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-30
   Priority > Level     > Description
   Level 1  > TRACE_L3  > Unused
   Level 2  > TRACE_L2  > Unused
   Level 3  > TRACE_L1  > Unused
   Level 4  > DEBUG     > Details that would only be useful in a debug environment
   Level 5  > INFO      > State Changes, RoveComm Updates GPS/IMU/Autonomy, etc
   Level 6  > WARNING   > Something unexpected happened - application could potentially error soon.
   Level 7  > ERROR     > Something went wrong - application could potentially have critical error soon.
   Level 8  > CRITICAL  > Something went very wrong - application will exit after logging is sent.

   Note: At testing sessions we will have "DEBUG" Logging set as the level that is being outputted.
         However, at competition and when using "RELEASE" code we will be using "INFO" Logging. When
         a logging level is set, we only receive logging messages that are that level or higher
         priority.

   Example: When INFO is set, we only receive: INFO, WARNING, ERROR, CRITICAL
            When DEBUG is set, we only receive: DEBUG, INFO, WARNING, ERROR, CRITICAL
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2023-08-22
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-08
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-07

Function Documentation

◆ InitializeLoggers()

void logging::InitializeLoggers ( std::string  szLoggingOutputPath,
std::string  szProgramTimeLogsDir 
)

Logger Initializer - Sets Up all the logging handlers required for having the above loggers.

Parameters
szLoggingOutputPath- A string containing the filepath to output log files to. Must be properly formatted.
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2023-08-22
61 {
62 // Store start time string in member variable.
63 g_szProgramStartTimeString = szProgramTimeLogsDir;
64
65 // Assemble filepath string.
66 std::filesystem::path szFilePath;
67 std::filesystem::path szFilename;
68 szFilePath = szLoggingOutputPath; // Main location for all recordings.
69 szFilePath += g_szProgramStartTimeString + "/"; // Folder for each program run.
70 szFilename = "console_output"; // Base file name.
71
72 // Store the logging output path.
73 g_szLoggingOutputPath = szFilePath;
74
75 // Check if directory exists.
76 if (!std::filesystem::exists(szFilePath))
77 {
78 // Create directory.
79 if (!std::filesystem::create_directories(szFilePath))
80 {
81 // Submit logger message.
82 std::cerr << "Unable to create the logging output directory: " << szFilePath.string() << " for console output file." << std::endl;
83 }
84 }
85 else
86 {
87 // Submit logger message.
88 std::cerr << "Unable to create logging output directory " << szFilePath.string() << ": it already exists." << std::endl;
89 }
90
91 // Construct the full output path.
92 std::filesystem::path szFullOutputPath = szFilePath / szFilename;
93
94 // Set Console Color Profile
95 quill::ConsoleSinkConfig::Colours qColors;
96 qColors.apply_default_colours();
97 qColors.assign_colour_to_log_level(quill::LogLevel::TraceL3, constants::szTraceL3Color);
98 qColors.assign_colour_to_log_level(quill::LogLevel::TraceL2, constants::szTraceL2Color);
99 qColors.assign_colour_to_log_level(quill::LogLevel::TraceL1, constants::szTraceL1Color);
100 qColors.assign_colour_to_log_level(quill::LogLevel::Debug, constants::szDebugColor);
101 qColors.assign_colour_to_log_level(quill::LogLevel::Info, constants::szInfoColor);
102 qColors.assign_colour_to_log_level(quill::LogLevel::Warning, constants::szWarningColor);
103 qColors.assign_colour_to_log_level(quill::LogLevel::Error, constants::szErrorColor);
104 qColors.assign_colour_to_log_level(quill::LogLevel::Critical, constants::szCriticalColor);
105 qColors.assign_colour_to_log_level(quill::LogLevel::Backtrace, constants::szBacktraceColor);
106
107 // Create Patterns
108 std::string szLogFilePattern = "%(time) %(log_level) [%(thread_id)] [%(file_name):%(line_number)] %(message)";
109 std::string szCSVFilePattern = "%(time),\t%(log_level),\t[%(thread_id)],\t[%(file_name):%(line_number)],\t\"%(message)\"";
110 std::string szConsolePattern = "%(time) %(log_level:9) [%(thread_id)] [%(file_name):%(line_number)] %(message)";
111 std::string szRoveCommPattern = "%(time) %(log_level) [%(thread_id)] [%(file_name):%(line_number)] %(message)";
112 std::string szTimestampPattern = "%Y-%m-%d %H:%M:%S.%Qms";
113
114 // Create Sinks
115 std::shared_ptr<quill::Sink> qLogFileSink = quill::Frontend::create_or_get_sink<MRDTRotatingFileSink>(
116 szFullOutputPath.replace_extension(".log"), // Log Output Path
117 []()
118 {
119 quill::RotatingFileSinkConfig cfg;
120 cfg.set_open_mode('a');
121 return cfg; // Rotating File Sink Configs
122 }(),
123 szLogFilePattern, // Log Output Pattern
124 szTimestampPattern, // Log Timestamp Pattern
125 quill::Timezone::LocalTime // Log Timezone
126 );
127
128 std::shared_ptr<quill::Sink> qCSVFileSink = quill::Frontend::create_or_get_sink<MRDTRotatingFileSink>(
129 szFullOutputPath.replace_extension(".csv"), // Log Output Path
130 []()
131 {
132 quill::RotatingFileSinkConfig cfg;
133 cfg.set_open_mode('a');
134 return cfg; // Rotating File Sink Configs
135 }(),
136 szCSVFilePattern, // Log Output Pattern
137 szTimestampPattern, // Log Timestamp Pattern
138 quill::Timezone::LocalTime // Log Timezone
139 );
140
141 std::shared_ptr<quill::Sink> qConsoleSink =
142 quill::Frontend::create_or_get_sink<MRDTConsoleSink>("ConsoleSink", // Log Name
143 qColors, // Log Custom Colors
144 quill::ConsoleSinkConfig::ColourMode::Automatic, // Detect is console supports colors.
145 szConsolePattern, // Log Output Pattern
146 szTimestampPattern // Log Timestamp Pattern
147 );
148
149 std::shared_ptr<quill::Sink> qMRDTRoveCommSink = quill::Frontend::create_or_get_sink<MRDTRoveCommSink>("MRDTRoveCommSink", // Log Name
150 szRoveCommPattern, // Log Output Pattern
151 szTimestampPattern, // Log Timestamp Pattern
152 quill::Timezone::LocalTime // Log Timezone
153 );
154
155 // Configure Quill
156 quill::BackendOptions qBackendConfig;
157
158 // Start Quill
159 quill::Backend::start(qBackendConfig);
160
161 // Create Loggers
162 g_qFileLogger = quill::Frontend::create_or_get_logger("FILE_LOGGER", {qLogFileSink, qCSVFileSink});
163 g_qConsoleLogger = quill::Frontend::create_or_get_logger("CONSOLE_LOGGER", {qConsoleSink});
164 g_qRoveCommLogger = quill::Frontend::create_or_get_logger("ROVECOMM_LOGGER", {qMRDTRoveCommSink});
165 g_qSharedLogger = quill::Frontend::create_or_get_logger("SHARED_LOGGER", {qLogFileSink, qCSVFileSink, qConsoleSink, qMRDTRoveCommSink});
166
167 // Set Internal Logging Level Limiters
168 g_eFileLogLevel = constants::FILE_DEFAULT_LEVEL;
169 g_eConsoleLogLevel = constants::CONSOLE_DEFAULT_LEVEL;
170 g_eRoveCommLogLevel = constants::ROVECOMM_DEFAULT_LEVEL;
171
172 // Set Base Logging Levels
173 g_qFileLogger->set_log_level(quill::LogLevel::TraceL3);
174 g_qConsoleLogger->set_log_level(quill::LogLevel::TraceL3);
175 g_qSharedLogger->set_log_level(quill::LogLevel::TraceL3);
176 g_qRoveCommLogger->set_log_level(quill::LogLevel::Info);
177
178 // Enable Backtrace
179 g_qFileLogger->init_backtrace(10, quill::LogLevel::Critical);
180 g_qConsoleLogger->init_backtrace(10, quill::LogLevel::Critical);
181 g_qRoveCommLogger->init_backtrace(10, quill::LogLevel::Critical);
182 g_qSharedLogger->init_backtrace(10, quill::LogLevel::Critical);
183 }
Here is the caller graph for this function:

Variable Documentation

◆ SetLoggingLevelsCallback

const std::function<void(const rovecomm::RoveCommPacket<uint8_t>&, const sockaddr_in&)> logging::SetLoggingLevelsCallback
Initial value:
=
[](const rovecomm::RoveCommPacket<uint8_t>& stPacket, const sockaddr_in& stdAddr)
{
(void) stdAddr;
const int nMinConsoleLevel = static_cast<int>(constants::CONSOLE_MIN_LEVEL);
const int nMinFileLevel = static_cast<int>(constants::FILE_MIN_LEVEL);
const int nMinRoveCommLevel = static_cast<int>(constants::ROVECOMM_MIN_LEVEL);
const int nRequestedConsoleLevel = stPacket.vData[0];
const int nRequestedFileLevel = stPacket.vData[1];
const int nRequestedRoveCommLevel = stPacket.vData[2];
bool bConsoleLevelChangePermitted = nRequestedConsoleLevel >= nMinConsoleLevel;
bool bFileLevelChangePermitted = nRequestedFileLevel >= nMinFileLevel;
bool bRoveCommLevelChangePermitted = nRequestedRoveCommLevel >= nMinRoveCommLevel;
logging::g_eConsoleLogLevel = bConsoleLevelChangePermitted ? static_cast<quill::LogLevel>(stPacket.vData[0]) : logging::g_eConsoleLogLevel;
logging::g_eFileLogLevel = bFileLevelChangePermitted ? static_cast<quill::LogLevel>(stPacket.vData[1]) : logging::g_eFileLogLevel;
logging::g_eRoveCommLogLevel = bRoveCommLevelChangePermitted ? static_cast<quill::LogLevel>(stPacket.vData[2]) : logging::g_eRoveCommLogLevel;
LOG_INFO(logging::g_qSharedLogger, "Incoming SETLOGGINGLEVELS: [Console: {}, File: {}, RoveComm: {}]", stPacket.vData[0], stPacket.vData[1], stPacket.vData[2]);
}
Namespace containing all global type/structs that will be used project wide for logging.
Definition AutonomyLogging.cpp:34
99 {
100 // Not using this.
101 (void) stdAddr;
102
103 // Convert Minimum Permitted Console Level to Integer Value
104 const int nMinConsoleLevel = static_cast<int>(constants::CONSOLE_MIN_LEVEL);
105 const int nMinFileLevel = static_cast<int>(constants::FILE_MIN_LEVEL);
106 const int nMinRoveCommLevel = static_cast<int>(constants::ROVECOMM_MIN_LEVEL);
107
108 // Convert Requested Console Level to Integer Value
109 const int nRequestedConsoleLevel = stPacket.vData[0];
110 const int nRequestedFileLevel = stPacket.vData[1];
111 const int nRequestedRoveCommLevel = stPacket.vData[2];
112
113 // Determine if change is allowed
114 bool bConsoleLevelChangePermitted = nRequestedConsoleLevel >= nMinConsoleLevel;
115 bool bFileLevelChangePermitted = nRequestedFileLevel >= nMinFileLevel;
116 bool bRoveCommLevelChangePermitted = nRequestedRoveCommLevel >= nMinRoveCommLevel;
117
118 // Convert RoveComm Enumeration to Quill Enumeration and store to logging globals if permitted
119 logging::g_eConsoleLogLevel = bConsoleLevelChangePermitted ? static_cast<quill::LogLevel>(stPacket.vData[0]) : logging::g_eConsoleLogLevel;
120 logging::g_eFileLogLevel = bFileLevelChangePermitted ? static_cast<quill::LogLevel>(stPacket.vData[1]) : logging::g_eFileLogLevel;
121 logging::g_eRoveCommLogLevel = bRoveCommLevelChangePermitted ? static_cast<quill::LogLevel>(stPacket.vData[2]) : logging::g_eRoveCommLogLevel;
122
123 // Submit logger message.
124 LOG_INFO(logging::g_qSharedLogger, "Incoming SETLOGGINGLEVELS: [Console: {}, File: {}, RoveComm: {}]", stPacket.vData[0], stPacket.vData[1], stPacket.vData[2]);
125 };