SpyBara
Go Premium

self-hosted-environments-reference.md 2026-11-05 23:03 UTC to 2026-11-06 23:01 UTC

No changes for this document in this history range.

2026
Tue 3 23:58 Thu 5 23:03 Mon 9 23:02 Tue 10 21:57 Wed 11 22:59

Referensi lingkungan yang di-host sendiri

Referensi lengkap untuk runner dan orchestrator yang di-host sendiri: flag CLI, variabel lingkungan, dan metrik Prometheus.

[!NOTE]

Lingkungan yang di-host sendiri berada dalam beta publik pada paket Team dan Enterprise; seorang Owner mengaktifkannya dengan mengaktifkan Allow self-hosted environments di halaman admin Cloud environments. Halaman ini adalah referensi flag dan metrik; lihat quickstart untuk setup dan Deploy to production untuk resep fleet.

Halaman ini adalah referensi untuk dua proses yang Anda jalankan dalam lingkungan yang di-host sendiri: runner, yang mengeksekusi Claude Code cloud sessions di host Anda, dan orchestrator autoscaling opsional, yang memulai runner saat session antri. Masing-masing memiliki tabel flag-nya sendiri. Keduanya berjalan di host Linux atau macOS, yang default seperti /workspace dan ~/.claude asumsikan. Jalankan claude self-hosted-runner --help untuk daftar otoritatif pada versi terinstal Anda.

Seri metrik dan beberapa field API masih menggunakan pool untuk apa yang halaman ini sebut lingkungan; kedua istilah menamakan hal yang sama. ID lingkungan adalah field pool_id, dengan bentuk ccpool_...: di mana pun halaman ini menunjukkan identifier pool, itu menamakan lingkungan. Flag CLI dan variabel lingkungan mengejanya environment, seperti --environment-secret-file; ejaan pool yang sudah usang masih berfungsi, seperti yang dijelaskan baris --environment-secret-file.

Flag CLI Runner

Sebagian besar flag memiliki variabel lingkungan yang sesuai. Ketika keduanya diatur, flag mengambil prioritas. Flag durasi mengambil menit atau detik di CLI, tetapi variabel lingkungan yang dipasangkan selalu dalam milidetik, ditunjukkan oleh suffix _MS, dan kolom Default menunjukkan unit flag: --exit-if-unused-min 10 setara dengan SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, dan nilai Helm seperti SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" berarti 15 milidetik, bukan default 15 menit.

