M module-cellular/modem/mux/CellularMux.cpp => module-cellular/modem/mux/CellularMux.cpp +3 -6
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "CellularMux.h"
@@ 554,7 554,6 @@ void CellularMux::processData(bsp::cellular::CellularDMAResultStruct &result)
LOG_DEBUG("DMA buffer full");
[[fallthrough]];
case bsp::cellular::CellularResultCode::ReceivedAfterFull:
- [[fallthrough]];
case bsp::cellular::CellularResultCode::ReceivedAndIdle:
inst->processData(result);
break;
@@ 562,9 561,7 @@ void CellularMux::processData(bsp::cellular::CellularDMAResultStruct &result)
LOG_DEBUG("DMA uninitialized");
[[fallthrough]];
case bsp::cellular::CellularResultCode::ReceivingNotStarted:
- [[fallthrough]];
case bsp::cellular::CellularResultCode::TransmittingNotStarted:
- [[fallthrough]];
case bsp::cellular::CellularResultCode::CMUXFrameError:
LOG_DEBUG("CellularResult Error: %s", c_str(result.resultCode));
inst->processError(result);
@@ 792,7 789,7 @@ void CellularMux::closeChannels()
bool CellularMux::searchATCommandResponse(const std::vector<std::string> &response,
const std::string &str,
size_t numberOfExpectedTokens,
- logger_level level)
+ LoggerLevel level)
{
const size_t numberOfTokens = response.size();
if (searchForString(response, str) && (numberOfExpectedTokens == 0 || numberOfTokens == numberOfExpectedTokens)) {
@@ 838,7 835,7 @@ const std::unique_ptr<ATParser> &CellularMux::getParser() const
return parser;
}
-bool CellularMux::checkATCommandPrompt(const std::vector<std::string> &response, logger_level level)
+bool CellularMux::checkATCommandPrompt(const std::vector<std::string> &response, LoggerLevel level)
{
return searchATCommandResponse(response, ">", 0, level);
}
M module-cellular/modem/mux/CellularMux.h => module-cellular/modem/mux/CellularMux.h +3 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 323,7 323,7 @@ class CellularMux
bool searchATCommandResponse(const std::vector<std::string> &response,
const std::string &str,
size_t numberOfExpectedTokens,
- logger_level level);
+ LoggerLevel level);
bool searchForString(const std::vector<std::string> &response, const std::string &str);
/// @brief It is serching the resposne for ">" string
@@ 333,7 333,7 @@ class CellularMux
/// @param response - tokenized resposne
/// @param level - determine how the errors are logged
/// @return true - str string is found, false - otherwise
- bool checkATCommandPrompt(const std::vector<std::string> &response, logger_level level = LOGERROR);
+ bool checkATCommandPrompt(const std::vector<std::string> &response, LoggerLevel level = LOGERROR);
void selectAntenna(bsp::cellular::antenna antenna);
[[nodiscard]] bsp::cellular::antenna getAntenna();
M module-utils/log/Logger.cpp => module-utils/log/Logger.cpp +118 -91
@@ 23,29 23,29 @@ namespace Log
return stream;
}
- Logger::Logger() : buffer{}, rotator{".log"}
+ Logger::Logger() : rotator{".log"}, streamBuffer{std::make_unique<char[]>(streamBufferSize)}
{
filtered = {
- {"ApplicationManager", logger_level::LOGINFO},
- {"CellularMux", logger_level::LOGINFO},
+ {"ApplicationManager", LoggerLevel::LOGINFO},
+ {"CellularMux", LoggerLevel::LOGINFO},
#if (!LOG_SENSITIVE_DATA_ENABLED)
- {"ServiceCellular", logger_level::LOGINFO},
+ {"ServiceCellular", LoggerLevel::LOGINFO},
#endif
- {"ServiceAntenna", logger_level::LOGERROR},
- {"ServiceAudio", logger_level::LOGINFO},
- {"ServiceBluetooth", logger_level::LOGINFO},
- {"ServiceBluetooth_w1", logger_level::LOGINFO},
- {"ServiceFota", logger_level::LOGINFO},
- {"ServiceEink", logger_level::LOGINFO},
- {"ServiceDB", logger_level::LOGINFO},
- {CRIT_STR, logger_level::LOGTRACE},
- {IRQ_STR, logger_level::LOGTRACE},
- {"FileIndexer", logger_level::LOGINFO},
- {"EventManager", logger_level::LOGINFO}
+ {"ServiceAntenna", LoggerLevel::LOGERROR},
+ {"ServiceAudio", LoggerLevel::LOGINFO},
+ {"ServiceBluetooth", LoggerLevel::LOGINFO},
+ {"ServiceBluetooth_w1", LoggerLevel::LOGINFO},
+ {"ServiceFota", LoggerLevel::LOGINFO},
+ {"ServiceEink", LoggerLevel::LOGINFO},
+ {"ServiceDB", LoggerLevel::LOGINFO},
+ {CRIT_STR, LoggerLevel::LOGTRACE},
+ {IRQ_STR, LoggerLevel::LOGTRACE},
+ {"FileIndexer", LoggerLevel::LOGINFO},
+ {"EventManager", LoggerLevel::LOGINFO}
};
- std::list<sys::WorkerQueueInfo> queueInfo{
- {LoggerWorker::SignalQueueName, LoggerWorker::SignalSize, LoggerWorker::SignalQueueLenght}};
+ const std::list<sys::WorkerQueueInfo> queueInfo{
+ {LoggerWorker::SignalQueueName, LoggerWorker::SignalSize, LoggerWorker::SignalQueueLength}};
worker = std::make_unique<LoggerWorker>(Log::workerName);
worker->init(queueInfo);
worker->run();
@@ 65,38 65,38 @@ namespace Log
void Logger::destroyInstance()
{
-
delete _logger;
_logger = nullptr;
}
Logger &Logger::get()
{
- static auto *logger = new Logger;
- _logger = logger;
- return *logger;
+ if (_logger == nullptr) {
+ _logger = new Logger;
+ }
+ return *_logger;
}
- auto Logger::getLogLevel(const std::string &name) -> logger_level
+ LoggerLevel Logger::getLogLevel(const std::string &name)
{
return filtered[name];
}
- auto Logger::getLogs() -> std::string
+ std::string Logger::getLogs()
{
LockGuard lock(mutex);
std::string logs;
while (!buffer.getFlushBuffer()->isEmpty()) {
- const auto [result, msg] = buffer.getFlushBuffer()->get();
- if (result) {
- logs += msg;
+ const auto msg = buffer.getFlushBuffer()->get();
+ if (msg.has_value()) {
+ logs += msg.value();
}
}
return logs;
}
- void Logger::init(Application app, size_t fileSize)
+ void Logger::init(Application app, std::size_t fileSize)
{
application = std::move(app);
maxFileSize = fileSize;
@@ 117,70 117,80 @@ namespace Log
writeLogsTimer.start();
}
- auto Logger::log(Device device, const char *fmt, va_list args) -> int
+ int Logger::log(Device device, const char *fmt, va_list args)
{
LockGuard lock(mutex);
- loggerBufferCurrentPos = 0;
+ lineBufferCurrentPos = 0;
return writeLog(device, fmt, args);
}
- auto Logger::log(
- logger_level level, const char *file, int line, const char *function, const char *fmt, va_list args) -> int
+ int Logger::log(LoggerLevel level, const char *file, int line, const char *function, const char *fmt, va_list args)
{
if (!filterLogs(level)) {
return -1;
}
LockGuard lock(mutex);
- loggerBufferCurrentPos = 0;
+ lineBufferCurrentPos = 0;
addLogHeader(level, file, line, function);
return writeLog(Device::DEFAULT, fmt, args);
}
- auto Logger::writeLog(Device device, const char *fmt, va_list args) -> int
+ [[nodiscard]] std::size_t Logger::lineBufferSizeLeft() const noexcept
+ {
+ const auto sizeLeft = LINE_BUFFER_SIZE - lineBufferCurrentPos;
+ assert(sizeLeft > 0);
+ return sizeLeft;
+ }
+
+ int Logger::writeLog(Device device, const char *fmt, va_list args)
{
- const auto sizeLeft = loggerBufferSizeLeft();
- const auto result = vsnprintf(&loggerBuffer[loggerBufferCurrentPos], sizeLeft, fmt, args);
- if (0 <= result) {
- const auto numOfBytesAddedToBuffer = static_cast<size_t>(result);
- loggerBufferCurrentPos += (numOfBytesAddedToBuffer < sizeLeft) ? numOfBytesAddedToBuffer : (sizeLeft - 1);
- loggerBufferCurrentPos += snprintf(&loggerBuffer[loggerBufferCurrentPos], loggerBufferSizeLeft(), "\n");
-
- logToDevice(Device::DEFAULT, loggerBuffer, loggerBufferCurrentPos);
- buffer.getCurrentBuffer()->put(std::string(loggerBuffer, loggerBufferCurrentPos));
+ constexpr auto lineTerminationString = "\n";
+ constexpr auto lineTerminationLength = 2; // '\n' + null-terminator
+
+ const auto bufferSizeLeft = lineBufferSizeLeft();
+ const auto bytesParsed = vsnprintf(&lineBuffer[lineBufferCurrentPos], bufferSizeLeft, fmt, args);
+ if (bytesParsed >= 0) {
+ /* Leave space for line termination */
+ lineBufferCurrentPos +=
+ std::min(bufferSizeLeft - lineTerminationLength, static_cast<std::size_t>(bytesParsed));
+ /* Terminate the line */
+ lineBufferCurrentPos +=
+ snprintf(&lineBuffer[lineBufferCurrentPos], lineBufferSizeLeft(), lineTerminationString);
+ /* Write the line to device and to the buffer */
+ logToDevice(Device::DEFAULT, lineBuffer, lineBufferCurrentPos);
+ buffer.getCurrentBuffer()->put(std::string(lineBuffer, lineBufferCurrentPos));
checkBufferState();
- return loggerBufferCurrentPos;
+ return lineBufferCurrentPos;
}
return -1;
}
- auto Logger::logAssert(const char *fmt, va_list args) -> int
+ int Logger::logAssert(const char *fmt, va_list args)
{
LockGuard lock(mutex);
-
logToDevice(fmt, args);
-
- return loggerBufferCurrentPos;
+ return lineBufferCurrentPos;
}
/// @param logPath: file path to store the log
/// @return: < 0 - error occured during log flush
/// @return: 0 - log flush did not happen
/// @return: 1 - log flush successflul
- auto Logger::dumpToFile(std::filesystem::path logPath, bool isLoggerRunning) -> int
+ int Logger::dumpToFile(const std::filesystem::path &logPath, LoggerState loggerState)
{
std::error_code errorCode;
auto firstDump = !std::filesystem::exists(logPath, errorCode);
if (errorCode) {
- if (isLoggerRunning) {
- LOG_ERROR("Failed to check if file %s exists, error: %d", logPath.c_str(), errorCode.value());
+ if (loggerState == LoggerState::RUNNING) {
+ LOG_ERROR("Failed to check if file '%s' exists, error: %d!", logPath.c_str(), errorCode.value());
}
return -EIO;
}
- if (const bool maxSizeExceeded = !firstDump && std::filesystem::file_size(logPath) > maxFileSize;
+ if (const auto maxSizeExceeded = (!firstDump && (std::filesystem::file_size(logPath) > maxFileSize));
maxSizeExceeded) {
- if (isLoggerRunning) {
+ if (loggerState == LoggerState::RUNNING) {
LOG_DEBUG("Max log file size exceeded. Rotating log files...");
}
@@ 191,56 201,62 @@ namespace Log
firstDump = true;
}
- int status = 1;
{
const auto &logs = getLogs();
LockGuard lock(logFileMutex);
- std::ofstream logFile(logPath, std::fstream::out | std::fstream::app);
- if (!logFile.good()) {
- status = -EIO;
- }
+ std::ofstream logFile;
- constexpr size_t streamBufferSize = 64 * 1024;
- auto streamBuffer = std::make_unique<char[]>(streamBufferSize);
+ /* In some implementations pubsetbuf has to be called before opening a stream to be effective */
logFile.rdbuf()->pubsetbuf(streamBuffer.get(), streamBufferSize);
+ logFile.open(logPath, std::fstream::out | std::fstream::app);
+ if (!logFile.good()) {
+ if (loggerState == LoggerState::RUNNING) {
+ LOG_ERROR("Failed to open log file '%s'!", logPath.c_str());
+ }
+ return -EIO;
+ }
+
if (firstDump) {
addFileHeader(logFile);
}
logFile.write(logs.data(), logs.size());
if (logFile.bad()) {
- status = -EIO;
+ if (loggerState == LoggerState::RUNNING) {
+ LOG_ERROR("Failed to flush logs to file '%s'!", logPath.c_str());
+ }
+ return -EIO;
}
}
- if (isLoggerRunning) {
- LOG_DEBUG("Flush ended with status: %d", status);
+ if (loggerState == LoggerState::RUNNING) {
+ LOG_DEBUG("Flush to file '%s' ended successfully!", logPath.c_str());
}
- return status;
+ return statusSuccess;
}
- auto Logger::diagnosticDump() -> int
+ int Logger::diagnosticDump()
{
buffer.nextBuffer();
worker->notify(LoggerWorker::Signal::DumpDiagnostic);
writeLogsTimer.restart(writeLogsToFileInterval);
- return 1;
+ return statusSuccess;
}
- auto Logger::flushLogs() -> int
+ int Logger::flushLogs()
{
LOG_INFO("Shutdown dump logs");
worker->close();
writeLogsTimer.stop();
buffer.nextBuffer();
- return dumpToFile(purefs::dir::getLogsPath() / LOG_FILE_NAME, false);
+ return dumpToFile(purefs::dir::getLogsPath() / LOG_FILE_NAME, LoggerState::STOPPED);
}
void Logger::checkBufferState()
{
- auto size = buffer.getCurrentBuffer()->getSize();
+ const auto size = buffer.getCurrentBuffer()->getSize();
if (size >= buffer.getCircularBufferSize()) {
worker->notify(LoggerWorker::Signal::DumpFilledBuffer);
@@ 256,35 272,46 @@ namespace Log
const char *getTaskDesc()
{
- return xTaskGetCurrentTaskHandle() == nullptr ? Log::Logger::CRIT_STR
- : xPortIsInsideInterrupt() ? Log::Logger::IRQ_STR
- : pcTaskGetName(xTaskGetCurrentTaskHandle());
+ if (xTaskGetCurrentTaskHandle() == nullptr) {
+ return Log::Logger::CRIT_STR;
+ }
+ if (xPortIsInsideInterrupt() == pdTRUE) {
+ return Log::Logger::IRQ_STR;
+ }
+ return pcTaskGetName(xTaskGetCurrentTaskHandle());
}
- bool Logger::filterLogs(logger_level level)
+ bool Logger::filterLogs(LoggerLevel level)
{
return getLogLevel(getTaskDesc()) <= level;
}
- void Logger::addLogHeader(logger_level level, const char *file, int line, const char *function)
+ void Logger::addLogHeader(LoggerLevel level, const char *file, int line, const char *function)
{
- loggerBufferCurrentPos += snprintf(&loggerBuffer[loggerBufferCurrentPos],
- LOGGER_BUFFER_SIZE - loggerBufferCurrentPos,
- "%" PRIu32 " ms ",
- cpp_freertos::Ticks::TicksToMs(cpp_freertos::Ticks::GetTicks()));
-
- loggerBufferCurrentPos += snprintf(&loggerBuffer[loggerBufferCurrentPos],
- LOGGER_BUFFER_SIZE - loggerBufferCurrentPos,
- "%s%-5s %s[%s] %s%s:%s:%d:%s ",
- logColors->levelColors[level].data(),
- levelNames[level],
- logColors->serviceNameColor.data(),
- getTaskDesc(),
- logColors->callerInfoColor.data(),
- file,
- function,
- line,
- logColors->resetColor.data());
- }
+ auto bufferSizeLeft = lineBufferSizeLeft();
+ auto bytesParsed = snprintf(&lineBuffer[lineBufferCurrentPos],
+ bufferSizeLeft,
+ "%" PRIu32 " ms ",
+ cpp_freertos::Ticks::TicksToMs(cpp_freertos::Ticks::GetTicks()));
+ if (bytesParsed >= 0) {
+ lineBufferCurrentPos += std::min(bufferSizeLeft, static_cast<std::size_t>(bytesParsed));
+ }
+ bufferSizeLeft = lineBufferSizeLeft();
+ bytesParsed = snprintf(&lineBuffer[lineBufferCurrentPos],
+ bufferSizeLeft,
+ "%s%-5s %s[%s] %s%s:%s:%d:%s ",
+ logColors->levelColors[level].data(),
+ levelNames[level],
+ logColors->serviceNameColor.data(),
+ getTaskDesc(),
+ logColors->callerInfoColor.data(),
+ file,
+ function,
+ line,
+ logColors->resetColor.data());
+ if (bytesParsed >= 0) {
+ lineBufferCurrentPos += std::min(bufferSizeLeft, static_cast<std::size_t>(bytesParsed));
+ }
+ }
} // namespace Log
M module-utils/log/Logger.hpp => module-utils/log/Logger.hpp +31 -29
@@ 24,6 24,12 @@ namespace Log
SEGGER_RTT
};
+ enum class LoggerState
+ {
+ STOPPED,
+ RUNNING
+ };
+
struct Application
{
std::string name;
@@ 36,19 42,18 @@ namespace Log
class Logger
{
public:
- void enableColors(bool enable);
[[nodiscard]] static Logger &get();
+ void enableColors(bool enable);
static void destroyInstance();
- auto getLogs() -> std::string;
- void init(Application app, size_t fileSize = MAX_LOG_FILE_SIZE);
+ std::string getLogs();
+ void init(Application app, std::size_t fileSize = MAX_LOG_FILE_SIZE);
void createTimer(sys::Service *parent);
- auto log(Device device, const char *fmt, va_list args) -> int;
- auto log(logger_level level, const char *file, int line, const char *function, const char *fmt, va_list args)
- -> int;
- auto logAssert(const char *fmt, va_list args) -> int;
- auto dumpToFile(std::filesystem::path logPath, bool isLoggerRunning = true) -> int;
- auto diagnosticDump() -> int;
- auto flushLogs() -> int;
+ int log(Device device, const char *fmt, va_list args);
+ int log(LoggerLevel level, const char *file, int line, const char *function, const char *fmt, va_list args);
+ int logAssert(const char *fmt, va_list args);
+ int dumpToFile(const std::filesystem::path &logPath, LoggerState loggerState = LoggerState::RUNNING);
+ int diagnosticDump();
+ int flushLogs();
static constexpr auto CRIT_STR = "CRIT";
static constexpr auto IRQ_STR = "IRQ";
@@ 56,37 61,29 @@ namespace Log
private:
Logger();
- void addLogHeader(logger_level level,
- const char *file = nullptr,
- int line = -1,
- const char *function = nullptr);
- [[nodiscard]] bool filterLogs(logger_level level);
+ void addLogHeader(LoggerLevel level, const char *file = nullptr, int line = -1, const char *function = nullptr);
+ [[nodiscard]] bool filterLogs(LoggerLevel level);
/// Filter out not interesting logs via thread Name
/// its' using fact that:
/// - TRACE is level 0, for unedfined lookups it will be alvways trace
/// - it will be one time init for apps which doesn't tell what level they should have
/// - for others it will be o1 lookup so it's fine
- [[nodiscard]] auto getLogLevel(const std::string &name) -> logger_level;
+ [[nodiscard]] LoggerLevel getLogLevel(const std::string &name);
void logToDevice(const char *fmt, va_list args);
- void logToDevice(Device device, std::string_view logMsg, size_t length);
- auto writeLog(Device device, const char *fmt, va_list args) -> int;
- [[nodiscard]] size_t loggerBufferSizeLeft() const noexcept
- {
- const auto sizeLeft = LOGGER_BUFFER_SIZE - loggerBufferCurrentPos;
- assert(sizeLeft > 0);
- return sizeLeft;
- }
+ void logToDevice(Device device, const char *logMsg, std::size_t length);
+ int writeLog(Device device, const char *fmt, va_list args);
+ std::size_t lineBufferSizeLeft() const noexcept;
void addFileHeader(std::ofstream &file) const;
void checkBufferState();
cpp_freertos::MutexStandard mutex;
cpp_freertos::MutexStandard logFileMutex;
- logger_level level{LOGTRACE};
+ LoggerLevel loggerLevel{LOGTRACE};
const LogColors *logColors = &logColorsOff;
- char loggerBuffer[LOGGER_BUFFER_SIZE] = {0};
- size_t loggerBufferCurrentPos = 0;
- size_t maxFileSize = MAX_LOG_FILE_SIZE;
+ char lineBuffer[LINE_BUFFER_SIZE] = {0};
+ std::size_t lineBufferCurrentPos = 0;
+ std::size_t maxFileSize = MAX_LOG_FILE_SIZE;
Application application;
@@ 97,9 94,14 @@ namespace Log
sys::TimerHandle writeLogsTimer;
static const char *levelNames[];
- std::map<std::string, logger_level> filtered;
+ std::map<std::string, LoggerLevel> filtered;
static Logger *_logger;
std::unique_ptr<LoggerWorker> worker;
+
+ static constexpr int statusSuccess = 1;
+
+ static constexpr std::size_t streamBufferSize = 64 * 1024;
+ std::unique_ptr<char[]> streamBuffer;
};
const char *getTaskDesc();
M module-utils/log/LoggerBuffer.cpp => module-utils/log/LoggerBuffer.cpp +14 -10
@@ 1,19 1,19 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "LoggerBuffer.hpp"
-std::pair<bool, std::string> LoggerBuffer::get()
+std::optional<std::string> LoggerBuffer::get()
{
- auto [result, logMsg] = StringCircularBuffer::get();
- if (!result) {
- return {result, logMsg};
+ auto logMsg = StringCircularBuffer::get();
+ if (!logMsg.has_value()) {
+ return std::nullopt;
}
if (numOfLostBytes > 0) {
- logMsg = std::to_string(numOfLostBytes) + " " + lostBytesMessage + "\n" + logMsg;
+ logMsg = std::to_string(numOfLostBytes) + " " + lostBytesMessage + "\n" + logMsg.value();
numOfLostBytes = 0;
}
- return {true, logMsg};
+ return logMsg;
}
void LoggerBuffer::put(const std::string &logMsg)
@@ 30,8 30,12 @@ void LoggerBuffer::put(std::string &&logMsg)
void LoggerBuffer::updateNumOfLostBytes()
{
- if (StringCircularBuffer::isFull()) {
- auto [_, lostMsg] = StringCircularBuffer::get();
- numOfLostBytes += lostMsg.length();
+ if (!StringCircularBuffer::isFull()) {
+ return;
+ }
+
+ const auto lostMsg = StringCircularBuffer::get();
+ if (lostMsg.has_value()) {
+ numOfLostBytes += lostMsg.value().length();
}
}
M module-utils/log/LoggerBuffer.hpp => module-utils/log/LoggerBuffer.hpp +3 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 11,11 11,11 @@ class LoggerBuffer : public StringCircularBuffer
explicit LoggerBuffer(size_t size) : StringCircularBuffer(size)
{}
- [[nodiscard]] std::pair<bool, std::string> get();
+ [[nodiscard]] std::optional<std::string> get();
void put(const std::string &logMsg);
void put(std::string &&logMsg);
- static constexpr auto lostBytesMessage = "bytes was lost.";
+ static constexpr auto lostBytesMessage = "bytes were lost.";
private:
void updateNumOfLostBytes();
M module-utils/log/LoggerWorker.cpp => module-utils/log/LoggerWorker.cpp +2 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "LoggerWorker.hpp"
@@ 9,7 9,7 @@
namespace Log
{
- LoggerWorker::LoggerWorker(const std::string name) : Worker(name, priority)
+ LoggerWorker::LoggerWorker(const std::string &name) : Worker(name, priority)
{}
void LoggerWorker::notify(Signal command)
M module-utils/log/LoggerWorker.hpp => module-utils/log/LoggerWorker.hpp +3 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 21,9 21,9 @@ namespace Log
static constexpr auto SignalQueueName = "LoggerSignal";
static constexpr auto SignalSize = sizeof(Signal);
- static constexpr auto SignalQueueLenght = 1;
+ static constexpr auto SignalQueueLength = 1;
- explicit LoggerWorker(const std::string name);
+ explicit LoggerWorker(const std::string &name);
void notify(Signal command);
bool handleMessage(std::uint32_t queueID) override;
void handleCommand(Signal command);
M module-utils/log/StringCircularBuffer.cpp => module-utils/log/StringCircularBuffer.cpp +6 -5
@@ 1,20 1,21 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "StringCircularBuffer.hpp"
-std::pair<bool, std::string> StringCircularBuffer::get()
+std::optional<std::string> StringCircularBuffer::get()
{
if (isEmpty()) {
- return {false, ""};
+ return std::nullopt;
}
- const std::string val = buffer[tail];
+ const auto val = buffer[tail];
+
full = false;
tail = (tail + 1) % capacity;
--size;
- return {true, val};
+ return val;
}
void StringCircularBuffer::put(const std::string &item)
M module-utils/log/StringCircularBuffer.hpp => module-utils/log/StringCircularBuffer.hpp +3 -2
@@ 1,10 1,11 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
#include <memory>
#include <string>
+#include <optional>
class StringCircularBuffer
{
@@ 19,7 20,7 @@ class StringCircularBuffer
{
return size == 0;
}
- [[nodiscard]] virtual std::pair<bool, std::string> get();
+ [[nodiscard]] virtual std::optional<std::string> get();
[[nodiscard]] size_t getSize() const noexcept
{
return size;
M module-utils/log/api/log/log.hpp => module-utils/log/api/log/log.hpp +4 -4
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
/*
@@ 53,14 53,14 @@ extern "C"
LOGWARN,
LOGERROR,
LOGFATAL
- } logger_level;
+ } LoggerLevel;
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
/**
* Forward declarations
*/
- int log_Log(logger_level level, const char *file, int line, const char *function, const char *fmt, ...)
+ int log_Log(LoggerLevel level, const char *file, int line, const char *function, const char *fmt, ...)
__attribute__((format(printf, 5, 6)));
#ifdef LOG_IGNORE_ALL
int log_ignore(logger_level level, const char *file, int line, const char *function, const char *fmt, ...)
@@ 103,7 103,7 @@ extern "C"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
-static const size_t LOGGER_BUFFER_SIZE = 8192;
+static const size_t LINE_BUFFER_SIZE = 2048;
static const char *LOG_FILE_NAME = "MuditaOS.log";
static const int MAX_LOG_FILES_COUNT = 3;
static const size_t MAX_LOG_FILE_SIZE = 1024 * 1024 * 15; // 15 MB
M module-utils/log/board/linux/log_linux.cpp => module-utils/log/board/linux/log_linux.cpp +2 -4
@@ 1,10 1,8 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include <log/log.hpp>
#include <Logger.hpp>
#include <iostream>
-#include <string_view>
#include <ticks.hpp>
namespace Log
@@ 14,7 12,7 @@ namespace Log
assert(false && "Not implemented");
}
- void Logger::logToDevice(Device, std::string_view logMsg, size_t)
+ void Logger::logToDevice(Device, const char *logMsg, size_t)
{
std::cout << logMsg;
}
M module-utils/log/board/rt1051/log_rt1051.cpp => module-utils/log/board/rt1051/log_rt1051.cpp +31 -19
@@ 1,8 1,6 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include <board.h>
-#include <critical.hpp>
#include <macros.h>
#include <log/log.hpp>
#include <Logger.hpp>
@@ 13,31 11,45 @@ namespace Log
{
void Logger::logToDevice(const char *fmt, va_list args)
{
- loggerBufferCurrentPos = 0;
- loggerBufferCurrentPos += snprintf(&loggerBuffer[loggerBufferCurrentPos],
- loggerBufferSizeLeft(),
- "%lu ms ",
- cpp_freertos::Ticks::TicksToMs(cpp_freertos::Ticks::GetTicks()));
+ lineBufferCurrentPos = 0;
- loggerBufferCurrentPos += snprintf(&loggerBuffer[loggerBufferCurrentPos],
- loggerBufferSizeLeft(),
- "%-5s [%-10s] \x1b[31mASSERTION ",
- levelNames[LOGFATAL],
- getTaskDesc());
+ auto bufferSizeLeft = lineBufferSizeLeft();
+ auto bytesParsed = snprintf(&lineBuffer[lineBufferCurrentPos],
+ bufferSizeLeft,
+ "%lu ms ",
+ cpp_freertos::Ticks::TicksToMs(cpp_freertos::Ticks::GetTicks()));
+ if (bytesParsed >= 0) {
+ lineBufferCurrentPos += std::min(bufferSizeLeft, static_cast<std::size_t>(bytesParsed));
+ }
+
+ bufferSizeLeft = lineBufferSizeLeft();
+ bytesParsed = snprintf(&lineBuffer[lineBufferCurrentPos],
+ bufferSizeLeft,
+ "%-5s [%-10s] \x1b[31mASSERTION ",
+ levelNames[LOGFATAL],
+ getTaskDesc());
+ if (bytesParsed >= 0) {
+ lineBufferCurrentPos += std::min(bufferSizeLeft, static_cast<std::size_t>(bytesParsed));
+ }
+
+ bufferSizeLeft = lineBufferSizeLeft();
+ bytesParsed = vsnprintf(&lineBuffer[lineBufferCurrentPos], bufferSizeLeft, fmt, args);
+ if (bytesParsed >= 0) {
+ lineBufferCurrentPos += std::min(bufferSizeLeft, static_cast<std::size_t>(bytesParsed));
+ }
- loggerBufferCurrentPos += vsnprintf(&loggerBuffer[loggerBufferCurrentPos], loggerBufferSizeLeft(), fmt, args);
- logToDevice(Device::DEFAULT, loggerBuffer, loggerBufferCurrentPos);
- buffer.getCurrentBuffer()->put(std::string(loggerBuffer, loggerBufferCurrentPos));
+ logToDevice(Device::DEFAULT, lineBuffer, lineBufferCurrentPos);
+ buffer.getCurrentBuffer()->put(std::string(lineBuffer, lineBufferCurrentPos));
}
- void Logger::logToDevice(Device device, std::string_view logMsg, size_t length)
+ void Logger::logToDevice(Device device, const char *logMsg, std::size_t length)
{
switch (device) {
case Device::DEFAULT:
- log_WriteToDevice(reinterpret_cast<const uint8_t *>(logMsg.data()), length);
+ log_WriteToDevice(reinterpret_cast<const uint8_t *>(logMsg), length);
break;
case Device::SEGGER_RTT:
- SEGGER_RTT_Write(0, reinterpret_cast<const void *>(logMsg.data()), length);
+ SEGGER_RTT_Write(0, logMsg, length);
break;
default:
break;
M module-utils/log/log.cpp => module-utils/log/log.cpp +3 -3
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <log/log.hpp>
@@ 23,7 23,7 @@ int log_Printf(const char *fmt, ...)
return result;
}
-int log_ignore(logger_level level, const char *file, int line, const char *function, const char *fmt, ...)
+int log_ignore(LoggerLevel level, const char *file, int line, const char *function, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
@@ 31,7 31,7 @@ int log_ignore(logger_level level, const char *file, int line, const char *funct
return 0;
}
-int log_Log(logger_level level, const char *file, int line, const char *function, const char *fmt, ...)
+int log_Log(LoggerLevel level, const char *file, int line, const char *function, const char *fmt, ...)
{
va_list args;
M module-utils/log/tests/test_LoggerBuffer.cpp => module-utils/log/tests/test_LoggerBuffer.cpp +16 -16
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
@@ 38,39 38,39 @@ TEST_CASE("LoggerBuffer tests")
auto putMsgFunc = [&](const auto &msg) { buffer.put(msg); };
auto getMsgFunc = [&](const auto &originalMsg) {
- const auto [result, msg] = buffer.get();
- REQUIRE(result);
- REQUIRE(msg == originalMsg);
+ const auto msg = buffer.get();
+ REQUIRE(msg.has_value());
+ REQUIRE(msg.value() == originalMsg);
};
auto putAllMsgsFunc = [&](const vector<string> &msgs) { for_each(msgs.begin(), msgs.end(), putMsgFunc); };
auto getAllMsgsFunc = [&](const vector<string> &msgs) { for_each(msgs.begin(), msgs.end(), getMsgFunc); };
auto checkLostBytes = [&](size_t numOfBytes, const string &originalMsg) {
- const auto [result, msg] = buffer.get();
- REQUIRE(result);
- REQUIRE(msg.find(originalMsg) != string::npos);
- REQUIRE(msg.find(to_string(numOfBytes)) != string::npos);
- REQUIRE(msg.find(LoggerBuffer::lostBytesMessage) != string::npos);
+ const auto msg = buffer.get();
+ REQUIRE(msg.has_value());
+ REQUIRE(msg.value().find(originalMsg) != string::npos);
+ REQUIRE(msg.value().find(to_string(numOfBytes)) != string::npos);
+ REQUIRE(msg.value().find(LoggerBuffer::lostBytesMessage) != string::npos);
};
SECTION("calling get on empty buffer should return false")
{
- const auto [result, _] = buffer.get();
- REQUIRE(!result);
+ const auto msg = buffer.get();
+ REQUIRE(!msg.has_value());
TestBuffer(buffer, capacity, 0);
}
SECTION("after putting one msg in buffer, get should return this msg")
{
- const string originalMsg = randomStringGenerator.getRandomString();
+ const auto originalMsg = randomStringGenerator.getRandomString();
buffer.put(originalMsg);
TestBuffer(buffer, capacity, 1);
- const auto [result, msg] = buffer.get();
- REQUIRE(result);
- REQUIRE(msg == originalMsg);
+ const auto msg = buffer.get();
+ REQUIRE(msg.has_value());
+ REQUIRE(msg.value() == originalMsg);
TestBuffer(buffer, capacity, 0);
}
- SECTION("after filling whole buffer with msgs, caliling get repeatedly should return all these msgs back")
+ SECTION("after filling whole buffer with msgs, calling get repeatedly should return all these msgs back")
{
const auto msgs = randomStringGenerator.createRandomStringVector(capacity);
putAllMsgsFunc(msgs);
M module-utils/log/tests/test_log.cpp => module-utils/log/tests/test_log.cpp +9 -10
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <catch2/catch.hpp>
@@ 10,17 10,16 @@ using namespace std;
TEST_CASE("Log tests")
{
- int value = -423;
+ const int value = -423;
const char *carray = "carray";
- string str = "string";
- double double_value = 6.5323;
- unsigned int unsigned_value = 7821;
- constexpr auto big_array_size = LOGGER_BUFFER_SIZE + 2;
- char big_array[big_array_size];
- memset(big_array, 'X', big_array_size);
- big_array[big_array_size - 1] = '\0';
+ const string str = "string";
+ const double double_value = 6.5323;
+ const unsigned int unsigned_value = 7821;
+ char big_array[LINE_BUFFER_SIZE + 2];
+ memset(big_array, 'X', sizeof(big_array));
+ big_array[sizeof(big_array) - 1] = '\0';
- int loggerBufferSize = static_cast<int>(LOGGER_BUFFER_SIZE);
+ const auto loggerBufferSize = static_cast<int>(LINE_BUFFER_SIZE);
int result = LOG_TRACE("value: %d", value);
REQUIRE(0 < result);
REQUIRE(result <= loggerBufferSize);
M test/mock-logs.cpp => test/mock-logs.cpp +1 -1
@@ 4,7 4,7 @@
#include <log/log.hpp>
#include <cstdarg>
__attribute__((weak)) int log_Log(
- logger_level level, const char *file, int line, const char *function, const char *fmt, ...)
+ LoggerLevel level, const char *file, int line, const char *function, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);