Skip to content

fix(health): rename public liveness route to /livez - #257

Merged
moonming merged 12 commits into
mainfrom
fix/issue-253-rename-health-to-livez
May 12, 2026
Merged

fix(health): rename public liveness route to /livez#257
moonming merged 12 commits into
mainfrom
fix/issue-253-rename-health-to-livez

Conversation

@moonming

@moonming moonming commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • rename the unauthenticated public liveness route from /health to /livez on both proxy and standalone admin listeners
  • keep /admin/v1/health unchanged for authenticated operator health, and update OpenAPI, docs, and e2e coverage to match
  • wire the shared livez state into shutdown so the liveness response can fail during graceful termination

Summary by CodeRabbit

  • New Features

    • Added an unauthenticated liveness endpoint at /livez (plain-text "ok" by default) with optional verbose output and shutdown detection; liveness state is shared across components.
  • Bug Fixes

    • Removed the previous public /health route (now returns 404).
  • Documentation

    • Updated API and testing docs to reference /livez for probes.
  • Tests

    • Added/updated unit and E2E tests for /livez; test harness can forward signals to the spawned app.

Review Change Stack

Copilot AI review requested due to automatic review settings May 12, 2026 04:02
@coderabbitai

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: d3578329-d0af-4f83-80e9-c7060eaa4211

📥 Commits

Reviewing files that changed from the base of the PR and between 48967d6 and 0b138cd.

📒 Files selected for processing (1)
  • tests/e2e/src/harness/app.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/e2e/src/harness/app.ts

📝 Walkthrough

Walkthrough

This PR replaces the unauthenticated /health endpoint with a minimal /livez liveness probe. LivezState tracks shutdown and generates plain-text HTTP responses with security headers. The proxy and admin services both expose /livez backed by shared state, server initialization threads this state through shutdown coordination, and documentation and tests are updated accordingly.

Changes

Liveness endpoint migration from /health to /livez

Layer / File(s) Summary
LivezState and livez_response implementation
crates/aisix-proxy/src/health.rs
LivezState tracks process shutdown via AtomicBool. livez_response(livez, verbose) returns 200 OK with plain-text "ok" body or 500 INTERNAL_SERVER_ERROR with "livez check failed" when shutdown is detected. Response includes security headers Content-Type: text/plain; charset=utf-8 and X-Content-Type-Options: nosniff. Tests validate terse success, verbose success with ping/shutdown/pass markers, and 500 shutdown failure behavior.
Proxy service livez wiring
crates/aisix-proxy/src/state.rs, crates/aisix-proxy/src/lib.rs
ProxyState gains exported livez: Arc<LivezState> field, initialized in all constructors. Router mounts GET /livez handler that reads optional verbose query parameter and delegates to livez_response. LivezState added to public re-exports alongside HealthTracker. Tests validate /livez returns plain "ok" by default, rejects non-GET with 405, and /health is not found.
Admin service livez wiring
crates/aisix-admin/src/state.rs, crates/aisix-admin/src/lib.rs, crates/aisix-admin/src/openapi.rs
AdminState gains exported livez_state: Arc<LivezState> field with builder with_livez_state() to enable sharing proxy's shutdown state. Router mounts GET /livez handler backed by livez_response. OpenAPI documents /livez as a public GET endpoint with optional verbose query and 200/500 text/plain string responses (no enum constraint). Admin tests validate /livez returns 200/"ok", rejects non-GET, and /health returns 404.
Server initialization and shutdown coordination
crates/aisix-server/src/main.rs
Clones livez_state from proxy_state, shares it with admin via .with_livez_state() in standalone mode, and passes livez_state into wait_for_signal. On SIGINT/SIGTERM the code calls livez_state.mark_shutting_down() then waits briefly before sending the global cancellation signal.
Documentation and e2e test coverage
crates/aisix-etcd/src/supervisor.rs, docs/api-admin.md, docs/testing.md, tests/e2e/src/harness/app.ts, tests/e2e/src/cases/health-minimal-e2e.test.ts
Supervisor comments updated to reference /admin/v1/health. Admin API docs and testing docs updated to mention /livez. E2E harness readiness probe changed to /livez for the proxy; SpawnedApp gains signal() method. New minimal e2e test asserts proxy and admin /livez return 200/"ok" and /health returns 404.

