Skip to content

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

# Settings -> Alert Channels -> Add PagerDuty
# Provide integration key from PagerDuty service

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;

Sources