chmonitor · ClickHouse monitoring dashboard and CLI

0 people used it yesterday · 0 this week · 0 this month.

2 users and 18 events so far today, live. 952 events in the last 90 days.

Daily users

31 users40 events
Daily users and events, Jul 22 to Oct 19. Peak 31 users on Aug 17; 952 events in total.
Jul 22Oct 19
The line is daily users; the bars are events on their own scale. 90 days. Yesterday closes at 00:10 UTC; today refreshes every few minutes.

Breakdown

EventsUser-daysEvents
ping413413
app_loaded0206
queries_viewed0159
health_viewed0132
ai_query_sent041
cluster_connected01
Operating systemsUser-daysEvents
macos226226
windows9090
linux6767
unknown2121
android77
ios22
CountriesUser-daysEvents
IN6464
SG6161
UNKNOWN4343
US2929
VN2828
ZA2626
DE2424
KZ2020
RU1919
ID1313
ES1212
MX1111
RS88
RO66
TH55
TR44
KE44
CN44
NL44
AR33
prop · ch_flavorUser-daysEvents
unknown258796
oss152153
altinity33
prop · ch_versionUser-daysEvents
26.35151
25.112424
26.42323
26.71212
25.888
26.577
24.1066
25.366
24.344
25.1022
26.622
24.622
25.1222
26.222
24.822
26.812
25.611
prop · deploy_targetUser-daysEvents
docker303565
cf75267
unknown35100
dev020

Integrate

Ingest URL https://telemetry.anyr.workers.dev/chmonitor, OTLP endpoint https://telemetry.anyr.workers.dev/chmonitor/v1. Pick a client below, or let an agent do it.

curl -fsS -m 1 -X POST https://telemetry.anyr.workers.dev/chmonitor \
  -H 'content-type: application/json' \
  -d '{"event":"ping","id":"<random-install-id>","version":"1.0.0","os":"linux","arch":"x64"}'
# Anonymous install ping. Put it near the end of install.sh. No id: counts daily users only.
# An env var is "set" for any value except empty, 0 or false.
truthy() { case $(printf %s "$1" | tr '[:upper:]' '[:lower:]') in ""|0|false) return 1 ;; *) return 0 ;; esac; }
if ! truthy "${DO_NOT_TRACK-}" && ! truthy "${CHMONITOR_TELEMETRY_DISABLED-}" \
  && { ! truthy "${CI-}" || truthy "${CHMONITOR_TELEMETRY_CI-}"; }; then
  os=$(uname -s | tr '[:upper:]' '[:lower:]')
  arch=$(uname -m | tr '[:upper:]' '[:lower:]')
  if truthy "${CI-}"; then ci=true; else ci=false; fi
  body=$(printf '{"event":"install","os":"%s","arch":"%s","ci":%s}' "$os" "$arch" "$ci")
  if truthy "${CHMONITOR_TELEMETRY_DEBUG-}"; then
    echo "[telemetry] $body" >&2
  else
    (curl -fsS -m 1 -X POST -H 'content-type: application/json' -d "$body" https://telemetry.anyr.workers.dev/chmonitor >/dev/null 2>&1 &)
  fi
fi
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { homedir } from "node:os";
import { dirname, join } from "node:path";

const ENDPOINT = "https://telemetry.anyr.workers.dev/chmonitor";
const VERSION = "0.0.0"; // set from your package metadata
const env = process.env;

// "Set" means any value except empty, 0 or false.
const truthy = (v?: string): boolean => !!v && !["0", "false"].includes(v.toLowerCase());

function enabled(): boolean {
	if (truthy(env.DO_NOT_TRACK) || truthy(env.CHMONITOR_TELEMETRY_DISABLED)) return false;
	return !truthy(env.CI) || truthy(env.CHMONITOR_TELEMETRY_CI);
}

// Returns undefined when the event must be skipped: the id cannot be saved (fail closed).
// Debug mode never writes. It reads the id, or shows a placeholder.
function installId(debug: boolean): string | undefined {
	const file = join(env.XDG_CONFIG_HOME || join(homedir(), ".config"), "chmonitor", "telemetry-id");
	try {
		const id = readFileSync(file, "utf8").trim();
		if (id) return id;
	} catch {}
	if (debug) return "new-install-id";
	try {
		const id = crypto.randomUUID();
		mkdirSync(dirname(file), { recursive: true });
		writeFileSync(file, id);
		console.error("chmonitor collects anonymous usage data. Opt out: CHMONITOR_TELEMETRY_DISABLED=1 or DO_NOT_TRACK=1. Details: https://telemetry.anyr.workers.dev/chmonitor"); // stderr suits a CLI. A daemon or plugin should use its log channel.
		return id;
	} catch {
		return undefined;
	}
}

export function track(event: string, props: Record<string, string | number | boolean> = {}): void {
	try {
		if (!enabled()) return;
		const debug = truthy(env.CHMONITOR_TELEMETRY_DEBUG);
		const id = installId(debug);
		if (!id) return;
		const body = JSON.stringify({
			event,
			id,
			version: VERSION,
			os: process.platform,
			arch: process.arch,
			ci: truthy(env.CI),
			props,
		});
		if (debug) {
			console.error("[telemetry]", body);
			return;
		}
		fetch(ENDPOINT, {
			method: "POST",
			headers: { "content-type": "application/json" },
			body,
			signal: AbortSignal.timeout(1000),
		}).catch(() => {});
	} catch {}
}
// Cargo.toml: ureq = "2"
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hasher};
use std::path::PathBuf;
use std::{env, fs, thread, time::Duration};

