Vault is usually on the critical path for database credentials, PKI, application secrets, and service authentication. If Vault is sealed, has no active node, or starts returning `5xx` responses, applications can fail in ways that are hard to debug from the application side. This post covers scraping Vault metrics with Prometheus and monitoring them with Grafana using the…
Kubernetes, Docker, and tailnet services often end up split across ingress objects, container labels, private DNS names, Grafana dashboards, runbooks, and a self-hosted homepage that has to be updated by hand. [Compass](https://github.com/adinhodovic/compass) turns those sources into a searchable service dashboard by discovering Kubernetes `HTTPRoute`, `GRPCRoute`, and `Ingress` resources, Docker…
Karpenter now exposes enough pricing data to estimate Kubernetes node costs directly from Prometheus metrics. The existing Karpenter dashboards in the [kubernetes-autoscaling-mixin](https://github.com/adinhodovic/kubernetes-autoscaling-mixin) already cover node pools, instance types, and scaling behavior. This post focuses on the new cost dashboard: estimated monthly cost, spot instance savings,…
Getting distributed tracing working in Django usually means stitching together OpenTelemetry SDK setup, Django instrumentation, OTLP export, database and Redis hooks, outbound HTTP tracing, and Celery propagation. This post walks through a general Django tracing setup with OpenTelemetry, what to instrument, how to propagate traces into Celery, and how to add custom span data. At the end, I cover…
Argo Workflows exposes enough metrics to see whether workflows are backing up, CronWorkflows are firing, and the controller is keeping up, but raw `/metrics` output does not make any of that easy to read. This post covers `argo-workflows-mixin`, a Prometheus and Grafana mixin that adds two dashboards and a focused alert set for Argo Workflows. The mixin is available on…
Managing multiple AI coding sessions gets messy fast once you use more than one tool. Sessions end up scattered across local transcript files, JSONL logs, and SQLite databases. Finding an old session, checking which model was used, or jumping back into the right project usually means opening each tool separately and remembering where it stores state.…
Go applications expose a useful set of runtime metrics, but raw `/metrics` output does not make it easy to spot GC pressure, scheduler latency, memory growth, or file descriptor exhaustion. This post covers a `go-mixin` for Prometheus and Grafana that adds a dashboard and alerts for the Go runtime. The mixin is available on [GitHub](https://github.com/adinhodovic/go-mixin). The dashboard is also…
Over the years I've written several blog posts covering different parts of Django observability - [Django Monitoring with Prometheus and Grafana](https://hodovi.cc/blog/django-monitoring-with-prometheus-and-grafana/), [Django Development and Production Logging](https://hodovi.cc/blog/django-development-and-production-logging/), [Celery Monitoring with Prometheus and…
I enabled Private Google Access (PGA) so our private GKE workloads could reach Google APIs without public node IPs. Everything “worked,” but when I dug into billing and flow logs, I kept seeing Google API traffic (notably `storage.googleapis.com`) classified as `PUBLIC_IP` connectivity - and I were getting surprisingly high “carrier peering / egress” charges....
Headscale is an open source, self-hosted control server compatible with the Tailscale clients. It lets you run your own Tailnet and have full control over users, nodes, keys, and routing policies without relying on Tailscale’s hosted control plane. This post introduces the [`tailscale-exporter`](https://github.com/adinhodovic/tailscale-exporter) and shows how to collect Headscale metrics via the…