-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor logging and allow setting a minimum log level that should no…
…t be emitted (#161) This pulls the logging code out into its own class as it was getting more complex. It also allows limiting sending of logs from a reactor. Sending out every trace message was causing a lot of overhead. Now there are two variables in each reactor, one to describe the displayed log level `log_level` and one to describe the minimum emitted log level `min_log_level`
- Loading branch information
1 parent
2b46a4d
commit 8496dca
Showing
8 changed files
with
382 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#include "Logger.hpp" | ||
|
||
#include "../Reactor.hpp" | ||
#include "../dsl/word/emit/Inline.hpp" | ||
#include "../message/LogMessage.hpp" | ||
#include "../threading/ReactionTask.hpp" | ||
|
||
namespace NUClear { | ||
namespace util { | ||
|
||
/** | ||
* Get the current reactor that is running based on the passed in reactor, or the current task if not in a reactor. | ||
* | ||
* @param calling_reactor The reactor that is calling this function or nullptr if not called from a reactor | ||
* | ||
* @return The current reactor or nullptr if not in a reactor | ||
*/ | ||
const Reactor* get_current_reactor(const Reactor* calling_reactor) { | ||
if (calling_reactor != nullptr) { | ||
return calling_reactor; | ||
} | ||
// Get the current task | ||
const auto* const current_task = threading::ReactionTask::get_current_task(); | ||
return current_task != nullptr && current_task->parent != nullptr ? ¤t_task->parent->reactor : nullptr; | ||
} | ||
|
||
Logger::LogLevels Logger::get_current_log_levels(const Reactor* calling_reactor) { | ||
// Get the current reactor either from the passed in reactor or the current task | ||
const auto* reactor = get_current_reactor(calling_reactor); | ||
return reactor != nullptr ? LogLevels(reactor->log_level, reactor->min_log_level) | ||
: LogLevels(LogLevel::UNKNOWN, LogLevel::UNKNOWN); | ||
} | ||
|
||
void Logger::do_log(const Reactor* calling_reactor, const LogLevel& level, const std::string& message) { | ||
// Get the current context | ||
const auto* reactor = get_current_reactor(calling_reactor); | ||
const auto* current_task = threading::ReactionTask::get_current_task(); | ||
auto log_levels = get_current_log_levels(reactor); | ||
|
||
// Inline emit the log message to default handlers to pause the current task until the log message is processed | ||
powerplant.emit<dsl::word::emit::Inline>( | ||
std::make_unique<message::LogMessage>(level, | ||
log_levels.display_log_level, | ||
message, | ||
reactor != nullptr ? reactor->reactor_name : "", | ||
current_task != nullptr ? current_task->statistics : nullptr)); | ||
} | ||
} // namespace util | ||
} // namespace NUClear |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* MIT License | ||
* | ||
* Copyright (c) 2013 NUClear Contributors | ||
* | ||
* This file is part of the NUClear codebase. | ||
* See https://github.com/Fastcode/NUClear for further info. | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated | ||
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the | ||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to | ||
* permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the | ||
* Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
|
||
#ifndef NUCLEAR_UTIL_LOGGER_HPP | ||
#define NUCLEAR_UTIL_LOGGER_HPP | ||
|
||
#include <sstream> | ||
#include <utility> | ||
|
||
#include "../LogLevel.hpp" | ||
#include "string_join.hpp" | ||
|
||
namespace NUClear { | ||
|
||
// Forward declarations | ||
class PowerPlant; | ||
class Reactor; | ||
|
||
namespace util { | ||
|
||
/** | ||
* The Logger class is used to handle converting the variardic log calls into an appropriate log message. | ||
* | ||
* It's also responsible for working out which messages should be emitted and which should be ignored. | ||
*/ | ||
class Logger { | ||
public: | ||
Logger(PowerPlant& powerplant) : powerplant(powerplant) {} | ||
|
||
/** | ||
* Log a message to the system. | ||
* | ||
* This function will check if a log message should be emitted based on the current log levels and then emit the | ||
* log message. | ||
*/ | ||
template <typename... Arguments> | ||
void log(const Reactor* reactor, const LogLevel& level, const Arguments&... args) { | ||
// Check if the log level is above the minimum log levels | ||
auto log_levels = get_current_log_levels(reactor); | ||
if (level >= log_levels.display_log_level || level >= log_levels.min_log_level) { | ||
// Collapse the arguments into a string and perform the log action | ||
do_log(reactor, level, string_join(" ", std::forward<const Arguments&>(args)...)); | ||
} | ||
} | ||
|
||
private: | ||
/** | ||
* Describes the log levels for a particular reactor. | ||
*/ | ||
struct LogLevels { | ||
LogLevels(LogLevel display_log_level, LogLevel min_log_level) | ||
: display_log_level(display_log_level), min_log_level(min_log_level) {} | ||
|
||
/// The log level that should be displayed | ||
LogLevel display_log_level; | ||
/// The minimum log level that should be emitted | ||
LogLevel min_log_level; | ||
}; | ||
|
||
/** | ||
* Get the log levels for the current reactor or UNKNOWN if not in a reactor. | ||
*/ | ||
static LogLevels get_current_log_levels(const Reactor* reactor); | ||
|
||
/** | ||
* Perform the log action and emit the log message. | ||
*/ | ||
void do_log(const Reactor* reactor, const LogLevel& level, const std::string& message); | ||
|
||
/// The powerplant that this logger is logging for, used for emitting log messages | ||
PowerPlant& powerplant; | ||
}; | ||
|
||
} // namespace util | ||
} // namespace NUClear | ||
|
||
#endif // NUCLEAR_UTIL_LOGGER_HPP |
Oops, something went wrong.