Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
dbba2b2
Added log levels. Ensured that C++17 is needed to compile.
balazs-bamer Dec 22, 2020
3f28181
More docs.
balazs-bamer Dec 22, 2020
0955d5d
More docs.
balazs-bamer Dec 22, 2020
2ddb05f
Bugfix in decs.
balazs-bamer Dec 22, 2020
5ead4cd
Added benchmarks using picobench.
balazs-bamer Dec 24, 2020
e08f9ad
Bugfix. Added benchmark docs.
balazs-bamer Dec 24, 2020
d60d7ba
More benchmarks.
balazs-bamer Dec 26, 2020
8a0ecd0
New measurement.
balazs-bamer Dec 26, 2020
7437389
Added atomic buffer. Refactor for better template API. Bugfixes. Need…
balazs-bamer Dec 29, 2020
06cc58e
Bugfix.
balazs-bamer Dec 30, 2020
203df41
Bugfix. Documented AtomicBuffers.
balazs-bamer Dec 30, 2020
73b532c
Bugfix.
balazs-bamer Dec 31, 2020
9cc558b
Bugfix.
balazs-bamer Dec 31, 2020
0538a24
More testing, docs.
balazs-bamer Dec 31, 2020
a848405
Updated benchmarks.
balazs-bamer Jan 1, 2021
0317fa0
Ensured that removing the lock on notifying won't cause problem but r…
balazs-bamer Jan 1, 2021
ce677c0
Added comment about removed lock_guard.
balazs-bamer Jan 1, 2021
53912df
Finished the FreeRTOS AppInterface and updated the docs with size mea…
balazs-bamer Jan 2, 2021
988fe76
Added ROS2 sender. Note, it has a hardcoded loglevel set by trial-error.
balazs-bamer Jan 31, 2021
1f1a68c
Bugfix. Added std::string support. Added ROS2 log support.
balazs-bamer Jan 31, 2021
21b9f32
Removed unnecessary comment.
balazs-bamer Jan 31, 2021
2af5255
More docs.
balazs-bamer Feb 1, 2021
ca44ba8
Bugfix.
balazs-bamer Feb 12, 2021
ac35a7c
Changed the boost::lockfree::queue to have compile-time fixed capacity.
balazs-bamer Aug 25, 2021
58cc37a
Added queue with lock and circular buffer.
balazs-bamer Aug 25, 2021
8ed92cb
Bugfix and new benchmark.
balazs-bamer Sep 3, 2021
5848dac
Fixed spelling in README.md
balazs-bamer Nov 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ test-stdthreadostream
*.exe
*.out
*.app
picobench
test-stdthreadostream
test-stdostream
test-sizes
Expand Down
2 changes: 2 additions & 0 deletions .idea/cpp_logger.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/test-stdostream",
"program": "${workspaceFolder}/test-stdthreadostream",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
Expand Down
1 change: 1 addition & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"command": "/usr/bin/clang++",
"args": [
"-ggdb",
"-Og",
"test/test-stdthreadostream.cpp",
"-Wall",
"-Wpedantic",
Expand Down
7 changes: 4 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
cmake_minimum_required(VERSION 3.17)
project(cpp_logger)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 17)

include_directories(cpp-memory-manager)
include_directories(src)

add_compile_options(-Os -Wall -Wextra -Wpedantic)
add_compile_options(-Og -ggdb -Wall -Wextra -Wpedantic)
add_link_options(-lpthread)

add_executable(cpp_logger
cpp-memory-manager/PoolAllocator.h
src/Log.h
src/LogAtomicBuffers.h
src/LogAppInterfaceStd.h
src/LogConverterCustomText.h
src/LogMessageBase.h
Expand All @@ -22,4 +23,4 @@ add_executable(cpp_logger
src/LogQueueVoid.h
src/LogSenderStdOstream.h
src/LogSenderVoid.h
test/test-sizes-stdthreadostream.cpp)
test/test-stdthreadostream.cpp)
308 changes: 216 additions & 92 deletions README.md

Large diffs are not rendered by default.

