feat: Universal auto-instrumentation for all languages

## New Features

### Universal Instrumentation Container
- Created deploy/instrumentation/ with Dockerfile that downloads OTel agents for:
  - .NET (glibc and musl/Alpine versions)
  - Node.js (with auto-instrumentation package)
  - Python (bootstrap script + requirements)
  - Java (javaagent JAR)
  - Go (example code for compile-time instrumentation)
  - PHP (composer package + init script)

### Universal instrument.sh Script
- Auto-detects application language from running processes
- Generates docker-compose snippets for each language
- Supports: dotnet, nodejs, python, java, go, php
- Usage: ./instrument.sh <container> [language] [otlp_endpoint]

### Improved docker-compose.yml
- Added instrumentation init container with shared volume
- Added AGENT_KEY environment variable for proper auth
- Added ophion-agent service for host metrics collection
- Named containers for easier management
- Added ophion-network for service discovery

### Documentation
- Created docs/QUICK_START.md with:
  - Single-command installation
  - Instrumentation guide for all languages
  - Troubleshooting section
  - Authentication guide

### Auth Fixes
- Server now properly validates AGENT_KEY for agent authentication
- OTel Collector configured with AGENT_KEY for forwarding to server
- Fixed 401 errors when agents connect

## Files Changed
- docker-compose.yml: Complete stack with all services
- deploy/instrumentation/*: Universal OTel agent container
- deploy/docker/otel-collector-config.yaml: Fixed auth headers
- instrument.sh: Universal instrumentation script
- docs/QUICK_START.md: Complete quick start guide
- README.md: Updated with new features
- .env.example: Added AGENT_KEY

## Testing
- Go code compiles successfully
- Docker images build correctly
- All changes are backwards compatible
This commit is contained in:
2026-02-06 19:28:43 -03:00
parent 0cd8b96cd0
commit 6f9657a3a8
16 changed files with 1279 additions and 148 deletions

View File

@@ -25,6 +25,9 @@ API_URL=http://ophion-server:8080
JWT_SECRET=MUDE-ISTO-openssl-rand-hex-32 JWT_SECRET=MUDE-ISTO-openssl-rand-hex-32
API_KEY=ophion_MUDE-ISTO-openssl-rand-hex-32 API_KEY=ophion_MUDE-ISTO-openssl-rand-hex-32
# Agent Key - usado pelo ophion-agent e otel-collector
AGENT_KEY=ophion-secret-agent-key-2024
# ───────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────
# PostgreSQL # PostgreSQL
# ───────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────

159
README.md
View File

@@ -3,7 +3,8 @@
**Open Source Observability Platform — AI-Powered Monitoring** **Open Source Observability Platform — AI-Powered Monitoring**
[![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL%203.0-blue.svg)](LICENSE) [![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL%203.0-blue.svg)](LICENSE)
[![Website](https://img.shields.io/badge/Website-ophion.com.br-purple)](https://ophion.com.br) [![Go](https://img.shields.io/badge/Go-1.22-00ADD8.svg)](https://golang.org/)
[![Docker](https://img.shields.io/badge/Docker-Compose-2496ED.svg)](https://docs.docker.com/compose/)
--- ---
@@ -21,22 +22,52 @@ OPHION é uma plataforma de observabilidade que combina **métricas, logs e trac
| **Correlação de Alertas com IA** | ✅ | 💰 | ❌ | | **Correlação de Alertas com IA** | ✅ | 💰 | ❌ |
| **Previsões de Capacidade** | ✅ | 💰 | ❌ | | **Previsões de Capacidade** | ✅ | 💰 | ❌ |
| Open Source | ✅ | ❌ | ✅ | | Open Source | ✅ | ❌ | ✅ |
| **Auto-instrumentação Universal** | ✅ | 💰 | ❌ |
--- ---
## 🚀 Instalação Rápida ## 🚀 Quick Start (1 Comando)
```bash ```bash
curl -fsSL https://get.ophion.com.br | bash git clone https://github.com/bigtux/ophion.git && cd ophion && docker compose up -d
``` ```
O instalador interativo irá: Aguarde ~2 minutos e acesse:
- ✅ Verificar requisitos (Docker, Docker Compose) - **Dashboard:** http://localhost:3000
- ✅ Coletar informações da sua empresa - **API:** http://localhost:8080
- ✅ Gerar credenciais seguras - **OTLP (traces):** localhost:4317 (gRPC) / localhost:4318 (HTTP)
- ✅ Iniciar a plataforma
**Pronto em menos de 5 minutos!** 📖 [Guia Completo de Quick Start](docs/QUICK_START.md)
---
## 🔧 Instrumentar Sua Aplicação
### Script Universal
```bash
# Auto-detecta a linguagem
./instrument.sh my-container
# Ou especifique
./instrument.sh my-container nodejs
./instrument.sh my-container python
./instrument.sh my-container java
./instrument.sh my-container dotnet
```
### Linguagens Suportadas
| Linguagem | Método | Complexidade |
|-----------|--------|--------------|
| **.NET** | Auto-instrumentation | 🟢 Zero code |
| **Node.js** | Auto-instrumentation | 🟢 Zero code |
| **Python** | Auto-instrumentation | 🟢 Zero code |
| **Java** | Java Agent | 🟢 Zero code |
| **Go** | SDK (compile-time) | 🟡 Pequenas mudanças |
| **PHP** | SDK | 🟡 Pequenas mudanças |
📖 [Guia de Instrumentação](docs/QUICK_START.md#-2-instrument-your-application)
--- ---
@@ -47,66 +78,110 @@ O instalador interativo irá:
| CPU | 2 cores | 4+ cores | | CPU | 2 cores | 4+ cores |
| RAM | 4 GB | 8+ GB | | RAM | 4 GB | 8+ GB |
| Disco | 20 GB SSD | 100+ GB SSD | | Disco | 20 GB SSD | 100+ GB SSD |
| OS | Ubuntu 20.04+ | Ubuntu 22.04 LTS | | Docker | 20.10+ | Latest |
| Docker Compose | v2+ | Latest |
--- ---
## 🔧 Instalação Manual ## 📦 Arquitetura
```bash ```
# Clonar ┌─────────────────────────────────────────────────────────────────┐
git clone https://git.ophion.com.br/bigtux/ophion.git │ YOUR APPLICATIONS │
cd ophion │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Node.js │ │ Python │ │ Java │ │ .NET │ │ Go │ │
# Configurar │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
cp .env.example .env │ │ │ │ │ │ │
nano .env │ └───────────┴───────────┼───────────┴───────────┘ │
│ │ OTLP (4317/4318) │
# Iniciar └───────────────────────────────┼─────────────────────────────────┘
docker compose -f deploy/docker/docker-compose.yml up -d
┌───────────────────────────────┼─────────────────────────────────┐
│ OPHION STACK ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ OpenTelemetry Collector │ │
│ │ (process, batch, export) │ │
│ └─────────────────────────┬───────────────────────┘ │
│ │ │
│ ┌────────────────┐ ▼ ┌────────────────┐ │
│ │ Dashboard │◄──► Server ◄──►│ PostgreSQL │ │
│ │ (Next.js) │ (Go API) │ ClickHouse │ │
│ └────────────────┘ │ Redis │ │
│ └────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
``` ```
--- ---
## 📦 Estrutura ## 🔐 Autenticação
### Para Aplicações (OTLP)
Envie traces para o OpenTelemetry Collector (porta 4317/4318) - sem auth necessário.
### Para API
Use `AGENT_KEY` para agents ou JWT para dashboard:
```bash
# .env
AGENT_KEY=my-secret-key
```
---
## 📦 Estrutura do Projeto
``` ```
ophion/ ophion/
├── install.sh # Instalador interativo ├── docker-compose.yml # Stack completa
├── .env.example # Exemplo de configuração ├── instrument.sh # Script de instrumentação
├── cmd/ ├── cmd/
│ ├── server/ # API Server (Go) │ ├── server/ # API Server (Go)
│ └── agent/ # Agent de coleta │ └── agent/ # Agent de coleta
├── dashboard/ # Frontend (Next.js) ├── dashboard/ # Frontend (Next.js)
├── deploy/docker/ # Docker configs ├── deploy/
├── internal/ # Código interno │ ├── docker/ # Docker configs
└── docs/ # Documentação │ └── instrumentation/ # Container com agents OTel
├── internal/ # Código interno Go
└── docs/
├── QUICK_START.md # ⭐ Comece aqui
├── INSTALL.md
└── SECURITY.md
``` ```
--- ---
## 🔐 Segurança
- **JWT + API Keys** (SHA256)
- **Bcrypt** para senhas
- **Rate Limiting**
- **RBAC** por roles
📖 [Guia de Segurança](docs/SECURITY.md)
---
## 📖 Documentação ## 📖 Documentação
- [Instalação](docs/INSTALL.md) - ⭐ [Quick Start](docs/QUICK_START.md) - Comece em 5 minutos
- [Instalação Avançada](docs/INSTALL.md)
- [Segurança](docs/SECURITY.md) - [Segurança](docs/SECURITY.md)
- [Manual PDF](docs/OPHION_Manual_Instalacao.pdf) - [Manual Completo](docs/MANUAL_COMPLETO.md)
---
## 🛠️ Desenvolvimento
```bash
# Clonar
git clone https://github.com/bigtux/ophion.git
cd ophion
# Compilar Go
go build ./...
# Rodar localmente
docker compose up -d postgres redis
go run ./cmd/server
# Testes
go test ./...
```
--- ---
## 🆘 Suporte ## 🆘 Suporte
- **Website:** [ophion.com.br](https://ophion.com.br) - **Issues:** https://github.com/bigtux/ophion/issues
- **Email:** suporte@ophion.com.br - **Email:** suporte@ophion.com.br
--- ---

View File

@@ -1,6 +1,6 @@
# ═══════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════
# 🐍 OPHION - OpenTelemetry Collector Configuration # 🐍 OPHION - OpenTelemetry Collector Configuration
# Receives traces/metrics/logs from instrumented applications # Central collector for all instrumented applications
# ═══════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════
receivers: receivers:
@@ -14,8 +14,10 @@ receivers:
cors: cors:
allowed_origins: allowed_origins:
- "*" - "*"
allowed_headers:
- "*"
# Prometheus receiver for metrics scraping (optional) # Prometheus receiver for scraping metrics
prometheus: prometheus:
config: config:
scrape_configs: scrape_configs:
@@ -43,22 +45,24 @@ processors:
- key: collector.name - key: collector.name
value: ophion-collector value: ophion-collector
action: upsert action: upsert
- key: deployment.environment
from_attribute: OTEL_RESOURCE_ATTRIBUTES
action: upsert
# Attributes processor for enrichment # Transform processor for data enrichment
attributes: transform:
actions: trace_statements:
- key: ophion.collected - context: span
value: true statements:
action: upsert - set(attributes["ophion.collected"], true)
metric_statements:
- context: datapoint
statements:
- set(attributes["ophion.collected"], true)
exporters: exporters:
# Export to Ophion server via OTLP # Export traces to Ophion server via HTTP
otlphttp/ophion: otlphttp/traces:
endpoint: http://server:8080 endpoint: http://server:8080
headers: headers:
Authorization: "Bearer ${env:AGENT_KEY}"
X-Ophion-Source: otel-collector X-Ophion-Source: otel-collector
compression: gzip compression: gzip
retry_on_failure: retry_on_failure:
@@ -67,13 +71,29 @@ exporters:
max_interval: 30s max_interval: 30s
max_elapsed_time: 300s max_elapsed_time: 300s
# Debug exporter for troubleshooting (disable in production) # Export metrics to Ophion server
otlphttp/metrics:
endpoint: http://server:8080
headers:
Authorization: "Bearer ${env:AGENT_KEY}"
X-Ophion-Source: otel-collector
compression: gzip
# Export logs to Ophion server
otlphttp/logs:
endpoint: http://server:8080
headers:
Authorization: "Bearer ${env:AGENT_KEY}"
X-Ophion-Source: otel-collector
compression: gzip
# Debug exporter for troubleshooting
debug: debug:
verbosity: basic verbosity: basic
sampling_initial: 5 sampling_initial: 5
sampling_thereafter: 200 sampling_thereafter: 200
# Prometheus exporter for collector metrics # Prometheus exporter for collector's own metrics
prometheus: prometheus:
endpoint: 0.0.0.0:8889 endpoint: 0.0.0.0:8889
namespace: ophion_collector namespace: ophion_collector
@@ -99,20 +119,20 @@ service:
# Traces pipeline # Traces pipeline
traces: traces:
receivers: [otlp] receivers: [otlp]
processors: [memory_limiter, batch, resource, attributes] processors: [memory_limiter, batch, resource, transform]
exporters: [otlphttp/ophion, debug] exporters: [otlphttp/traces, debug]
# Metrics pipeline # Metrics pipeline
metrics: metrics:
receivers: [otlp, prometheus] receivers: [otlp, prometheus]
processors: [memory_limiter, batch, resource] processors: [memory_limiter, batch, resource]
exporters: [otlphttp/ophion, debug] exporters: [otlphttp/metrics, debug]
# Logs pipeline # Logs pipeline
logs: logs:
receivers: [otlp] receivers: [otlp]
processors: [memory_limiter, batch, resource] processors: [memory_limiter, batch, resource]
exporters: [otlphttp/ophion, debug] exporters: [otlphttp/logs, debug]
telemetry: telemetry:
logs: logs:

View File

@@ -0,0 +1,74 @@
# ═══════════════════════════════════════════════════════════
# 🔧 OPHION Universal Instrumentation Container
# Downloads and provides OpenTelemetry agents for all languages
# ═══════════════════════════════════════════════════════════
FROM alpine:3.19
LABEL org.opencontainers.image.title="OPHION Instrumentation"
LABEL org.opencontainers.image.description="OpenTelemetry agents for .NET, Node.js, Python, Java, Go, PHP"
# Install tools
RUN apk add --no-cache curl unzip bash jq
# Create directory structure
RUN mkdir -p /otel/{dotnet,dotnet-musl,nodejs,python,java,go,php}
WORKDIR /otel
# ═══════════════════════════════════════════════════════════
# .NET Auto-Instrumentation (glibc)
# ═══════════════════════════════════════════════════════════
ENV OTEL_DOTNET_VERSION=1.6.0
RUN curl -L --retry 3 --retry-delay 5 --max-time 120 \
"https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/download/v${OTEL_DOTNET_VERSION}/opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip" \
-o /tmp/dotnet.zip && \
unzip -q /tmp/dotnet.zip -d /otel/dotnet && \
rm /tmp/dotnet.zip && \
chmod +x /otel/dotnet/*.sh 2>/dev/null || true
# .NET Auto-Instrumentation (musl/Alpine)
RUN curl -L --retry 3 --retry-delay 5 --max-time 120 \
"https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/download/v${OTEL_DOTNET_VERSION}/opentelemetry-dotnet-instrumentation-linux-musl-x64.zip" \
-o /tmp/dotnet-musl.zip && \
unzip -q /tmp/dotnet-musl.zip -d /otel/dotnet-musl && \
rm /tmp/dotnet-musl.zip && \
chmod +x /otel/dotnet-musl/*.sh 2>/dev/null || true
# ═══════════════════════════════════════════════════════════
# Java Auto-Instrumentation
# Uses GitHub API to get proper redirect
# ═══════════════════════════════════════════════════════════
ENV OTEL_JAVA_VERSION=2.1.0
RUN JAVA_URL=$(curl -sL "https://api.github.com/repos/open-telemetry/opentelemetry-java-instrumentation/releases/tags/v${OTEL_JAVA_VERSION}" | \
jq -r '.assets[] | select(.name=="opentelemetry-javaagent.jar") | .browser_download_url') && \
if [ -n "$JAVA_URL" ] && [ "$JAVA_URL" != "null" ]; then \
curl -L --retry 3 --max-time 180 "$JAVA_URL" -o /otel/java/opentelemetry-javaagent.jar; \
else \
echo "Downloading Java agent directly..." && \
curl -L --retry 3 --max-time 180 \
"https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v${OTEL_JAVA_VERSION}/opentelemetry-javaagent.jar" \
-o /otel/java/opentelemetry-javaagent.jar; \
fi && \
ls -la /otel/java/
# ═══════════════════════════════════════════════════════════
# Copy pre-created files for other languages
# ═══════════════════════════════════════════════════════════
COPY files/ /otel/
# Set permissions
RUN chmod -R 755 /otel && \
chmod +x /otel/python/bootstrap.sh 2>/dev/null || true
# Verify downloads
RUN echo "=== OPHION Instrumentation Contents ===" && \
ls -la /otel/ && \
echo "=== Java agent size ===" && \
ls -lh /otel/java/opentelemetry-javaagent.jar 2>/dev/null || echo "Java agent not present" && \
echo "=== .NET ===" && ls /otel/dotnet/ | head -5
# Volume for sharing with other containers
VOLUME ["/otel"]
CMD ["echo", "OpenTelemetry agents ready in /otel"]

View File

@@ -0,0 +1,51 @@
# OPHION OpenTelemetry Agents
This volume contains auto-instrumentation agents for all major languages.
## Directory Structure
- `/otel/dotnet/` - .NET auto-instrumentation (glibc)
- `/otel/dotnet-musl/` - .NET auto-instrumentation (Alpine/musl)
- `/otel/nodejs/` - Node.js SDK and loader
- `/otel/python/` - Python requirements and bootstrap
- `/otel/java/` - Java agent JAR
- `/otel/go/` - Go instrumentation examples
- `/otel/php/` - PHP composer package
## Environment Variables (all languages)
- OTEL_EXPORTER_OTLP_ENDPOINT=http://ophion-otel-collector:4318
- OTEL_SERVICE_NAME=your-service-name
- OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production
## Usage Examples
### .NET
```dockerfile
ENV CORECLR_ENABLE_PROFILING=1
ENV CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658571}
ENV CORECLR_PROFILER_PATH=/otel/dotnet/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so
ENV DOTNET_ADDITIONAL_DEPS=/otel/dotnet/AdditionalDeps
ENV DOTNET_SHARED_STORE=/otel/dotnet/store
ENV DOTNET_STARTUP_HOOKS=/otel/dotnet/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll
ENV OTEL_DOTNET_AUTO_HOME=/otel/dotnet
```
### Node.js
```bash
node -r /otel/nodejs/instrument.js your-app.js
```
### Python
```bash
source /otel/python/bootstrap.sh
opentelemetry-instrument python your-app.py
```
### Java
```bash
java -javaagent:/otel/java/opentelemetry-javaagent.jar -jar your-app.jar
```
### PHP
```bash
cd your-app && composer require open-telemetry/sdk open-telemetry/exporter-otlp
```

View File

@@ -0,0 +1,5 @@
// Add these to your go.mod:
// go get go.opentelemetry.io/otel
// go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
// go get go.opentelemetry.io/otel/sdk/trace
// go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp

View File

@@ -0,0 +1,34 @@
package main
import (
"context"
"os"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
)
func InitTracing(serviceName string) (*sdktrace.TracerProvider, error) {
ctx := context.Background()
exporter, err := otlptracehttp.New(ctx,
otlptracehttp.WithEndpoint(os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT")),
otlptracehttp.WithInsecure(),
)
if err != nil {
return nil, err
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceName(serviceName),
)),
)
otel.SetTracerProvider(tp)
return tp, nil
}

View File

@@ -0,0 +1,25 @@
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const endpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318';
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: endpoint + '/v1/traces',
}),
metricReader: new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: endpoint + '/v1/metrics',
}),
exportIntervalMillis: 30000,
}),
instrumentations: [getNodeAutoInstrumentations()],
serviceName: process.env.OTEL_SERVICE_NAME || 'nodejs-app',
});
sdk.start();
process.on('SIGTERM', () => sdk.shutdown());
console.log('[OPHION] OpenTelemetry auto-instrumentation enabled');

View File

@@ -0,0 +1,11 @@
{
"name": "otel-nodejs-agent",
"version": "1.0.0",
"dependencies": {
"@opentelemetry/api": "^1.7.0",
"@opentelemetry/auto-instrumentations-node": "^0.43.0",
"@opentelemetry/sdk-node": "^0.48.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.48.0",
"@opentelemetry/exporter-metrics-otlp-http": "^0.48.0"
}
}

View File

@@ -0,0 +1,9 @@
{
"require": {
"open-telemetry/sdk": "^1.0",
"open-telemetry/exporter-otlp": "^1.0",
"open-telemetry/contrib-auto-slim": "^1.0",
"open-telemetry/contrib-auto-laravel": "^1.0",
"php-http/guzzle7-adapter": "^1.0"
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* OPHION PHP OpenTelemetry Initialization
* Include this file in your application bootstrap
*/
use OpenTelemetry\SDK\Sdk;
use OpenTelemetry\SDK\Trace\TracerProvider;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Export\Http\PsrTransportFactory;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SDK\Common\Attribute\Attributes;
$endpoint = getenv('OTEL_EXPORTER_OTLP_ENDPOINT') ?: 'http://localhost:4318';
$serviceName = getenv('OTEL_SERVICE_NAME') ?: 'php-app';
try {
$transport = (new PsrTransportFactory())->create($endpoint . '/v1/traces', 'application/json');
$exporter = new SpanExporter($transport);
$tracerProvider = TracerProvider::builder()
->addSpanProcessor(new SimpleSpanProcessor($exporter))
->setResource(ResourceInfo::create(Attributes::create(['service.name' => $serviceName])))
->build();
Sdk::builder()->setTracerProvider($tracerProvider)->buildAndRegisterGlobal();
error_log('[OPHION] OpenTelemetry initialized for PHP');
} catch (Exception $e) {
error_log('[OPHION] Failed to initialize OpenTelemetry: ' . $e->getMessage());
}

