Skip to content

feat(runtime): forward stdout and stderr to os_log for the CLI - #532

Open
rigor789 wants to merge 2 commits into
feat/ios-log-chunksfrom
feat/ios-stdio-forwarding
Open

rigor789 wants to merge 2 commits into
feat/ios-log-chunksfrom
feat/ios-stdio-forwarding

Conversation

@rigor789

@rigor789 rigor789 commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

What is the current behavior?

Without a console, an app's stdio is /dev/null. print() output is lost, and so is NSLog on devices, where it only goes to stderr on iPadOS 26.7. A CLI can't attach to it after launch, because stdio is fixed when the process starts.

What is the new behavior?

In debug builds whose CLI sets forwardStdio in the app's package.json, with stdout still /dev/null, the runtime pipes stdout and stderr into os_log under the org.nativescript.stdio subsystem, with stdout and stderr as categories.

  • Older CLIs never set the key, and release builds and attached consoles fail the checks, so nothing changes for them.
  • stdout becomes line buffered, or print() would wait for a full buffer.
  • Long lines are split the same way as console messages.
  • Devices forward both streams. The simulator forwards stdout only, because NSLog there also reaches the unified log and would print twice. That means fputs(..., stderr) isn't forwarded on the simulator.

Known limits: output buffered at the moment of a crash is lost, so the last lines before an abort() may not appear. An unterminated final line isn't forwarded until a newline arrives or it reaches 64 KB.

Testing

Demo app with Swift code calling print() (short, 5,000 characters, background thread), NSLog and fputs(stderr), on both launches of each run:

Setup Result
New CLI, default, simulator and iPad Hidden, and all 11 console messages intact
New CLI, --log debug, simulator print() shown, 5,000-character line intact, NSLog once (from Foundation)
New CLI, --log debug, iPad (iPadOS 26.7) print(), NSLog and stderr all shown once
Published CLI 9.1.1, simulator No forwarding
simctl launch --console-pty print() goes to the console directly

Older iOS versions weren't tested, and NSLog may behave differently there. A launch from Xcode itself wasn't tested either.

Part of a stack

Base: #530. The CLI side is NativeScript/nativescript-cli#6181.

Summary by CodeRabbit

  • New Features
    • In eligible debug builds, application output written to stdout—and stderr on supported devices—can be forwarded to system logs when enabled in the app configuration. Output is recorded as newline-delimited entries; long lines are also captured in chunks. Forwarding is available only when the app’s output streams meet the required configuration and connection conditions.

@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The change adds configurable log destinations and a stdio forwarder. During runtime initialization, the forwarder checks the debug configuration and stdout descriptor before redirecting streams to unified logging.

Changes: Logging and stdio forwarding

Layer / File(s) Summary
Log destination and descriptor helpers
NativeScript/runtime/Helpers.h, NativeScript/runtime/Helpers.mm
Logging helpers accept an explicit os_log_t destination. IsDevNull(int fd) is declared in tns and retains its existing implementation.
Conditional stdio forwarding
NativeScript/runtime/StdioForwarder.h, NativeScript/runtime/StdioForwarder.mm
StartStdioForwarding() runs once and proceeds only when the stated debug, application path, forwardStdio, and stdout conditions are met. It forwards stdout, and on non-simulator platforms stderr, through pipes to unified logging.
Runtime and project integration
NativeScript/NativeScript.mm, v8ios.xcodeproj/project.pbxproj
Runtime initialization calls StartStdioForwarding(). The Xcode project adds the forwarder header and implementation to the framework.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Runtime
  participant StartStdioForwarding
  participant Forward
  participant UnifiedLog
  Runtime->>StartStdioForwarding: Call after Runtime::Initialize()
  StartStdioForwarding->>Forward: Redirect eligible stdout and stderr
  Forward->>UnifiedLog: Write newline-delimited output
Loading

Possibly related PRs

  • NativeScript/ios#530: It adds log-chunk support and modifies the same logging helpers and project area.

Suggested reviewers: edusperoni, nathanwalker

Merge Risk: Low · up to c839e

Opt-in forwarding may corrupt characters in very long output lines. The change is otherwise mergeable with this limitation noted.

Pre-merge checks: Passed 5

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names the primary change: adding forwarding of stdout and stderr to os_log for the CLI. The changeset adds StartStdioForwarding(), which forwards stdout and stderr to unified logging for deb…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
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.
Full details: Title check

Explanation

The title names the primary change: adding forwarding of stdout and stderr to os_log for the CLI. The changeset adds StartStdioForwarding(), which forwards stdout and stderr to unified logging for debug builds when the forwardStdio app-config key is set. The title also matches the PR objectives. It is specific and uses the conventional feat(runtime) scope, so it is not vague.

Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 1 functions across 2 files.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

A rabbit taps the logging pipe,
While stdout lines go hop by hop.
A newline sends each message on,
A full buffer clears before too long.
The runtime starts the quiet stream,
And logs each line into the gleam.

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a8cb33d5-eabc-4f29-83ab-055f2ddfe74d
Commits

Reviewing files that changed from the base of the PR and between 4f05142 and c839e4a.

Files selected for processing: 1

  • NativeScript/runtime/Helpers.h

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.

Without a console an app's stdio is /dev/null, so print() and, on devices, NSLog never reach any log stream, and a CLI can't attach to them after launch. In debug builds whose CLI sets forwardStdio in the app's package.json, with stdout still /dev/null, the runtime now pipes them into os_log under the org.nativescript.stdio subsystem. Long lines are split like console messages.
@edusperoni
edusperoni force-pushed the feat/ios-stdio-forwarding branch from 4f05142 to c839e4a Compare November 8, 2026 19:39

This branch has not been deployed

No deployments
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.

1 participant