Skip to content

fix: Enhance logging examples and configuration for cross-platform use - #20

Merged
ajeetsinghyadav merged 16 commits into
mainfrom
VNE_LOGGING_REFACTORING_FLUSH
May 22, 2026
Merged

ajeetsinghyadav merged 16 commits into
mainfrom
VNE_LOGGING_REFACTORING_FLUSH

Conversation

@ajeetsinghyadav

@ajeetsinghyadav ajeetsinghyadav commented May 22, 2026 •

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Added a platform logging example demonstrating cross-platform logger setup.
    • Applications can override the default log directory path.
  • Enhancements

    • File logging supports append or overwrite modes.
    • Flushing is now level-aware and defaults to a more verbose flush threshold.
    • Improved automatic color detection on Web, iOS/visionOS, and Android.
  • Tests

    • Updated and added tests for level-aware flushing and app log directory behavior.

Review Change Stack

Copilot AI review requested due to automatic review settings May 22, 2026 01:16
@coderabbitai

coderabbitai Bot commented May 22, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 21d1e2ff-89d5-4ffe-a4dd-6fd02b9274d5

📥 Commits

Reviewing files that changed from the base of the PR and between 46b6960 and cf3e6a5.

📒 Files selected for processing (1)
  • src/vertexnova/logging/core/text_color.cpp

📝 Walkthrough

Walkthrough

Refactors VNeLogging to support level-aware sink flushing, adds a configurable file-append option and an application override for platform log directory selection, refines ANSI color detection, updates tests/mocks, and adds a desktop-only platform logging example with CMake wiring.

Changes

Logging Infrastructure Enhancements

Layer / File(s) Summary
Level-aware flush interface
src/vertexnova/logging/core/log_sink.h, src/vertexnova/logging/core/log_dispatcher.*, src/vertexnova/logging/core/console_log_sink.*, src/vertexnova/logging/core/sync_logger.cpp, src/vertexnova/logging/core/async_logger.cpp, tests/core/mocks/log_sink_mock.h, tests/core/console_log_sink_test.cpp, tests/core/log_dispatcher_test.cpp
Adds ILogSink::flush(LogLevel) with a default forwarding implementation; updates LogDispatcher::flush to accept a LogLevel and forward it to sinks; ConsoleLogSink gains level-aware flushing (errors flush both stdout/stderr, others flush stdout); loggers call sink->flush(level); tests and mocks updated.
File append mode and logger wiring
include/vertexnova/logging/logging.h, src/vertexnova/logging/log_manager.*, src/vertexnova/logging/logging.cpp
LoggerConfig adds file_append (default true). LogManager::addFileSink and Logging::addFileSink gain an append parameter (default true). configureLogger() passes cfg.file_append when creating file sinks, enabling append vs truncate behavior.
Platform directory override and color detection
include/vertexnova/logging/logging.h, src/vertexnova/logging/logging.cpp, src/vertexnova/logging/core/text_color.cpp, tests/logging_path_test.cpp
Adds Logging::setAppLogDirectory() and static s_app_log_dir; getPlatformSpecificLogDirectory() prefers the app override and returns "" for sandbox/no-filesystem targets unless overridden; removes build-directory fallback. detectColorSupport() compile-time disables ANSI for Web/iOS/visionOS/Android. Tests reset app directory between cases and add validation tests.
Cross-platform logging example
examples/06_platform_logging/CMakeLists.txt, examples/06_platform_logging/main.cpp, examples/CMakeLists.txt
New 06_platform_logging example source and CMake: chooses sinks by platform, uses getPlatformSpecificLogDirectory(), sets file_append = false in the example config, emits multi-level logs, and conditionally builds the example on desktop targets. Also adds spacing in examples/CMakeLists.txt.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • vertexnova/vnelogging#18: Both PRs modify ConsoleLogSink flush behavior and related tests, making the level-aware flush changes closely related.

Poem

🐰 I hopped through logs at break of day,

