Signoz track 3 submission: Build your own. Automated Infrastructure Health & Monitoring Bot π€
In production SRE workflows, static metric alerts often leave engineering teams scrambling to correlate spikes with root causes. Knowing that CPU hit 95% is only half the battleβyou need distributed tracing to understand what process cycle triggered the spike and how the system responded in real time.
In this post, weβll break down the Automated Infrastructure Health & Monitoring Bot, a lightweight, OpenTelemetry-native SRE monitoring agent built for Track 3: Build Your Own of the SigNoz Hackathon.
π Live Demo & Repository
- GitHub Repository: https://github.com/era651868-ctrl/Signoz.git
- Live Deployment link: https://signoz-57js.onrender.com/
YouTube Demo: https://youtube.com/shorts/3iGRSQba2n8?si=1b0R1ZkqF9YjO6Dc
-
Local / Deployed Dashboard Endpoints:
- Health Endpoint:
/health - Live Metrics Stream:
/metrics - Incident Log Feed:
/incidents
- Health Endpoint:
ποΈ System Architecture & Workflow
The bot is designed to simulate a real-world SRE monitoring agent operating in constrained environments. It continuously samples system telemetry, evaluates rule-based alert conditions, and streams OTLP traces directly to SigNoz.
+-------------------------------------------------------------------+
| Infrastructure Health Agent (app.py) |
| |
| +------------------+ +-------------------+ |
| | System Collector | --> | Anomaly Detection | |
| | (CPU/Mem/Disk) | | (Threshold Engine)| |
| +------------------+ +-------------------+ |
| | |
| v |
| +-------------------+ |
| | OTLP Trace Engine| |
| +-------------------+ |
+-------------------------------------|-----------------------------+
| OTLP gRPC (Port 4317)
v
+---------------------------+
| SigNoz OTEL Collector |
| & Telemetry Store |
+---------------------------+
π» Core Implementation Deep Dive
1. Resilient OpenTelemetry Setup with Graceful Fallback (app.py)
To ensure the monitoring agent never crashes when network connectivity drops or during collector maintenance, the setup dynamically tests OTLP gRPC endpoint reachability before registering exporters.
import os
import socket
from urllib.parse import urlparse
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
SERVICE_NAME = os.getenv("SERVICE_NAME", "health-alert-bot")
OTLP_ENDPOINT = os.getenv("OTLP_ENDPOINT", "http://localhost:4317")
def is_otlp_endpoint_reachable(endpoint: str) -> bool:
parsed = urlparse(endpoint)
host = parsed.hostname or "localhost"
port = parsed.port or 4317
try:
with socket.create_connection((host, port), timeout=1):
return True
except OSError:
return False
def setup_tracing():
resource = Resource.create(attributes={"service.name": SERVICE_NAME})
provider = TracerProvider(resource=resource)
if is_otlp_endpoint_reachable(OTLP_ENDPOINT):
exporter = OTLPSpanExporter(endpoint=OTLP_ENDPOINT, insecure=True)
provider.add_span_processor(BatchSpanProcessor(exporter))
print(f"π‘ Tracing enabled. Sending OTLP spans to {OTLP_ENDPOINT}")
else:
provider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
print(f"β οΈ OTLP endpoint unreachable. Falling back to console spans.")
trace.set_tracer_provider(provider)
return trace.get_tracer("bot-tracer")
tracer = setup_tracing()
2. Anomaly Evaluation & Span Attribute Injection
Every monitoring cycle evaluates resource thresholds and attaches rich contextual metadata directly onto OpenTelemetry spans. Critical breaches trigger nested alert child spans.
def main():
threading.Thread(target=start_http_server, daemon=True).start()
print("π Health Alert Bot started running...")
while True:
metrics = collect_metrics()
severity, reasons = evaluate_health(metrics)
with tracer.start_as_current_span("monitor_cycle") as span:
# Set high-cardinality telemetry as span attributes
span.set_attribute("system.cpu.usage", metrics["cpu_percent"])
span.set_attribute("system.memory.usage", metrics["memory_percent"])
span.set_attribute("system.disk.usage", metrics["disk_percent"])
span.set_attribute("alert.threshold.cpu", CPU_ALERT_THRESHOLD)
span.set_attribute("alert.threshold.memory", MEMORY_ALERT_THRESHOLD)
span.set_attribute("health.severity", severity)
# Trigger sub-span drilldown on CRITICAL events
if severity == "CRITICAL":
with tracer.start_as_current_span("trigger_alert") as alert_span:
alert_span.set_attribute("alert.level", "CRITICAL")
alert_span.set_attribute("alert.reason", ",".join(reasons))
alert_span.add_event(
"cpu_threshold_exceeded",
{"cpu_percent": metrics["cpu_percent"]}
)
print(build_status_message(metrics, severity))
record_incident(metrics, severity, reasons)
time.sleep(CHECK_INTERVAL_SECONDS)
3. OpenTelemetry Collector Pipeline (pours/deployment/ingester/ingester.yaml)
The SigNoz collector configuration receives raw OTLP gRPC spans on port 4317 and processes them via ClickHouse batch exporters:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
send_batch_size: 50000
send_batch_max_size: 55000
timeout: 5s
exporters:
clickhousetraces:
datasource: tcp://signoz-telemetrystore-clickhouse-0-0:9000/signoz_traces
use_new_schema: true
timeout: 45s
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [clickhousetraces]
β‘ Quickstart & Testing
1. Run Unit Tests
Verify anomaly detection rules and JSONL logging:
python -m unittest discover -s tests
2. Run Containerized Deployment
Deploy using Docker or Foundry:
docker build -t health-bot .
docker run -p 8000:8000 -e OTLP_ENDPOINT=http://host.docker.internal:4317 health-bot
π Key Learnings & SigNoz Value
- Tracing Over Static Logging: Injecting CPU, memory, and disk utilization attributes into OpenTelemetry spans converts raw infrastructure spikes into searchable trace queries within SigNoz.
- Resilient Instrumentation: Building automatic fallback mechanisms (OTLP to Console) guarantees that monitoring tools continue operating even during local collector outages.
-
Full Reproducibility: Providing valid
casting.yamland ClickHouse configurations allows teams to deploy self-hosted observability stacks in minutes.

Top comments (0)