@0xlucasliao/techops-sidecar
v1.0.1
Published
TechOps runtime sidecar: health checks, daily heartbeat, and structured log ERROR alerts to Telegram.
Downloads
295
Maintainers
Readme
@0xlucasliao/techops-sidecar
Runtime monitoring sidecar for TechOps-managed services. It aligns with SOP-OPS-STACK-001 (health + structured logs + Telegram alerting): polls a health URL, sends a daily UTC midnight heartbeat, tails /logs/<SERVICE_NAME>/app.log, and on [ERROR] lines bundles logs by SESSION_ID and sends a .txt to Telegram.
Install and run
npx --yes @0xlucasliao/techops-sidecar
# or after npm install:
npx techops-sidecarRequired environment variables
| Variable | Description |
|----------|-------------|
| HEALTH_CHECK_URL | HTTP(S) URL the sidecar GETs on each interval (2xx = success). |
| TELEGRAM_BOT_TOKEN | Bot token from @BotFather. |
| TELEGRAM_CHAT_ID | Target chat or group ID (supergroups are often negative; use the full ID string). |
| SERVICE_NAME | Service id; default log path is /logs/<SERVICE_NAME>/app.log. |
Optional TECHOPS_* aliases are supported for the same values (see src/config.js).
Optional environment variables
| Variable | Default | Description |
|----------|---------|-------------|
| ENVIRONMENT | unknown | Shown in alerts (e.g. production). |
| RUNBOOK_URL | (empty) | Included in alert text when set (SOP recommends it). |
| LOG_FILE_PATH | /logs/<SERVICE_NAME>/app.log | Override log file path. |
| HEALTH_CHECK_INTERVAL_MS | 30000 | Health poll interval. |
| HEALTH_CONSECUTIVE_FAILURES | 5 | Failed pings in a row before Telegram alert. |
| HEALTH_REQUEST_TIMEOUT_MS | 10000 | Per-request timeout. |
| LOG_BUNDLE_WINDOW_MS | 30000 | After first [ERROR] for a SESSION_ID, collect same-session lines for this long, then send the bundle. |
| MAX_ALERTS_PER_MINUTE | 5 | Cap on Telegram sends per rolling minute (health + log alerts combined). |
| ALERT_DEDUP_TTL_MS | 120000 | Suppress repeats with the same dedupe signature. |
GitHub Actions → container env
Store secrets per repository (or per environment), then map them in the deploy workflow:
env:
HEALTH_CHECK_URL: ${{ secrets.HEALTH_CHECK_URL }}
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
SERVICE_NAME: my-service
ENVIRONMENT: production
RUNBOOK_URL: https://wiki.example.com/runbooks/my-serviceDocker (multi-stage pattern)
Install the package in the image and run the binary next to your app. Share a read-only volume for logs per SOP (/logs/<service-name>/app.log).
FROM node:22-bookworm-slim AS sidecar
RUN npm install -g @0xlucasliao/techops-sidecar@^1.0.0
FROM your-app-base
COPY --from=sidecar /usr/local/lib/node_modules/@0xlucasliao/techops-sidecar /opt/techops-sidecar
ENV PATH="/opt/techops-sidecar/node_modules/.bin:${PATH}"
# Or: node /opt/techops-sidecar/.../bin/techops-sidecar.js
# Your app writes logs here; sidecar reads read-only.
VOLUME ["/logs/my-service"]
# Example: supervisor or shell starts both processes.Using npx at runtime (slower cold start, always latest):
RUN npm install -g npm@latest
# CMD runs your app; start sidecar with:
# npx --yes @0xlucasliao/techops-sidecarFull sample (app + sidecar + GitHub Secrets)
Runnable reference in examples/:
| File | Purpose |
|------|---------|
| examples/Dockerfile.app-with-sidecar | Installs @0xlucasliao/techops-sidecar, copies a tiny sample app, starts sidecar then app via entrypoint. |
| examples/docker-entrypoint.sh | Runs techops-sidecar in the background, exec your main process in the foreground. |
| examples/sample-app/server.mjs | Placeholder app with /health and structured logs under /logs/<SERVICE_NAME>/app.log. |
| examples/github-actions.deploy.sample.yml | Build without secrets; docker run with -e from ${{ secrets.* }}. |
Build locally:
docker build -f examples/Dockerfile.app-with-sidecar -t myapp:with-sidecar .
docker run --rm -p 3000:3000 \
-e SERVICE_NAME=demo-service \
-e ENVIRONMENT=local \
-e TELEGRAM_BOT_TOKEN="your-token" \
-e TELEGRAM_CHAT_ID="your-chat-id" \
-e HEALTH_CHECK_URL="http://127.0.0.1:3000/health" \
myapp:with-sidecarSecrets rule of thumb: define them in GitHub → Settings → Secrets and variables → Actions, reference them only in workflow env: or docker run -e ..., never as docker build --build-arg for tokens (they can remain in image history).
Log format (mandatory for ERROR bundling)
Lines must match:
[TIMESTAMP] [LEVEL] [SERVICE] [SESSION_ID] MESSAGEExample:
2026-04-27T14:23:01Z [ERROR] payment-gateway sess-8f2a1c3e Connection to upstream failed: timeout after 30sBehaviour summary
- Health —
GETHEALTH_CHECK_URLeveryHEALTH_CHECK_INTERVAL_MS. AfterHEALTH_CONSECUTIVE_FAILURESconsecutive failures, sends one Telegram message (subject to rate limit + dedupe). Counter resets when a request succeeds. - Daily heartbeat — Every 00:00:00 UTC, sends an “I’m alive” style message.
- Logs — Tails the log file from EOF (no backlog replay on restart). On
[ERROR], waitsLOG_BUNDLE_WINDOW_MSand includes all parsed lines with the sameSESSION_IDseen in that window, then sends a UTF-8.txtdocument plus caption.
Development
npm testLicence
MIT
