Skip to content
Merged
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
16 changes: 9 additions & 7 deletions include/flow/impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include <flow/common.hpp>
#include <flow/log.hpp>
#include <log/env.hpp>
#include <log/level.hpp>
#include <log/log.hpp>

#include <stdx/ct_string.hpp>
Expand All @@ -20,9 +22,9 @@ constexpr auto run_func() -> void {
if constexpr (not FlowName.empty()) {
using log_spec_t =
decltype(get_log_spec<CTNode, log_spec_id_t<FlowName>>());
CIB_LOG(typename log_spec_t::flavor, log_spec_t::level,
"flow.{}({})", typename CTNode::type_t{},
typename CTNode::name_t{});
CIB_LOG_ENV(logging::get_level, log_spec_t::level);
CIB_LOG(typename log_spec_t::flavor, "flow.{}({})",
typename CTNode::type_t{}, typename CTNode::name_t{});
}
typename CTNode::func_t{}();
}
Expand Down Expand Up @@ -60,16 +62,16 @@ template <stdx::ct_string Name, auto... FuncPtrs> struct inlined_func_list {

if constexpr (loggingEnabled) {
using log_spec_t = decltype(get_log_spec<inlined_func_list>());
CIB_LOG(typename log_spec_t::flavor, log_spec_t::level,
"flow.start({})", name);
CIB_LOG_ENV(logging::get_level, log_spec_t::level);
CIB_LOG(typename log_spec_t::flavor, "flow.start({})", name);
}

(FuncPtrs(), ...);

if constexpr (loggingEnabled) {
using log_spec_t = decltype(get_log_spec<inlined_func_list>());
CIB_LOG(typename log_spec_t::flavor, log_spec_t::level,
"flow.end({})", name);
CIB_LOG_ENV(logging::get_level, log_spec_t::level);
CIB_LOG(typename log_spec_t::flavor, "flow.end({})", name);
}
}
};
Expand Down
21 changes: 11 additions & 10 deletions include/log/catalog/mipi_encoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@

