SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

Superlog 自行託管安裝與 VPS 資源需求

了解 Superlog 自行託管的實際安裝流程、VPS 資源需求與限制:需啟動 Postgres、ClickHouse、OpenTelemetry collector 及 4 個 Node 服務,且專案沒有 release tags。

自架 Superlog 實際會安裝的內容

若要自架 Superlog,需先複製儲存庫,再使用 Docker Compose 啟動 Postgres、ClickHouse 和 OpenTelemetry collector,執行一次資料庫遷移,最後從原始碼啟動 4 個 Node 服務。您的應用程式會將 OTLP(OpenTelemetry protocol)追蹤、日誌和指標傳送至 intake 埠。Superlog 會為這些資料建立指紋,將重複事件彙整為單一事件,並由 agent 撰寫初步分流結果。安裝需要一個下午。開始之前,最值得閱讀的是所需資源,以及這套系統實際上的限制。

Superlog 採用 Apache 2.0 授權,原始碼位於 github.com/superloglabs/superlog。截至 13 October 2026,該專案約有 1.5k 顆 stars、在 main 上約有 490 次提交,而且完全沒有 release tags。最後一點會直接影響安裝方式:git checkout v1.0.0 沒有可供 checkout 的內容,因此您必須自行固定某個 commit,否則就只能使用複製儲存庫當天早上 main 恰好所處的版本。

Superlog 能回答 Uptime Kuma 與 Langfuse 無法回答的問題

從外部看,自架監控工具似乎可以互相替代。實際上並非如此,選錯工具只會浪費伺服器資源,卻得不到任何好處。

Superlog 負責回答另一個問題:哪裡發生故障,以及原因為何。它不處理 LLM 呼叫,也不會從外部探測你的服務。它會接收一般應用程式程式碼產生的 OTLP,並在分流處理階段加入 agent。這正是值班人員通常會先執行的初步檢查。

對 VPS 預算而言,真正重要的差異在於儲存方式。Uptime Kuma 只需 1 GB RAM 也能順利運作,因為它只儲存幾千筆檢查結果。Superlog 使用 column store,因為遙測資料寫入一次後,還要依時間範圍查詢數百萬筆資料。這正是 ClickHouse 的用途,而不是 Postgres 的用途。Postgres 仍在整體架構中,負責儲存少量關聯式資料,例如專案、使用者、事件與 ingest key。

docker compose up -d 實際啟動了什麼?

會啟動 3 個容器,但其中沒有 Superlog。原本以為執行一個指令就能完成安裝的人,通常會對此感到意外。

  • postgres:16,發布至主機的 5434 埠
  • clickhouse/clickhouse-server:26.1,使用 8123 提供 HTTP,並使用 9000 提供原生通訊協定
  • otel/opentelemetry-collector-contrib:0.150.1,使用 4317 提供 gRPC,並使用 4318 提供透過 HTTP 的 OTLP

Superlog 應用程式會直接從原始碼在主機上執行,由 pnpm dev 啟動。截至 13 October 2026,該 repository 中沒有 production compose 檔案。因此,若要長期執行,必須自行建立 systemd units,或使用 tree 中各應用程式附帶的 Dockerfiles。api、worker 和 proxy 應用程式各有一個 start script,可用來包裝成 unit。web 應用程式沒有這類 script:它是 Vite 應用程式,因此可使用其 build script 建置,再由 nginx 或 Caddy 將輸出作為靜態檔案提供;也可以執行其 preview script,而該 script 是 vite preview。

請記住一個 span 經過的路徑,因為以下每個故障,都是其中一個 hop 中斷所造成。你的應用程式會將 OTLP 發送至 Superlog intake proxy。proxy 使用你的 ingest key 驗證請求,在請求上標記 project id,然後將其轉送至 collector。collector 會移除 client 嘗試設定的任何 superlog.* attributes,從 proxy 提供的 header 加入 superlog.project_id,再進行批次處理並寫入 ClickHouse。web 應用程式與 API 會從 ClickHouse 讀回 telemetry,其他資料則從 Postgres 讀取。

移除這些 attributes 是實際的多租戶控制措施,不是裝飾功能。若沒有這項控制,任何持有有效 ingest key 的人,都能自行設定 superlog.project_id,並將資料寫入其他 project。

