diff --git a/doc/FAQ.md b/doc/FAQ.md index 129498e4..370dd666 100644 --- a/doc/FAQ.md +++ b/doc/FAQ.md @@ -19,6 +19,7 @@ - [How does code-server decide what workspace or folder to open?](#how-does-code-server-decide-what-workspace-or-folder-to-open) - [How do I debug issues with code-server?](#how-do-i-debug-issues-with-code-server) - [Heartbeat File](#heartbeat-file) +- [Healthz endpoint](#healthz-endpoint) - [How does the config file work?](#how-does-the-config-file-work) - [Blank screen on iPad?](#blank-screen-on-ipad) - [Isn't an install script piped into sh insecure?](#isnt-an-install-script-piped-into-sh-insecure) @@ -242,6 +243,20 @@ older than X minutes, kill `code-server`. [#1636](https://github.com/cdr/code-server/issues/1636) will make the experience here better. +## Healthz endpoint + +`code-server` exposes an endpoint at `/healthz` which can be used to check +whether `code-server` is up without triggering a heartbeat. The response will +include a status (`alive` or `expired`) and a timestamp for the last heartbeat +(defaults to `0`). This endpoint does not require authentication. + +```json +{ + "status": "alive", + "lastHeartbeat": 1599166210566 +} +``` + ## How does the config file work? When `code-server` starts up, it creates a default config file in `~/.config/code-server/config.yaml` that looks diff --git a/src/node/app/health.ts b/src/node/app/health.ts index 6a3aae94..48d6897c 100644 --- a/src/node/app/health.ts +++ b/src/node/app/health.ts @@ -1,6 +1,4 @@ -import * as http from "http" -import { HttpCode, HttpError } from "../../common/http" -import { HttpProvider, HttpResponse, Route, Heart, HttpProviderOptions } from "../http" +import { HttpProvider, HttpResponse, Heart, HttpProviderOptions } from "../http" /** * Check the heartbeat. @@ -10,15 +8,8 @@ export class HealthHttpProvider extends HttpProvider { super(options) } - public async handleRequest(route: Route, request: http.IncomingMessage): Promise { - if (!this.authenticated(request)) { - if (this.isRoot(route)) { - return { redirect: "/login", query: { to: route.fullPath } } - } - throw new HttpError("Unauthorized", HttpCode.Unauthorized) - } - - const result = { + public async handleRequest(): Promise { + return { cache: false, mime: "application/json", content: { @@ -26,7 +17,5 @@ export class HealthHttpProvider extends HttpProvider { lastHeartbeat: this.heart.lastHeartbeat, }, } - - return result } }