const ENDPOINT: &str = "https://telemetry.anyr.workers.dev/chmonitor";

/// "Set" means any value except empty, 0 or false.
fn truthy(key: &str) -> bool {
    env::var(key).map_or(false, |v| !matches!(v.to_ascii_lowercase().as_str(), "" | "0" | "false"))
}

fn enabled() -> bool {
    if truthy("DO_NOT_TRACK") || truthy("CHMONITOR_TELEMETRY_DISABLED") {
        return false;
    }
    !truthy("CI") || truthy("CHMONITOR_TELEMETRY_CI")
}

fn random_id() -> String {
    // 128 random bits from the std hasher seed, no extra crate needed.
    (0..2).map(|_| format!("{:016x}", RandomState::new().build_hasher().finish())).collect()
}

/// None means skip the event: the id cannot be saved (fail closed).
/// Debug mode never writes. It reads the id, or shows a placeholder.
fn install_id(debug: bool) -> Option<String> {
    let file = env::var_os("XDG_CONFIG_HOME")
        .map(PathBuf::from)
        .or_else(|| env::var_os("HOME").map(|h| PathBuf::from(h).join(".config")))
        .or_else(|| env::var_os("APPDATA").map(PathBuf::from))?
        .join("chmonitor")
        .join("telemetry-id");
    if let Ok(id) = fs::read_to_string(&file) {
        if !id.trim().is_empty() {
            return Some(id.trim().to_string());
        }
    }
    if debug {
        return Some("new-install-id".to_string());
    }
    let id = random_id();
    fs::create_dir_all(file.parent()?).ok()?;
    fs::write(&file, &id).ok()?;
    eprintln!("chmonitor collects anonymous usage data. Opt out: CHMONITOR_TELEMETRY_DISABLED=1 or DO_NOT_TRACK=1. Details: https://telemetry.anyr.workers.dev/chmonitor"); // stderr suits a CLI. A daemon or plugin should use its log channel.
    Some(id)
}