Flag Env var Default Description
--api-url <url> none https://api.anthropic.com URL dasar API. Ganti hanya untuk pengujian.
--base-dir <path> SELF_HOSTED_RUNNER_BASE_DIR /workspace; tidak ada di Windows Direktori untuk checkout repositori dan direktori kerja per-session. Runner memerlukan akses tulis ke path ini atau induknya. Runner membuat direktori saat startup dan keluar dengan cannot create or write to base directory ketika tidak dapat membuat atau menulis ke dalamnya. Sebelum v2.1.225, runner membuat direktori ketika session pertama dimulai, jadi path yang tidak dapat digunakan gagal session daripada startup. Di Windows, yang bukan host runner yang didukung, tidak ada default: runner keluar saat startup kecuali Anda melewatkan flag atau mengatur variabel. Gunakan nilai yang sama di setiap runner dalam lingkungan. Lihat Keep the base directory and capacity identical across runners.
--capacity <n> none 1 Maksimum session bersamaan yang ditangani runner ini. Semua session milik owner yang terkunci sama. Gunakan nilai yang sama di setiap runner dalam lingkungan; lihat Keep the base directory and capacity identical across runners.
--client-label <label> SELF_HOSTED_RUNNER_CLIENT_LABEL hostname host Label yang dikirim runner saat mendaftar. Runner juga melaporkannya sebagai label client_label dari claude_code_self_hosted_runner_info. Memerlukan Claude Code v2.1.248 atau lebih baru.
--configure-git SELF_HOSTED_RUNNER_CONFIGURE_GIT=1 off Saat startup, tulis identitas git global, aktifkan penandatanganan commit Anthropic, aktifkan negosiasi push git, dan instal commit hooks yang menambahkan trailer Co-authored-by:. Negosiasi push memerlukan Claude Code v2.1.257 atau lebih baru. Lihat Configure git.
--confine-repo-settings <mode> SELF_HOSTED_RUNNER_CONFINE_REPO_SETTINGS warn Menetapkan mode guard yang menandai session ketika pengaturan repositori yang berkomitmen mencoba memberikan akses tulis atau baca di luar workspace session sendiri, mengatur variabel lingkungan, atau mengganti postur sandbox atau hooks operator, seperti sandbox.enabled: false atau disableAllHooks. Default warn mencatat pelanggaran dan masih memulai session, enforce menolak session, dan off menonaktifkan pemindaian. Lihat Harden your deployment.
--debug-token-dir <path> SELF_HOSTED_RUNNER_DEBUG_TOKEN_DIR unset Tulis token langsung ke disk untuk inspeksi. Debug saja; jangan gunakan dalam produksi.
--defer-shutdown-max-min <n> SELF_HOSTED_RUNNER_DEFER_SHUTDOWN_MAX_MS 0 Pada SIGTERM atau SIGINT pertama, terus melayani session yang sudah terpasang daripada mengalirnya, kemudian lepaskan apa pun yang masih terpasang N menit kemudian dan keluar. Naikkan timeout berhenti host Anda sebelum mengatur ini. Lihat Defer the drain past the first signal. 0 menonaktifkan. Memerlukan Claude Code v2.1.238 atau lebih baru.
--drain-grace-sec <n> SELF_HOSTED_RUNNER_DRAIN_GRACE_MS 0 Sampai runner menerima sinyal shutdown atau mencapai waktu pensiun, mengontrol kapan runner keluar setelah session aktifnya selesai: 0 keluar segera tanpa polling lebih lanjut, dan nilai positif membuat runner tetap hidup dan re-polling antrian owner yang terkunci untuk banyak detik itu terlebih dahulu, dengan biaya isolasi kontainer per-session yang dijelaskan di bagian hardening. Setelah sinyal pertama yang Anda tunda dengan --defer-shutdown-max-min, runner keluar segera setelah tidak memiliki session, apa pun yang Anda atur di sini.
--drain-marker-file <path> SELF_HOSTED_RUNNER_DRAIN_MARKER_FILE unset File penanda yang ditulis host Anda untuk mengumumkan drain yang elegan sebelum mengirim SIGTERM. Ketika file ada saat drain dimulai, runner melaporkan keluarnya ke Anthropic sebagai drain host daripada sinyal shutdown biasa. Drain itu sendiri, termasuk hold --drain-wait-sec, berjalan sama seperti tanpa flag. Beri nama path pada filesystem lokal yang tidak dapat ditulis session. Memerlukan Claude Code v2.1.271 atau lebih baru.
--drain-wait-sec <n> SELF_HOSTED_RUNNER_DRAIN_WAIT_MS 0 Setelah drain dimulai, yang mana pada SIGTERM kecuali Anda mengatur --defer-shutdown-max-min, tunggu hingga N detik untuk setiap turn in-flight session dan background task selesai sebelum menghentikan child. Selama menunggu ini, runner menghitung background task yang baru saja selesai sebagai masih berjalan sampai turn follow-up yang membaca hasilnya dimulai, untuk paling banyak jendela SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. Naikkan juga timeout berhenti Anda.
--environment-secret-file <path> SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET required Path ke file yang berisi rahasia lingkungan, atau, untuk runner yang dihasilkan oleh orchestrator, JWT work-order sekali pakai. SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET membawa nilai rahasia secara langsung, bukan path file. Flag --pool-secret-file yang lebih lama dan variabel SELF_HOSTED_RUNNER_POOL_SECRET masih berfungsi dan mencetak pemberitahuan deprecation ke stderr; build runner program preview yang lebih lama dari 2.1.216 hanya mengenali nama yang lebih lama itu.
--exec-path <path> SELF_HOSTED_RUNNER_EXEC_PATH binary sendiri Binary atau wrapper script untuk dihasilkan untuk setiap session. Lihat Wrapper scripts.
--exit-if-unused-min <n> SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS 0 Keluar setelah N menit polling tanpa pekerjaan yang pernah ditugaskan, untuk scale-down autoscaler. 0 menonaktifkan.
--git-host-rewrite <from>=<to> none unset Tulis ulang URL sumber https://<from>/... ke https://<to>/... sebelum cloning, untuk split-horizon DNS. Dapat diulang; flag saja.
--git-ssh-rewrite <host> none unset Tulis ulang URL sumber https://<host>/... ke git@<host>:... sebelum cloning, untuk git host SSH-only. Dapat diulang; flag saja.
--health-port <port> SELF_HOSTED_RUNNER_HEALTH_PORT 8080 Port untuk listener /healthz dan /metrics. Atur 0 untuk menonaktifkan.
--hold-idle-file <path> SELF_HOSTED_RUNNER_HOLD_IDLE_FILE unset File yang terus diubah oleh host Anda untuk menahan sesi idle di runner. Lihat Keep an idle session while its processes run. Memerlukan Claude Code v2.1.311 atau lebih baru.
--hooks-dir <path> SELF_HOSTED_RUNNER_HOOKS_DIR unset Direktori script hook lifecycle. Lihat Lifecycle hooks.
--host-config-snapshot <mode> SELF_HOSTED_RUNNER_HOST_CONFIG_SNAPSHOT disk Tempat runner menyimpan snapshot startup dari direktori host config yang diseednya dari setiap session. disk menyalin snapshot ke direktori yang dimiliki runner di bawah --base-dir dan, di setiap awal session, memverifikasi setiap file terhadap digest in-memory. Jika file dalam salinan telah dimodifikasi, session gagal dan runner menolak session sampai Anda memulainya ulang. memory menyimpan seluruh snapshot di heap, dibatasi pada 64 MiB; di atas batas, session dimulai tanpa host config dan menampilkan pemberitahuan yang mengatakan demikian. Ketika runner tidak dapat menulis snapshot disk, itu mencatat kegagalan dan menggunakan memory untuk run itu. Memerlukan Claude Code v2.1.271 atau lebih baru.
--kill-session-after-min <n> SELF_HOSTED_RUNNER_MAX_LIFETIME_MS 0 Batasi session ke N menit wall-clock, sebagai batas keselamatan untuk session yang macet. Pada v2.1.260 atau lebih baru, runner melepaskan session yang mencapai batas sehingga dapat dilanjutkan pada pesan berikutnya pengguna, dan menghentikannya hanya jika masih ada di runner ketika jendela grace SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS berakhir. Sebelum v2.1.260, runner menghentikan session pada batas. Lihat Some sessions don't count as idle untuk detail dan cara memilih nilai. 0 menonaktifkan.
--lock-to-account <id> SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT unset Pre-lock runner ke akun spesifik saat startup daripada mengunci pada session pertama. Menerima alamat email atau ID user_... dalam organisasi lingkungan. Runner yang pre-locked tidak pernah mengambil session Claude Tag channel, yang tidak memiliki akun.
--log-file <path> SELF_HOSTED_RUNNER_LOG_FILE unset Mirror log runner ke file selain stdout dan stderr, dibuat dengan izin 0600. Diperlukan untuk self-hosted-runner doctor untuk tail log secara lokal.
--log-level <level> none info info atau debug
--max-hold-min <n> SELF_HOSTED_RUNNER_MAX_HOLD_MS 1440 Dengan --hold-idle-file, tetap lepaskan sesi yang ditahan N menit setelah sesi tersebut menjadi idle. Nilai yang sama dengan atau di bawah --release-idle-session-min tidak menahan apa pun. 0 mematikan penahanan. Memerlukan Claude Code v2.1.311 atau lebih baru.
--post-session-hook-timeout-sec <n> SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS 60 Anggaran untuk hook post-session di setiap akhir session, termasuk shutdown runner
--proxy-authorization-command <command> SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND unset Perintah shell yang dijalankan runner untuk setiap koneksi ke proxy egress Anda, menggunakan stdout yang dipangkas sebagai nilai header Proxy-Authorization. Memerlukan HTTPS_PROXY atau HTTP_PROXY, dan tidak dapat digabungkan dengan --proxy-authorization-file. Lihat Authenticate to an egress proxy. Memerlukan Claude Code v2.1.238 atau lebih baru.
--proxy-authorization-file <path> SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE unset File yang dibaca runner untuk setiap koneksi ke proxy egress Anda, menggunakan isinya yang dipangkas sebagai nilai header Proxy-Authorization. Gunakan flag ini untuk token yang proses lain rotasi di tempat. Membawa persyaratan yang sama dengan --proxy-authorization-command, dan tidak dapat digabungkan dengannya. Lihat Authenticate to an egress proxy. Memerlukan Claude Code v2.1.238 atau lebih baru.
--push-outcome-on-release SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE off Saat akhir sesi yang dipicu runner, seperti drain atau idle release, runner melakukan push branch sesi utama yang memiliki commit baru ke origin sebelum menghapus workspace. Best-effort; menambah 30 detik ke anggaran shutdown. Memerlukan git 2.29 atau lebih baru untuk melanjutkan dari branch tersebut. Batasi akses push ke ref claude/*; lihat Sesi yang dilanjutkan kehilangan pekerjaan yang belum di-push. Repositori dari hook checkout tidak di-push; buat snapshot repositori tersebut dari hook post-session.
--release-idle-session-min <n> SELF_HOSTED_RUNNER_SESSION_IDLE_MS 0 Lepaskan slot sesi setelah N menit tanpa aktivitas begitu giliran selesai atau sesi menunggu tindakan pengguna. Some sessions don't count as idle, jadi pasangkan dengan --kill-session-after-min. Tugas latar belakang yang sudah selesai membuat sesi tetap sibuk paling lama selama jendela SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. Untuk menunda pelepasan, atur --hold-idle-file. 0 menonaktifkan.
--remove-session-state [bool] SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE off Hapus direktori per-session session di bawah <base-dir>/_sessions/ ketika session berakhir di runner ini, apa pun hasilnya. Reuse a pre-warmed checkout menjelaskan apa yang mereka pegang dan siapa yang dapat membacanya ketika mereka tetap. Penghapusan adalah best-effort: direktori per-session tetap ada ketika runner dibunuh atau mencapai deadline drain sebelum cleanup berjalan. Dengan flag aktif, debug log session yang gagal atau terputus tidak disimpan di disk. Memerlukan Claude Code v2.1.268 atau lebih baru.
--retire-at <epoch-seconds> SELF_HOSTED_RUNNER_RETIRE_AT unset Pensiun runner pada timestamp Unix absolut dalam detik, untuk infrastruktur yang membunuh runner pada waktu yang diketahui; Runner lifecycle menjelaskan urutan release dan cara mengukur margin. Nilai sebelum 2001 atau setelah tahun 5138 ditolak oleh flag dan diabaikan oleh variabel lingkungan.
--server-auto-mode-lists <mode> SELF_HOSTED_RUNNER_SERVER_AUTO_MODE_LISTS no-allow Daftar aturan pengklasifikasi auto mode mana yang dikirim control plane bersama sebuah sesi yang boleh mencapai sesi tersebut: all, no-allow, atau none. Lihat Daftar aturan auto mode untuk apa yang diterapkan setiap nilai. Nilai yang tidak valid menghentikan runner saat startup. Memerlukan Claude Code v2.1.295 atau lebih baru.
--session-stop-grace-sec <n> SELF_HOSTED_RUNNER_SESSION_STOP_GRACE_MS 5 Berapa lama menunggu proses Claude keluar dengan bersih setelah session berakhir, sebelum force-killing. Naikkan nilai jika hook SessionEnd child sendiri memerlukan lebih banyak waktu.
--startup-timeout-min <n> SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS 15 Berapa lama menunggu proses child yang belum diinisialisasi sebelum melepaskan slot sesi. Lihat Timeout startup sesi untuk kapan penghitungan dimulai dan sesi mana yang tetap dibiarkan berjalan. 0 menonaktifkan timeout.
--trust-workspace [bool] SELF_HOSTED_RUNNER_TRUST_WORKSPACE on Seed kepercayaan yang bertahan untuk setiap path repositori session sehingga permissions.allow dan additionalDirectories yang berkomitmen repo dihormati. Atur false untuk menghapus hibah izin yang berkomitmen repo dan mengonfigurasi aturan allow dalam settings.json konfigurasi host sebagai gantinya; pengaturan sandbox.* yang berkomitmen repo masih berlaku baik cara, itulah mengapa repo-settings guard memindainya terlepas dari flag ini.
--use-anthropic-git-proxy CLAUDE_RUNNER_USE_GIT_PROXY=1 off Clone repositori di github.com melalui Anthropic git proxy alih-alih auth git yang dikelola pelanggan. Memerlukan --capacity 1 dan git 2.32 atau lebih baru; jika tidak, runner menolak untuk dimulai. Menggantikan flag rewrite.

Sebagian besar flag durasi memiliki maksimum, dipilih untuk menjaga setiap timeout di dalam ceiling timer 32-bit runtime sekitar 24,85 hari. Flag --*-min cap pada 10080 menit, 7 hari; --drain-grace-sec pada 604800 detik, juga 7 hari; dan --drain-wait-sec pada 86400 detik, 24 jam. --session-stop-grace-sec dan --post-session-hook-timeout-sec tidak terbatas. Melampaui cap berperilaku berbeda per surface:

  • Flag: startup gagal dengan error.
  • Variabel lingkungan: runner menjepit nilai ke ceiling timer daripada menolaknya.

Timeout startup sesi

Jika sebuah sesi kehilangan slotnya selama giliran seperti /code-review, perbarui runner dan binary child ke v2.1.309 atau lebih baru. Dari v2.1.299 hingga v2.1.308, runner melepaskan sesi, bahkan di tengah giliran, begitu timeout startup terlewati tanpa pesan user atau assistant.

Dengan --startup-timeout-min <n>, runner melepaskan slot sesi ketika child-nya belum diinisialisasi dalam <n> menit setelah cloning. Selama giliran yang dimulai sebelum child diinisialisasi, sesi mempertahankan slotnya hingga <n> menit berlalu tanpa satu baris pun di activity channel milik child. Setelah child diinisialisasi, runner mengosongkan hitungan tersebut dan --release-idle-session-min mengatur pelepasan. Untuk membatasi sesi yang child-nya hidup tetapi macet, atur --kill-session-after-min.

Daftar aturan auto mode

--server-auto-mode-lists memungkinkan Anda memutuskan aturan pengklasifikasi auto mode mana dari luar runner yang mencapai sesi di runner Anda. Control plane Anthropic dapat mengirim daftar aturan bersama sebuah sesi dan meminta runner untuk menerapkannya. Beberapa entri mungkin merupakan aturan yang ditulis oleh admin organisasi Anda. Daftarnya adalah environment, soft_deny, dan allow:

  • environment: sebuah entri dapat membuat pengklasifikasi mengizinkan lebih banyak maupun lebih sedikit.
  • soft_deny: sebuah entri memblokir tindakan kecuali pengguna secara eksplisit memintanya atau pengecualian allow berlaku.
  • allow: pengecualian terhadap entri soft_deny.

Nilai flag menentukan daftar mana yang diterapkan runner:

  • no-allow: default. Menerapkan environment dan soft_deny serta menahan allow. Entri environment tetap dapat membuat pengklasifikasi mengizinkan lebih banyak, sehingga default tidak mencegah setiap pelonggaran.
  • all: menerapkan ketiga daftar.
  • none: tidak menerapkan satu pun. Pilih none untuk mencegah setiap pelonggaran dari daftar-daftar ini. Ini juga menghilangkan pembatasan soft_deny.

Tidak ada pengaturan runner yang membuat control plane meminta runner menerapkan daftar tersebut. Ketika control plane tidak meminta, sesi tidak menerima daftar apa pun, apa pun yang Anda atur. Untuk melihat mana yang terjadi, mulai runner dengan --log-level debug. Untuk setiap sesi, runner kemudian mencatat ke log baris yang berisi the server asked this runner to apply, atau baris yang berisi the server did not ask this runner to apply the auto mode lists it sends.

Flag CLI orchestrator

Subperintah self-hosted-runner orchestrator, yang menjalankan runner on-demand, menerima --api-url, --environment-secret-file, --hooks-dir, --health-port, dan --log-level dengan default yang sama seperti runner dan, jika flag runner memilikinya, environment variable yang sama, kecuali bahwa --hooks-dir wajib diisi dan harus berisi hook spawn-runner. Subperintah ini juga menerima flag-nya sendiri:

Flag Default Deskripsi
--hook-concurrency <n> 4 Jumlah maksimum hook spawn-runner yang berjalan secara paralel. Juga membatasi berapa banyak permintaan spawn yang diklaim per polling. Orchestrator memeriksa permintaan spawn baru hanya setelah setiap hook yang dimulainya selesai, sehingga satu hook yang lambat menunda hook berikutnya dari orchestrator tersebut.
--hook-timeout <sec> 60 Menghentikan pohon proses hook setelah sekian detik. Timeout ditambah masa tenggang kill 5 detik harus tetap di bawah --expected-spawn-seconds; orchestrator memberlakukan hal ini saat startup.
--expected-spawn-seconds <sec> 120 Perkiraan waktu p99 sejak orchestrator menerima permintaan spawn hingga runner terdaftar, termasuk waktu menunggu kapasitas di platform Anda. Server memberlakukan rentang 10 hingga 3600. Dikirim pada setiap polling sebagai lease sisi server: jika tidak ada runner yang terdaftar sebelum waktu tersebut berlalu, sesi ditawarkan kembali dengan ID pesanan baru. Semua replika harus menggunakan nilai yang sama.
--min-idle <n> 0 Menjaga setidaknya N slot sesi idle tetap tersedia (tidak terpakai) dengan menjalankan runner standby secara proaktif. 0 menonaktifkan pra-pemanasan. Pasangkan dengan --exit-if-unused-min milik runner agar runner standby yang berlebih mengakhiri dirinya sendiri.
--shutdown-drain-sec <n> 0 Saat menerima SIGTERM, berhenti melakukan polling untuk permintaan spawn dan beri hook spawn-runner yang sedang berjalan serta polling yang belum dijawab waktu hingga sekian detik untuk selesai sebelum menghentikan yang tersisa. Pada nilai 0, berhenti segera. Maksimum 3600, yang diberlakukan orchestrator saat startup. Untuk memilih nilai, lihat Menentukan ukuran --shutdown-drain-sec dan timeout penghentian orchestrator. Memerlukan Claude Code v2.1.299 atau yang lebih baru.
--debug-dir <path> tidak diatur Menulis work order setiap permintaan spawn dan stderr hook ke disk. Hanya untuk debug; jangan pernah diatur di lingkungan produksi.

Flag konektor SCM

Konektor SCM tidak tersedia, jadi biarkan flag di bagian ini tidak diatur. Jika Anda mengatur --scm-connector-host, koneksi tidak terbuka, dan orchestrator terus mencoba ulang. Runner tetap dimulai saat sesi masuk antrean.

Konektor ini adalah koneksi WebSocket tetap dari orchestrator ke control plane Anthropic. Konektor ini dirancang agar alur pra-sesi yang di-host, seperti pemilih repositori dan penentu branch atau ref, dapat menjangkau host GitHub Enterprise Server yang hanya dapat dirutekan dari dalam jaringan Anda. Lihat Persyaratan jaringan di halaman GitHub Enterprise Server untuk mengetahui apa yang dibutuhkan alur tersebut.

Flag Default Deskripsi
--scm-connector-host <host[:port]> tidak diatur Hostname GitHub Enterprise Server tujuan penerusan permintaan. Port default-nya adalah 443.
--scm-connector-id <n> wajib bersama --scm-connector-host ID numerik koneksi GitHub Enterprise Server organisasi Anda.
--scm-connector-provider <slug> ghe Segmen path yang mengidentifikasi penyedia, sesuai dengan ^[a-z0-9-]{1,32}$.
--scm-connector-ca-file <path> tidak diatur Bundel CA tambahan, dalam format PEM, untuk koneksi TLS ke host GitHub Enterprise Server.
--scm-connector-host-rewrite <from>=<to_host:to_port> tidak diatur Hanya untuk pengujian end-to-end: mengalihkan koneksi TCP sambil mempertahankan header Host dan TLS SNI sebagai --scm-connector-host.

Pada setiap upaya koneksi, orchestrator mengirimkan environment secret yang sudah ada, dan otomatis mencoba ulang dengan exponential backoff, dibatasi hingga 30 detik ditambah jitter.

Pengaturan variabel-lingkungan-saja

Pengaturan runner ini dibaca dari lingkungan saja dan mencakup perilaku yang sebagian besar deployment tinggalkan di default:

Env var Default Description
SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS 30000 Berapa lama runner menganggap session sibuk setelah background task selesai sementara turn follow-up yang membaca hasil belum dimulai. Baris --drain-wait-sec dan --release-idle-session-min menjelaskan di mana hold berlaku pada drain dan idle release, dan Runner lifecycle menjelaskan di mana itu berlaku pada pensiun --retire-at. 0 atau nilai yang tidak dapat digunakan kembali ke default, jadi hold tidak dapat dimatikan. Memerlukan Claude Code v2.1.228 atau lebih baru.
SELF_HOSTED_RUNNER_HOST_CONFIG_DIR ~/.claude Direktori ditangkap ke snapshot startup runner dan disemai ke CLAUDE_CONFIG_DIR setiap session; perubahan di disk berlaku setelah restart runner. Mengatur variabel juga memindahkan di mana runner membaca .claude.json untuk MCP seeding, jadi mengaturnya, termasuk ke default sendiri, merelokasi lookup itu; arahkan ke direktori kosong untuk menonaktifkan seeding sepenuhnya.
SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS 900000 Berapa lama runner menunggu setelah session mencapai batas --kill-session-after-min, untuk turn yang sedang berjalan selesai atau release selesai, sebelum itu menghentikan session
SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS 7000 Batas pada berapa lama runner menghitung session sebagai sibuk untuk drain --drain-wait-sec setelah turn selesai, sementara proses session melaporkan akhir turn ke Anthropic. 0 atau nilai yang tidak dapat digunakan kembali ke default, jadi hold tidak dapat dimatikan. Memerlukan Claude Code v2.1.275 atau lebih baru.
SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS 30000 Berapa lama runner menunggu OS untuk mengirimkan SIGKILL ke child yang macet dalam I/O yang tidak dapat diinterupsi sebelum keluar sendiri. Setidaknya --post-session-hook-timeout-sec plus 15 detik, dan 30 detik lagi ketika --push-outcome-on-release diatur, jadi minimum efektif adalah 75 detik di default.
CLAUDE_RUNNER_FETCH_DEPTH 50 Git fetch depth untuk fresh clone. Atur integer positif, atau full atau 0 untuk fetch lengkap. Untuk clone yang sudah ada di workspace, lihat Menggunakan kembali checkout yang telah disiapkan sebelumnya.
CLAUDE_RUNNER_FETCH_SERVER_PROGRESS_CAP_MS 600000 Berapa lama dalam milidetik, per percobaan, sebuah git fetch dapat menunggu data pertamanya sementara angka progres milik server git itu sendiri terus naik, seperti ketika server menyiapkan pack untuk repositori besar. 0 atau off mematikan penantian tersebut: fetch seperti itu kemudian dihentikan setelah dua menit tanpa data. Bilangan bulat lainnya dibatasi antara 120000 dan 1800000, yaitu 2 hingga 30 menit. Memerlukan Claude Code v2.1.295 atau lebih baru.
CLAUDE_RUNNER_SKIP_GIT_VERIFY unset Ketika 1, lewati pemeriksaan kehadiran .git setelah hook checkout berjalan. Atur ini ketika hook Anda materialize sumber non-git.
FORCE_AUTOUPDATE_PLUGINS unset Ketika 1, biarkan marketplace plugin auto-update meskipun binary disematkan
CLAUDE_CODE_DISABLE_ARTIFACT unset Ketika 1, nonaktifkan tool Artifact dalam session terlepas dari pengaturan admin organisasi, dan lepaskan persyaratan egress *.frame.claudeusercontent.com

Telemetry

Child session mengirim telemetry operasional ke Anthropic kecuali Anda mematikannya. Tidak ada kode atau konten repositori yang dikirim. Atur variabel telemetry pada proses runner; runner re-assert mereka setelah menerapkan variabel lingkungan yang disediakan server, jadi pengaturan operator selalu mengambil prioritas.

Satu kontrol spesifik untuk lingkungan yang di-host sendiri: CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 opt in ke metrik operasional Datadog, yang off secara default dalam lingkungan yang di-host sendiri. Kontrol telemetry Claude Code umum, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING, dan CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, berlaku untuk child session seperti yang didokumentasikan dalam referensi variabel lingkungan. DISABLE_GROWTHBOOK terkait tetapi berbeda: mengatur DISABLE_GROWTHBOOK=1 menonaktifkan pengambilan feature-flag, dan telemetry tetap on kecuali DISABLE_TELEMETRY juga diatur.

CLAUDE_CODE_ENABLE_TELEMETRY tidak terkait: itu mengaktifkan export OpenTelemetry ke collector Anda sendiri, seperti yang dijelaskan dalam Monitoring, dan tidak mengontrol analytics Anthropic.

Health endpoint

Runner melayani GET /healthz pada port health yang dikonfigurasi. Respons adalah 200 OK kapan pun proses hidup, apa pun state poll loop, jadi probe HTTP pada endpoint ini mendeteksi proses mati saja. Badan JSON menjelaskan state saat ini:

{
  "status": "ok",
  "runner_id": "ccrunner_...",
  "active_sessions": 2,
  "last_poll_at": "2026-03-31T18:04:11.220Z",
  "last_poll_age_ms": 842
}

Buat peringatan berdasarkan last_poll_age_ms, tetapi jangan menggunakannya dalam probe liveness; pertahankan probe tersebut pada kode status HTTP. Nilai ini adalah waktu sejak poll terakhir yang berhasil, sehingga nilainya juga naik saat runner tidak dapat menjangkau Anthropic. Baik last_poll_at maupun last_poll_age_ms bernilai null sampai poll pertama berhasil. Untuk menangkap poll yang gagal sejak awal, buat juga peringatan berdasarkan claude_code_self_hosted_runner_poll_errors_total, yang tercantum di bawah metrik Prometheus.

/healthz milik orchestrator sendiri, pada port health-nya, selalu mengembalikan 200. Badan membawa field connected yang melaporkan apakah poll terbaru berhasil, plus spawn-queue count per-state dalam queue_counts. Untuk melihat mengapa connected bernilai false, baca field last_error tingkat atas, yang diatur ulang menjadi null oleh setiap poll yang berhasil. Gate readiness dan alerting pada connected daripada status code.

Ketika SCM connector dikonfigurasi, badan /healthz orchestrator juga membawa scm_connector_connected dan objek scm_connector dengan connected, last_connected_at, last_error, reconnects, dan requests_forwarded. Kedua field adalah null ketika --scm-connector-host tidak diatur.

Metrik Prometheus

Setiap runner menyajikan metrik Prometheus di GET /metrics pada port yang sama dengan /healthz. Seri utama:

Seri Catatan
claude_code_self_hosted_runner_info{runner_id,version,client_label} Selalu 1; berguna untuk inventaris armada dan deteksi perbedaan versi
claude_code_self_hosted_runner_capacity --capacity yang dikonfigurasi
claude_code_self_hosted_runner_active_sessions Sesi yang sedang berjalan
claude_code_self_hosted_runner_locked_account{email} Ada setelah runner terkunci ke seorang pengguna dan token sesi yang membawa klaim act.email telah diterbitkan. Seri ini tidak ada pada runner yang terkunci ke agent Claude Tag, yang token sesinya tidak membawa act.email. Nilai label adalah email akun; jika penyimpanan metrik Anda dapat dibaca secara luas, hapus atau hash label tersebut saat scrape, misalnya dengan metric_relabel_configs Prometheus.
claude_code_self_hosted_runner_last_poll_age_seconds Detik sejak poll terakhir yang berhasil. Kirim peringatan jika lebih dari 60.
claude_code_self_hosted_runner_poll_errors_total{error_kind} Kegagalan PollWork kumulatif berdasarkan jenis: transport, timeout, 5xx, 429, atau 4xx. Kelima seri ada sejak proses dimulai; kirim peringatan pada rate(...[5m]) > 0.
claude_code_self_hosted_runner_sessions_started_total{client_platform} Proses anak sesi yang di-spawn selama masa hidup runner, satu seri per asal sesi seperti web_claude_ai, ios, android, desktop_app, atau claude_code_cli, atau unknown ketika server tidak mengirimkannya. Sesi Slack membawa claude_in_slack atau claude-in-slack tergantung integrasi Slack mana yang membuatnya, jadi cocokkan keduanya dengan selektor regex seperti {client_platform=~"claude[-_]in[-_]slack"}. Gunakan sum() untuk total armada.
claude_code_self_hosted_runner_sessions_completed_total{client_platform} Sesi yang berakhir dengan bersih, dengan label yang sama. Lebih luas dari sekadar keluar dengan bersih: lihat semantik penghitung siklus hidup sesi untuk apa saja yang dihitung.
claude_code_self_hosted_runner_sessions_failed_total{client_platform} Sesi yang berakhir dengan kegagalan, dengan label yang sama. Catatan yang sama: lihat semantik penghitung siklus hidup sesi.
claude_code_self_hosted_runner_sessions_interrupted_total{client_platform} Sesi yang dihentikan runner karena alasan operasional, bukan karena hasil sesi, dengan label yang sama. Lihat semantik penghitung siklus hidup sesi.
claude_code_self_hosted_runner_initializing_sessions Sesi yang saat ini berada dalam fase init, dari penugasan hingga event init milik proses anak
claude_code_self_hosted_runner_session_init_duration_seconds Histogram durasi init sesi
claude_code_self_hosted_runner_session_init_errors_total Sesi yang gagal sebelum mencapai init: kegagalan hook checkout, persiapan git, masalah token, atau crash proses anak sebelum init
claude_code_self_hosted_runner_session_start_hook_errors_total Hook SessionStart yang melaporkan hasil error, satu per eksekusi hook yang gagal
claude_code_self_hosted_runner_session_idle_seconds{session_id,client_platform} Gauge per sesi berisi detik sejak sesi menjadi idle. Berguna untuk menghentikan sesi yang macet pada permintaan izin yang belum dijawab.

Orchestrator menyajikan serinya sendiri di GET /metrics pada port yang sama dengan /healthz miliknya:

Seri Catatan
claude_code_self_hosted_orchestrator_info{version,pool_id,orchestrator_uuid,hostname} Selalu 1
claude_code_self_hosted_orchestrator_connected 1 ketika poll terbaru berhasil; turun ke 0 setelah poll apa pun gagal, apa pun jenis kegagalannya
claude_code_self_hosted_orchestrator_last_poll_age_seconds Detik sejak percobaan poll terakhir, berhasil atau gagal, berbeda dengan metrik runner yang bernama sama, yang mengukur sejak keberhasilan terakhir; pasangkan dengan connected untuk menangkap poll yang gagal. Loop poll orchestrator menunggu eksekusi hook, jadi kirim peringatan di atas --hook-timeout ditambah margin, sekitar 90 detik pada nilai default, alih-alih nilai tetap 60.
claude_code_self_hosted_orchestrator_poll_errors_total{error_kind} Kegagalan PollSpawnHints kumulatif berdasarkan jenis: transport, timeout, 5xx, 429, atau 4xx. Kelima seri ada sejak proses dimulai; kirim peringatan pada rate(...[5m]) > 0.
claude_code_self_hosted_orchestrator_queue_pending_sessions Permintaan spawn yang dapat diklaim saat ini
claude_code_self_hosted_orchestrator_queue_backing_off_sessions Permintaan spawn dalam backoff retry setelah kegagalan hook yang dapat dicoba ulang
claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions Sesi yang diblokir dari spawn. Masing-masing tetap diblokir hingga pengguna mengirim pesan baru ke sesi tersebut atau seorang Owner mencobanya ulang dari tab Activity environment. Jumlahnya dapat tetap di atas nol setelah Anda memperbaiki penyebabnya. Kirim peringatan jika di atas nol.
claude_code_self_hosted_orchestrator_pool_pending_sessions Total sesi yang menunggu runner untuk environment ini. Agregat seluruh environment, identik di setiap instans orchestrator: gunakan MAX alih-alih SUM di seluruh instans.
claude_code_self_hosted_orchestrator_pool_active_sessions Sesi yang saat ini ditugaskan ke runner yang hidup di environment ini. Agregat seluruh environment, identik di setiap instans orchestrator: gunakan MAX alih-alih SUM di seluruh instans.
claude_code_self_hosted_orchestrator_spawn_hooks_total{result} Hasil hook spawn-runner kumulatif: ok, retryable, non_retryable. Menghitung pemanggilan hook orchestrator, bukan proses anak sesi yang di-spawn runner: tidak dapat dibandingkan dengan sessions_started_total, karena kapasitas di atas satu, warm pool, dan runner yang di-spawn ulang untuk sesi yang sama semuanya membuat keduanya berbeda.
claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds Histogram durasi hook
claude_code_self_hosted_orchestrator_warm_hints_dispatched_total Permintaan spawn standby yang dikirim sejak proses dimulai
claude_code_self_hosted_orchestrator_session_queue_wait_seconds Histogram detik yang dihabiskan setiap sesi menunggu dalam antrean sebelum orchestrator mengklaimnya untuk spawn, dicatat dari timestamp tunggu antrean yang dikirim control plane bersama permintaan spawn setiap sesi. Gunakan untuk peringatan waktu antrean p50/p99. Spawn pre-warming tidak diambil sampelnya.
claude_code_self_hosted_orchestrator_clock_skew_seconds Selisih jam lokal dikurangi server; diagnostik, ada setelah diukur
claude_code_self_hosted_orchestrator_scm_connector_connected 1 ketika WebSocket konektor SCM terbuka; 0 saat sedang menyambung atau dalam backoff. Tidak ada ketika --scm-connector-host tidak diatur.
claude_code_self_hosted_orchestrator_scm_connector_requests_forwarded_total Permintaan HTTP kumulatif yang di-proxy ke host SCM yang dikonfigurasi sejak proses dimulai. Tidak ada ketika --scm-connector-host tidak diatur.

Untuk autoscaling, pilih seri yang sesuai dengan gaya scaling Anda dan beri gerbang padanya sebelum diumpankan ke scaler:

  • Scaling berdasarkan kedalaman antrean: umpankan claude_code_self_hosted_orchestrator_pool_pending_sessions ke scaler HPA atau KEDA Anda, bukan queue_pending_sessions.
  • Scaling berdasarkan kapasitas: lakukan scaling berdasarkan rasio active_sessions runner terhadap capacity.
  • Gerbang pada connected: filter kueri dengan claude_code_self_hosted_orchestrator_connected == 1 per instans, sehingga nilai usang dari replika yang terputus tidak diumpankan ke scaler.

Selama gangguan poll total, ketika setiap replika terputus, kueri yang diberi gerbang tidak mengembalikan data. HPA mempertahankan jumlah replika saat ini ketika metrik tidak ada, tetapi scaler Prometheus KEDA dengan default ignoreNullValues: "true" membaca hasil kosong sebagai nol dan melakukan scale in; atur ignoreNullValues: "false" pada ScaledObject, opsional dengan batas bawah replika fallback.

PodMonitor Prometheus Operator berikut mencakup kedua proses. Ini memilih pod berdasarkan label app.kubernetes.io/part-of: claude-code-self-hosted-runner dan port bernama health yang diatur oleh resep Kubernetes; sesuaikan namespace agar cocok dengan deployment Anda:

# Example Prometheus Operator PodMonitor for the Claude Code self-hosted
# runner + orchestrator. Adjust the namespace and label selectors to match
# your deployment. Both the runner and the orchestrator serve /metrics on
# their --health-port (default 8080).
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: claude-code-self-hosted-runner
  namespace: monitoring
spec:
  namespaceSelector:
    matchNames:
      - claude-runners
  selector:
    matchExpressions:
      # Matches the runner Deployment from the Kubernetes recipe, plus any
      # on-demand runner Jobs and orchestrator pods you label the same way
      # and give a named 'health' containerPort.
      - key: app.kubernetes.io/part-of
        operator: In
        values: [claude-code-self-hosted-runner]
  podMetricsEndpoints:
    - port: health
      path: /metrics
      interval: 30s

Contoh aturan peringatan

Contoh aturan peringatan ini adalah titik awal; sesuaikan ambang batasnya untuk ukuran armada Anda:

# Example Prometheus alert rules for the Claude Code self-hosted runner
# + orchestrator. Tune thresholds for your fleet size and SLOs.
groups:
  - name: claude-code-self-hosted-runner
    rules:
      - alert: ClaudeRunnerPollStale
        expr: claude_code_self_hosted_runner_last_poll_age_seconds > 60
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Runner {{ $labels.pod }} has not polled in >60s"
      - alert: ClaudeRunnerVersionDrift
        expr: count(count by (version) (claude_code_self_hosted_runner_info)) > 1
        for: 30m
        labels: {severity: info}
        annotations:
          summary: "Runners are running mixed versions"
      - alert: ClaudeRunnerInitErrorsHigh
        expr: sum by (namespace) (increase(claude_code_self_hosted_runner_session_init_errors_total[10m])) > 3
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "Sessions are failing before init (checkout hook / git / token / pre-init crash)"
      - alert: ClaudeRunnerPollErrors
        expr: sum by (pod) (rate(claude_code_self_hosted_runner_poll_errors_total[5m])) > 0
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Runner {{ $labels.pod }}: PollWork failing ({{ $value | humanize }}/s over 5m)"
      - alert: ClaudeRunnerSessionStartHookErrors
        expr: sum by (namespace) (increase(claude_code_self_hosted_runner_session_start_hook_errors_total[10m])) > 3
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "SessionStart hooks are failing"

  - name: claude-code-self-hosted-orchestrator
    rules:
      - alert: ClaudeOrchestratorDisconnected
        expr: claude_code_self_hosted_orchestrator_connected == 0
        for: 2m
        labels: {severity: critical}
        annotations:
          summary: "Orchestrator {{ $labels.pod }} cannot reach the Anthropic control plane"
      - alert: ClaudeOrchestratorPollStale
        expr: claude_code_self_hosted_orchestrator_last_poll_age_seconds > 90
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Orchestrator {{ $labels.pod }} has not polled in >90s (poll loop waits on hook execution)"
      - alert: ClaudeOrchestratorCircuitBroken
        expr: max by (namespace) (claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions and on (instance) max_over_time(claude_code_self_hosted_orchestrator_connected[2m]) == 1) > 0
        for: 1m
        labels: {severity: critical}
        annotations:
          summary: "Sessions blocked from spawning: {{ $value }}. Read each one's error in the Activity tab, fix the cause, then select Retry"
      - alert: ClaudeOrchestratorPollErrors
        expr: sum by (pod) (rate(claude_code_self_hosted_orchestrator_poll_errors_total[5m])) > 0
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Orchestrator {{ $labels.pod }}: PollSpawnHints failing ({{ $value | humanize }}/s over 5m)"
      - alert: ClaudeOrchestratorSpawnHookFailing
        expr: sum by (pod) (increase(claude_code_self_hosted_orchestrator_spawn_hooks_total{result!="ok"}[5m])) > 3
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "Orchestrator {{ $labels.pod }}: >3 spawn-runner hook failures in 5m"

Peringatan untuk runner yang hilang dan sesi yang menunggu

Agar mendapat peringatan ketika runner hilang, sesi menunggu, atau orchestrator mati, muat aturan peringatan Prometheus berikut bersama contoh aturan peringatan:

  • Armada tetap: ClaudeRunnersBelowFloor
  • Runner on-demand: ClaudeOrchestratorSessionsWaiting, ClaudeOrchestratorQueueWaitHigh, dan ClaudeOrchestratorAbsent

Peringatan ketika armada tetap kehilangan runner

ClaudeRunnersBelowFloor dipicu ketika jumlah runner yang terdaftar dan di-scrape yang tersisa lebih sedikit dari batas bawah selama 10 menit:

groups:
  # Fixed fleets only. With on-demand runners the count follows demand,
  # so ClaudeRunnersBelowFloor would fire whenever demand is low.
  - name: claude-code-self-hosted-fixed-fleet-capacity
    rules:
      - alert: ClaudeRunnersBelowFloor
        expr: (count(claude_code_self_hosted_runner_info{namespace="claude-runners"}) or vector(0)) < 2
        for: 10m
        labels: {severity: critical, namespace: claude-runners}
        annotations:
          summary: "Runners registered and scraped: {{ $value }}, below the floor. Check the runner workloads first, then the scrape targets if all are running."
  • Batas bawah: atur 2 dalam expr ke sekitar setengah jumlah replika Anda, dibulatkan ke atas. Dengan tiga replika, pertahankan 2, dan peringatan dipicu ketika tersisa satu runner atau tidak ada sama sekali.
  • Namespace: ganti claude-runners di matcher dan di labels, lalu salin peringatan tersebut untuk setiap namespace tambahan. Jika target Anda tidak memiliki label namespace, hapus matcher dan label tersebut, jika tidak peringatan akan membaca 0 dan dipicu.
  • ClaudeRunnerPollStale dan ClaudeRunnerPollErrors: tetap muat keduanya dari contoh aturan peringatan, karena ClaudeRunnersBelowFloor tetap menghitung runner yang tidak dapat melakukan poll

Peringatan ketika sesi menunggu runner on-demand

ClaudeOrchestratorSessionsWaiting dipicu ketika jumlah sesi yang menunggu runner tetap di atas 0 selama 10 menit. ClaudeOrchestratorQueueWaitHigh dipicu ketika lebih dari 1% waktu tunggu antrean dalam 10 menit terakhir melebihi 160 detik, dan kondisi itu bertahan selama 5 menit:

groups:
  # On-demand runners only. Needs no edit for the namespace.
  - name: claude-code-self-hosted-on-demand-capacity
    rules:
      - alert: ClaudeOrchestratorSessionsWaiting
        expr: |
          max by (namespace) (
            claude_code_self_hosted_orchestrator_pool_pending_sessions
            and on (instance)
            max_over_time(claude_code_self_hosted_orchestrator_connected[2m]) == 1
          ) > 0
        for: 10m
        labels: {severity: warning}
        annotations:
          summary: "Sessions waiting for a runner: {{ $value }}, above the threshold for 10 minutes. Check claude_code_self_hosted_orchestrator_spawn_hooks_total by result, then runner workloads that don't start."
      - alert: ClaudeOrchestratorQueueWaitHigh
        expr: |
          histogram_quantile(0.99, sum by (namespace, le) (
            rate(claude_code_self_hosted_orchestrator_session_queue_wait_seconds_bucket[10m])
          )) > 160
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "Over 1% of queue waits in the last 10 minutes exceeded 160 seconds. Check whether ClaudeOrchestratorDisconnected is firing, then claude_code_self_hosted_orchestrator_spawn_hooks_total by result and claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds."
  • Ambang batas: jika selalu ada sesi yang menunggu, naikkan > 0 dalam ClaudeOrchestratorSessionsWaiting di atas jumlah yang biasanya Anda lihat
  • ClaudeOrchestratorDisconnected: tetap muat dari contoh aturan peringatan, karena ClaudeOrchestratorSessionsWaiting berhenti dipicu sekitar 2 menit setelah orchestrator terakhir di namespace tersebut terputus

Peringatan ketika orchestrator mati

Untuk mengetahui bahwa orchestrator itu sendiri mati, muat ClaudeOrchestratorAbsent. Peringatan ini dipicu ketika tidak ada orchestrator di namespace tersebut yang di-scrape selama 5 menit:

groups:
  # On-demand runners only. Replace claude-runners with the orchestrator's namespace.
  - name: claude-code-self-hosted-on-demand-orchestrator
    rules:
      - alert: ClaudeOrchestratorAbsent
        expr: absent(claude_code_self_hosted_orchestrator_connected{namespace="claude-runners"})
        for: 5m
        labels: {severity: critical}
        annotations:
          summary: "No orchestrator has been scraped for 5 minutes. If it's down, no on-demand runner starts, and sessions wait. Check the orchestrator workload first, then its scrape target if it's running."
  • Namespace: ganti claude-runners dengan namespace orchestrator, lalu salin peringatan tersebut untuk setiap namespace tambahan yang menjalankan orchestrator. Jika target Anda tidak memiliki label namespace, hapus matcher tersebut, jika tidak peringatan akan dipicu setelah 5 menit dan tetap aktif.
  • Server Prometheus yang tidak melakukan scrape pada orchestrator: jangan sertakan peringatan ini dalam file aturan server tersebut, karena pada server seperti itu peringatan akan dipicu setelah 5 menit dan tetap aktif
  • Jangan mengandalkan peringatan orchestrator lainnya: peringatan tersebut membaca metrik yang disajikan oleh orchestrator itu sendiri. ClaudeOrchestratorSessionsWaiting, ClaudeOrchestratorQueueWaitHigh, dan contoh aturan peringatan orchestrator semuanya berhenti dipicu dalam sekitar 10 menit setelah orchestrator mati.

Meneruskan metrik proses anak sesi

Setiap sesi berjalan dalam proses anaknya sendiri dengan metrik OpenTelemetry-nya sendiri; pada --capacity di atas satu, runner menulis ulang cara metrik proses anak tersebut diekspos. Mengatur OTEL_METRICS_EXPORTER=prometheus pada host runner dan CLAUDE_CODE_ENABLE_TELEMETRY=1 di environment sesi, misalnya dari skrip wrapper Anda atau environment runner itu sendiri, yang diwarisi oleh sesi, akan mengekspos ulang instrumen counter dan gauge setiap proses anak pada endpoint /metrics milik runner sendiri, bersama seri runner. Runner menulis ulang exporter proses anak agar mengirim melalui OTLP ke receiver khusus loopback pada port health, menandai setiap seri dengan label session_id dan client_platform, dan menghapus seri sebuah sesi ketika sesi tersebut berakhir. Histogram tidak diteruskan, dan metrik proses anak yang namanya akan bertabrakan dengan prefiks milik runner sendiri akan dibuang.

Pada --capacity 1 default, penulisan ulang ini tidak berlaku: proses anak sesi mengikat endpoint Prometheus-nya sendiri pada port 9464 seperti biasa.

Menggabungkan metrik sesi dengan metrik runner

Untuk melihat biaya yang telah dihabiskan sesi yang idle, lakukan join claude_code_self_hosted_runner_session_idle_seconds milik runner dengan metrik biaya Claude Code pada ccr_session_id. Metrik runner tidak membawa label tersebut, jadi berikan label itu dengan label_replace, seperti dalam kueri ini:

sum by (ccr_session_id) (claude_code_cost_usage_total)
and on (ccr_session_id)
label_replace(
  claude_code_self_hosted_runner_session_idle_seconds > 600,
  "ccr_session_id", "cse_$1", "session_id", "session_(.*)"
)

Kueri ini mengembalikan satu hasil per sesi yang idle lebih dari sepuluh menit: biaya dalam dolar AS yang telah dihitung oleh proses Claude Code sesi tersebut sejauh ini. Untuk melakukan join dengan metrik Claude Code lainnya, ganti claude_code_cost_usage_total dalam kueri. Kueri ini berfungsi pada --capacity berapa pun.

  • session_id: pada port 9464, label tersebut pada metrik Claude Code berisi session.id milik Claude Code sendiri, yang tidak cocok dengan seri runner mana pun. Join pada label itu tidak mengembalikan apa pun, jadi lakukan join pada ccr_session_id.
  • Metrik Claude Code tidak memiliki ccr_session_id: periksa bahwa OTEL_METRICS_INCLUDE_SESSION_ID tidak diatur ke false

Semantik penghitung siklus hidup sesi

Penghitung sessions_started_total, sessions_completed_total, sessions_failed_total, dan sessions_interrupted_total mengklasifikasikan setiap sesi berdasarkan cara sesi tersebut berakhir. Setiap proses anak sesi yang di-spawn menambah sessions_started_total pada saat spawn, dan tepat satu dari tiga lainnya bertambah saat keluar, sehingga sessions_started_total dikurangi jumlah tiga lainnya sama dengan jumlah proses anak sesi yang sedang berjalan.

  • completed: sesi berakhir dengan bersih. Ini mencakup proses anak yang keluar dengan sendirinya dengan kode 0, sesi yang diarsipkan atau dihapus saat proses anak masih terhubung, dan runner yang menyerahkan kembali slot dengan bersih: melepaskan sesi pada idle timeout, waktu pensiun, atau batas --kill-session-after-min; timeout startup; atau deassign dari sisi server yang diketahui loop poll sebelum proses anak keluar. Menambah sessions_completed_total.
  • failed: proses anak keluar dengan sendirinya dengan kode bukan nol, baik karena crash maupun kegagalan setup setelah spawn. Menambah sessions_failed_total.
  • interrupted: runner menghentikan proses anak karena alasan operasional yang bukan keberhasilan sesi maupun kesalahan runner, seperti drain, atau menghentikan sesi yang masih berada di runner ketika jendela tenggang SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS setelah batas --kill-session-after-min-nya berakhir. Rolling restart Kubernetes yang mengirim SIGTERM adalah salah satu contoh drain. Menambah sessions_interrupted_total.

Sebelum v2.1.260, runner menghentikan setiap sesi yang mencapai batas --kill-session-after-min-nya dan menghitungnya dalam sessions_interrupted_total.

CLAUDE_RUNNER_EXIT_REASON milik hook post-session mengklasifikasikan penyerahan bersih secara berbeda. Hook melaporkannya sebagai interrupted, karena runner menghentikan proses anak: pelepasan, timeout startup, deassign server, serta pengarsipan atau penghapusan yang diketahui poll terlebih dahulu. Penghitung ini mencatat peristiwa yang sama sebagai completed, karena slot diserahkan kembali dengan bersih.

Jika Anda merekonsiliasi tanda terima hook langsung terhadap sessions_completed_total, Anda akan menghitung penyelesaian lebih sedikit dari yang sebenarnya. Gunakan hook untuk jaminan per sesi dan penghitung untuk laju agregat.

Pada environment sekali pakai, yaitu --capacity 1 dengan --drain-grace-sec 0 default, setiap proses runner keluar sesaat setelah satu sesinya berakhir. sessions_completed_total, sessions_failed_total, dan sessions_interrupted_total hanya bertambah di akhir sesi, tepat sebelum keluar, sehingga scrape Prometheus setiap 15 hingga 60 detik jarang menangkap penambahan tersebut sebelum seri runner menghilang; ketiga penghitung akhir sesi ini adalah penghitung terminal yang dirujuk di sisa bagian ini. sessions_started_total bertambah saat spawn dan tetap terlihat selama masa hidup sesi, sehingga dapat diandalkan muncul, tetapi pada environment sekali pakai nilainya lebih mendekati "sesi yang sedang berjalan" daripada hitungan kumulatif.

Gunakan seri dalam tabel ini untuk tujuan yang sesuai alih-alih penghitung terminal:

Tujuan Gunakan
Throughput claude_code_self_hosted_orchestrator_spawn_hooks_total{result="ok"}, sebuah counter pada orchestrator berumur panjang yang bertambah sekali per hook spawn-runner yang berhasil dan tetap bermakna di bawah rate(). Ini menghitung pemanggilan hook, bukan sesi, sehingga pre-warming dan spawn berulang untuk sesi yang sama membuatnya berbeda dari hitungan sesi.
Utilisasi sum(claude_code_self_hosted_runner_active_sessions) terhadap sum(claude_code_self_hosted_runner_capacity), keduanya gauge yang valid pada setiap scrape terlepas dari masa hidup runner
Backlog claude_code_self_hosted_orchestrator_pool_pending_sessions untuk kedalaman antrean, dan claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions, dengan peringatan jika di atas nol
Kegagalan claude_code_self_hosted_runner_sessions_failed_total, upaya terbaik: crash nyata setelah spawn memang menambahnya, dan rate() bermakna pada runner yang hidup lebih lama dari sesinya dengan --drain-grace-sec di atas 0. Environment sekali pakai memiliki masalah jendela scrape yang sama dengan penghitung terminal lainnya, jadi anggap nilai bukan nol apa pun yang Anda lihat layak diselidiki. Kegagalan sebelum spawn, seperti kegagalan hook checkout, persiapan git, atau masalah token, hanya muncul di session_init_errors_total.

Baris orchestrator_* hanya ada pada environment yang menjalankan orchestrator on-demand. Pada armada tetap yang runner-nya hidup lebih lama dari sesinya, dengan --drain-grace-sec di atas 0, gunakan sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) untuk throughput; pada armada sekali pakai, seri tersebut memiliki masalah jendela scrape yang sama dengan penghitung terminal, jadi andalkan hitungan sesi yang diantrekan sebagai gantinya. Periksa backlog di tab Activity environment, pada halaman admin Cloud environments: runner tidak mengekspor seri kedalaman antrean.

Untuk pelaporan hasil per sesi, gunakan hook post-session sebagai gantinya: hook ini dipicu di setiap akhir sesi ketika proses anak telah di-spawn, kecuali pada penghentian runner secara mendadak seperti preemption VM, sesuai kontrak hook itu sendiri.

Apa selanjutnya