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
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ if(CONSOLIX_BUILD_TESTS)

if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_log_stream_macros.cpp")
consolix_add_test(test_log_stream_macros "tests/test_log_stream_macros.cpp")
target_compile_definitions(test_log_stream_macros
PRIVATE
CONSOLIX_FILE_LOGGER_PATH="tmp/agent-work/test-log-stream-macros"
CONSOLIX_UNIQUE_FILE_LOGGER_PATH="tmp/agent-work/test-unique-log-stream-macros"
)
endif()

if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_app_component_manager_shutdown_order.cpp")
Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,31 +162,31 @@ Consolix provides two multi-target log macros that route messages through
LogIt backends. The console backend is configured so that `ERROR` and `FATAL`
levels go to `std::cerr`, while `TRACE` through `WARN` go to `std::cout`.

| Macro | Console backend | File logger | Extra backends | Color |
| Macro | Console backend | Regular backends | Extra backends | Color |
|---|---|---|---|---|
| `CONSOLIX_LOG_STREAM(level)` | yes (level-based routing) | yes | — | via `<< color(...)` |
| `CONSOLIX_LOG_STREAM_EX(level, ...)` | yes (level-based routing) | yes | inline indices | via `<< color(...)` |
| `CONSOLIX_LOG_STREAM(level)` | yes (level-based routing) | broadcast | - | via `<< color(...)` |
| `CONSOLIX_LOG_STREAM_NO_BROADCAST(level)` | yes (level-based routing) | file fallback only | - | via `<< color(...)` |
| `CONSOLIX_LOG_STREAM_EX(level, ...)` | yes (level-based routing) | file fallback only | inline indices | via `<< color(...)` |

The `level` argument is mandatory (`logit::LogLevel::LOG_LVL_INFO`,
`LOG_LVL_ERROR`, etc.). Color is applied explicitly by the caller through
`<< consolix::color(consolix::TextColor::Red)`.

**Note on `_EX` variants.** The standard console backend (`CONSOLIX_LOGIT_CONSOLE_INDEX`)
and file logger (`CONSOLIX_LOGIT_LOGGER_INDEX`) are already included by both
`CONSOLIX_LOG_STREAM` and `CONSOLIX_LOG_STREAM_EX`. Only pass *additional*
backend indices to `_EX`:
is already included by both `CONSOLIX_LOG_STREAM` and `CONSOLIX_LOG_STREAM_EX`.
`CONSOLIX_LOG_STREAM` broadcasts to regular non-single backends, including the
standard file logger and user-added regular backends. `CONSOLIX_LOG_STREAM_EX`
does not broadcast; it writes to the file fallback and to the listed backend
indices.

```cpp
CONSOLIX_LOG_STREAM_EX(logit::LogLevel::LOG_LVL_ERROR, 5)
<< "Hello with extra backend" << std::endl;
```

**Inline override.** To fan out to additional LogIt backends beyond the
standard console and file logger, use the `_EX` variant:
**Inline targets.** To target selected LogIt backends beyond the standard
console and file fallback, use the `_EX` variant:

```cpp
CONSOLIX_LOG_STREAM_EX(logit::LogLevel::LOG_LVL_ERROR, 0, 2, 5)
<< "Hello with extra backends" << std::endl;
CONSOLIX_LOG_STREAM_EX(
logit::LogLevel::LOG_LVL_ERROR,
CONSOLIX_LOGIT_UNIQUE_FILE_INDEX)
<< "Hello with an extra single-mode backend" << std::endl;
```

See `examples/example_stderr_diagnostics.cpp` for a runnable example.
Expand Down
38 changes: 28 additions & 10 deletions include/consolix/components/LoggerComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,42 @@
#define CONSOLIX_LOGIT_UNIQUE_FILE_INDEX 4

/// \brief Defines the general log stream for the application.
/// Redirects logs to the main console backend with detailed context.
/// Redirects display output to the main console backend and broadcasts the
/// same record to regular LogIt backends.
#define CONSOLIX_STREAM() \
consolix::MultiStream( \
logit::LogLevel::LOG_LVL_TRACE, \
logit::make_relative(__FILE__, LOGIT_BASE_PATH), \
__LINE__, \
LOGIT_FUNCTION)

/// \brief Defines a multi-target log stream (file logger + console + extra LogIt backends).
/// \brief Defines a multi-target log stream (console + regular LogIt backends).
/// \param level LogIt level for the multi-target stream.
/// \details Routes the message to the standard file logger, the main console
/// backend, and any explicit inline backend indices supplied via
/// the `CONSOLIX_LOG_STREAM_EX` variant.
/// \details Routes the message to the main single-mode console backend and
/// broadcasts it to regular non-single LogIt backends, including the
/// standard file logger and user-added regular backends.
#define CONSOLIX_LOG_STREAM(level) \
consolix::MultiStream( \
(level), \
logit::make_relative(__FILE__, LOGIT_BASE_PATH), \
__LINE__, \
LOGIT_FUNCTION)

/// \brief Defines a log stream that targets the console and file fallback
/// without broadcasting to user-added regular LogIt backends.
/// \param level LogIt level for the stream.
#define CONSOLIX_LOG_STREAM_NO_BROADCAST(level) \
consolix::MultiStream( \
(level), \
logit::make_relative(__FILE__, LOGIT_BASE_PATH), \
__LINE__, \
LOGIT_FUNCTION, \
{})