/// Fire and forget. Event names must be plain literals. A short-lived CLI can
/// join the returned handle before exit: the request is bounded by the 1 s timeout.
pub fn track(event: &str) -> Option<thread::JoinHandle<()>> {
    if !enabled() {
        return None;
    }
    let debug = truthy("CHMONITOR_TELEMETRY_DEBUG");
    let id = install_id(debug)?;
    let body = format!(
        r#"{{"event":"{event}","id":"{id}","version":"{}","os":"{}","arch":"{}","ci":{}}}"#,
        env!("CARGO_PKG_VERSION"),
        env::consts::OS,
        env::consts::ARCH,
        truthy("CI")
    );
    if debug {
        eprintln!("[telemetry] {body}");
        return None;
    }
    Some(thread::spawn(move || {
        let _ = ureq::post(ENDPOINT)
            .timeout(Duration::from_secs(1))
            .set("content-type", "application/json")
            .send_string(&body);
    }))
}
package telemetry

import (
	"bytes"
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"
)

const endpoint = "https://telemetry.anyr.workers.dev/chmonitor"
const version = "0.0.0" // set from your build, for example with -ldflags

// truthy: "set" means any value except empty, 0 or false.
func truthy(key string) bool {
	switch strings.ToLower(os.Getenv(key)) {
	case "", "0", "false":
		return false
	}
	return true
}

func enabled() bool {
	if truthy("DO_NOT_TRACK") || truthy("CHMONITOR_TELEMETRY_DISABLED") {
		return false
	}
	return !truthy("CI") || truthy("CHMONITOR_TELEMETRY_CI")
}

// installID returns "" when the event must be skipped: the id cannot be saved (fail closed).
// Debug mode never writes. It reads the id, or shows a placeholder.
func installID(debug bool) string {
	dir, err := os.UserConfigDir()
	if err != nil {
		return ""
	}
	file := filepath.Join(dir, "chmonitor", "telemetry-id")
	if b, err := os.ReadFile(file); err == nil {
		if id := strings.TrimSpace(string(b)); id != "" {
			return id
		}
	}
	if debug {
		return "new-install-id"
	}
	buf := make([]byte, 16)
	if _, err := rand.Read(buf); err != nil {
		return ""
	}
	id := hex.EncodeToString(buf)
	if os.MkdirAll(filepath.Dir(file), 0o755) != nil || os.WriteFile(file, []byte(id), 0o600) != nil {
		return ""
	}
	fmt.Fprintln(os.Stderr, "chmonitor collects anonymous usage data. Opt out: CHMONITOR_TELEMETRY_DISABLED=1 or DO_NOT_TRACK=1. Details: https://telemetry.anyr.workers.dev/chmonitor") // stderr suits a CLI. A daemon or plugin should use its log channel.
	return id
}

// Track sends one event in the background. The channel closes when the attempt
// ends (at most 1 s), so a short-lived CLI can wait on it before exit.
func Track(event string, props map[string]any) <-chan struct{} {
	done := make(chan struct{})
	if !enabled() {
		close(done)
		return done
	}
	debug := truthy("CHMONITOR_TELEMETRY_DEBUG")
	id := installID(debug)
	if id == "" {
		close(done)
		return done
	}
	payload := map[string]any{
		"event":   event,
		"id":      id,
		"version": version,
		"os":      runtime.GOOS,
		"arch":    runtime.GOARCH,
		"ci":      truthy("CI"),
	}
	if len(props) > 0 {
		payload["props"] = props
	}
	body, err := json.Marshal(payload)
	if err != nil {
		close(done)
		return done
	}
	if debug {
		fmt.Fprintf(os.Stderr, "[telemetry] %s\n", body)
		close(done)
		return done
	}
	go func() {
		defer close(done)
		client := http.Client{Timeout: time.Second}
		if resp, err := client.Post(endpoint, "application/json", bytes.NewReader(body)); err == nil {
			resp.Body.Close()
		}
	}()
	return done
}
import json
import os
import platform
import sys
import threading
import urllib.request
import uuid
from pathlib import Path

