Skip to content

feat(logging): add unified logging macros and helper functions (#175)#182

Merged
kcenon merged 4 commits into
mainfrom
feat/175-unified-logging-macros
Dec 5, 2025
Merged

feat(logging): add unified logging macros and helper functions (#175)#182
kcenon merged 4 commits into
mainfrom
feat/175-unified-logging-macros

Conversation

@kcenon

@kcenon kcenon commented Dec 5, 2025

Copy link
Copy Markdown
Owner

Summary

This PR implements Issue #175, adding unified logging macros and helper functions that provide a consistent logging interface across all subsystems with automatic source_location capture.

Key Features

1. Inline Logging Functions (log_functions.h)

  • Level-specific functions: log_trace(), log_debug(), log_info(), log_warning(), log_error(), log_critical()
  • Automatic source_location capture (C++17/C++20 compatible via custom wrapper)
  • Support for default logger and named loggers
  • Utility functions: is_enabled(), flush()
  • All functions are inline for zero overhead when logging is disabled

2. Logging Macros (log_macros.h)

  • Standard macros: LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_CRITICAL
  • Named logger macros: LOG_*_TO(logger_name, msg)
  • Conditional logging: LOG_IF(level, msg) for avoiding expensive message construction when level is disabled
  • Compile-time level filtering via KCENON_MIN_LOG_LEVEL
  • Legacy compatibility: THREAD_LOG_* macros redirect to LOG_*

Files Changed

File Description
include/kcenon/common/logging/log_functions.h New: Inline logging functions with source_location
include/kcenon/common/logging/log_macros.h New: Preprocessor macros for convenient logging
include/kcenon/common/common.h Updated: Include new logging headers
tests/log_functions_test.cpp New: Comprehensive unit tests (30 tests)
tests/CMakeLists.txt Updated: Add test target
docs/API_REFERENCE.md Updated: Document new logging API
docs/CHANGELOG.md Updated: Add changelog entry

Usage Examples

#include <kcenon/common/logging/log_macros.h>

// Simple logging
LOG_INFO("Application started");
LOG_DEBUG("Processing item " + std::to_string(id));

// Named logger
LOG_ERROR_TO("database", "Connection timeout");

// Conditional (efficient when debug is disabled)
LOG_IF(log_level::debug, expensive_debug_string());

// Compile-time filtering (define before include)
#define KCENON_MIN_LOG_LEVEL 2  // Disable trace and debug

Test Plan

  • All 30 unit tests pass (common_log_functions_test)
  • All 35 GlobalLoggerRegistry tests still pass (no regressions)
  • Build succeeds on macOS with C++17
  • Documentation updated with complete API reference

Dependencies

Closes #175

…port

This commit introduces inline logging functions that integrate with
GlobalLoggerRegistry and automatically capture source location information
at the call site.

Key features implemented:
- Level-specific functions: log_trace(), log_debug(), log_info(),
  log_warning(), log_error(), log_critical()
- Automatic source_location capture (C++17/C++20 compatible)
- Support for default logger and named loggers
- Utility functions: is_enabled(), flush()
- All functions are inline for zero overhead when logging is disabled

The log_functions.h header provides:
- log(level, message): Log to default logger
- log(level, message, logger): Log to specific logger instance
- log(level, message, logger_name): Log to named logger from registry
- Level-specific convenience functions with source location capture

Thread Safety:
- All functions are thread-safe
- Source location capture happens at compile-time
- Logger retrieval uses thread-safe GlobalLoggerRegistry

Updated common.h to include new logging headers for easy access.

Refs: #175
…and macros

This commit adds unit tests covering all aspects of the unified logging
implementation, ensuring correctness and thread safety.

Test categories implemented:

1. Basic Logging Function Tests:
   - Log message with correct level
   - Source location automatic capture
   - All log levels (trace, debug, info, warning, error, critical)

2. Named Logger Tests:
   - Logging to named loggers via registry
   - Logging to specific logger instances
   - Named logger with level-specific functions

3. Level Filtering Tests:
   - Log level filtering behavior
   - is_enabled() function correctness
   - Named logger level checking

4. Flush Tests:
   - Default logger flush
   - Named logger flush

5. Macro Tests:
   - LOG_* macros for all levels
   - LOG_*_TO macros for named loggers
   - LOG_IF conditional logging
   - LOG_FLUSH and LOG_IS_ENABLED utilities

6. Legacy Compatibility Tests:
   - THREAD_LOG_* macros redirect to LOG_*
   - All legacy levels work correctly

7. NullLogger Fallback Tests:
   - Unregistered logger returns NullLogger
   - No default logger uses NullLogger

8. Thread Safety Tests:
   - Concurrent logging to default logger
   - Concurrent logging to multiple loggers

9. String Compatibility Tests:
   - std::string_view input
   - const char* input
   - std::string input

All 30 tests pass successfully.

Refs: #175
This commit updates documentation to reflect the new unified logging
functions and macros introduced in Issue #175.

API Reference updates:
- Added "Unified Logging" section with complete API documentation
- Documented log_functions.h with all function signatures
- Documented log_macros.h with all macro definitions
- Added usage examples for both functions and macros
- Documented compile-time level filtering via KCENON_MIN_LOG_LEVEL
- Documented legacy THREAD_LOG_* compatibility macros
- Updated version to 2.1 and last updated date

Changelog updates:
- Added entry for unified logging functions and macros
- Listed all new features:
  - Level-specific functions with source_location
  - Standard LOG_* macros
  - Named logger LOG_*_TO macros
  - Conditional LOG_IF macros
  - Compile-time level filtering
  - Legacy THREAD_LOG_* compatibility

Refs: #175
@codecov

codecov Bot commented Dec 5, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (a05cbab) to head (5c29d46).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@          Coverage Diff          @@
##            main    #182   +/-   ##
=====================================
  Coverage   0.00%   0.00%           
=====================================
  Files         13      13           
  Lines       1582    1582           
=====================================
  Misses      1582    1582           
Flag Coverage Δ
integration-tests 0.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This commit fixes a compilation error on Clang where calls like
`log_info("message", "logger_name")` were ambiguous between:
- `log_info(string_view message, source_location loc = current())`
- `log_info(string_view message, string logger_name, source_location loc = current())`

The issue occurred because C string literals can implicitly convert to both
source_location (via default parameter) and std::string, causing Clang to
report "call to 'log_info' is ambiguous".

Solution:
- Renamed named logger functions from `log_*()` to `log_*_to()`
- Changed parameter order to `log_*_to(logger_name, message)`
- This eliminates overload ambiguity by using distinct function names

API changes:
- Old: `log_info("msg", "logger")` - REMOVED (ambiguous)
- New: `log_info_to("logger", "msg")` - ADDED (unambiguous)

The LOG_*_TO macros continue to work with the same syntax:
`LOG_INFO_TO("logger", "msg")` - unchanged interface

Updated:
- log_functions.h: Renamed functions with "_to" suffix
- log_macros.h: Updated macro implementations
- Tests: Updated to use new function names
- API documentation: Reflected new function signatures

Refs: #175
@kcenon kcenon merged commit 19504f7 into main Dec 5, 2025
25 checks passed
@kcenon kcenon deleted the feat/175-unified-logging-macros branch December 5, 2025 14:51
kcenon added a commit that referenced this pull request Apr 13, 2026
…#182)

* feat(logging): add unified logging functions with source_location support

This commit introduces inline logging functions that integrate with
GlobalLoggerRegistry and automatically capture source location information
at the call site.

Key features implemented:
- Level-specific functions: log_trace(), log_debug(), log_info(),
  log_warning(), log_error(), log_critical()
- Automatic source_location capture (C++17/C++20 compatible)
- Support for default logger and named loggers
- Utility functions: is_enabled(), flush()
- All functions are inline for zero overhead when logging is disabled

The log_functions.h header provides:
- log(level, message): Log to default logger
- log(level, message, logger): Log to specific logger instance
- log(level, message, logger_name): Log to named logger from registry
- Level-specific convenience functions with source location capture

Thread Safety:
- All functions are thread-safe
- Source location capture happens at compile-time
- Logger retrieval uses thread-safe GlobalLoggerRegistry

Updated common.h to include new logging headers for easy access.

Refs: #175

* test(logging): add comprehensive tests for unified logging functions and macros

This commit adds unit tests covering all aspects of the unified logging
implementation, ensuring correctness and thread safety.

Test categories implemented:

1. Basic Logging Function Tests:
   - Log message with correct level
   - Source location automatic capture
   - All log levels (trace, debug, info, warning, error, critical)

2. Named Logger Tests:
   - Logging to named loggers via registry
   - Logging to specific logger instances
   - Named logger with level-specific functions

3. Level Filtering Tests:
   - Log level filtering behavior
   - is_enabled() function correctness
   - Named logger level checking

4. Flush Tests:
   - Default logger flush
   - Named logger flush

5. Macro Tests:
   - LOG_* macros for all levels
   - LOG_*_TO macros for named loggers
   - LOG_IF conditional logging
   - LOG_FLUSH and LOG_IS_ENABLED utilities

6. Legacy Compatibility Tests:
   - THREAD_LOG_* macros redirect to LOG_*
   - All legacy levels work correctly

7. NullLogger Fallback Tests:
   - Unregistered logger returns NullLogger
   - No default logger uses NullLogger

8. Thread Safety Tests:
   - Concurrent logging to default logger
   - Concurrent logging to multiple loggers

9. String Compatibility Tests:
   - std::string_view input
   - const char* input
   - std::string input

All 30 tests pass successfully.

Refs: #175

* docs(logging): update API reference and changelog for unified logging

This commit updates documentation to reflect the new unified logging
functions and macros introduced in Issue #175.

API Reference updates:
- Added "Unified Logging" section with complete API documentation
- Documented log_functions.h with all function signatures
- Documented log_macros.h with all macro definitions
- Added usage examples for both functions and macros
- Documented compile-time level filtering via KCENON_MIN_LOG_LEVEL
- Documented legacy THREAD_LOG_* compatibility macros
- Updated version to 2.1 and last updated date

Changelog updates:
- Added entry for unified logging functions and macros
- Listed all new features:
  - Level-specific functions with source_location
  - Standard LOG_* macros
  - Named logger LOG_*_TO macros
  - Conditional LOG_IF macros
  - Compile-time level filtering
  - Legacy THREAD_LOG_* compatibility

Refs: #175

* fix(logging): resolve function overload ambiguity with Clang compiler

This commit fixes a compilation error on Clang where calls like
`log_info("message", "logger_name")` were ambiguous between:
- `log_info(string_view message, source_location loc = current())`
- `log_info(string_view message, string logger_name, source_location loc = current())`

The issue occurred because C string literals can implicitly convert to both
source_location (via default parameter) and std::string, causing Clang to
report "call to 'log_info' is ambiguous".

Solution:
- Renamed named logger functions from `log_*()` to `log_*_to()`
- Changed parameter order to `log_*_to(logger_name, message)`
- This eliminates overload ambiguity by using distinct function names

API changes:
- Old: `log_info("msg", "logger")` - REMOVED (ambiguous)
- New: `log_info_to("logger", "msg")` - ADDED (unambiguous)

The LOG_*_TO macros continue to work with the same syntax:
`LOG_INFO_TO("logger", "msg")` - unchanged interface

Updated:
- log_functions.h: Renamed functions with "_to" suffix
- log_macros.h: Updated macro implementations
- Tests: Updated to use new function names
- API documentation: Reflected new function signatures

Refs: #175
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(logging): add unified logging macros and helper functions

1 participant