/// \brief Defines a multi-target log stream with an explicit inline list of
/// additional LogIt backend indices.
/// \brief Defines a log stream with an explicit inline list of extra LogIt
/// backend indices and no regular broadcast.
/// \param level LogIt level for the multi-target stream.
/// \param ... Comma-separated LogIt backend indices (e.g. `0,3`).
/// \param ... Comma-separated extra LogIt backend indices.
#define CONSOLIX_LOG_STREAM_EX(level, ...) \
consolix::MultiStream( \
(level), \
Expand Down Expand Up @@ -209,8 +220,10 @@ namespace consolix {
if (is_once) return;
is_once = true;

// Primary console backend with level-based routing:
// Primary single-mode console backend with level-based routing:
// TRACE..WARN -> std::cout, ERROR..FATAL -> std::cerr.
// General LogIt broadcasts skip it; Consolix display streams
// target it explicitly.
// The config object's primary stream (std::cout by default) is only
// used as a fallback when no route matches; our routes cover all
// levels, so every record is dispatched by level.
Expand All @@ -224,7 +237,7 @@ namespace consolix {
logit::ConsoleStreamRoute::to_cerr(
logit::LogLevel::LOG_LVL_ERROR,
logit::LogLevel::LOG_LVL_FATAL));
LOGIT_ADD_CONSOLE_CONFIG(console_cfg, console_pattern);
LOGIT_ADD_CONSOLE_CONFIG_SINGLE_MODE(console_cfg, console_pattern);

LOGIT_ADD_CONSOLE_SINGLE_MODE("%^%v%$", true); // Logo log stream
LOGIT_ADD_CONSOLE(m_debug_pattern, true); // Debug log stream
Expand Down Expand Up @@ -262,6 +275,11 @@ namespace consolix {
#define CONSOLIX_LOG_STREAM(level) \
consolix::MultiStream()

/// \brief Fallback no-broadcast log stream. The `level` argument is
/// ignored when LogIt is disabled.
#define CONSOLIX_LOG_STREAM_NO_BROADCAST(level) \
consolix::MultiStream()

/// \brief Fallback multi-target log stream with an ignored backend list.
#define CONSOLIX_LOG_STREAM_EX(level, ...) \
consolix::MultiStream()
Expand Down
38 changes: 32 additions & 6 deletions include/consolix/components/LoggerComponent/MultiStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ namespace consolix {
: m_level(logit::LogLevel::LOG_LVL_TRACE),
m_file(__FILE__),
m_line(__LINE__),
m_function(logit::make_relative(__FILE__, LOGIT_BASE_PATH)) {
m_function(logit::make_relative(__FILE__, LOGIT_BASE_PATH)),
m_broadcast_regular(true) {
}

/// \brief Parameterized constructor for LogIt integration.
Expand All @@ -49,7 +50,11 @@ namespace consolix {
const std::string& file,
int line,
const std::string& function)
: m_level(level), m_file(file), m_line(line), m_function(function) {
: m_level(level),
m_file(file),
m_line(line),
m_function(function),
m_broadcast_regular(true) {
}

/// \brief Parameterized constructor for LogIt integration with
Expand All @@ -59,18 +64,23 @@ namespace consolix {
/// \param line Line number in the source file.
/// \param function Function name.
/// \param logger_indices Extra LogIt backend indices to fan out to
/// in addition to the standard file/console targets.
/// when regular backend broadcast is disabled, or extra
/// single-mode indices when regular backend broadcast is enabled.
/// \param broadcast_regular Whether to broadcast to regular
/// non-single LogIt backends.
MultiStream(
logit::LogLevel level,
const std::string& file,
int line,
const std::string& function,
std::initializer_list<int> logger_indices)
std::initializer_list<int> logger_indices,
bool broadcast_regular = false)
: m_level(level),
m_file(file),
m_line(line),
m_function(function),
m_logger_indices(logger_indices) {
m_logger_indices(logger_indices),
m_broadcast_regular(broadcast_regular) {
}

# else
Expand All @@ -97,8 +107,23 @@ namespace consolix {
if (LOGIT_IS_SINGLE_MODE(CONSOLIX_LOGIT_CONSOLE_INDEX)) {
logit::LogStream(m_level, m_file, m_line, m_function, CONSOLIX_LOGIT_CONSOLE_INDEX) << str;
}
logit::LogStream(m_level, m_file, m_line, m_function, CONSOLIX_LOGIT_LOGGER_INDEX) << str;
if (m_broadcast_regular) {
logit::LogStream(m_level, m_file, m_line, m_function, -1) << str;
} else {
logit::LogStream(m_level, m_file, m_line, m_function, CONSOLIX_LOGIT_LOGGER_INDEX) << str;
}
for (int logger_index : m_logger_indices) {
if (logger_index == CONSOLIX_LOGIT_CONSOLE_INDEX) {
continue;
}
if (!m_broadcast_regular &&
logger_index == CONSOLIX_LOGIT_LOGGER_INDEX) {
continue;
}
if (m_broadcast_regular &&
!LOGIT_IS_SINGLE_MODE(logger_index)) {
continue;
}
logit::LogStream(m_level, m_file, m_line, m_function, logger_index) << str;
}
# else
Expand Down Expand Up @@ -139,6 +164,7 @@ namespace consolix {
int m_line; ///< Line number.
std::string m_function; ///< Function name.
std::vector<int> m_logger_indices; ///< Extra LogIt backend indices for fan-out.
bool m_broadcast_regular; ///< Broadcast to regular non-single backends.
# else
bool m_use_utf8; ///< Flag indicating whether UTF-8 encoding should be used.
# endif
Expand Down
Loading
Loading