telemetry#

namespace heph

Functions

template<typename ...Args>
void log(LogLevel level, telemetry::MessageWithLocation &&msg, Args&&... fields) noexcept#

Log a message. Example: heph::log(heph::LogLevel::WARN, "speed is over limit", "current_speed", 31.3, "limit", 30.0, "entity", "km/h")

template<typename ...Args>
void log(LogLevel level, telemetry::MessageWithLocation &&msg) noexcept#

Log a message without fields. Example: heph::log(heph::LogLevel::WARN, "speed is over limit")

template<typename ...Args>
void logIf(LogLevel level, bool condition, telemetry::MessageWithLocation &&msg, Args&&... fields) noexcept#

Conditionally log a message. Example: heph::log(heph::LogLevel::WARN, a==3, "speed is over limit", "current_speed", 31.3, "limit", 30.0, "entity", "km/h")

template<typename ...Args>
void logIf(LogLevel level, bool condition, telemetry::MessageWithLocation &&msg) noexcept#

Conditionally log a message without fields. Example: heph::log(heph::LogLevel::WARN, a==3, "speed is over limit")

namespace telemetry#

Functions

void registerLogSink(std::unique_ptr<telemetry::ILogSink> sink) noexcept#

Register a sink for logging.

void flushLogEntries()#

Flush all log entries to the sink. Block until flush is completed.

NOTE: if messages keep coming, this could block forever.

namespace heph
namespace telemetry
class IMetricSink#

Public Functions

virtual ~IMetricSink() = default#
virtual void send(const Metric&) = 0#
struct Metric#

Public Types

using ValueType = std::variant<int64_t, double, std::string, bool>#

Public Members

std::string component#

The component that is logging the metric_record, e.g. SLAM, Navigation, etc.

std::string tag#

The tag of the metric_record used to identify who created it, e.g. “front_camera”, “motor1”, etc.

ClockT::time_point timestamp#
std::unordered_map<std::string, ValueType> values#

Public Functions

bool=default operator== (const Metric &) const
std::string toString() const#

Typedefs

using ClockT = std::chrono::system_clock#
template<>
struct formatter<heph::telemetry::Metric> : public fmt::formatter<std::string_view>#

Public Static Functions

static inline auto format(const heph::telemetry::Metric &metric, fmt::format_context &ctx)#
namespace heph
namespace telemetry

Functions

const Scope::Context *getCurrentContext()#
class Scope#
struct Context#

Public Members

std::string robot_name#
std::string module#

Public Functions

explicit Scope(std::string robot_name, std::string module)#
~Scope()#
Scope(const Scope&) = delete#
Scope &=delete operator= (const Scope &)
Scope(Scope&&) = delete#
Scope &=delete operator= (Scope &&)
namespace heph
namespace telemetry

Functions

void registerMetricSink(std::unique_ptr<IMetricSink> sink)#

Register a new metric sink. For every metric recorded, the sink will be called to consume the data. There is no limit on the number of sinks supported.

void record(Metric metric)#

Record a metric. The metric is forwarded to all registered sinks. Sinks process the metric in a dedicated thread, this means that this function is non-blocking and deterministic.

void record(heph::UniqueFunction<Metric()> &&metric)#
template<typename DataT>
void record(std::string component, std::string tag, DataT &&data, ClockT::time_point timestamp = ClockT::now())#

Record a user defined metric. NOTE: the data needs to be serializable to JSON. For details on how to achieve this, see heph::serdes::serializeToJSON.

Parameters:
  • component – The component that is logging the metric_record, e.g. SLAM, Navigation, etc.

  • tag – The tag of the metric_record used to identify who created it, e.g. “front_camera”, “motor1”, etc.

  • data – The data to record, needs to be json serializable.

  • timestamp – The timestamp of the metric, if not provided, the current time is used.

void flushMetrics()#
namespace heph
namespace telemetry
namespace metric_sinks#
class TerminalMetricSink : public heph::telemetry::IMetricSink#

Public Functions

void send(const Metric &metric) override#
namespace heph

Enums

enum LogLevel#

Forward declaration of LogLevel. Definition is in log.h, since we only want to include that when logging.

Values:

enumerator TRACE#
enumerator DEBUG#
enumerator INFO#
enumerator WARN#
enumerator ERROR#
enumerator FATAL#
namespace telemetry
template<typename T>
struct Field#

Public Members

std::string key#
T value#
struct ILogSink#
#include “/home/runner/.bazel/sandbox/processwrapper-sandbox/347/execroot/_main/modules/telemetry/telemetry/include/hephaestus/telemetry/log_sink.h”

Interface for sinks that log entries can be sent to.