VPS 需要多大的規模?

對於低攝取量的單節點安裝,建議規劃 4 vCPU、8 GB RAM 與 40 GB SSD。這是規劃下限,不是實測結果,因此應先以此作為起始規模,再根據實際流量驗證。

記憶體主要分配到 4 個部分。ClickHouse 的設計目標是具備充足 RAM 的機器,其預設值也以此為前提。Postgres 16 在這裡的需求較低,因為它儲存的是中繼資料,而不是遙測資料。collector 的需求也不高。4 個 Node 程序則不同:Vite 開發伺服器加上 3 個 tsx watch 程序,每個都可能占用數百 MB,因此在 2 GB 的主機上執行 pnpm dev 會很吃力。

磁碟空間是較不明顯的問題。在這個 monorepo 中,pnpm install 會先拉取 AWS SDK、ClickHouse client、OpenTelemetry SDK 與 React toolchain,之後你才會攝取第一個 span。ClickHouse 接著會隨流量增加。請同時測量:

df -h /
free -m
docker stats --no-stream
docker compose exec clickhouse clickhouse-client --database superlog --query "SELECT table, formatReadableSize(sum(bytes_on_disk)) AS size FROM system.parts WHERE active AND database = 'superlog' GROUP BY table ORDER BY sum(bytes_on_disk) DESC"

在低流量下,少數服務每分鐘傳送幾百個 span,主機負載很低,ClickHouse 大多時間處於閒置狀態。真正造成負載的是突發流量:例如一次錯誤的部署,導致每分鐘產生數千筆相同錯誤。指紋比對會將這些錯誤彙整為讀者看到的一個 incident,但 ClickHouse 底層仍會寫入每一筆資料列。

保留期限由你設定。collector 的 ClickHouse exporter 會建立資料表、otel_traces、otel_logs,以及每種 metric type 各自的一個資料表。只有在 infra/collector/config.yaml 中的設定指定 time to live 時,才會套用到期時間。資料不會自行過期,因此若未事先規劃,繁忙的一個月就可能耗盡整個磁碟。

從固定 commit 安裝

git clone https://github.com/superloglabs/superlog.git
cd superlog
git tag -l
git log -1 --format='%H %cs %s'

git tag -l 截至 13 October 2026 預期不會輸出任何內容。選定已測試的 commit,並固定使用該版本:

git checkout 0d3a6c8bb63eda3493e6ba0003e7c2a70750bc1e

接著處理工具鏈:

node -v
corepack enable
corepack prepare pnpm@9.12.0 --activate
pnpm -v

package.json 將 engines.node 宣告為 >=20.0.0,並將 packageManager 宣告為 pnpm@9.12.0。在較舊的 Node 上執行安裝時,pnpm 會停止並顯示 ERR_PNPM_UNSUPPORTED_ENGINE,其中會列出所需的版本。Ubuntu 24.04 套件庫中的 nodejs 套件早於 20,因此請透過 NodeSource 或 nvm 安裝 Node 20 或更新版本。該 repository 提供 .nvmrc,因此若已安裝 nvm,nvm use 會選取指定的版本。

pnpm install
docker compose up -d
docker compose ps

請等待 health check 完成,不要將 up -d 視為服務已就緒。Postgres 與 ClickHouse 都在 compose 檔案中宣告 health check:

curl -sS http://127.0.0.1:8123/ping
pg_isready -h 127.0.0.1 -p 5434 -U postgres

ClickHouse 會回應 Ok.,而 pg_isready 會回應 accepting connections。若 8123 拒絕連線,表示容器仍在啟動,或容器已停止。docker compose logs clickhouse 可顯示是哪一種情況;若 kernel 因記憶體不足終止容器,docker inspect $(docker compose ps -q clickhouse) | grep -i oomkilled 會回報 true。這表示主機容量不足,而不是設定錯誤。

接著執行 migration 並啟動應用程式:

pnpm --filter @superlog/db db:migrate
pnpm dev

