Catalog npm
PACKAGE EXPLORERView in registry

@0xlucasliao/techops-sidecar

npm

TechOps runtime sidecar: health checks, daily heartbeat, and structured log ERROR alerts to Telegram.

0xlucasliaohealth-checksidecartechopstelegram
Versions collected2
Direct dependencies0From release 1.0.1
Last observed21 Oct, 09:06 UTC

README

Current package documentation

@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-sidecar

Required environment variables

VariableDescription
HEALTH_CHECK_URLHTTP(S) URL the sidecar GETs on each interval (2xx = success).
TELEGRAM_BOT_TOKENBot token from @BotFather.
TELEGRAM_CHAT_IDTarget chat or group ID (supergroups are often negative; use the full ID string).
SERVICE_NAMEService 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

VariableDefaultDescription
ENVIRONMENTunknownShown in alerts (e.g. production).
RUNBOOK_URL(empty)Included in alert text when set (SOP recommends it).
LOG_FILE_PATH/logs/<SERVICE_NAME>/app.logOverride log file path.
HEALTH_CHECK_INTERVAL_MS30000Health poll interval.
HEALTH_CONSECUTIVE_FAILURES5Failed pings in a row before Telegram alert.
HEALTH_REQUEST_TIMEOUT_MS10000Per-request timeout.
LOG_BUNDLE_WINDOW_MS30000After first [ERROR] for a SESSION_ID, collect same-session lines for this long, then send the bundle.
MAX_ALERTS_PER_MINUTE5Cap on Telegram sends per rolling minute (health + log alerts combined).
ALERT_DEDUP_TTL_MS120000Suppress 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-service

Docker (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-sidecar

Full sample (app + sidecar + GitHub Secrets)

Runnable reference in examples/:

FilePurpose
examples/Dockerfile.app-with-sidecarInstalls @0xlucasliao/techops-sidecar, copies a tiny sample app, starts sidecar then app via entrypoint.
examples/docker-entrypoint.shRuns techops-sidecar in the background, exec your main process in the foreground.
examples/sample-app/server.mjsPlaceholder app with /health and structured logs under /logs/<SERVICE_NAME>/app.log.
examples/github-actions.deploy.sample.ymlBuild 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-sidecar

Secrets 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] MESSAGE

Example:

2026-04-27T14:23:01Z [ERROR] payment-gateway sess-8f2a1c3e Connection to upstream failed: timeout after 30s

Behaviour summary

  1. Health — GET HEALTH_CHECK_URL every HEALTH_CHECK_INTERVAL_MS. After HEALTH_CONSECUTIVE_FAILURES consecutive failures, sends one Telegram message (subject to rate limit + dedupe). Counter resets when a request succeeds.
  2. Daily heartbeat — Every 00:00:00 UTC, sends an “I’m alive” style message.
  3. Logs — Tails the log file from EOF (no backlog replay on restart). On [ERROR], waits LOG_BUNDLE_WINDOW_MS and includes all parsed lines with the same SESSION_ID seen in that window, then sends a UTF-8 .txt document plus caption.

Development

npm test

Licence

MIT

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 2

Collected releases
VersionPublishedDirect dependenciesOpen version
1.0.1Registry latest27 Apr 20260
1.0.027 Apr 20260

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
0xlucasliao/techops-sidecar

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 21 Oct, 09:06 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:6cc241dbfd11c5d67090b1199aaa1dae4ea56a1e2e8b02c0f8fed00effdef094