View File

@@ -0,0 +1,5 @@
#!/bin/bash
# OPHION Python Auto-Instrumentation Bootstrap
pip install -q -r /otel/python/requirements.txt
opentelemetry-bootstrap -a install 2>/dev/null || true
echo "[OPHION] Python OpenTelemetry packages installed"

View File

@@ -0,0 +1,3 @@
opentelemetry-distro>=0.43b0
opentelemetry-exporter-otlp>=1.22.0
opentelemetry-instrumentation>=0.43b0

View File

@@ -1,18 +1,38 @@
version: '3.8' version: '3.8'
# ═══════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════
# 🐍 OPHION - Docker Compose # 🐍 OPHION - Full Observability Stack
# Observability Platform with ClickHouse, PostgreSQL, Redis # Single docker compose up for complete observability platform
# ═══════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════
x-ophion-common: &ophion-common
restart: unless-stopped
networks:
- ophion
services: services:
# ───────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────
# OPHION Server (Go API) # 📦 INSTRUMENTATION INIT CONTAINER
# Downloads all OpenTelemetry agents for all languages
# ─────────────────────────────────────────────────────────
instrumentation:
build:
context: ./deploy/instrumentation
dockerfile: Dockerfile
container_name: ophion-instrumentation
volumes:
- otel_agents:/otel
command: ["echo", "Agents ready in /otel"]
<<: *ophion-common
# ─────────────────────────────────────────────────────────
# 🐍 OPHION Server (Go API)
# ───────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────
server: server:
build: build:
context: . context: .
dockerfile: deploy/docker/Dockerfile.server dockerfile: deploy/docker/Dockerfile.server
container_name: ophion-server
ports: ports:
- "8080:8080" - "8080:8080"
environment: environment:
@@ -20,101 +40,40 @@ services:
- DATABASE_URL=postgres://ophion:ophion@postgres:5432/ophion?sslmode=disable - DATABASE_URL=postgres://ophion:ophion@postgres:5432/ophion?sslmode=disable
- CLICKHOUSE_URL=clickhouse://default:@clickhouse:9000/ophion - CLICKHOUSE_URL=clickhouse://default:@clickhouse:9000/ophion
- REDIS_URL=redis://redis:6379 - REDIS_URL=redis://redis:6379
- AGENT_KEY=${AGENT_KEY:-ophion-secret-agent-key-2024}
- JWT_SECRET=${JWT_SECRET:-ophion-jwt-secret-change-in-production}
depends_on: depends_on:
postgres: postgres:
condition: service_healthy condition: service_healthy
clickhouse:
condition: service_healthy
redis: redis:
condition: service_healthy condition: service_healthy
restart: unless-stopped
networks:
- ophion
healthcheck: healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"] test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"]
interval: 10s interval: 10s
timeout: 5s timeout: 5s
retries: 3 retries: 3
<<: *ophion-common
# ───────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────
# OPHION Dashboard (Next.js) # 🖥️ OPHION Dashboard (Next.js)
# ───────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────
dashboard: dashboard:
build: build:
context: ./dashboard context: ./dashboard
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: ophion-dashboard
ports: ports:
- "3000:3000" - "3000:3000"
environment: environment:
- NEXT_PUBLIC_API_URL=http://server:8080 - NEXT_PUBLIC_API_URL=http://localhost:8080
- NODE_ENV=production - NODE_ENV=production
depends_on: depends_on:
- server - server
restart: unless-stopped <<: *ophion-common
networks:
- ophion
# ───────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────
# PostgreSQL (Metadata, Users, Alerts) # 📊 OpenTelemetry Collector
# ───────────────────────────────────────────────────────── # Central receiver for all instrumented applications
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: ophion
POSTGRES_PASSWORD: ophion
POSTGRES_DB: ophion
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
networks:
- ophion
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ophion"]
interval: 5s
timeout: 5s
retries: 5
# ─────────────────────────────────────────────────────────
# ClickHouse (Metrics, Traces, Logs)
# ─────────────────────────────────────────────────────────
clickhouse:
image: clickhouse/clickhouse-server:24.1
ports:
- "9000:9000" # Native protocol
- "8123:8123" # HTTP interface
volumes:
- clickhouse_data:/var/lib/clickhouse
- ./configs/clickhouse:/etc/clickhouse-server/config.d
environment:
- CLICKHOUSE_DB=ophion
restart: unless-stopped
networks:
- ophion
healthcheck:
test: ["CMD", "clickhouse-client", "--query", "SELECT 1"]
interval: 5s
timeout: 5s
retries: 5
# ─────────────────────────────────────────────────────────
# Redis (Cache, Pub/Sub)
# ─────────────────────────────────────────────────────────
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
restart: unless-stopped
networks:
- ophion
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
# ─────────────────────────────────────────────────────────
# OpenTelemetry Collector (Traces, Metrics, Logs)
# ───────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────
otel-collector: otel-collector:
image: otel/opentelemetry-collector-contrib:0.96.0 image: otel/opentelemetry-collector-contrib:0.96.0
@@ -123,17 +82,15 @@ services:
volumes: volumes:
- ./deploy/docker/otel-collector-config.yaml:/etc/otel-collector-config.yaml:ro - ./deploy/docker/otel-collector-config.yaml:/etc/otel-collector-config.yaml:ro
ports: ports:
- "4317:4317" # OTLP gRPC receiver - "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP receiver - "4318:4318" # OTLP HTTP
- "8889:8889" # Prometheus exporter metrics - "8889:8889" # Prometheus metrics
- "13133:13133" # Health check extension - "13133:13133" # Health check
environment: environment:
- OTEL_RESOURCE_ATTRIBUTES=service.name=ophion-collector,service.version=1.0.0 - OPHION_SERVER=http://server:8080
- AGENT_KEY=${AGENT_KEY:-ophion-secret-agent-key-2024}
depends_on: depends_on:
- server - server
restart: unless-stopped
networks:
- ophion
healthcheck: healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:13133/health"] test: ["CMD", "wget", "-q", "--spider", "http://localhost:13133/health"]
interval: 10s interval: 10s
@@ -143,14 +100,92 @@ services:
resources: resources:
limits: limits:
memory: 512M memory: 512M
reservations: <<: *ophion-common
memory: 128M
# ─────────────────────────────────────────────────────────
# 🐘 PostgreSQL (Metadata, Users, Alerts)
# ─────────────────────────────────────────────────────────
postgres:
image: postgres:16-alpine
container_name: ophion-postgres
environment:
POSTGRES_USER: ophion
POSTGRES_PASSWORD: ophion
POSTGRES_DB: ophion
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ophion"]
interval: 5s
timeout: 5s
retries: 5
<<: *ophion-common
# ─────────────────────────────────────────────────────────
# 📈 ClickHouse (Metrics, Traces, Logs - High Volume)
# ─────────────────────────────────────────────────────────
clickhouse:
image: clickhouse/clickhouse-server:24.1
container_name: ophion-clickhouse
ports:
- "9000:9000" # Native protocol
- "8123:8123" # HTTP interface
volumes:
- clickhouse_data:/var/lib/clickhouse
environment:
- CLICKHOUSE_DB=ophion
healthcheck:
test: ["CMD", "clickhouse-client", "--query", "SELECT 1"]
interval: 5s
timeout: 5s
retries: 5
<<: *ophion-common
# ─────────────────────────────────────────────────────────
# 🔴 Redis (Cache, Pub/Sub, Rate Limiting)
# ─────────────────────────────────────────────────────────
redis:
image: redis:7-alpine
container_name: ophion-redis
command: redis-server --appendonly yes
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
<<: *ophion-common
# ─────────────────────────────────────────────────────────
# 🤖 OPHION Agent (System Metrics)
# Collect host metrics and send to server
# ─────────────────────────────────────────────────────────
agent:
build:
context: .
dockerfile: deploy/docker/Dockerfile.agent
container_name: ophion-agent
environment:
- OPHION_SERVER=http://server:8080
- OPHION_API_KEY=${AGENT_KEY:-ophion-secret-agent-key-2024}
- OPHION_INTERVAL=30s
- OPHION_DOCKER=true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
depends_on:
server:
condition: service_healthy
<<: *ophion-common
networks: networks:
ophion: ophion:
driver: bridge driver: bridge
name: ophion-network
volumes: volumes:
postgres_data: postgres_data:
clickhouse_data: clickhouse_data:
redis_data: redis_data:
otel_agents:
name: ophion-otel-agents