I made flushes smart so errors spray,
Files now choose to append or not,
Paths find their home where apps have sought,
A tiny example hops on desktop way.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: enhancing logging configuration with cross-platform support (file append mode, app log directory override, level-aware flushing) and adding a platform logging example.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch VNE_LOGGING_REFACTORING_FLUSH

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
include/vertexnova/logging/logging.h (1)

135-143: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Document the new append parameter in the public API comment.

Line 143 adds append, but the Doxygen block above it has no @param append, so the header docs are incomplete for callers.

Suggested doc fix
  * `@param` logger_name The name of the logger to which the file sink will be added.
  * `@param` file The name of the file where logs will be written.
+ * `@param` append Whether to append to an existing file (true) or truncate it (false).
  */
 static void addFileSink(const std::string& logger_name, const std::string& file, bool append = true);

As per coding guidelines, "Ensure public C++ APIs have brief doc comments if behavior isn't obvious."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@include/vertexnova/logging/logging.h` around lines 135 - 143, The Doxygen for
addFileSink is missing documentation for the new parameter append; update the
comment block for the static method addFileSink(const std::string& logger_name,
const std::string& file, bool append = true) to include an `@param` append line
describing that this flag (default true) controls whether the file sink opens
the log file in append mode (true) or truncates/overwrites it (false), and
mention the default behavior.
🧹 Nitpick comments (3)
include/vertexnova/logging/logging.h (2)

193-217: ⚡ Quick win

Add thread-safety contract for setAppLogDirectory.

The new public API on Line 217 mutates shared global logging state, but the docs do not state whether it is thread-safe or when it is safe to call.

Suggested doc fix
  * `@param` path Absolute writable path for log files. Empty string resets to auto-detection.
+ *
+ * `@note` Thread-safety: call during startup before logger configuration.
+ *       Concurrent calls with logging/configuration APIs are not guaranteed to be safe.
  */
 static void setAppLogDirectory(const std::string& path);

As per coding guidelines, "Flag missing or incorrect thread-safety documentation for public C++ APIs."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@include/vertexnova/logging/logging.h` around lines 193 - 217, Document the
thread-safety contract for setAppLogDirectory: state explicitly whether
setAppLogDirectory(const std::string& path) is thread-safe or must only be
called from a single thread during process initialization, and clarify its
relationship with configureLogger() (e.g., "call before configureLogger() and
not concurrently with any logging calls"). If it is not thread-safe, instruct
callers to synchronize externally (or mention that the implementation acquires
an internal mutex if it is thread-safe). Also mention the empty-string behavior
(resets to auto-detection) and that callers on mobile platforms should call this
from their platform startup code before starting other threads that may log.

280-280: ⚡ Quick win

Align private member naming with project C++ convention.

Line 280 introduces s_app_log_dir, which does not follow the private-member convention requiring snake_case with a trailing underscore.

As per coding guidelines, "Use snake_case + trailing underscore for C++ private members."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@include/vertexnova/logging/logging.h` at line 280, The static private member
s_app_log_dir violates the project's private-member naming rule (snake_case +
trailing underscore); rename it to s_app_log_dir_ (or app_log_dir_ if you prefer
dropping the s_ prefix) and update all declarations, definitions, and usages
(e.g., references in setAppLogDirectory, any getters, and .cpp definitions) to
the new identifier so the symbol remains static and behavior is unchanged while
matching the naming convention.
examples/06_platform_logging/main.cpp (1)

97-97: ⚡ Quick win

Use std::filesystem::path join instead of hardcoded "/" in cross-platform example.

Hardcoding separators in a cross-platform sample adds avoidable platform coupling.

🔧 Suggested refactor
+#include <filesystem>
...
-        config.file_path = log_dir + "/platform_example.log";
+        config.file_path = (std::filesystem::path(log_dir) / "platform_example.log").string();

As per coding guidelines, "Avoid introducing C++ platform-specific behavior without guards and tests".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/06_platform_logging/main.cpp` at line 97, The code sets
config.file_path by concatenating log_dir + "/platform_example.log", which
hardcodes a path separator; update this to use std::filesystem::path to join
paths portablely by constructing a std::filesystem::path from log_dir and
appending "platform_example.log" (e.g., std::filesystem::path(log_dir) /
"platform_example.log") and then assign the resulting path.string() (or
path.native()) to config.file_path so the change touches the assignment
involving config.file_path and the variable log_dir.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/vertexnova/logging/core/log_dispatcher.h`:
- Line 86: Change the API so callers must explicitly choose what to flush:
remove the default parameter on LogDispatcher::flush (the declaration of void
flush(const std::vector<std::unique_ptr<ILogSink>>& log_sinks, LogLevel level))
so it no longer defaults to LogLevel::eTrace, and add an explicit helper
overload or method (e.g., flushAll or flush(const
std::vector<std::unique_ptr<ILogSink>>&) ) if you need the old “full flush”
behavior; update callers of LogDispatcher::flush and any call sites that relied
on the implicit default to pass the intended LogLevel or call the new flushAll
helper.

In `@src/vertexnova/logging/core/text_color.cpp`:
- Around line 18-20: The translation unit uses stdout/fileno inside
detectColorSupport() but doesn't include <cstdio>/<stdio.h>, risking missing
declarations on some platforms; add an explicit `#include` <cstdio> (or <stdio.h>)
at the top of src/vertexnova/logging/core/text_color.cpp (within the same
non-Windows include block or unconditionally) so detectColorSupport() can safely
call fileno(stdout) and isatty(fileno(stdout)).

In `@src/vertexnova/logging/logging.cpp`:
- Around line 223-228: The static s_app_log_dir must be protected with a mutex
to avoid data races: add a static std::mutex (e.g., s_app_log_dir_mutex) to the
Logging class and include <mutex>, then take a lock_guard<std::mutex> when
writing in Logging::setAppLogDirectory and when reading in
Logging::getPlatformSpecificLogDirectory (and any other accessors) so
ensureLogDirectoryExists is still called while holding the lock or called on a
local copy after locking; update references to use the locked access to
s_app_log_dir.

---

Outside diff comments:
In `@include/vertexnova/logging/logging.h`:
- Around line 135-143: The Doxygen for addFileSink is missing documentation for
the new parameter append; update the comment block for the static method
addFileSink(const std::string& logger_name, const std::string& file, bool append
= true) to include an `@param` append line describing that this flag (default
true) controls whether the file sink opens the log file in append mode (true) or
truncates/overwrites it (false), and mention the default behavior.

---

Nitpick comments:
In `@examples/06_platform_logging/main.cpp`:
- Line 97: The code sets config.file_path by concatenating log_dir +
"/platform_example.log", which hardcodes a path separator; update this to use
std::filesystem::path to join paths portablely by constructing a
std::filesystem::path from log_dir and appending "platform_example.log" (e.g.,
std::filesystem::path(log_dir) / "platform_example.log") and then assign the
resulting path.string() (or path.native()) to config.file_path so the change
touches the assignment involving config.file_path and the variable log_dir.

In `@include/vertexnova/logging/logging.h`:
- Around line 193-217: Document the thread-safety contract for
setAppLogDirectory: state explicitly whether setAppLogDirectory(const
std::string& path) is thread-safe or must only be called from a single thread
during process initialization, and clarify its relationship with
configureLogger() (e.g., "call before configureLogger() and not concurrently
with any logging calls"). If it is not thread-safe, instruct callers to
synchronize externally (or mention that the implementation acquires an internal
mutex if it is thread-safe). Also mention the empty-string behavior (resets to
auto-detection) and that callers on mobile platforms should call this from their
platform startup code before starting other threads that may log.
- Line 280: The static private member s_app_log_dir violates the project's
private-member naming rule (snake_case + trailing underscore); rename it to
s_app_log_dir_ (or app_log_dir_ if you prefer dropping the s_ prefix) and update
all declarations, definitions, and usages (e.g., references in
setAppLogDirectory, any getters, and .cpp definitions) to the new identifier so
the symbol remains static and behavior is unchanged while matching the naming
convention.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8e83e07e-cb7c-4906-8c40-06c4257f6c36

📥 Commits

Reviewing files that changed from the base of the PR and between fb9c0a3 and bd89f5b.

📒 Files selected for processing (22)
  • examples/06_platform_logging/CMakeLists.txt
  • examples/06_platform_logging/main.cpp
  • examples/CMakeLists.txt
  • include/vertexnova/logging/logging.h
  • src/vertexnova/logging/core/async_logger.cpp
  • src/vertexnova/logging/core/console_log_sink.cpp
  • src/vertexnova/logging/core/console_log_sink.h
  • src/vertexnova/logging/core/file_log_sink.cpp
  • src/vertexnova/logging/core/file_log_sink.h
  • src/vertexnova/logging/core/log_dispatcher.cpp
  • src/vertexnova/logging/core/log_dispatcher.h
  • src/vertexnova/logging/core/log_sink.h
  • src/vertexnova/logging/core/sync_logger.cpp
  • src/vertexnova/logging/core/text_color.cpp
  • src/vertexnova/logging/log_manager.cpp
  • src/vertexnova/logging/log_manager.h
  • src/vertexnova/logging/logging.cpp
  • tests/core/console_log_sink_test.cpp
  • tests/core/file_log_sink_test.cpp
  • tests/core/log_dispatcher_test.cpp
  • tests/core/mocks/log_sink_mock.h
  • tests/logging_path_test.cpp

Comment thread src/vertexnova/logging/core/log_dispatcher.h Outdated
Comment thread src/vertexnova/logging/core/text_color.cpp Outdated
Comment thread src/vertexnova/logging/logging.cpp

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the logging library’s flushing semantics and file-sink configuration, and adds a new cross-platform example for initializing logging with an app-provided log directory (for sandboxed/mobile targets).

Changes:

  • Extend sink flushing to accept a LogLevel so console sinks can flush the relevant stream (stdout vs stderr).
  • Add LoggerConfig::file_append and plumb it through Logging::configureLogger()/LogManager::addFileSink() to control append vs truncate.
  • Add Logging::setAppLogDirectory() + a new example demonstrating platform-specific initialization.

BLOCKER (must fix before merge)

  • src/vertexnova/logging/core/text_color.cpp (includes / isatty+fileno usage): isatty(fileno(stdout)) is used without including <cstdio> / <stdio.h>, which can cause compilation failures because stdout/fileno may be undeclared. Add the proper header and (optionally) qualify with ::stdout/::fileno.

MAJOR (strongly recommended)

  • include/vertexnova/logging/logging.h (LoggerConfig default): Defaulting flush_level to eTrace makes every log flush (since all levels are >= eTrace), which can significantly reduce logging throughput for both sync and async modes. Consider restoring the previous default (e.g., eError) and letting users opt in to aggressive flushing.
  • src/vertexnova/logging/core/console_log_sink.cpp (flush semantics): ConsoleLogSink::flush(level) currently flushes only one stream. If flush_level is configured as eError, an error-triggered flush won’t flush prior stdout logs (buffered) and they can be lost on crash/abort. Consider flushing both std::cout and std::cerr when level >= eError (or redefining console flush to “flush all”).
  • src/vertexnova/logging/core/log_sink.h (public API break): Changing ILogSink::flush() to flush(LogLevel) is source-breaking for downstream custom sinks and any call sites using flush(). If compatibility is a concern, consider keeping flush() and adding flush(LogLevel) with a default implementation that forwards to flush(), plus migration/deprecation guidance.
  • src/vertexnova/logging/logging.cpp (new behaviors lack tests):
    • file_append behavior (truncate vs append) should be covered by a deterministic unit test.
    • setAppLogDirectory() override/reset behavior should be validated (override takes effect; empty string resets to auto-detection).

MINOR (nice-to-have)

  • examples/06_platform_logging/main.cpp (Swift snippet): The Swift bridging snippet is misleading about @_silgen_name and direct calls into C++ from Swift. Adjust the snippet to show a C/extern "C" wrapper implemented in C++ that Swift calls, and keep the Swift sample focused on resolving the directory and passing it to that wrapper.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/logging_path_test.cpp Updates default config expectation for new flush default.
tests/core/mocks/log_sink_mock.h Updates mock sink flush signature to accept LogLevel.
tests/core/log_dispatcher_test.cpp Updates dispatcher flush test to pass LogLevel.
tests/core/file_log_sink_test.cpp Updates file sink flush calls to pass a LogLevel.
tests/core/console_log_sink_test.cpp Updates console sink flush call to pass a LogLevel.
src/vertexnova/logging/logging.cpp Adds setAppLogDirectory, plumbs file_append, updates default flush level and platform log dir behavior.
src/vertexnova/logging/log_manager.h Extends addFileSink with an append parameter (defaulted).
src/vertexnova/logging/log_manager.cpp Passes append into FileLogSink construction.
src/vertexnova/logging/core/text_color.cpp Adds runtime color detection via isatty, plus platform exclusions.
src/vertexnova/logging/core/sync_logger.cpp Forwards log level into sink flush calls; manual flush now flushes both streams via two calls.
src/vertexnova/logging/core/log_sink.h Changes sink flush interface to flush(LogLevel).
src/vertexnova/logging/core/log_dispatcher.h Extends dispatcher flush API to accept LogLevel (defaulted).
src/vertexnova/logging/core/log_dispatcher.cpp Forwards LogLevel into sink flush calls.
src/vertexnova/logging/core/file_log_sink.h Updates file sink flush signature to accept LogLevel (unused).
src/vertexnova/logging/core/file_log_sink.cpp Implements flush(LogLevel) for file sink.
src/vertexnova/logging/core/console_log_sink.h Updates console sink flush signature to accept LogLevel.
src/vertexnova/logging/core/console_log_sink.cpp Flushes either cout or cerr based on log level.
src/vertexnova/logging/core/async_logger.cpp Passes triggering log level into dispatcher flush calls; manual flush flushes both streams via two calls.
include/vertexnova/logging/logging.h Adds file_append, changes default flush level, adds setAppLogDirectory API + docs.
examples/CMakeLists.txt Adds new example subdirectory.
examples/06_platform_logging/main.cpp New example demonstrating platform-specific log dir handling.
examples/06_platform_logging/CMakeLists.txt Adds desktop-only build for the new example.
Comments suppressed due to low confidence (1)

src/vertexnova/logging/logging.cpp:212

  • New behavior: configureLogger now forwards LoggerConfig::file_append into addFileSink (truncation vs append), but there are no tests covering that the log file is actually truncated when file_append=false (or appended when true). Add a deterministic test (e.g., write once, reconfigure with same path + file_append=false, write again, then assert the old content was removed).
    // Configure file sink (not on web)
#ifndef VNE_PLATFORM_WEB
    if (cfg.sink == LogSinkType::eFile || cfg.sink == LogSinkType::eBoth) {
        if (!cfg.file_path.empty()) {
            addFileSink(cfg.name, cfg.file_path, cfg.file_append);
            if (!cfg.file_pattern.empty()) {
                setFilePattern(cfg.name, cfg.file_pattern);
            }
        }
    }

Comment thread src/vertexnova/logging/core/text_color.cpp Outdated
Comment thread examples/06_platform_logging/main.cpp Outdated
Comment thread src/vertexnova/logging/core/console_log_sink.cpp
Comment thread include/vertexnova/logging/logging.h Outdated
Comment thread src/vertexnova/logging/core/log_sink.h Outdated
Comment thread src/vertexnova/logging/logging.cpp
Copilot AI review requested due to automatic review settings May 22, 2026 02:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.

Comment thread src/vertexnova/logging/core/text_color.cpp
Comment thread include/vertexnova/logging/logging.h
Comment thread src/vertexnova/logging/logging.cpp
Comment thread examples/06_platform_logging/CMakeLists.txt
@ajeetsinghyadav
ajeetsinghyadav enabled auto-merge (squash) May 22, 2026 02:35
@ajeetsinghyadav
ajeetsinghyadav merged commit 967e449 into main May 22, 2026
17 checks passed
@ajeetsinghyadav
ajeetsinghyadav deleted the VNE_LOGGING_REFACTORING_FLUSH branch May 22, 2026 02:40
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.

2 participants