namespace logging::mipi {
namespace detail {
template <logging::level L, typename S, typename... Args>
constexpr auto to_message() {
template <auto L, typename S, typename... Args> constexpr auto to_message() {
constexpr auto s = S::value;
using char_t = typename std::remove_cv_t<decltype(s)>::value_type;
return [&]<std::size_t... Is>(std::integer_sequence<std::size_t, Is...>) {
return sc::message<
L, sc::undefined<sc::args<Args...>, char_t, s[Is]...>>{};
static_cast<logging::level>(L),
sc::undefined<sc::args<Args...>, char_t, s[Is]...>>{};
}(std::make_integer_sequence<std::size_t, std::size(s)>{});
}

Expand Down Expand Up @@ -103,21 +103,22 @@ using catalog_msg_t =
template <typename TDestinations> struct log_handler {
constexpr explicit log_handler(TDestinations &&ds) : dests{std::move(ds)} {}

template <logging::level Level, typename Env, typename FilenameStringType,
template <typename Env, typename FilenameStringType,
typename LineNumberType, typename MsgType>
ALWAYS_INLINE auto log(FilenameStringType, LineNumberType,
MsgType const &msg) -> void {
log_msg<Level, Env>(msg);
log_msg<Env>(msg);
}

template <logging::level Level, typename Env, typename Msg>
template <typename Env, typename Msg>
ALWAYS_INLINE auto log_msg(Msg msg) -> void {
msg.apply([&]<typename S, typename... Args>(S, Args... args) {
using Message = decltype(detail::to_message<Level, S, Args...>());
constexpr auto L = stdx::to_underlying(get_level(Env{}).value);
using Message = decltype(detail::to_message<L, S, Args...>());
using Module =
decltype(detail::to_module<get_module(Env{}).value>());
dispatch_message<Level>(catalog<Message>(), module<Module>(),
static_cast<std::uint32_t>(args)...);
dispatch_message<L>(catalog<Message>(), module<Module>(),
static_cast<std::uint32_t>(args)...);
});
}

Expand Down Expand Up @@ -173,7 +174,7 @@ template <typename TDestinations> struct log_handler {
dests);
}

template <logging::level Level, std::same_as<std::uint32_t>... MsgDataTypes>
template <auto Level, std::same_as<std::uint32_t>... MsgDataTypes>
ALWAYS_INLINE auto dispatch_message(string_id id,
[[maybe_unused]] module_id m,
MsgDataTypes... msg_data) -> void {
Expand Down
15 changes: 13 additions & 2 deletions include/log/env.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ template <std::size_t... Is> struct for_each_pair<std::index_sequence<Is...>> {
2 * Is + 1>::value.value>()>...>;
};
} // namespace detail

template <typename Env = env<>>
constexpr auto make_env = []<detail::autowrap... Args> {
using new_env_t = typename detail::for_each_pair<
std::make_index_sequence<sizeof...(Args) / 2>>::template type<Args...>;
return boost::mp11::mp_append<new_env_t, Env>{};
};

template <detail::autowrap... Args>
using make_env_t = decltype(make_env<>.template operator()<Args...>());
} // namespace logging

using cib_log_env_t = logging::env<>;
Expand All @@ -82,10 +92,11 @@ using cib_log_env_t = logging::env<>;
#endif

#define CIB_LOG_ENV_DECL(...) \
[[maybe_unused]] typedef decltype([]<logging::detail::autowrap... Args> { \
[[maybe_unused]] typedef decltype([]<logging::detail:: \
autowrap... _env_args> { \
using new_env_t = \
typename logging::detail::for_each_pair<std::make_index_sequence< \
sizeof...(Args) / 2>>::template type<Args...>; \
sizeof...(_env_args) / 2>>::template type<_env_args...>; \
return boost::mp11::mp_append<new_env_t, cib_log_env_t>{}; \
}.template operator()<__VA_ARGS__>()) cib_log_env_t

Expand Down
13 changes: 9 additions & 4 deletions include/log/fmt/logger.hpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
#pragma once

#include <log/level.hpp>
#include <log/log.hpp>
#include <log/module.hpp>

#include <stdx/ct_format.hpp>
#include <stdx/tuple.hpp>
#include <stdx/tuple_algorithms.hpp>
#include <stdx/utility.hpp>

#include <fmt/format.h>

#include <chrono>
#include <type_traits>
#include <utility>

template <auto L> struct fmt::formatter<logging::level_constant<L>> {
template <logging::level L>
struct fmt::formatter<std::integral_constant<logging::level, L>> {
constexpr static auto parse(format_parse_context &ctx) {
return ctx.begin();
}

template <typename FormatContext>
auto format(logging::level_constant<L>, FormatContext &ctx) const {
auto format(std::integral_constant<logging::level, L>,
FormatContext &ctx) const {
return ::fmt::format_to(ctx.out(), logging::to_text<L>());
}
};
Expand All @@ -27,7 +32,7 @@ namespace logging::fmt {
template <typename TDestinations> struct log_handler {
constexpr explicit log_handler(TDestinations &&ds) : dests{std::move(ds)} {}

template <logging::level L, typename Env, typename FilenameStringType,
template <typename Env, typename FilenameStringType,
typename LineNumberType, typename MsgType>
auto log(FilenameStringType, LineNumberType, MsgType const &msg) -> void {
auto const currentTime =
Expand All @@ -38,7 +43,7 @@ template <typename TDestinations> struct log_handler {
stdx::for_each(
[&](auto &out) {
::fmt::format_to(out, "{:>8}us {} [{}]: ", currentTime,
level_constant<L>{}, get_module(Env{}).value);
get_level(Env{}), get_module(Env{}).value);
msg.apply(
[&]<typename StringType>(StringType, auto const &...args) {
::fmt::format_to(out, StringType::value, args...);
Expand Down
12 changes: 11 additions & 1 deletion include/log/level.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#pragma once

#include <log/env.hpp>

#include <stdx/type_traits.hpp>

#include <array>
#include <cstdint>
#include <string_view>
#include <type_traits>
#include <utility>

namespace logging {
// enum assignment is according to Mipi_Sys-T Severity definition
Expand All @@ -30,5 +33,12 @@ template <level L>
return level_text[stdx::to_underlying(L)];
}

template <level L> struct level_constant : std::integral_constant<level, L> {};
[[maybe_unused]] constexpr inline struct get_level_t {
template <typename T>
CONSTEVAL auto operator()(T &&t) const noexcept(
noexcept(std::forward<T>(t).query(std::declval<get_level_t>())))
-> decltype(std::forward<T>(t).query(*this)) {
return std::forward<T>(t).query(*this);
}
} get_level;
} // namespace logging
33 changes: 20 additions & 13 deletions include/log/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace logging {
namespace null {
struct config {
struct {
template <level, typename>
template <typename>
constexpr auto log(auto &&...) const noexcept -> void {}
} logger;
};
Expand All @@ -46,33 +46,39 @@ ALWAYS_INLINE constexpr static auto get_config() -> auto & {
}
}

template <typename Flavor, level L, typename Env, typename... Ts,
typename... TArgs>
template <typename Flavor, typename Env, typename... Ts, typename... TArgs>
ALWAYS_INLINE static auto log(TArgs &&...args) -> void {
auto &cfg = get_config<Flavor, Ts...>();
cfg.logger.template log<L, Env>(std::forward<TArgs>(args)...);
cfg.logger.template log<Env>(std::forward<TArgs>(args)...);
}
} // namespace logging

// NOLINTBEGIN(cppcoreguidelines-macro-usage)

#define CIB_LOG(FLAVOR, LEVEL, MSG, ...) \
logging::log<FLAVOR, LEVEL, cib_log_env_t>( \
#define CIB_LOG(FLAVOR, MSG, ...) \
logging::log<FLAVOR, cib_log_env_t>( \
__FILE__, __LINE__, sc::format(MSG##_sc __VA_OPT__(, ) __VA_ARGS__))

#define CIB_LOG_WITH_LEVEL(LEVEL, ...) \
do { \
CIB_LOG_ENV(logging::get_level, LEVEL); \
CIB_LOG(logging::default_flavor_t __VA_OPT__(, ) __VA_ARGS__); \
} while (false)

#define CIB_TRACE(...) \
CIB_LOG(logging::default_flavor_t, logging::level::TRACE, __VA_ARGS__)
CIB_LOG_WITH_LEVEL(logging::level::TRACE __VA_OPT__(, ) __VA_ARGS__)
#define CIB_INFO(...) \
CIB_LOG(logging::default_flavor_t, logging::level::INFO, __VA_ARGS__)
CIB_LOG_WITH_LEVEL(logging::level::INFO __VA_OPT__(, ) __VA_ARGS__)
#define CIB_WARN(...) \
CIB_LOG(logging::default_flavor_t, logging::level::WARN, __VA_ARGS__)
CIB_LOG_WITH_LEVEL(logging::level::WARN __VA_OPT__(, ) __VA_ARGS__)
#define CIB_ERROR(...) \
CIB_LOG(logging::default_flavor_t, logging::level::ERROR, __VA_ARGS__)
CIB_LOG_WITH_LEVEL(logging::level::ERROR __VA_OPT__(, ) __VA_ARGS__)

#define CIB_FATAL(MSG, ...) \
[](auto &&str) { \
logging::log<logging::default_flavor_t, logging::level::FATAL, \
cib_log_env_t>(__FILE__, __LINE__, str); \
CIB_LOG_ENV(logging::get_level, logging::level::FATAL); \
logging::log<logging::default_flavor_t, cib_log_env_t>(__FILE__, \
__LINE__, str); \
FWD(str).apply([]<typename S, typename... Args>(S s, Args... args) { \
constexpr auto cts = stdx::ct_string_from_type(s); \
stdx::panic<cts>(args...); \
Expand All @@ -93,7 +99,8 @@ ALWAYS_INLINE static auto log_version() -> void {
}) {
l_cfg.logger.template log_build<v_cfg.build_id, v_cfg.version_string>();
} else {
l_cfg.logger.template log<level::MAX, cib_log_env_t>(
CIB_LOG_ENV(logging::get_level, logging::level::MAX);
l_cfg.logger.template log<cib_log_env_t>(
"", 0,
sc::format("Version: {} ({})"_sc, sc::uint_<v_cfg.build_id>,
stdx::ct_string_to_type<v_cfg.version_string,
Expand Down
8 changes: 4 additions & 4 deletions test/flow/custom_log_levels.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <cib/cib.hpp>
#include <flow/flow.hpp>
#include <log/level.hpp>

#include <catch2/catch_test_macros.hpp>

Expand Down Expand Up @@ -37,11 +38,10 @@ constexpr auto msB = flow::milestone<"msB">();

struct log_config {
struct log_handler {
template <logging::level Level, typename ModuleId,
typename FilenameStringType, typename LineNumberType,
typename MsgType>
template <typename Env, typename FilenameStringType,
typename LineNumberType, typename MsgType>
auto log(FilenameStringType, LineNumberType, MsgType const &) -> void {
log_calls.push_back(Level);
log_calls.push_back(logging::get_level(Env{}).value);
}
};
log_handler logger;
Expand Down
8 changes: 4 additions & 4 deletions test/flow/log_levels.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <cib/cib.hpp>
#include <flow/flow.hpp>
#include <log/level.hpp>

#include <catch2/catch_test_macros.hpp>

Expand Down Expand Up @@ -34,11 +35,10 @@ constexpr auto ms = flow::milestone<"ms">();

struct log_config {
struct log_handler {
template <logging::level Level, typename ModuleId,
typename FilenameStringType, typename LineNumberType,
typename MsgType>
template <typename Env, typename FilenameStringType,
typename LineNumberType, typename MsgType>
auto log(FilenameStringType, LineNumberType, MsgType const &) -> void {
log_calls.push_back(Level);
log_calls.push_back(logging::get_level(Env{}).value);
}
};
log_handler logger;
Expand Down
9 changes: 8 additions & 1 deletion test/log/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
add_tests(FILES log module_id env LIBRARIES cib_log)
add_tests(
FILES
level
log
module_id
env
LIBRARIES
cib_log)
add_tests(FILES fmt_logger LIBRARIES cib_log_fmt)
add_tests(FILES mipi_encoder mipi_logger LIBRARIES cib_log_mipi)

Expand Down
30 changes: 17 additions & 13 deletions test/log/catalog1_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ struct test_log_args_destination {
last_header = hdr;
}
};

using log_env1 = logging::make_env_t<logging::get_level, logging::level::TRACE>;
} // namespace

auto log_zero_args() -> void;
Expand All @@ -27,32 +29,34 @@ auto log_with_fixed_module_id() -> void;

auto log_zero_args() -> void {
auto cfg = logging::mipi::config{test_log_args_destination{}};
cfg.logger.log_msg<logging::level::TRACE, cib_log_env_t>(
"A string with no placeholders"_sc);
cfg.logger.log_msg<log_env1>("A string with no placeholders"_sc);
}

auto log_one_ct_arg() -> void {
auto cfg = logging::mipi::config{test_log_args_destination{}};
cfg.logger.log_msg<logging::level::TRACE, cib_log_env_t>(
cfg.logger.log_msg<log_env1>(
format("B string with {} placeholder"_sc, "one"_sc));
}

auto log_one_rt_arg() -> void {
auto cfg = logging::mipi::config{test_log_args_destination{}};
cfg.logger.log_msg<logging::level::TRACE, cib_log_env_t>(
format("C string with {} placeholder"_sc, 1));
cfg.logger.log_msg<log_env1>(format("C string with {} placeholder"_sc, 1));
}

auto log_with_non_default_module_id() -> void {
CIB_LOG_MODULE("not default");
auto cfg = logging::mipi::config{test_log_args_destination{}};
cfg.logger.log_msg<logging::level::TRACE, cib_log_env_t>(
format("ModuleID string with {} placeholder"_sc, 1));
CIB_WITH_LOG_ENV(logging::get_level, logging::level::TRACE,
logging::get_module, "not default") {
auto cfg = logging::mipi::config{test_log_args_destination{}};
cfg.logger.log_msg<cib_log_env_t>(
format("ModuleID string with {} placeholder"_sc, 1));
}
}

auto log_with_fixed_module_id() -> void {
CIB_LOG_MODULE("fixed");
auto cfg = logging::mipi::config{test_log_args_destination{}};
cfg.logger.log_msg<logging::level::TRACE, cib_log_env_t>(
format("Fixed ModuleID string with {} placeholder"_sc, 1));
CIB_WITH_LOG_ENV(logging::get_level, logging::level::TRACE,
logging::get_module, "fixed") {
auto cfg = logging::mipi::config{test_log_args_destination{}};
cfg.logger.log_msg<cib_log_env_t>(
format("Fixed ModuleID string with {} placeholder"_sc, 1));
}
}
Loading
Loading