請注意連接埠是 5434,不是 5432。compose 檔案將 Postgres 發布在 5434,避免與主機上已安裝的 Postgres 發生衝突;應用程式的 .env.example 檔案也相應使用該連接埠,並包含 DATABASE_URL=postgres://postgres:postgres@localhost:5434/superlog。若在已執行 Postgres 的主機上,將 migration 指向 5432,可能會得到拒絕連線;更嚴重時,還可能將 migration 套用到錯誤的資料庫。

pnpm dev 會執行 turbo run dev,透過 Turborepo 啟動各應用程式的 dev script,包括 api、web、worker 與 proxy,並將輸出混合在同一個終端機中。repository 的 Procfile 列出相同的 4 個程序,並將每個程序的輸出同步寫入 tmp/logs/。若希望在 tail -f tmp/logs/proxy.log 中監看 ingest,請使用 overmind 或 foreman 等 Procfile runner 啟動服務,不要使用 pnpm dev。README 將 web app 指定在 http://localhost:5173、API 指定在 http://localhost:4100,並將 OTLP intake 指定在 http://localhost:4101。

在將任何服務指向該連接埠前,先確認實際正在監聽的連接埠:

ss -lntp | grep -E '4000|4100|4101|5173'
curl -sS http://127.0.0.1:4101/health

這項資訊稍後會用到。proxy 從 PORT 環境變數讀取自身的連接埠;若未設定 PORT,則回退到 4000。它載入的 apps/proxy/.env.example 也會設定 PORT=4000,但 README 列出的 intake 連接埠是 4101(兩者均於 13 October 2026 核對)。請使用 ss 顯示的連接埠。以下範例使用 4101;若實際監聽的是 4000,請替換為 4000。自行撰寫的 systemd unit 不會自動設定任何值,除非在其中加入 PORT。因此,若 exporter 指向 4101,而 proxy 實際監聽 4000,連線會遭拒絕,且不會提供其他線索。

傳送一筆追蹤資料、產生一個錯誤、查看一個事件

在 Web 應用程式中建立專案,並複製其 ingest key。接收端會使用該 key 驗證每個請求,因此未附帶 key 的遙測資料不會送達 ClickHouse。

使用標準環境變數,將任一 OpenTelemetry SDK 指向接收端:

export OTEL_SERVICE_NAME=checkout-api
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4101
export OTEL_EXPORTER_OTLP_HEADERS='x-api-key=YOUR_INGEST_KEY'

接收端會從 x-api-key 標頭讀取 key;如果 exporter 以這種方式較容易設定,也接受 authorization: bearer YOUR_INGEST_KEY。它提供 3 個標準 OTLP 路徑:/v1/traces、/v1/logs 與 /v1/metrics,以及 /health。

有一個陷阱值得特別說明。OTEL_EXPORTER_OTLP_ENDPOINT 是基礎 URL,SDK 會將訊號路徑附加到此 URL。訊號專用變數(例如 OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)則會完全依原值使用,不會附加路徑。若將訊號專用變數設為 http://127.0.0.1:4101,每次匯出都會 POST 至 /。這不是有效路由,因此不會有資料抵達;SDK 會記錄匯出失敗,但應用程式看起來仍然正常。

對於 Node 服務,不需修改程式碼即可驗證整個資料管線:

npm install @opentelemetry/api @opentelemetry/auto-instrumentations-node
node --require @opentelemetry/auto-instrumentations-node/register server.js

現在刻意造成一個錯誤。任何會拋出例外的路由都可以:

curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/boom

依序檢查各個環節,因為第一個出現間斷的位置會指出失敗的環節:

tail -n 50 tmp/logs/proxy.log
docker compose exec clickhouse clickhouse-client --database superlog --query 'SELECT count() FROM otel_traces'

如果 otel_traces 的計數持續增加,但 Web 應用程式中沒有資料,表示專案不一致。請確認 ingest key 所屬的專案。如果計數沒有增加,但 proxy log 有活動,問題可能出在 collector 或 ClickHouse 寫入流程,請查看 docker compose logs collector。如果 proxy log 完全沒有活動,表示 exporter 未抵達接收端:可能是連接埠錯誤、路徑錯誤,或 key 被拒絕。

在 Web 應用程式中,這些重複失敗會合併為一個事件,而不是每個請求各列一筆。Superlog 會為傳入的訊號建立指紋,並將相符的訊號分組。這能將收件匣中 4,000 個相同錯誤整合為一個事件。接著,agent 會在該群組上記錄調查結果。