94 changes: 94 additions & 0 deletions benchmark/picobench-direct.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#define PICOBENCH_IMPLEMENT
#define PICOBENCH_DEFAULT_SAMPLES 10
#define PICOBENCH_DEFAULT_ITERATIONS { 64, 512, 4096, 32768, 262144, 2097152 }
#include "picobench/picobench.hpp"

#include "LogAppInterfaceStd.h"
#include "LogConverterCustomText.h"
#include "LogSenderStdOstream.h"
#include "LogSenderVoid.h"
#include "LogQueueVoid.h"
#include "LogMessageCompact.h"
#include "LogMessageVariant.h"
#include "Log.h"
#include <fstream>

constexpr nowtech::log::TaskId cgMaxTaskCount = 1;
constexpr bool cgAllowRegistrationLog = true;
constexpr bool cgLogFromIsr = false;
constexpr size_t cgTaskShutdownSleepPeriod = 100u;
constexpr bool cgArchitecture64 = true;
constexpr uint8_t cgAppendStackBufferSize = 100u;
constexpr bool cgAppendBasePrefix = true;
constexpr bool cgAlignSigned = false;
using AtomicBufferType = int32_t;
constexpr size_t cgAtomicBufferExponent = 14u;
constexpr AtomicBufferType cgAtomicBufferInvalidValue = 1234546789;
constexpr size_t cgTransmitBufferSize = 123u;
constexpr size_t cgPayloadSize = 14u;
constexpr bool cgSupportFloatingPoint = true;
constexpr size_t cgQueueSize = 444u;
constexpr nowtech::log::LogTopic cgMaxTopicCount = 2;
constexpr nowtech::log::TaskRepresentation cgTaskRepresentation = nowtech::log::TaskRepresentation::cName;
constexpr size_t cgDirectBufferSize = 1234u;
constexpr nowtech::log::ErrorLevel cgErrorLevel = nowtech::log::ErrorLevel::Info;

using LogAppInterface = nowtech::log::AppInterfaceStd<cgMaxTaskCount, cgLogFromIsr, cgTaskShutdownSleepPeriod>;
constexpr typename LogAppInterface::LogTime cgTimeout = 123u;
constexpr typename LogAppInterface::LogTime cgRefreshPeriod = 444;
using LogMessage = nowtech::log::MessageVariant<cgPayloadSize, cgSupportFloatingPoint>;
using LogConverter = nowtech::log::ConverterCustomText<LogMessage, cgArchitecture64, cgAppendStackBufferSize, cgAppendBasePrefix, cgAlignSigned>;
using LogSender = nowtech::log::SenderStdOstream<LogAppInterface, LogConverter, cgTransmitBufferSize, cgTimeout>;
using LogQueue = nowtech::log::QueueVoid<LogMessage, LogAppInterface>;
using LogAtomicBuffer = nowtech::log::AtomicBufferOperational<LogAppInterface, AtomicBufferType, cgAtomicBufferExponent, cgAtomicBufferInvalidValue>;
using LogConfig = nowtech::log::Config<cgAllowRegistrationLog, cgMaxTopicCount, cgTaskRepresentation, cgDirectBufferSize, cgRefreshPeriod, cgErrorLevel>;
using Log = nowtech::log::Log<LogQueue, LogSender, LogAtomicBuffer, LogConfig>;

nowtech::log::TaskId gTaskId;

void nowtechLogRefTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>(gTaskId) << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogRefTaskId);

void nowtechLogCopyTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>(gTaskId) << LC::St << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogCopyTaskId);

void nowtechLogRefNoTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>() << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogRefNoTaskId);

void nowtechLogCopyNoTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>() << LC::St << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogCopyNoTaskId);


int main(int argc, char* argv[])
{
nowtech::log::LogFormatConfig logConfig;
std::ofstream out("/tmp/x");
LogSender::init(&out);
Log::init(logConfig);
Log::registerCurrentTask("main");
gTaskId = Log::getCurrentTaskId();

picobench::runner r;
r.parse_cmd_line(argc, argv);
auto ret = r.run();
Log::sendAtomicBuffer();
Log::unregisterCurrentTask();
Log::done();
return ret;
}
93 changes: 93 additions & 0 deletions benchmark/picobench-msg-compact-boost.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#define PICOBENCH_IMPLEMENT
#define PICOBENCH_DEFAULT_SAMPLES 10
#include "picobench/picobench.hpp"