ENDPOINT = "https://telemetry.anyr.workers.dev/chmonitor"
VERSION = "0.0.0"  # set from your package metadata


def _truthy(key):
    # "Set" means any value except empty, 0 or false.
    return os.environ.get(key, "").lower() not in ("", "0", "false")


def _enabled():
    if _truthy("DO_NOT_TRACK") or _truthy("CHMONITOR_TELEMETRY_DISABLED"):
        return False
    return not _truthy("CI") or _truthy("CHMONITOR_TELEMETRY_CI")


def _install_id(debug):
    # Returns None when the event must be skipped: the id cannot be saved (fail closed).
    # Debug mode never writes. It reads the id, or shows a placeholder.
    try:
        base = Path(os.environ.get("XDG_CONFIG_HOME") or Path.home() / ".config")
        file = base / "chmonitor" / "telemetry-id"
        try:
            found = file.read_text().strip()
            if found:
                return found
        except OSError:
            pass
        if debug:
            return "new-install-id"
        install_id = uuid.uuid4().hex
        file.parent.mkdir(parents=True, exist_ok=True)
        file.write_text(install_id)
        # stderr suits a CLI. A daemon or plugin should use its log channel.
        print("chmonitor collects anonymous usage data. Opt out: CHMONITOR_TELEMETRY_DISABLED=1 or DO_NOT_TRACK=1. Details: https://telemetry.anyr.workers.dev/chmonitor", file=sys.stderr)
        return install_id
    except Exception:
        return None


def track(event, **props):
    try:
        if not _enabled():
            return
        debug = _truthy("CHMONITOR_TELEMETRY_DEBUG")
        install_id = _install_id(debug)
        if not install_id:
            return
        body = {
            "event": event,
            "id": install_id,
            "version": VERSION,
            "os": platform.system().lower(),
            "arch": platform.machine().lower(),
            "ci": _truthy("CI"),
        }
        if props:
            body["props"] = props
        if debug:
            print("[telemetry]", json.dumps(body), file=sys.stderr)
            return

        def send():
            try:
                req = urllib.request.Request(
                    ENDPOINT,
                    json.dumps(body).encode(),
                    {"content-type": "application/json"},
                )
                urllib.request.urlopen(req, timeout=1).close()
            except Exception:
                pass

        # Daemon thread: never delays exit. A very short script may exit before it sends.
        threading.Thread(target=send, daemon=True).start()
    except Exception:
        pass
const ENDPOINT = "https://telemetry.anyr.workers.dev/chmonitor";
const ID_KEY = "chmonitor-telemetry-id";
const OFF_KEY = "chmonitor-telemetry-disabled";

export function track(event, props) {
	try {
		if (navigator.doNotTrack === "1" || navigator.globalPrivacyControl === true) return;
		if (localStorage.getItem(OFF_KEY) === "1") return;
		let id = localStorage.getItem(ID_KEY);
		if (!id) {
			id = crypto.randomUUID();
			localStorage.setItem(ID_KEY, id);
		}
		const body = JSON.stringify({ event, id, props });
		navigator.sendBeacon(ENDPOINT, new Blob([body], { type: "application/json" }));
	} catch {}
}

// track("ping"); // once per page load or once per day. Never send URLs, paths or user input.
export OTEL_EXPORTER_OTLP_ENDPOINT=https://telemetry.anyr.workers.dev/chmonitor
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json
export OTEL_SERVICE_NAME=chmonitor
# The install id keeps users distinct. Generate it once and persist it.
export OTEL_RESOURCE_ATTRIBUTES=service.instance.id=<random-install-id>,service.version=1.0.0

With an agent

Copy this prompt into Claude Code, Codex or Cursor. It points the agent at the project playbook.

Add anonymous usage telemetry to this repo. Follow https://telemetry.anyr.workers.dev/chmonitor/install.md exactly. Respect DO_NOT_TRACK, add an opt-out env var and a Telemetry section to the README, never send PII, never block the main path.