調查步驟會呼叫模型,因此 worker 必須設定 model provider。請從你鎖定版本的 commit 中,每個應用程式目錄內的 .env.example 檔案取得這些變數名稱,不要依賴外部文件,因為這些名稱會隨 main 一起變更。GitHub 與 Sentry 整合也適用相同原則;它們各自在 docs/github-app-setup.md 與 docs/sentry-app-setup.md 提供設定文件,webhook payload 則記錄於 docs/webhooks.md。

保持接收端私有,並讓 agent 僅具備讀取權限

Docker 預設會將容器連接埠發布至 0.0.0.0,而且這些已發布的連接埠會繞過 ufw。Docker 會在 nat 表中路由容器流量,因此,送往已發布連接埠的封包會在抵達 ufw 規則所在的 INPUT 和 OUTPUT chain 之前先被導向,ufw 完全無法介入。在具備公開 IP 的 VPS 上,compose 檔案的預設設定會將 ClickHouse HTTP 放在 8123,並將 Postgres 放在 5434,導致網際網路可以連入。該檔案中的認證資訊是開發環境預設值:ClickHouse 使用者為 default,密碼為空;Postgres 則將 postgres 同時作為使用者名稱與密碼。

將它們綁定至 loopback。compose 檔案中的每個已發布連接埠,都會從環境變數取得主機端設定,因此只要在 repository 根目錄建立 .env 即可:

POSTGRES_HOST_PORT=127.0.0.1:5434
CLICKHOUSE_HTTP_HOST_PORT=127.0.0.1:8123
CLICKHOUSE_TCP_HOST_PORT=127.0.0.1:9000
COLLECTOR_GRPC_HOST_PORT=127.0.0.1:4317
COLLECTOR_HTTP_HOST_PORT=127.0.0.1:4318

在信任結果前先確認設定,然後重新建立容器:

docker compose config
docker compose up -d
ss -lntp | grep -E '5434|8123|9000|4317|4318'

docker compose config 會輸出解析後的檔案,因此你可以直接查看 127.0.0.1:5434:5432,不必猜測。此時 ss 應顯示 127.0.0.1:5434,且絕不應顯示 0.0.0.0:5434。不要使用會重新宣告 ports 的 compose override 檔案來修正此問題,因為 Compose 會串接多個檔案中的連接埠清單,而不是取代清單,結果會同時保留兩個綁定,公開綁定仍然開放。

接收端也需要相同的防護。你的 ingest key 會隨標頭傳送,因此前方必須使用 TLS(transport layer security):在 proxy 前方以 nginx 或 Caddy 終止 TLS,或將 ingest 保留在私有網路或 WireGuard tunnel 中。位於 5173 的 web app 是 Vite development server,完全不應直接面向網際網路。

接著處理 agent 本身。Superlog 的定位是讓 agent 調查問題並提出修正方案,關鍵在於「提出」。在你觀察它處理幾起真實事件前,先讓它對 production 保持 read only。為 GitHub App 授予 read scopes,並允許它建立由你審查的 pull requests。能讀取 telemetry 並寫入 patch 的 agent 很有用。能重新啟動服務的 agent 具有不同層級的風險;這應該是你刻意做出的決定,而不是沿用預設設定。成本也需要同等重視,因為每次調查都會呼叫模型:在將 agent 指向嘈雜的 production system 前,先規劃 VPS 上的 agent 支出預算,並保留agent 實際執行內容的紀錄,讓突如其來的 pull request 背後具備 audit trail。

會遇到的失敗情況,以及用來識別它們的訊息

  • ERR_PNPM_UNSUPPORTED_ENGINE 期間出現 pnpm install,表示 Node 版本低於 20。node -v 可用一行指令確認版本。
  • 遷移期間出現 ECONNREFUSED 127.0.0.1:5434,表示 compose stack 尚未啟動,或 DATABASE_URL 指定了錯誤的連接埠。
  • ClickHouse 反覆重新啟動通常是記憶體問題。先讀取 docker compose logs clickhouse,再檢查容器中的 OOMKilled 是否為 true。
  • exporter 回報成功,但 Web 應用程式仍沒有資料,通常表示資料直接送到 4318 上的 collector,略過了 proxy 會加入的 project 標記。
  • 4101 上的連線遭拒通常表示 proxy 正在監聽 4000。這是程式的預設連接埠,也是 .env.example 設定的連接埠。請在 unit file 或應用程式的 .env 中明確設定 PORT。
  • docker compose ps 顯示 0.0.0.0:8123,表示 loopback 綁定位址未生效。執行 docker compose config,並查看解析後的連接埠。