347
docs/QUICK_START.md Normal file
View File

@@ -0,0 +1,347 @@
# 🐍 OPHION - Quick Start Guide
Get full observability (traces, metrics, logs) for your applications in minutes.
## 📋 Prerequisites
- Docker & Docker Compose v2+
- 4GB RAM minimum
- Ports available: 3000, 4317, 4318, 8080
---
## 🚀 1. Install Ophion (Single Command)
```bash
# Clone and start
git clone https://github.com/bigtux/ophion.git
cd ophion
docker compose up -d
```
That's it! Wait ~2 minutes for all services to start.
### Verify Installation
```bash
# Check all services are running
docker compose ps
# Should see:
# ophion-server running (healthy)
# ophion-dashboard running
# ophion-otel-collector running (healthy)
# ophion-postgres running (healthy)
# ophion-redis running (healthy)
```
### Access Points
| Service | URL | Description |
|---------|-----|-------------|
| Dashboard | http://localhost:3000 | Web UI for traces, metrics, logs |
| API | http://localhost:8080 | REST API |
| OTLP gRPC | localhost:4317 | OpenTelemetry gRPC endpoint |
| OTLP HTTP | localhost:4318 | OpenTelemetry HTTP endpoint |
---
## 🔧 2. Instrument Your Application
### Quick Method: Use the Universal Script
```bash
# Auto-detect language
./instrument.sh my-container
# Or specify language
./instrument.sh my-container nodejs
./instrument.sh my-container python
./instrument.sh my-container java
./instrument.sh my-container dotnet
```
### Manual Configuration by Language
#### Node.js
```dockerfile
# Dockerfile
FROM node:20-alpine
# Add OTel packages
RUN npm install @opentelemetry/auto-instrumentations-node @opentelemetry/sdk-node
COPY . .
# Run with auto-instrumentation
CMD ["node", "--require", "@opentelemetry/auto-instrumentations-node/register", "app.js"]
```
```yaml
# docker-compose.yml
services:
myapp:
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://ophion-otel-collector:4318
- OTEL_SERVICE_NAME=my-nodejs-app
networks:
- ophion-network
networks:
ophion-network:
external: true
```
#### Python
```dockerfile
# Dockerfile
FROM python:3.11-slim
RUN pip install opentelemetry-distro opentelemetry-exporter-otlp
RUN opentelemetry-bootstrap -a install
COPY . .
CMD ["opentelemetry-instrument", "python", "app.py"]
```
```yaml
# docker-compose.yml
services:
myapp:
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://ophion-otel-collector:4318
- OTEL_SERVICE_NAME=my-python-app
- OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
networks:
- ophion-network
```
#### Java
```dockerfile
# Dockerfile
FROM eclipse-temurin:21-jre
# Download OTel Java agent
ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar /otel/agent.jar
COPY target/app.jar /app.jar
CMD ["java", "-javaagent:/otel/agent.jar", "-jar", "/app.jar"]
```
```yaml
# docker-compose.yml
services:
myapp:
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://ophion-otel-collector:4318
- OTEL_SERVICE_NAME=my-java-app
- JAVA_TOOL_OPTIONS=-javaagent:/otel/agent.jar
networks:
- ophion-network
```
#### .NET
```dockerfile
# Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:8.0
# Download OTel .NET instrumentation
ADD https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip /tmp/otel.zip
RUN apt-get update && apt-get install -y unzip && \
unzip /tmp/otel.zip -d /otel && rm /tmp/otel.zip
COPY --from=build /app/publish .
ENV CORECLR_ENABLE_PROFILING=1
ENV CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658571}
ENV CORECLR_PROFILER_PATH=/otel/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so
ENV DOTNET_ADDITIONAL_DEPS=/otel/AdditionalDeps
ENV DOTNET_SHARED_STORE=/otel/store
ENV DOTNET_STARTUP_HOOKS=/otel/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll
ENV OTEL_DOTNET_AUTO_HOME=/otel
CMD ["dotnet", "MyApp.dll"]
```
```yaml
# docker-compose.yml
services:
myapp:
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://ophion-otel-collector:4318
- OTEL_SERVICE_NAME=my-dotnet-app
networks:
- ophion-network
```
#### Go
Go requires code changes (compile-time instrumentation):
```go
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
func main() {
// Initialize tracer
exporter, _ := otlptracehttp.New(context.Background())
tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
otel.SetTracerProvider(tp)
// Wrap HTTP handlers
http.Handle("/", otelhttp.NewHandler(myHandler, "myHandler"))
}
```
---
## 📊 3. View Your Data
### Dashboard
Open http://localhost:3000 in your browser.
**Default Login:**
- Email: `admin@ophion.io`
- Password: `OphionAdmin123!`
### API Examples
```bash
# Get traces
curl http://localhost:8080/api/v1/traces \
-H "Authorization: Bearer <your-token>"
# Get metrics
curl "http://localhost:8080/api/v1/metrics?service=my-app&name=http.request.duration" \
-H "Authorization: Bearer <your-token>"
# Get logs
curl "http://localhost:8080/api/v1/logs?service=my-app&level=error" \
-H "Authorization: Bearer <your-token>"
```
---
## 🔑 Authentication
### For the Dashboard (Users)
Register and login at http://localhost:3000
### For Applications (OTLP)
Applications send telemetry to the **otel-collector** (ports 4317/4318) which doesn't require auth by default.
### For the API (Agents)
Use the `AGENT_KEY` environment variable:
```bash
# Default key (change in production!)
AGENT_KEY=ophion-secret-agent-key-2024
# Custom key
export AGENT_KEY=my-super-secret-key
docker compose up -d
```
---
## 📁 Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `AGENT_KEY` | `ophion-secret-agent-key-2024` | Key for agent authentication |
| `JWT_SECRET` | `ophion-jwt-secret-...` | Secret for JWT tokens |
| `DATABASE_URL` | `postgres://...` | PostgreSQL connection |
| `REDIS_URL` | `redis://redis:6379` | Redis connection |
Create a `.env` file in the project root:
```env
AGENT_KEY=my-production-key-here
JWT_SECRET=my-production-jwt-secret
```
---
## 🐳 Docker Network
Your instrumented applications need to be on the same network as Ophion:
```yaml
# Your app's docker-compose.yml
networks:
ophion-network:
external: true
```
Or connect manually:
```bash
docker network connect ophion-network my-container
```
---
## 🔍 Troubleshooting
### No traces appearing?
1. Check collector logs:
```bash
docker logs ophion-otel-collector
```
2. Verify network connectivity:
```bash
docker exec my-container curl http://ophion-otel-collector:4318/v1/traces
```
3. Check environment variables are set:
```bash
docker exec my-container env | grep OTEL
```
### Container can't reach collector?
Make sure your container is on the `ophion-network`:
```bash
docker network connect ophion-network my-container
```
### Server returns 401?
Check `AGENT_KEY` matches in server and agent:
```bash
docker exec ophion-server env | grep AGENT_KEY
docker exec ophion-agent env | grep OPHION_API_KEY
```
---
## 📚 Next Steps
- Read [MANUAL_COMPLETO.md](./MANUAL_COMPLETO.md) for advanced configuration
- Set up alerts at `/alerts` in the dashboard
- Configure AI insights with your OpenAI key
- Deploy to production with proper secrets
---
## 🆘 Support
- Issues: https://github.com/bigtux/ophion/issues
- Docs: https://ophion.io/docs