Public Types

using Formatter = std::function<std::string(const LogEntry &log)>#

Public Functions

virtual ~ILogSink() = default#
virtual void send(const LogEntry &log_entry) = 0#

Main interface to the sink, gets called on log.

Parameters:

log_entry

struct LogEntry#
#include “/home/runner/.bazel/sandbox/processwrapper-sandbox/347/execroot/_main/modules/telemetry/telemetry/include/hephaestus/telemetry/log_sink.h”

A class that allows easy composition of logs for structured logging. Example(see also log.cpp): cpp namespace ht=heph::telemetry; log(LogLevel::INFO, "adding", "speed", 31.3, "tag", "test"); logs ‘level=info hostname=goofy location=log.h:123 thread-id=5124 time=2023-12-3T8:52:02+0 module=”my module” message=”adding” id=12345 speed=31.3 tag=”test”’ Remark: We would like to use libfmt with quoted formatting as proposed in fmtlib/fmt#825 once its included (instead of sstream).

Public Types

using FieldsT = std::vector<Field<std::string>>#
using ClockT = std::chrono::system_clock#

Public Members

heph::LogLevel level#
std::string message#
std::source_location location#
std::thread::id thread_id#
ClockT::time_point time#
std::string hostname#
std::string module#
std::optional<std::string> stack_trace#
FieldsT fields#

Public Functions

LogEntry(heph::LogLevel level, MessageWithLocation &&message)#
template<NonQuotable T>
inline LogEntry &&operator<<(const Field<T> &field)#

General loginfo consumer, should be used like LogEntry(“my message”) << Field{“field”, 1234} Converted to string with stringstream.

Template Parameters:

T – any type that is consumeable by stringstream

Parameters:
  • key – identifier for the logging data

  • value – value of the logging data

Returns:

LogEntry&&

template<Quotable S>
inline LogEntry &&operator<<(const Field<S> &field)#

Specialized loginfo consumer for string types so that they are quoted, should be used like LogEntry(“my message”) << Field{“field”, “mystring”}.

Template Parameters:

T – any type that is consumeable by stringstream

Parameters:
  • key – identifier for the logging data

  • val – value of the logging data

Returns:

LogEntry&&

struct MessageWithLocation#
#include “/home/runner/.bazel/sandbox/processwrapper-sandbox/347/execroot/_main/modules/telemetry/telemetry/include/hephaestus/telemetry/log_sink.h”

Wrapper around string literals to enhance them with a location. Note that the message is not owned by this class. We need to use a const char* here in order to enable implicit conversion from log(LogLevel::INFO,"my string");. The standard guarantees that string literals exist for the entirety of the program lifetime, so it is fine to use it as MessageWithLocation("my message");

Public Members

std::string value#
std::source_location location#

Public Functions

inline MessageWithLocation(const char *s, const std::source_location &l = std::source_location::current())#

Constructor for interface as log(Level::Warn, "msg");

inline MessageWithLocation(std::string s, const std::source_location &l = std::source_location::current())#

Constructor for interface as log(Level::Warn, "msg"s); or log(Level::Warn, std::format(...));

template<>
struct formatter<heph::telemetry::Field<std::string>> : public fmt::formatter<std::string_view>#

Public Static Functions

static inline auto format(const heph::telemetry::Field<std::string> &field, fmt::format_context &ctx)#
template<>
struct formatter<heph::LogLevel> : public fmt::formatter<std::string_view>#

Public Static Functions

static inline auto format(const heph::LogLevel &level, fmt::format_context &ctx)#
template<>
struct formatter<heph::telemetry::LogEntry> : public fmt::formatter<std::string_view>#
#include “/home/runner/.bazel/sandbox/processwrapper-sandbox/347/execroot/_main/modules/telemetry/telemetry/include/hephaestus/telemetry/log_sink.h”

Formatter for LogEntry adhering to logfmt rules.

Public Static Functions

static inline auto format(const heph::telemetry::LogEntry &log, fmt::format_context &ctx)#
namespace heph
namespace telemetry
class AbslLogSink : public heph::telemetry::ILogSink#
#include “/home/runner/.bazel/sandbox/processwrapper-sandbox/347/execroot/_main/modules/telemetry/telemetry/include/hephaestus/telemetry/log_sinks/absl_sink.h”

A simple sink that passes the logs to ABSL. Per default entry is formatted via heph::telemetry::format.

Public Functions

explicit AbslLogSink(LogLevel log_level = LogLevel::INFO)#
explicit AbslLogSink(ILogSink::Formatter &&f)#
virtual void send(const LogEntry &entry) override#

Main interface to the sink, gets called on log.

Parameters:

log_entry