Flawless、HyperProbe,以及 Superlog 的定位

這個類別仍在發展初期,各工具對 agent 可接觸範圍的定義也不同。Flawless 是開放原始碼的 AI SRE(site reliability engineering)工具,主要用於 Kubernetes。它會讀取既有的 Prometheus、Loki 與 Grafana stack,而不是自行管理整個資料管線。HyperProbe 則採取相反方向:截至 2026 年 8 月,它是閉源的託管產品,會在執行中的程序內放置唯讀 probe,以擷取變數狀態,並透過 MCP(model context protocol)將這些狀態提供給 assistant。

Superlog 位於兩者之間。它端到端管理整個資料管線,從 OTLP intake 一直到 ClickHouse 儲存,並將 agent 放在問題分流步驟,而不是修復步驟。這種設計正是自行託管 Superlog 屬於基礎架構決策,而不是啟動後就能置之不理的 container 的原因。執行 Superlog 後,你同時也在執行 column store;它需要與你自行管理的其他 database 一樣受到妥善維護。

FAQ

自架 Superlog 需要多少 RAM?

單一節點且資料寫入量低時,請準備 8 GB RAM、4 vCPU 和 40 GB 磁碟空間。此技術堆疊包含 Postgres、ClickHouse、OpenTelemetry collector 和 4 個 Node 程序,而 ClickHouse 也需要額外的記憶體餘裕。1 GB 或 2 GB 的 VPS 不足以支撐:僅 pnpm install 就相當耗用資源,而在負載下,ClickHouse 可能會被 kernel 的 out-of-memory killer 終止。請使用 docker stats --no-stream 和 free -m 測量自己的數值,不要直接採信任何已發布的數據,包括本文數據。

OTLP exporter 應指向哪個埠?

請指向 Superlog intake proxy;README 將其設定在 http://localhost:4101。它提供 /v1/traces、/v1/logs 和 /v1/metrics,並使用從 x-api-key 標頭或 authorization: bearer 標頭取得的專案 ingest key 進行驗證。4318 埠是底層的 OpenTelemetry collector。直接將資料匯出到該埠會略過 proxy,而 proxy 會將專案 ID 寫入資料。PORT 未設定時,proxy 會回退到 4000 埠;其 .env.example 也會將埠設定為 4000。因此,請執行 ss -lntp,確認實際繫結的埠,再假設使用 4101。

Superlog 能取代 Uptime Kuma 或 Zabbix 嗎?

不能。Uptime Kuma 會從網路外部確認端點是否回應,Zabbix 則會依據你設定的閾值監控主機和服務指標。Superlog 會接收應用程式產生的追蹤、日誌和指標,並將重複發生的錯誤歸納為事件。請同時保留外部 uptime probe,因為當承載遙測管線的主機故障時,執行於其他位置的 probe 仍能回報這項故障。

Superlog agent 能變更我的 production system 嗎?

只能執行你授予的權限所允許的操作。它輸出的是調查結果和建議變更,必須由人員審查。初期請讓 GitHub App 僅使用讀取範圍,並處理 pull request;worker 持有的任何憑證也應限制為讀取權限。請將 production 的寫入權限視為另一項需要刻意決定的事項,因為能重新啟動服務的 agent,所需承擔的風險遠高於只讀取遙測資料並提交 patch 供審查的 agent。

應固定 commit,還是追蹤 main?

請固定 commit。截至 13 October 2026,該 repository 沒有 release tag,因此 main 是目前唯一可追蹤的變動目標,而且每週會產生數個 commit。請記錄測試過的 SHA,部署該版本,並在升級前閱讀 diff。git log --oneline <old-sha>..main 是審查依據,而各應用程式的 .env.example 檔案則是在任何版本更新後,首先查找新增必要變數的位置。