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
15 changes: 15 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ option(LOGIT_CPP_BUILD_TESTS "Build log-it-cpp tests" ${PROJECT_IS_TOP_LEVEL})
option(LOGIT_CPP_BUILD_EXAMPLES "Build log-it-cpp examples" OFF)
option(LOGIT_WITH_GZIP "Enable gzip via zlib" OFF)
option(LOGIT_WITH_ZSTD "Enable zstd" OFF)
option(LOGIT_WITH_FMT "Enable fmt support" OFF)
option(LOGIT_USE_SUBMODULES "Allow bundled third_party fallback" OFF)
option(LOGIT_WITH_SYSLOG "Enable POSIX syslog backend" ON)
option(LOGIT_WITH_WIN_EVENT_LOG "Enable Windows Event Log backend" ON)
Expand Down Expand Up @@ -62,6 +63,20 @@ if(LOGIT_WITH_WIN_EVENT_LOG AND WIN32)
target_link_libraries(log-it-cpp INTERFACE advapi32)
endif()

if(LOGIT_WITH_FMT)
if(NOT TARGET fmt::fmt)
find_package(fmt QUIET CONFIG)
endif()
if(NOT TARGET fmt::fmt AND LOGIT_USE_SUBMODULES)
add_subdirectory(libs/fmt EXCLUDE_FROM_ALL)
endif()
if(NOT TARGET fmt::fmt)
message(FATAL_ERROR "fmt not found. Enable LOGIT_USE_SUBMODULES or install fmt.")
endif()
target_compile_definitions(log-it-cpp INTERFACE LOGIT_WITH_FMT=1)
target_link_libraries(log-it-cpp INTERFACE fmt::fmt)
endif()