🎯 3 (Moderate) | ⏱️ ~20 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

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

Copilot AI 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.

Pull request overview

Renames the public unauthenticated liveness endpoint from /health to /livez across the proxy and standalone admin listeners, while keeping the authenticated operator health endpoint at /admin/v1/health. It also shares a common liveness state so /livez can fail during graceful shutdown, and updates docs and tests to match.

Changes:

  • Replace public /health with /livez on proxy and admin listeners; add coverage that /health is now absent.
  • Introduce shared LivezState and mark it shutting down on SIGINT/SIGTERM so liveness can fail during termination.
  • Update e2e harness readiness checks, docs, and admin OpenAPI to reflect /livez and retain /admin/v1/health.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/e2e/src/harness/app.ts Updates readiness probe from proxy /health to /livez while keeping admin readiness on /admin/v1/health.
tests/e2e/src/cases/health-minimal-e2e.test.ts Adds e2e regression test asserting /livez works and /health returns 404 on both listeners.
docs/testing.md Updates testing doc to reference /livez as the minimal public probe.
docs/api-admin.md Updates admin API docs to list /livez as the unauthenticated liveness probe.
crates/aisix-server/src/main.rs Threads shared LivezState into shutdown signal handling and into AdminState in standalone mode.
crates/aisix-proxy/src/state.rs Adds livez: Arc<LivezState> to ProxyState and initializes it in constructors.
crates/aisix-proxy/src/lib.rs Replaces router mount /health with /livez and routes to livez_response; adds unit tests for /livez and /health absence.
crates/aisix-proxy/src/health.rs Introduces LivezState + livez_response (plain text “ok”, verbose mode, and shutdown-failure behavior).
crates/aisix-etcd/src/supervisor.rs Updates comments to reference /admin/v1/health instead of /health.
crates/aisix-admin/src/state.rs Adds livez_state to admin state and a builder method to share it with the proxy.
crates/aisix-admin/src/openapi.rs Renames documented public route from /health to /livez and adds schema for plain “ok” response.
crates/aisix-admin/src/lib.rs Replaces router mount /health with /livez (using shared livez_response) and updates tests accordingly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +31 to +41
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"type": "string",
"enum": ["ok"]
}
}
}
Comment on lines +51 to +62
pub fn livez_response(livez: &LivezState, verbose: bool) -> Response {
let mut body = String::new();
let mut failed = false;

body.push_str("[+]ping ok\n");
match livez.shutdown_check() {
Ok(()) => body.push_str("[+]shutdown ok\n"),
Err(_) => {
failed = true;
body.push_str("[-]shutdown failed: reason withheld\n");
}
}
Copilot AI review requested due to automatic review settings May 12, 2026 06:59

Copilot AI 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.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment on lines +51 to +60
pub fn livez_response(livez: &LivezState, verbose: bool) -> Response {
let mut body = String::new();
let mut failed = false;

body.push_str("[+]ping ok\n");
match livez.shutdown_check() {
Ok(()) => body.push_str("[+]shutdown ok\n"),
Err(_) => {
failed = true;
body.push_str("[-]shutdown failed: reason withheld\n");
Comment on lines +31 to +41
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"type": "string",
"enum": ["ok"]
}
}
}
Copilot AI review requested due to automatic review settings May 12, 2026 08:13

Copilot AI 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.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment on lines +48 to +69
app.signal("SIGTERM");

const deadline = Date.now() + 3000;
let observedUnhealthy = false;
while (Date.now() < deadline) {
try {
const res = await harnessRequest(`${app.proxyUrl}/livez`, { method: "GET" });
if (res.statusCode !== 200) {
observedUnhealthy = true;
await res.body.dump();
break;
}
await res.body.dump();
} catch {
observedUnhealthy = true;
break;
}
await new Promise((r) => setTimeout(r, 50));
}

expect(observedUnhealthy).toBe(true);
app = undefined;
}