#include "LogAppInterfaceStd.h"
#include "LogConverterCustomText.h"
#include "LogSenderStdOstream.h"
#include "LogSenderVoid.h"
#include "LogQueueStdBoost.h"
#include "LogQueueVoid.h"
#include "LogMessageCompact.h"
#include "LogMessageVariant.h"
#include "Log.h"
#include <fstream>
#include <memory>

constexpr nowtech::log::TaskId cgMaxTaskCount = 1;
constexpr bool cgAllowRegistrationLog = true;
constexpr bool cgLogFromIsr = false;
constexpr size_t cgTaskShutdownSleepPeriod = 100u;
constexpr bool cgArchitecture64 = true;
constexpr uint8_t cgAppendStackBufferSize = 100u;
constexpr bool cgAppendBasePrefix = true;
constexpr bool cgAlignSigned = false;
using AtomicBufferType = int32_t;
constexpr size_t cgAtomicBufferExponent = 14u;
constexpr AtomicBufferType cgAtomicBufferInvalidValue = 1234546789;
constexpr size_t cgTransmitBufferSize = 444444u;
constexpr size_t cgPayloadSize = 8u;
constexpr bool cgSupportFloatingPoint = true;
constexpr size_t cgQueueSize = 44444u;
constexpr nowtech::log::LogTopic cgMaxTopicCount = 2;
constexpr nowtech::log::TaskRepresentation cgTaskRepresentation = nowtech::log::TaskRepresentation::cName;
constexpr size_t cgDirectBufferSize = 0u;
constexpr nowtech::log::ErrorLevel cgErrorLevel = nowtech::log::ErrorLevel::Info;

using LogAppInterface = nowtech::log::AppInterfaceStd<cgMaxTaskCount, cgLogFromIsr, cgTaskShutdownSleepPeriod>;
constexpr typename LogAppInterface::LogTime cgTimeout = 123u;
constexpr typename LogAppInterface::LogTime cgRefreshPeriod = 444;
using LogMessage = nowtech::log::MessageCompact<cgPayloadSize, cgSupportFloatingPoint>;
using LogConverter = nowtech::log::ConverterCustomText<LogMessage, cgArchitecture64, cgAppendStackBufferSize, cgAppendBasePrefix, cgAlignSigned>;
using LogSender = nowtech::log::SenderStdOstream<LogAppInterface, LogConverter, cgTransmitBufferSize, cgTimeout>;
using LogQueue = nowtech::log::QueueStdBoost<LogMessage, LogAppInterface, cgQueueSize>;
using LogAtomicBuffer = nowtech::log::AtomicBufferOperational<LogAppInterface, AtomicBufferType, cgAtomicBufferExponent, cgAtomicBufferInvalidValue>;
using LogConfig = nowtech::log::Config<cgAllowRegistrationLog, cgMaxTopicCount, cgTaskRepresentation, cgDirectBufferSize, cgRefreshPeriod, cgErrorLevel>;
using Log = nowtech::log::Log<LogQueue, LogSender, LogAtomicBuffer, LogConfig>;

nowtech::log::TaskId gTaskId;

void nowtechLogRefTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>(gTaskId) << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogRefTaskId);

void nowtechLogCopyTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>(gTaskId) << LC::St << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogCopyTaskId);

void nowtechLogRefNoTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>() << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogRefNoTaskId);

void nowtechLogCopyNoTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>() << LC::St << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogCopyNoTaskId);

int main(int argc, char* argv[])
{
nowtech::log::LogFormatConfig logConfig;
std::ofstream out("tmp");
LogSender::init(&out);
Log::init(logConfig);
Log::registerCurrentTask("main");
gTaskId = Log::getCurrentTaskId();

picobench::runner r;
r.parse_cmd_line(argc, argv);
auto ret = r.run();
Log::unregisterCurrentTask();
Log::done();
return ret;
}
93 changes: 93 additions & 0 deletions benchmark/picobench-msg-compact-circular.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#define PICOBENCH_IMPLEMENT
#define PICOBENCH_DEFAULT_SAMPLES 10
#include "picobench/picobench.hpp"