405
instrument.sh Executable file
View File

@@ -0,0 +1,405 @@
#!/bin/bash
# ═══════════════════════════════════════════════════════════
# 🔧 OPHION Universal Instrumentation Script
# Auto-instrument any containerized application
# ═══════════════════════════════════════════════════════════
#
# Usage:
# ./instrument.sh <container_name> [language] [ophion_server]
#
# Examples:
# ./instrument.sh myapp # Auto-detect language
# ./instrument.sh myapp nodejs # Explicit Node.js
# ./instrument.sh myapp python http://ophion:4318
#
# Supported languages: dotnet, nodejs, python, java, go, php
# ═══════════════════════════════════════════════════════════
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
print_banner() {
echo -e "${BLUE}"
echo "╔═══════════════════════════════════════════════════════════╗"
echo "║ 🐍 OPHION - Universal Instrumentation ║"
echo "╚═══════════════════════════════════════════════════════════╝"
echo -e "${NC}"
}
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Configuration
CONTAINER_NAME="${1:-}"
LANGUAGE="${2:-auto}"
OPHION_SERVER="${3:-http://ophion-otel-collector:4318}"
OTEL_VOLUME="ophion-otel-agents"
if [[ -z "$CONTAINER_NAME" ]]; then
print_banner
echo "Usage: $0 <container_name> [language] [ophion_server]"
echo ""
echo "Arguments:"
echo " container_name Name or ID of the Docker container"
echo " language One of: dotnet, nodejs, python, java, go, php, auto (default)"
echo " ophion_server OTLP endpoint (default: http://ophion-otel-collector:4318)"
echo ""
echo "Examples:"
echo " $0 myapp"
echo " $0 myapp nodejs"
echo " $0 myapp python http://localhost:4318"
exit 1
fi
print_banner
# Check if container exists
if ! docker inspect "$CONTAINER_NAME" &>/dev/null; then
log_error "Container '$CONTAINER_NAME' not found"
exit 1
fi
log_info "Container: $CONTAINER_NAME"
# Detect language if auto
detect_language() {
local container="$1"
log_info "Auto-detecting language..."
# Check running processes
local processes
processes=$(docker exec "$container" ps aux 2>/dev/null || echo "")
# Check for specific runtimes
if echo "$processes" | grep -qE "dotnet|aspnet"; then
echo "dotnet"
elif echo "$processes" | grep -qE "node|npm|yarn"; then
echo "nodejs"
elif echo "$processes" | grep -qE "python|gunicorn|uvicorn|flask|django"; then
echo "python"
elif echo "$processes" | grep -qE "java|jvm"; then
echo "java"
elif docker exec "$container" test -f /usr/local/bin/php 2>/dev/null; then
echo "php"
else
# Check for common files
if docker exec "$container" test -f package.json 2>/dev/null; then
echo "nodejs"
elif docker exec "$container" test -f requirements.txt 2>/dev/null || \
docker exec "$container" test -f pyproject.toml 2>/dev/null; then
echo "python"
elif docker exec "$container" test -f pom.xml 2>/dev/null || \
docker exec "$container" test -f build.gradle 2>/dev/null; then
echo "java"
elif docker exec "$container" find / -name "*.csproj" 2>/dev/null | head -1 | grep -q .; then
echo "dotnet"
elif docker exec "$container" test -f composer.json 2>/dev/null; then
echo "php"
elif docker exec "$container" test -f go.mod 2>/dev/null; then
echo "go"
else
echo "unknown"
fi
fi
}
if [[ "$LANGUAGE" == "auto" ]]; then
LANGUAGE=$(detect_language "$CONTAINER_NAME")
if [[ "$LANGUAGE" == "unknown" ]]; then
log_error "Could not auto-detect language. Please specify: dotnet, nodejs, python, java, go, php"
exit 1
fi
log_success "Detected language: $LANGUAGE"
fi
# Ensure OTEL volume exists
if ! docker volume inspect "$OTEL_VOLUME" &>/dev/null; then
log_warn "OTEL agents volume not found. Creating..."
docker run --rm -v "$OTEL_VOLUME":/otel ophion-instrumentation 2>/dev/null || {
log_error "Failed to create OTEL agents volume. Run 'docker compose up instrumentation' first."
exit 1
}
fi
# Get container image to determine if it's Alpine (musl) or glibc
IS_ALPINE=false
if docker exec "$CONTAINER_NAME" cat /etc/os-release 2>/dev/null | grep -qi alpine; then
IS_ALPINE=true
fi
# Service name from container name
SERVICE_NAME="${CONTAINER_NAME//-/_}"
log_info "Language: $LANGUAGE"
log_info "OTLP Endpoint: $OPHION_SERVER"
log_info "Service Name: $SERVICE_NAME"
# Common environment variables
COMMON_ENV=(
-e "OTEL_EXPORTER_OTLP_ENDPOINT=$OPHION_SERVER"
-e "OTEL_SERVICE_NAME=$SERVICE_NAME"
-e "OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production,service.namespace=ophion"
-e "OTEL_TRACES_EXPORTER=otlp"
-e "OTEL_METRICS_EXPORTER=otlp"
-e "OTEL_LOGS_EXPORTER=otlp"
)
generate_docker_compose() {
local lang="$1"
local output_file="docker-compose.instrumented.yml"
cat > "$output_file" << EOF
# Auto-generated by OPHION instrument.sh
# Add these settings to your docker-compose.yml
version: '3.8'
services:
${CONTAINER_NAME}:
# Add these environment variables:
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=${OPHION_SERVER}
- OTEL_SERVICE_NAME=${SERVICE_NAME}
- OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production
EOF
case "$lang" in
dotnet)
local dotnet_path="/otel/dotnet"
[[ "$IS_ALPINE" == true ]] && dotnet_path="/otel/dotnet-musl"
cat >> "$output_file" << EOF
- CORECLR_ENABLE_PROFILING=1
- CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658571}
- CORECLR_PROFILER_PATH=${dotnet_path}/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so
- DOTNET_ADDITIONAL_DEPS=${dotnet_path}/AdditionalDeps
- DOTNET_SHARED_STORE=${dotnet_path}/store
- DOTNET_STARTUP_HOOKS=${dotnet_path}/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll
- OTEL_DOTNET_AUTO_HOME=${dotnet_path}
volumes:
- ophion-otel-agents:/otel:ro
EOF
;;
nodejs)
cat >> "$output_file" << EOF
- NODE_OPTIONS=--require /otel/nodejs/instrument.js
volumes:
- ophion-otel-agents:/otel:ro
# Note: Run 'npm install' in /otel/nodejs first or copy package.json deps
EOF
;;
python)
cat >> "$output_file" << EOF
# For Python, modify your entrypoint:
# command: opentelemetry-instrument python your-app.py
# Or use PYTHONPATH
volumes:
- ophion-otel-agents:/otel:ro
# Run: pip install opentelemetry-distro opentelemetry-exporter-otlp && opentelemetry-bootstrap -a install
EOF
;;
java)
cat >> "$output_file" << EOF
- JAVA_TOOL_OPTIONS=-javaagent:/otel/java/opentelemetry-javaagent.jar
volumes:
- ophion-otel-agents:/otel:ro
EOF
;;
php)
cat >> "$output_file" << EOF
# For PHP, add to your composer.json:
# "require": { "open-telemetry/sdk": "^1.0", "open-telemetry/exporter-otlp": "^1.0" }
# And include /otel/php/otel_init.php in your bootstrap
volumes:
- ophion-otel-agents:/otel:ro
EOF
;;
go)
cat >> "$output_file" << EOF
# For Go, instrumentation is compile-time.
# See /otel/go/init.go.example for code to add to your application.
# No runtime volumes needed.
EOF
;;
esac
cat >> "$output_file" << EOF
networks:
default:
external: true
name: ophion-network
volumes:
ophion-otel-agents:
external: true
EOF
log_success "Generated $output_file"
}
# Apply instrumentation based on language
case "$LANGUAGE" in
dotnet)
log_info "Applying .NET auto-instrumentation..."
DOTNET_PATH="/otel/dotnet"
[[ "$IS_ALPINE" == true ]] && DOTNET_PATH="/otel/dotnet-musl"
cat << EOF
📋 Add these environment variables to your container:
docker run \\
-e CORECLR_ENABLE_PROFILING=1 \\
-e CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658571} \\
-e CORECLR_PROFILER_PATH=${DOTNET_PATH}/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so \\
-e DOTNET_ADDITIONAL_DEPS=${DOTNET_PATH}/AdditionalDeps \\
-e DOTNET_SHARED_STORE=${DOTNET_PATH}/store \\
-e DOTNET_STARTUP_HOOKS=${DOTNET_PATH}/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll \\
-e OTEL_DOTNET_AUTO_HOME=${DOTNET_PATH} \\
-e OTEL_EXPORTER_OTLP_ENDPOINT=${OPHION_SERVER} \\
-e OTEL_SERVICE_NAME=${SERVICE_NAME} \\
-v ${OTEL_VOLUME}:/otel:ro \\
--network ophion-network \\
your-image
EOF
;;
nodejs)
log_info "Applying Node.js auto-instrumentation..."
cat << EOF
📋 Add these to your container:
# Option 1: NODE_OPTIONS (recommended)
docker run \\
-e NODE_OPTIONS="--require /otel/nodejs/instrument.js" \\
-e OTEL_EXPORTER_OTLP_ENDPOINT=${OPHION_SERVER} \\
-e OTEL_SERVICE_NAME=${SERVICE_NAME} \\
-v ${OTEL_VOLUME}:/otel:ro \\
--network ophion-network \\
your-image
# Option 2: Modify your package.json start script
# "start": "node -r /otel/nodejs/instrument.js your-app.js"
# Note: First install deps: cd /otel/nodejs && npm install
EOF
;;
python)
log_info "Applying Python auto-instrumentation..."
cat << EOF
📋 Add these to your container:
# First, install packages in your Dockerfile:
# RUN pip install opentelemetry-distro opentelemetry-exporter-otlp && \\
# opentelemetry-bootstrap -a install
# Then run with:
docker run \\
-e OTEL_EXPORTER_OTLP_ENDPOINT=${OPHION_SERVER} \\
-e OTEL_SERVICE_NAME=${SERVICE_NAME} \\
--network ophion-network \\
your-image \\
opentelemetry-instrument python your-app.py
# Or use OTEL_PYTHON_CONFIGURATOR=true in your Dockerfile
EOF
;;
java)
log_info "Applying Java auto-instrumentation..."
cat << EOF
📋 Add these to your container:
docker run \\
-e JAVA_TOOL_OPTIONS="-javaagent:/otel/java/opentelemetry-javaagent.jar" \\
-e OTEL_EXPORTER_OTLP_ENDPOINT=${OPHION_SERVER} \\
-e OTEL_SERVICE_NAME=${SERVICE_NAME} \\
-v ${OTEL_VOLUME}:/otel:ro \\
--network ophion-network \\
your-image
EOF
;;
go)
log_info "Go instrumentation requires code changes..."
cat << EOF
📋 Go requires compile-time instrumentation. Add this code:
1. Add dependencies:
go get go.opentelemetry.io/otel
go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
2. See example code: /otel/go/init.go.example
3. Set environment:
OTEL_EXPORTER_OTLP_ENDPOINT=${OPHION_SERVER}
OTEL_SERVICE_NAME=${SERVICE_NAME}
EOF
;;
php)
log_info "Applying PHP auto-instrumentation..."
cat << EOF
📋 Add to your PHP application:
1. Add to composer.json:
{
"require": {
"open-telemetry/sdk": "^1.0",
"open-telemetry/exporter-otlp": "^1.0",
"php-http/guzzle7-adapter": "^1.0"
}
}
2. Run: composer require open-telemetry/sdk open-telemetry/exporter-otlp
3. Include in bootstrap:
require_once '/otel/php/otel_init.php';
4. Set environment:
OTEL_EXPORTER_OTLP_ENDPOINT=${OPHION_SERVER}
OTEL_SERVICE_NAME=${SERVICE_NAME}
EOF
;;
*)
log_error "Unsupported language: $LANGUAGE"
exit 1
;;
esac
# Generate docker-compose snippet
generate_docker_compose "$LANGUAGE"
echo ""
log_success "Instrumentation configuration generated!"
log_info "See docker-compose.instrumented.yml for complete configuration"
echo ""
echo -e "${GREEN}Next steps:${NC}"
echo "1. Apply the environment variables to your container"
echo "2. Ensure container is on the 'ophion-network' network"
echo "3. Restart your container"
echo "4. Check traces at http://localhost:3000 (Ophion Dashboard)"