livez_state.mark_shutting_down();
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
@moonming
moonming merged commit 2884ff4 into main May 12, 2026
11 checks passed
moonming added a commit that referenced this pull request May 14, 2026
- quickstart/self-hosted: document the /livez liveness route and plain-text
  body (per #257); add Cleanup
- quickstart/openai-sdk: switch to .mjs so \`node\` runs the example without
  a TypeScript loader
- quickstart/first-model-first-key-first-request: add production-credentials
  warning, 401/403 verification step using the real proxy error envelope,
  Cleanup, and a per-provider api_base callout
- integration/openai-compatible-api: add mermaid diagram of the request
  path; route list reflects the /livez rename
- integration/errors-and-retries: replace placeholder error.type strings
  with the real ProxyError mapping; add 413 RequestTooLarge row; note the
  admin {error_msg} envelope distinction
- configuration/provider-keys: warn about plaintext secret storage; replace
  the inaccurate OpenAI api_base normalization claim with a per-provider
  truth table (refs #270)
- operations/health-checks: rewrite for the /livez liveness contract plus
  the /admin/v1/health per-model shape (per #256 + #257)
- reference/proxy-api-reference: /livez instead of /health in the route
  list
- tutorials/build-a-virtual-model-with-failover: rewrite end-to-end against
  routing-strategies-e2e (deliberately break primary, observe cooldown)
- tutorials/enable-response-caching: rewrite against cache-policy-e2e
  (x-aisix-cache miss then hit, different prompt misses again)
- tutorials/add-keyword-guardrails: rewrite against guardrail-keyword-e2e
  (422 content_filter; no-leak message contract per #203)
- tutorials/openai-client-to-anthropic-upstream: rewrite against
  anthropic-upstream-e2e; document bare-host api_base for Anthropic

Every command, field, header, and error code was cross-checked against the
relevant crate or e2e test on this branch. No mock data; nothing speculative.
moonming added a commit that referenced this pull request May 14, 2026
- quickstart/self-hosted: document the /livez liveness route and plain-text
  body (per #257); add Cleanup
- quickstart/openai-sdk: switch to .mjs so \`node\` runs the example without
  a TypeScript loader
- quickstart/first-model-first-key-first-request: add production-credentials
  warning, 401/403 verification step using the real proxy error envelope,
  Cleanup, and a per-provider api_base callout
- integration/openai-compatible-api: add mermaid diagram of the request
  path; route list reflects the /livez rename
- integration/errors-and-retries: replace placeholder error.type strings
  with the real ProxyError mapping; add 413 RequestTooLarge row; note the
  admin {error_msg} envelope distinction
- configuration/provider-keys: warn about plaintext secret storage; replace
  the inaccurate OpenAI api_base normalization claim with a per-provider
  truth table (refs #270)
- operations/health-checks: rewrite for the /livez liveness contract plus
  the /admin/v1/health per-model shape (per #256 + #257)
- reference/proxy-api-reference: /livez instead of /health in the route
  list
- tutorials/build-a-virtual-model-with-failover: rewrite end-to-end against
  routing-strategies-e2e (deliberately break primary, observe cooldown)
- tutorials/enable-response-caching: rewrite against cache-policy-e2e
  (x-aisix-cache miss then hit, different prompt misses again)
- tutorials/add-keyword-guardrails: rewrite against guardrail-keyword-e2e
  (422 content_filter; no-leak message contract per #203)
- tutorials/openai-client-to-anthropic-upstream: rewrite against
  anthropic-upstream-e2e; document bare-host api_base for Anthropic

Every command, field, header, and error code was cross-checked against the
relevant crate or e2e test on this branch. No mock data; nothing speculative.
@jarvis9443
jarvis9443 deleted the fix/issue-253-rename-health-to-livez branch June 25, 2026 06:26
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