Skip to content

fix(xray): honor log "none" and stop traffic lines from failing startup - #123

Closed
xmohammad1 wants to merge 3 commits into
PasarGuard:devfrom
xmohammad1:fix/xray-log-none-startup-diagnostics
Closed

xmohammad1 wants to merge 3 commits into
PasarGuard:devfrom
xmohammad1:fix/xray-log-none-startup-diagnostics

Conversation

@xmohammad1

Copy link
Copy Markdown

Summary

Three bugs in how the node handles Xray's log output, found on a production node (v0.5.4, Xray 26.3.27, ~200k users). The same code is in v0.5.7 and dev.

  1. "log": {"access": "none"} does not turn the access log off. Config.ToBytes() clears access and error before starting Xray, "none" included. Xray reads an empty value as "log to stdout", so every connection is still logged and streamed to the panel.
  2. "none" is opened as a file. Core.Start passes the configured value to logger.SetLogFile, and openLogFile only skips "". With "access": "none", the node appended every access entry to /app/none in the container, with no rotation: 27.5 MB in the first 25 minutes on that node (~18 KB/s).
  3. Traffic lines fail healthy starts. isStartupFailureLog looks for its keywords in every line Xray prints before its API answers, and clients reconnect during that window. Seen in production:
    • an access entry for a domain containing fatal (accepted tcp:…fatal…:443) returned failed to start xray: … accepted tcp:…, the node stopped Xray, and the node stayed down until the panel retried about 40 s later;
    • at log level info, [Info] … proxy/freedom: failed to open connection to … lines failed the start the same way on three nodes during one panel restart.

Changes

  • logger: add DisabledLog = "none"; openLogFile treats it like an empty path.
  • backend/xray/config.go: ToBytes keeps "none" for access/error. Real paths are still cleared.
  • backend/xray/startup_diagnostics.go: skip access entries and [Info]/[Debug] lines. Access entries are matched by the new isAccessLogEntry, which also covers rejected entries: Xray writes two spaces after rejected when there is no destination, so the existing "rejected proxy/" check never matched a real line. Real failures still match: Failed to start: …, panics, Warning/Error lines.

Tests

  • New: TestToBytesKeepsDisabledLogs, TestSetLogFileTreatsNoneAsDisabled, TestIsAccessLogEntry, and new cases in TestIsStartupFailureLog (the false positives above, plus real Failed to start: lines that must still fail).
  • Set up as in run-tests.yml (WireGuard integration tests not run): TEST_INTEGRATION=true go test ./... -v -p 1 gives 276 passed, 0 failed with Xray v26.10.31, and the TestCoreStarted race run passes.
  • Also run with Xray v26.3.27, the version on the affected nodes: same results as dev. The only failure, TestConvertLivePartsUsesTheInstalledXray, fails on dev too, because that Xray still accepts the VLESS outbound the test expects it to refuse.

Not changed

A config without a log section still gets "loglevel": "info" from GetLogFiles(). Xray's own default is warning with the access log off, so these nodes stream every connection plus all Info lines. That may be intended, so this PR leaves it alone.

🤖 Generated with Claude Code

xmohammad1 and others added 3 commits November 4, 2026 08:01
Xray accepts "none" for log.access and log.error to turn that log off.
The node passes the configured values to its own logger, which opened
"none" as a relative path: with "access": "none" every access entry was
appended to /app/none inside the container, with no rotation.

openLogFile now skips "none" the same way it skips an empty path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ToBytes clears the log paths because the node reads Xray's stdout and
writes the files itself. It also cleared "none", which Xray then reads
as "log to stdout", so "access": "none" never turned the access log off:
every connection was still logged and streamed to the panel.

Keep "none" for both logs; real paths are still cleared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
isStartupFailureLog looks for keywords such as "fatal", "panic" and
"failed to open" in every line Xray prints before its API answers.
Clients reconnect during that window, so ordinary traffic lines failed
healthy starts and the node stopped Xray, e.g.:

  from <ip> accepted tcp:fatal-error.example:443 [in >> direct] email: <user>
  [Info] [id] ... proxy/freedom: failed to open connection to tcp:<ip>:443 > ... connection refused

Skip access entries, accepted and rejected (matched on fields, because
Xray writes two spaces after "rejected"), and Info/Debug lines. A failed
start still matches through "Failed to start:", panics and Warning/Error
lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1a605760-5b70-40c1-a4d1-1d7c7af9a165

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

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

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