# ---------- GZIP (zlib) ----------
if(LOGIT_WITH_GZIP)
if(NOT TARGET ZLIB::ZLIB)
Expand Down
207 changes: 207 additions & 0 deletions include/logit_cpp/logit/LogMacros.hpp

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions include/logit_cpp/logit/formatter/compiler/PatternCompiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,26 @@ namespace logit {
case ValueType::SMART_POINTER_VAL:
case ValueType::VARIANT_VAL:
case ValueType::OPTIONAL_VAL:
#ifdef LOGIT_WITH_FMT
temp_stream << (record.fmt_mode ? arg.to_string_fmt(record.format.c_str()) : arg.to_string(record.format.c_str()));
#else
temp_stream << arg.to_string(record.format.c_str());
#endif
break;
default:
#ifdef LOGIT_WITH_FMT
if (arg.is_literal) {
temp_stream << arg.name << ": " << (record.fmt_mode ? arg.to_string_fmt(record.format.c_str()) : arg.to_string(record.format.c_str()));
} else {
temp_stream << (record.fmt_mode ? arg.to_string_fmt(record.format.c_str()) : arg.to_string(record.format.c_str()));
}
#else
if (arg.is_literal) {
temp_stream << arg.name << ": " << arg.to_string(record.format.c_str());
} else {
temp_stream << arg.to_string(record.format.c_str());
}
#endif
break;
};
}
Expand Down
7 changes: 5 additions & 2 deletions include/logit_cpp/logit/utils/LogRecord.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace logit {
std::thread::id thread_id; ///< ID of the logging thread.
const int logger_index; ///< Logger index (-1 to log to all).
const bool print_mode; ///< Flag to determine whether arguments are printed in a raw format without special symbols.
const bool fmt_mode; ///< Flag indicating if fmt formatting should be used.

/// \brief Constructor with argument names.
/// \param log_level Log severity level.
Expand All @@ -46,7 +47,8 @@ namespace logit {
const std::string& format,
const std::string& arg_names,
int logger_index,
bool print_mode) :
bool print_mode,
bool fmt_mode = false) :
log_level(log_level),
timestamp_ms(timestamp_ms),
file(file),
Expand All @@ -56,7 +58,8 @@ namespace logit {
arg_names(arg_names),
thread_id(std::this_thread::get_id()),
logger_index(logger_index),
print_mode(print_mode) {
print_mode(print_mode),
fmt_mode(fmt_mode) {
};
};

Expand Down
41 changes: 41 additions & 0 deletions include/logit_cpp/logit/utils/VariableValue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include <optional>
#include <variant>
#endif
#ifdef LOGIT_WITH_FMT
#include <fmt/format.h>
#endif

namespace logit {

Expand Down Expand Up @@ -376,6 +379,44 @@ namespace logit {
return "unknown";
}

#ifdef LOGIT_WITH_FMT
/// \brief Method to get the value as a formatted string using fmt.
/// \param fmt The fmt format string.
/// \return Formatted string representation of the value.
std::string to_string_fmt(const char* fmt) const {
switch (type) {
case ValueType::INT8_VAL: return fmt::format(fmt, pod_value.int8_value);
case ValueType::UINT8_VAL: return fmt::format(fmt, pod_value.uint8_value);
case ValueType::INT16_VAL: return fmt::format(fmt, pod_value.int16_value);
case ValueType::UINT16_VAL: return fmt::format(fmt, pod_value.uint16_value);
case ValueType::INT32_VAL: return fmt::format(fmt, pod_value.int32_value);
case ValueType::UINT32_VAL: return fmt::format(fmt, pod_value.uint32_value);
case ValueType::INT64_VAL: return fmt::format(fmt, pod_value.int64_value);
case ValueType::UINT64_VAL: return fmt::format(fmt, pod_value.uint64_value);
case ValueType::BOOL_VAL: return fmt::format(fmt, pod_value.bool_value);
case ValueType::CHAR_VAL: return fmt::format(fmt, pod_value.char_value);
case ValueType::FLOAT_VAL: return fmt::format(fmt, pod_value.float_value);
case ValueType::DOUBLE_VAL: return fmt::format(fmt, pod_value.double_value);
case ValueType::LONG_DOUBLE_VAL: return fmt::format(fmt, static_cast<double>(pod_value.long_double_value));
case ValueType::STRING_VAL:
case ValueType::EXCEPTION_VAL:
case ValueType::ENUM_VAL:
case ValueType::PATH_VAL:
case ValueType::DURATION_VAL:
case ValueType::TIME_POINT_VAL:
case ValueType::POINTER_VAL:
case ValueType::SMART_POINTER_VAL:
case ValueType::VARIANT_VAL:
case ValueType::OPTIONAL_VAL:
return fmt::format(fmt, string_value);
case ValueType::ERROR_CODE_VAL:
return fmt::format(fmt, error_code_value.message(), error_code_value.value());
default: break;
}
return "unknown";
}
#endif

private:
/// \brief Helper function to check if a name is a valid literal.
/// \param name The name to check.
Expand Down
3 changes: 3 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ else()
if(NOT LOGIT_WITH_ZSTD)
list(REMOVE_ITEM TEST_SOURCES ${CMAKE_CURRENT_LIST_DIR}/file_logger_zstd_compression_test.cpp)
endif()
if(NOT LOGIT_WITH_FMT)
list(REMOVE_ITEM TEST_SOURCES ${CMAKE_CURRENT_LIST_DIR}/fmt_macros_test.cpp)
endif()
foreach(test_src ${TEST_SOURCES})
get_filename_component(test_name ${test_src} NAME_WE)
add_executable(${test_name} ${test_src})
Expand Down
12 changes: 12 additions & 0 deletions tests/compiled_level_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ int main() {
LOGIT_FORMAT_TRACE("%d", should_not_compile<int>());
LOGIT_PRINT_TRACE(should_not_compile<int>());
LOGIT_PRINTF_TRACE("%d", should_not_compile<int>());
LOGITF_TRACE("{}", should_not_compile<int>());
LOGIT_FMT_TRACE("{}", should_not_compile<int>());
LOGIT_TRACE_TO(0, should_not_compile<int>());
LOGIT_TRACE0_TO(0);
LOGIT_0TRACE_TO(0);
Expand All @@ -25,6 +27,8 @@ int main() {
LOGIT_FORMAT_TRACE_TO(0, "%d", should_not_compile<int>());
LOGIT_PRINT_TRACE_TO(0, should_not_compile<int>());
LOGIT_PRINTF_TRACE_TO(0, "%d", should_not_compile<int>());
LOGITF_TRACE_TO(0, "{}", should_not_compile<int>());
LOGIT_FMT_TRACE_TO(0, "{}", should_not_compile<int>());
LOGIT_TRACE_IF(false, should_not_compile<int>());
LOGIT_TRACE0_IF(false);
LOGIT_0TRACE_IF(false);
Expand All @@ -33,6 +37,8 @@ int main() {
LOGIT_FORMAT_TRACE_IF(false, "%d", should_not_compile<int>());
LOGIT_PRINT_TRACE_IF(false, should_not_compile<int>());
LOGIT_PRINTF_TRACE_IF(false, "%d", should_not_compile<int>());
LOGITF_TRACE_IF(false, "{}", should_not_compile<int>());
LOGIT_FMT_TRACE_IF(false, "{}", should_not_compile<int>());

// DEBUG macros
LOGIT_DEBUG(should_not_compile<int>());
Expand All @@ -43,6 +49,8 @@ int main() {
LOGIT_FORMAT_DEBUG("%d", should_not_compile<int>());
LOGIT_PRINT_DEBUG(should_not_compile<int>());
LOGIT_PRINTF_DEBUG("%d", should_not_compile<int>());
LOGITF_DEBUG("{}", should_not_compile<int>());
LOGIT_FMT_DEBUG("{}", should_not_compile<int>());
LOGIT_DEBUG_TO(0, should_not_compile<int>());
LOGIT_DEBUG0_TO(0);
LOGIT_0DEBUG_TO(0);
Expand All @@ -51,6 +59,8 @@ int main() {
LOGIT_FORMAT_DEBUG_TO(0, "%d", should_not_compile<int>());
LOGIT_PRINT_DEBUG_TO(0, should_not_compile<int>());
LOGIT_PRINTF_DEBUG_TO(0, "%d", should_not_compile<int>());
LOGITF_DEBUG_TO(0, "{}", should_not_compile<int>());
LOGIT_FMT_DEBUG_TO(0, "{}", should_not_compile<int>());
LOGIT_DEBUG_IF(false, should_not_compile<int>());
LOGIT_DEBUG0_IF(false);
LOGIT_0DEBUG_IF(false);
Expand All @@ -59,5 +69,7 @@ int main() {
LOGIT_FORMAT_DEBUG_IF(false, "%d", should_not_compile<int>());
LOGIT_PRINT_DEBUG_IF(false, should_not_compile<int>());
LOGIT_PRINTF_DEBUG_IF(false, "%d", should_not_compile<int>());
LOGITF_DEBUG_IF(false, "{}", should_not_compile<int>());
LOGIT_FMT_DEBUG_IF(false, "{}", should_not_compile<int>());
return 0;
}
22 changes: 22 additions & 0 deletions tests/fmt_macros_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#define LOGIT_FILE_LOGGER_PATH "."
#include <LogIt.hpp>
#include <fstream>
#include <string>

int main() {
LOGIT_ADD_FILE_LOGGER_DEFAULT();
LOGITF_INFO("fmt {}", 42);
int value = 5;
LOGIT_FMT_INFO("{:04}", value);
LOGIT_WAIT();
std::ifstream in(LOGIT_GET_LAST_FILE_PATH(0));
std::string line;
bool found_fmt = false;
bool found_fmt_arg = false;
while (std::getline(in, line)) {
if (line.find("fmt 42") != std::string::npos) found_fmt = true;
if (line.find("0005") != std::string::npos) found_fmt_arg = true;
}
LOGIT_SHUTDOWN();
return (found_fmt && found_fmt_arg) ? 0 : 1;
}
Loading