Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update quill to 6.1.2 #137

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ if(CACTUS_RT_ENABLE_FETCH_DEPENDENCIES)
FetchContent_Declare(
quill
GIT_REPOSITORY https://github.com/odygrd/quill.git
GIT_TAG 9a270d5d6f57a3ac19451292e3a9f370fcd744b1
# GIT_TAG v3.3.2
GIT_TAG 1401d2d90f85a6b83ab1b259590d8ba227446a92
# GIT_TAG v6.1.2
)

FetchContent_MakeAvailable(quill)
Expand Down
27 changes: 20 additions & 7 deletions examples/logging_example/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <chrono>
#include <iostream>

#include "quill/sinks/FileSink.h"

using cactus_rt::App;
using cactus_rt::CyclicThread;

Expand All @@ -26,7 +28,7 @@ class ExampleRTThread : public CyclicThread {
if (loop_counter_ % 1000 == 0) {
LOG_INFO(Logger(), "Loop {}", loop_counter_);
}
LOG_INFO_LIMIT(std::chrono::milliseconds{1500}, Logger(), "Log limit: Loop {}", loop_counter_);
LOG_DEBUG_LIMIT(std::chrono::milliseconds{1500}, Logger(), "Log limit: Loop {}", loop_counter_);
return LoopControl::Continue;
}
};
Expand All @@ -40,14 +42,25 @@ int main() {
// Create a cactus_rt app configuration
cactus_rt::AppConfig app_config;

// Create a Quill logging config to configure logging
quill::Config logging_config;

// Disable strict timestamp order - this will be faster, but logs may appear out of order
logging_config.backend_thread_strict_log_timestamp_order = false;
// Create a logging config to configure logging
cactus_rt::LoggerConfig logging_config;

// Set the background logging thread CPU affinity
logging_config.backend_thread_cpu_affinity = 1; // Different CPU than the CyclicThread CPU!
logging_config.backend_options.backend_cpu_affinity = 1; // Different CPU than the CyclicThread CPU!

// Configure the log level for debug messages
logging_config.log_level = quill::LogLevel::Debug;

logging_config.sink = cactus_rt::Frontend::create_or_get_sink<quill::FileSink>(
"log_file",
[]() {
quill::FileSinkConfig cfg;
cfg.set_open_mode('w');
cfg.set_filename_append_option(quill::FilenameAppendOption::StartDateTime);
return cfg;
}(),
quill::FileEventNotifier{}
);

app_config.logger_config = logging_config;
App app("LoggingExampleApp", app_config);
Expand Down
1 change: 1 addition & 0 deletions examples/message_passing_example/data_logger_thread.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "data_logger_thread.h"

#include <chrono>
#include <iomanip>

DataLogger::DataLogger(
const std::string& data_file_path,
Expand Down
2 changes: 2 additions & 0 deletions examples/message_passing_example/rt_thread.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "rt_thread.h"

#include <cmath>

cactus_rt::CyclicThread::LoopControl RtThread::Loop(int64_t ellapsed_ns) noexcept {
const double ellapsed_ms = static_cast<double>(ellapsed_ns) / 1'000'000.0;

Expand Down
12 changes: 10 additions & 2 deletions examples/tracing_example_no_rt/main.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include <cactus_rt/logger.h>
#include <cactus_rt/tracing.h>
#include <quill/Backend.h>
#include <quill/sinks/ConsoleSink.h>

#include <memory>
#include <thread>
Expand All @@ -19,13 +22,18 @@ void StartTracing(const char* app_name, const char* filename) {
// Enable the tracing.
cactus_rt::tracing::EnableTracing();

// Create a logger
cactus_rt::Logger* logger = cactus_rt::Frontend::create_or_get_logger(
"TraceAggregatorLogger", cactus_rt::Frontend::create_or_get_sink<quill::ConsoleSink>("console_sink")
);

// Create the trace aggregator that will pop the queues and write the events to sinks.
trace_aggregator = std::make_unique<TraceAggregator>(app_name);
trace_aggregator = std::make_unique<TraceAggregator>(app_name, logger);

// Create the file sink so the data aggregated by the TraceAggregator will be written to somewhere.
auto file_sink = std::make_shared<FileSink>(filename);

quill::start();
quill::Backend::start();
trace_aggregator->Start(file_sink);
}

Expand Down
21 changes: 6 additions & 15 deletions include/cactus_rt/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <vector>

#include "config.h"
#include "quill/Quill.h"
#include "logger.h"
#include "thread.h"
#include "tracing/thread_tracer.h"
#include "tracing/trace_aggregator.h"
Expand All @@ -29,26 +29,14 @@ class App {
size_t heap_size_;

// Configuration for quill logging
quill::Config logger_config_;
LoggerConfig logger_config_;

TracerConfig tracer_config_;

std::shared_ptr<tracing::TraceAggregator> trace_aggregator_; // Must be above threads_ to guarantee destructor order.

std::vector<std::shared_ptr<Thread>> threads_;

void SetDefaultLogFormat(quill::Config& cfg) {
// Create a handler of stdout
const std::shared_ptr<quill::Handler> handler = quill::stdout_handler();

// Enable console colours on the handler
static_cast<quill::ConsoleHandler*>(handler.get())->enable_console_colours();

// Set the default pattern
handler->set_pattern("[%(ascii_time)][%(level_id)][%(logger_name)][%(filename):%(lineno)] %(message)", "%Y-%m-%d %H:%M:%S.%Qns");
cfg.default_handlers.push_back(handler);
}

public:
explicit App(std::string name = "RTApp", AppConfig config = AppConfig());

Expand All @@ -62,6 +50,8 @@ class App {
App(App&&) noexcept = delete;
App& operator=(App&&) noexcept = delete;

cactus_rt::Logger* CreateLogger(const std::string& name) const;

template <typename ThreadT, typename... Args>
std::shared_ptr<ThreadT> CreateThread(Args&&... args) {
static_assert(std::is_base_of_v<Thread, ThreadT>, "Must derive from cactus_rt::Thread");
Expand All @@ -70,6 +60,7 @@ class App {
Thread* base_thread = thread.get();
base_thread->trace_aggregator_ = trace_aggregator_;
base_thread->created_by_app_ = true;
base_thread->logger_ = CreateLogger(base_thread->name_);

threads_.push_back(thread);

Expand Down Expand Up @@ -143,7 +134,7 @@ class App {
/**
* Starts the Quill background logging thread.
*/
void StartQuill();
void StartQuill() const;

private:
void StopTraceAggregator() noexcept;
Expand Down
37 changes: 34 additions & 3 deletions include/cactus_rt/config.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#ifndef CACTUS_RT_CONFIG_H_
#define CACTUS_RT_CONFIG_H_

#include <quill/Quill.h>

#include <memory>

#include "cactus_rt/scheduler.h"
#include "logger.h"
#include "quill/backend/BackendOptions.h"
#include "quill/core/LogLevel.h"
#include "quill/sinks/ConsoleSink.h"
#include "quill/sinks/Sink.h"

namespace cactus_rt {

Expand All @@ -19,6 +22,34 @@ struct TracerConfig {
std::vector<size_t> trace_aggregator_cpu_affinity;
};

struct LoggerConfig {
/**
* @brief Backend options for Quill logging
*/
quill::BackendOptions backend_options;

/**
* @brief Pattern for formatting logs
*/
std::string format_pattern = "[%(time)][%(log_level)][%(logger)][%(file_name):%(line_number)] %(message)";

/**
* @brief Pattern for formatting time
*/
std::string time_pattern = "%Y-%m-%d %H:%M:%S.%Qns";

/**
* @brief Log level for Quill logging
*/
quill::LogLevel log_level = quill::LogLevel::Info;

/**
* @brief The sink to log to. Default is console.
*/
std::shared_ptr<quill::Sink> sink;

LoggerConfig() : sink(Frontend::create_or_get_sink<quill::ConsoleSink>("console_sink")) {}
};
/**
* @brief The configuration required for an App
*/
Expand All @@ -31,7 +62,7 @@ struct AppConfig {
/**
* @brief The configuration for quill logging
*/
quill::Config logger_config;
LoggerConfig logger_config;

/**
* @brief The config for the tracer if enabled (ENABLE_TRACING option in cmake)
Expand Down
35 changes: 35 additions & 0 deletions include/cactus_rt/logger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef CACTUS_RT_LOGGER_H_
#define CACTUS_RT_LOGGER_H_

#include "quill/Frontend.h"
#include "quill/LogMacros.h"
#include "quill/core/Common.h"
#include "quill/std/Array.h"
#include "quill/std/Chrono.h"
#include "quill/std/Deque.h"
#include "quill/std/FilesystemPath.h"
#include "quill/std/ForwardList.h"
#include "quill/std/List.h"
#include "quill/std/Map.h"
#include "quill/std/Optional.h"
#include "quill/std/Pair.h"
#include "quill/std/Set.h"
#include "quill/std/Tuple.h"
#include "quill/std/UnorderedMap.h"
#include "quill/std/UnorderedSet.h"
#include "quill/std/Vector.h"
#include "quill/std/WideString.h"

namespace cactus_rt {
struct FrontendOptions {
// Set the queue to BoundedDropping to prevent allocation
static constexpr quill::QueueType queue_type = quill::QueueType::BoundedDropping;
static constexpr uint32_t initial_queue_capacity = 131'072;
static constexpr int32_t blocking_queue_retry_interval_ns = 800;
static constexpr bool huge_pages_enabled = false;
};

using Frontend = quill::FrontendImpl<FrontendOptions>;
using Logger = quill::LoggerImpl<FrontendOptions>;
} // namespace cactus_rt
#endif
8 changes: 4 additions & 4 deletions include/cactus_rt/ros2/publisher.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <rclcpp/rclcpp.hpp>
#include <type_traits>

#include "quill/Quill.h"
#include "../logger.h"

namespace cactus_rt::ros2 {
class Ros2Adapter;
Expand All @@ -31,7 +31,7 @@ class Publisher : public IPublisher {
using NoConversion = std::is_same<RealtimeT, RosT>;
using AdaptedRosType = typename std::conditional_t<NoConversion::value, RosT, rclcpp::TypeAdapter<RealtimeT, RosT>>;

quill::Logger* logger_;
cactus_rt::Logger* logger_;
typename rclcpp::Publisher<AdaptedRosType>::SharedPtr publisher_;
moodycamel::ReaderWriterQueue<RealtimeT> queue_;

Expand Down Expand Up @@ -77,7 +77,7 @@ class Publisher : public IPublisher {
}

static std::shared_ptr<Publisher<RealtimeT, RosT, CheckForTrivialRealtimeT>> Create(
quill::Logger* logger,
cactus_rt::Logger* logger,
rclcpp::Node& node,
const std::string& topic_name,
const rclcpp::QoS& qos,
Expand All @@ -93,7 +93,7 @@ class Publisher : public IPublisher {
}

Publisher(
quill::Logger* logger,
cactus_rt::Logger* logger,
typename rclcpp::Publisher<AdaptedRosType>::SharedPtr publisher,
moodycamel::ReaderWriterQueue<RealtimeT>&& queue
) : logger_(logger), publisher_(publisher), queue_(std::move(queue)) {}
Expand Down
3 changes: 1 addition & 2 deletions include/cactus_rt/ros2/ros2_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include <vector>

#include "publisher.h"
#include "quill/Quill.h"
#include "subscription.h"

namespace cactus_rt::ros2 {
Expand Down Expand Up @@ -44,7 +43,7 @@ class Ros2Adapter {
std::vector<std::shared_ptr<IPublisher>> publishers_;
std::vector<std::shared_ptr<ISubscription>> subscriptions_;

quill::Logger* logger_;
cactus_rt::Logger* logger_;

public:
Ros2Adapter(const std::string& name_, const Config& config);
Expand Down
8 changes: 4 additions & 4 deletions include/cactus_rt/ros2/subscription.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <type_traits>

#include "../experimental/lockless/spsc/realtime_readable_value.h"
#include "quill/Quill.h"
#include "quill/Frontend.h"

// Note: ROS subscription dispatch is here: https://github.com/ros2/rclcpp/blob/e10728c/rclcpp/include/rclcpp/any_subscription_callback.hpp#L481
// We are using the TypeAdapter method.
Expand Down Expand Up @@ -40,7 +40,7 @@ class SubscriptionLatest : public ISubscription {

using RealtimeReadableValue = cactus_rt::experimental::lockless::spsc::RealtimeReadableValue<StampedValue<RealtimeT>>;

quill::Logger* logger_;
cactus_rt::Logger* logger_;
typename rclcpp::Subscription<AdaptedRosType>::SharedPtr ros_subscription_;
int64_t current_msg_id_ = 0;
RealtimeReadableValue latest_value_;
Expand All @@ -57,7 +57,7 @@ class SubscriptionLatest : public ISubscription {
}

static std::shared_ptr<SubscriptionLatest<RealtimeT, RosT, CheckForTrivialRealtimeT>> Create(
quill::Logger* logger,
cactus_rt::Logger* logger,
rclcpp::Node& node,
const std::string& topic_name,
const rclcpp::QoS& qos
Expand All @@ -78,7 +78,7 @@ class SubscriptionLatest : public ISubscription {
return subscription;
}

explicit SubscriptionLatest(quill::Logger* logger) : logger_(logger) {}
explicit SubscriptionLatest(cactus_rt::Logger* logger) : logger_(logger) {}

public:
StampedValue<RealtimeT> ReadLatest() noexcept {
Expand Down
8 changes: 3 additions & 5 deletions include/cactus_rt/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <string>

#include "config.h"
#include "quill/Quill.h"
#include "tracing/thread_tracer.h"
#include "tracing/trace_aggregator.h"

Expand All @@ -30,7 +29,7 @@ class Thread {
std::vector<size_t> cpu_affinity_;
size_t stack_size_;

quill::Logger* logger_;
cactus_rt::Logger* logger_;
std::shared_ptr<tracing::ThreadTracer> tracer_ = nullptr;

std::atomic_bool stop_requested_ = false;
Expand Down Expand Up @@ -59,8 +58,7 @@ class Thread {
: config_(config),
name_(name),
cpu_affinity_(config_.cpu_affinity),
stack_size_(static_cast<size_t>(PTHREAD_STACK_MIN) + config_.stack_size),
logger_(quill::create_logger(name_)) {
stack_size_(static_cast<size_t>(PTHREAD_STACK_MIN) + config_.stack_size) {
if (!config.scheduler) {
throw std::runtime_error("ThreadConfig::scheduler cannot be nullptr");
}
Expand Down Expand Up @@ -118,7 +116,7 @@ class Thread {
void Start(int64_t start_monotonic_time_ns);

protected:
inline quill::Logger* Logger() const { return logger_; }
inline cactus_rt::Logger* Logger() const { return logger_; }

/**
* Gets the current tracer object. Should only ever be called from within the thread itself.
Expand Down
Loading
Loading