Commands & Recipes¶
Docker commands, SDK setup, OTel Collector configuration, and API snippets for Monoscope.
Docker Commands¶
Quick Start¶
git clone https://github.com/monoscope-tech/monoscope.git
cd monoscope
docker-compose up -d
# http://localhost:8080 (admin/changeme)
Run TimeFusion Standalone¶
docker run -d --name timefusion \
-p 5432:5432 \
-e AWS_S3_BUCKET=your-bucket \
-e AWS_ACCESS_KEY_ID=your-key \
-e AWS_SECRET_ACCESS_KEY=your-secret \
timefusion/timefusion:latest
# Query with any PostgreSQL client
psql -h localhost -p 5432 -c "SELECT * FROM otel_logs_and_spans LIMIT 10;"
OpenTelemetry Collector Configuration¶
Basic OTLP Export to Monoscope¶
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
exporters:
otlphttp:
endpoint: http://monoscope:4317
headers:
Authorization: "Bearer YOUR_API_KEY"
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlphttp]
logs:
receivers: [otlp]
exporters: [otlphttp]
metrics:
receivers: [otlp]
exporters: [otlphttp]
Multi-Source Collector¶
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
prometheus:
config:
scrape_configs:
- job_name: 'my-app'
scrape_interval: 15s
static_configs:
- targets: ['my-app:8080']
exporters:
otlphttp:
endpoint: https://app.monoscope.tech
headers:
Authorization: "Bearer YOUR_API_KEY"
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlphttp]
logs:
receivers: [otlp]
exporters: [otlphttp]
metrics:
receivers: [otlp, prometheus]
exporters: [otlphttp]
SDK Setup¶
Python (Flask)¶
from apitoolkit_flask import observe_app
from flask import Flask
app = Flask(__name__)
observe_app(app, api_key="YOUR_API_KEY")
@app.route("/api/users")
def get_users():
return {"users": []}
Python (Django)¶
# settings.py
APITOOLKIT = {
"API_KEY": "YOUR_API_KEY",
}
# In middleware
MIDDLEWARE = [
"apitoolkit_django.APIToolkitDjangoMiddleware",
# ... other middleware
]
Node.js (Express)¶
const express = require("express");
const { observe } = require("apitoolkit-express");
const app = express();
observe(app, { apiKey: "YOUR_API_KEY" });
app.get("/api/users", (req, res) => {
res.json({ users: [] });
});
app.listen(3000);
Go¶
package main
import (
"net/http"
monoscope "github.com/monoscope-tech/monoscope-go"
)
func main() {
client, err := monoscope.NewClient(monoscope.Config{
APIKey: "YOUR_API_KEY",
})
if err != nil {
panic(err)
}
defer client.Close()
mux := http.NewServeMux()
mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"users":[]}`))
})
http.ListenAndServe(":8080", client.Middleware(mux))
}
Java (Spring Boot)¶
// Add OTel Java Agent at startup
java -javaagent:otel-agent.jar \
-Dotel.exporter.otlp.endpoint=http://monoscope:4317 \
-Dotel.exporter.otlp.headers="Authorization=Bearer YOUR_API_KEY" \
-Dotel.service.name=my-service \
-jar my-app.jar
PHP (Laravel)¶
// config/app.php — add service provider
'providers' => [
APIToolkit\Laravel\APIToolkitServiceProvider::class,
];
// .env
APITOOLKIT_API_KEY=YOUR_API_KEY
Kubernetes Auto-Instrumentation¶
Install OTel Operator¶
kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
Create Instrumentation Resource¶
apiVersion: opentelemetry.io/v1beta1
kind: Instrumentation
metadata:
name: monoscope
namespace: observability
spec:
exporter:
endpoint: http://monoscope.observability:4317
propagators:
- tracecontext
- baggage
java:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest
python:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python:latest
nodejs:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs:latest
Annotate Deployments¶
# Java app
kubectl annotate deployment my-java-app \
instrumentation.opentelemetry.io/inject-java="true" \
instrumentation.opentelemetry.io/otel-exporter-otlp-endpoint="http://monoscope:4317"
# Python app
kubectl annotate deployment my-python-app \
instrumentation.opentelemetry.io/inject-python="true"
# Node.js app
kubectl annotate deployment my-node-app \
instrumentation.opentelemetry.io/inject-nodejs="true"
Alert Channel Configuration¶
Slack Webhook¶
# Configure in Monoscope UI or API
# Settings -> Alert Channels -> Add Slack
# Provide webhook URL: https://hooks.slack.com/services/T.../B.../xxx
# Use slash command: /monoscope-here in channel
Discord Webhook¶
# Settings -> Alert Channels -> Add Discord
# Provide webhook URL: https://discord.com/api/webhooks/.../...
# Daily admin summary enabled automatically
PagerDuty¶
Querying TimeFusion¶
-- Connect to TimeFusion via PostgreSQL wire protocol
psql -h localhost -p 5432
-- Recent errors
SELECT timestamp, name, duration, attributes___error___type
FROM otel_logs_and_spans
WHERE attributes___http___response___status_code LIKE '5%'
AND timestamp > NOW() - INTERVAL '1 hour'
ORDER BY timestamp DESC
LIMIT 50;
-- Top slowest endpoints (last 24 hours)
SELECT name, COUNT(*) as requests,
AVG(duration) / 1000000 as avg_ms,
MAX(duration) / 1000000 as max_ms
FROM otel_logs_and_spans
WHERE kind = 'SERVER'
AND timestamp > NOW() - INTERVAL '24 hours'
GROUP BY name
ORDER BY avg_ms DESC
LIMIT 20;