#include "LogAppInterfaceStd.h"
#include "LogConverterCustomText.h"
#include "LogSenderStdOstream.h"
#include "LogQueueStdCircular.h"
#include "LogQueueVoid.h"
#include "LogMessageCompact.h"
#include "LogMessageVariant.h"
#include "Log.h"
#include <fstream>
#include <memory>

constexpr nowtech::log::TaskId cgMaxTaskCount = 1;
constexpr bool cgAllowRegistrationLog = true;
constexpr bool cgLogFromIsr = false;
constexpr size_t cgTaskShutdownSleepPeriod = 100u;
constexpr bool cgArchitecture64 = true;
constexpr uint8_t cgAppendStackBufferSize = 100u;
constexpr bool cgAppendBasePrefix = true;
constexpr bool cgAlignSigned = false;
using AtomicBufferType = int32_t;
constexpr size_t cgAtomicBufferExponent = 14u;
constexpr AtomicBufferType cgAtomicBufferInvalidValue = 1234546789;
constexpr size_t cgTransmitBufferSize = 444444u;
constexpr size_t cgPayloadSize = 8u;
constexpr bool cgSupportFloatingPoint = true;
constexpr size_t cgQueueSize = 444444u;
constexpr nowtech::log::LogTopic cgMaxTopicCount = 2;
constexpr nowtech::log::TaskRepresentation cgTaskRepresentation = nowtech::log::TaskRepresentation::cName;
constexpr size_t cgDirectBufferSize = 0u;
constexpr nowtech::log::ErrorLevel cgErrorLevel = nowtech::log::ErrorLevel::Info;

using LogAppInterface = nowtech::log::AppInterfaceStd<cgMaxTaskCount, cgLogFromIsr, cgTaskShutdownSleepPeriod>;
constexpr typename LogAppInterface::LogTime cgTimeout = 123u;
constexpr typename LogAppInterface::LogTime cgRefreshPeriod = 444;
using LogMessage = nowtech::log::MessageCompact<cgPayloadSize, cgSupportFloatingPoint>;
using LogConverter = nowtech::log::ConverterCustomText<LogMessage, cgArchitecture64, cgAppendStackBufferSize, cgAppendBasePrefix, cgAlignSigned>;
using LogSender = nowtech::log::SenderStdOstream<LogAppInterface, LogConverter, cgTransmitBufferSize, cgTimeout>;
using LogQueue = nowtech::log::QueueStdCircular<LogMessage, LogAppInterface, cgQueueSize>;
using LogAtomicBuffer = nowtech::log::AtomicBufferOperational<LogAppInterface, AtomicBufferType, cgAtomicBufferExponent, cgAtomicBufferInvalidValue>;
using LogConfig = nowtech::log::Config<cgAllowRegistrationLog, cgMaxTopicCount, cgTaskRepresentation, cgDirectBufferSize, cgRefreshPeriod, cgErrorLevel>;
using Log = nowtech::log::Log<LogQueue, LogSender, LogAtomicBuffer, LogConfig>;

nowtech::log::TaskId gTaskId;

void nowtechLogRefTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>(gTaskId) << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogRefTaskId);

void nowtechLogCopyTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>(gTaskId) << LC::St << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogCopyTaskId);

void nowtechLogRefNoTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>() << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogRefNoTaskId);

void nowtechLogCopyNoTaskId(picobench::state& s) {
for (auto _ : s) {
Log::i<Log::info>() << LC::St << "Info message" << Log::end;
}
}
PICOBENCH(nowtechLogCopyNoTaskId);


int main(int argc, char* argv[])
{
nowtech::log::LogFormatConfig logConfig;
std::ofstream out("tmp");
LogSender::init(&out);
Log::init(logConfig);
Log::registerCurrentTask("main");
gTaskId = Log::getCurrentTaskId();

picobench::runner r;
r.parse_cmd_line(argc, argv);
auto ret = r.run();
Log::unregisterCurrentTask();
Log::done();
return ret;
}
Loading