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:
@@ -25,6 +25,9 @@ API_URL=http://ophion-server:8080
|
||||
JWT_SECRET=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
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
|
||||
165
README.md
165
README.md
@@ -3,7 +3,8 @@
|
||||
**Open Source Observability Platform — AI-Powered Monitoring**
|
||||
|
||||
[](LICENSE)
|
||||
[](https://ophion.com.br)
|
||||
[](https://golang.org/)
|
||||
[](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** | ✅ | 💰 | ❌ |
|
||||
| **Previsões de Capacidade** | ✅ | 💰 | ❌ |
|
||||
| Open Source | ✅ | ❌ | ✅ |
|
||||
| **Auto-instrumentação Universal** | ✅ | 💰 | ❌ |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Instalação Rápida
|
||||
## 🚀 Quick Start (1 Comando)
|
||||
|
||||
```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á:
|
||||
- ✅ Verificar requisitos (Docker, Docker Compose)
|
||||
- ✅ Coletar informações da sua empresa
|
||||
- ✅ Gerar credenciais seguras
|
||||
- ✅ Iniciar a plataforma
|
||||
Aguarde ~2 minutos e acesse:
|
||||
- **Dashboard:** http://localhost:3000
|
||||
- **API:** http://localhost:8080
|
||||
- **OTLP (traces):** localhost:4317 (gRPC) / localhost:4318 (HTTP)
|
||||
|
||||
**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 |
|
||||
| RAM | 4 GB | 8+ GB |
|
||||
| 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
|
||||
cd ophion
|
||||
|
||||
# Configurar
|
||||
cp .env.example .env
|
||||
nano .env
|
||||
|
||||
# Iniciar
|
||||
docker compose -f deploy/docker/docker-compose.yml up -d
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ YOUR APPLICATIONS │
|
||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ Node.js │ │ Python │ │ Java │ │ .NET │ │ Go │ │
|
||||
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
|
||||
│ │ │ │ │ │ │
|
||||
│ └───────────┴───────────┼───────────┴───────────┘ │
|
||||
│ │ OTLP (4317/4318) │
|
||||
└───────────────────────────────┼─────────────────────────────────┘
|
||||
│
|
||||
┌───────────────────────────────┼─────────────────────────────────┐
|
||||
│ 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/
|
||||
├── install.sh # Instalador interativo
|
||||
├── .env.example # Exemplo de configuração
|
||||
├── docker-compose.yml # Stack completa
|
||||
├── instrument.sh # Script de instrumentação
|
||||
├── cmd/
|
||||
│ ├── server/ # API Server (Go)
|
||||
│ └── agent/ # Agent de coleta
|
||||
├── dashboard/ # Frontend (Next.js)
|
||||
├── deploy/docker/ # Docker configs
|
||||
├── internal/ # Código interno
|
||||
└── docs/ # Documentação
|
||||
│ ├── server/ # API Server (Go)
|
||||
│ └── agent/ # Agent de coleta
|
||||
├── dashboard/ # Frontend (Next.js)
|
||||
├── deploy/
|
||||
│ ├── docker/ # Docker configs
|
||||
│ └── 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
|
||||
|
||||
- [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)
|
||||
- [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
|
||||
|
||||
- **Website:** [ophion.com.br](https://ophion.com.br)
|
||||
- **Issues:** https://github.com/bigtux/ophion/issues
|
||||
- **Email:** suporte@ophion.com.br
|
||||
|
||||
---
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
# 🐍 OPHION - OpenTelemetry Collector Configuration
|
||||
# Receives traces/metrics/logs from instrumented applications
|
||||
# Central collector for all instrumented applications
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
receivers:
|
||||
@@ -14,8 +14,10 @@ receivers:
|
||||
cors:
|
||||
allowed_origins:
|
||||
- "*"
|
||||
allowed_headers:
|
||||
- "*"
|
||||
|
||||
# Prometheus receiver for metrics scraping (optional)
|
||||
# Prometheus receiver for scraping metrics
|
||||
prometheus:
|
||||
config:
|
||||
scrape_configs:
|
||||
@@ -43,22 +45,24 @@ processors:
|
||||
- key: collector.name
|
||||
value: ophion-collector
|
||||
action: upsert
|
||||
- key: deployment.environment
|
||||
from_attribute: OTEL_RESOURCE_ATTRIBUTES
|
||||
action: upsert
|
||||
|
||||
# Attributes processor for enrichment
|
||||
attributes:
|
||||
actions:
|
||||
- key: ophion.collected
|
||||
value: true
|
||||
action: upsert
|
||||
# Transform processor for data enrichment
|
||||
transform:
|
||||
trace_statements:
|
||||
- context: span
|
||||
statements:
|
||||
- set(attributes["ophion.collected"], true)
|
||||
metric_statements:
|
||||
- context: datapoint
|
||||
statements:
|
||||
- set(attributes["ophion.collected"], true)
|
||||
|
||||
exporters:
|
||||
# Export to Ophion server via OTLP
|
||||
otlphttp/ophion:
|
||||
# Export traces to Ophion server via HTTP
|
||||
otlphttp/traces:
|
||||
endpoint: http://server:8080
|
||||
headers:
|
||||
Authorization: "Bearer ${env:AGENT_KEY}"
|
||||
X-Ophion-Source: otel-collector
|
||||
compression: gzip
|
||||
retry_on_failure:
|
||||
@@ -67,13 +71,29 @@ exporters:
|
||||
max_interval: 30s
|
||||
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:
|
||||
verbosity: basic
|
||||
sampling_initial: 5
|
||||
sampling_thereafter: 200
|
||||
|
||||
# Prometheus exporter for collector metrics
|
||||
# Prometheus exporter for collector's own metrics
|
||||
prometheus:
|
||||
endpoint: 0.0.0.0:8889
|
||||
namespace: ophion_collector
|
||||
@@ -99,20 +119,20 @@ service:
|
||||
# Traces pipeline
|
||||
traces:
|
||||
receivers: [otlp]
|
||||
processors: [memory_limiter, batch, resource, attributes]
|
||||
exporters: [otlphttp/ophion, debug]
|
||||
processors: [memory_limiter, batch, resource, transform]
|
||||
exporters: [otlphttp/traces, debug]
|
||||
|
||||
# Metrics pipeline
|
||||
# Metrics pipeline
|
||||
metrics:
|
||||
receivers: [otlp, prometheus]
|
||||
processors: [memory_limiter, batch, resource]
|
||||
exporters: [otlphttp/ophion, debug]
|
||||
exporters: [otlphttp/metrics, debug]
|
||||
|
||||
# Logs pipeline
|
||||
logs:
|
||||
receivers: [otlp]
|
||||
processors: [memory_limiter, batch, resource]
|
||||
exporters: [otlphttp/ophion, debug]
|
||||
exporters: [otlphttp/logs, debug]
|
||||
|
||||
telemetry:
|
||||
logs:
|
||||
|
||||
74
deploy/instrumentation/Dockerfile
Normal file
74
deploy/instrumentation/Dockerfile
Normal 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"]
|
||||
51
deploy/instrumentation/files/README.md
Normal file
51
deploy/instrumentation/files/README.md
Normal 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
|
||||
```
|
||||
5
deploy/instrumentation/files/go/go.mod.example
Normal file
5
deploy/instrumentation/files/go/go.mod.example
Normal 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
|
||||
34
deploy/instrumentation/files/go/init.go.example
Normal file
34
deploy/instrumentation/files/go/init.go.example
Normal 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
|
||||
}
|
||||
25
deploy/instrumentation/files/nodejs/instrument.js
Normal file
25
deploy/instrumentation/files/nodejs/instrument.js
Normal 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');
|
||||
11
deploy/instrumentation/files/nodejs/package.json
Normal file
11
deploy/instrumentation/files/nodejs/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
9
deploy/instrumentation/files/php/composer.json
Normal file
9
deploy/instrumentation/files/php/composer.json
Normal 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"
|
||||
}
|
||||
}
|
||||
29
deploy/instrumentation/files/php/otel_init.php
Normal file
29
deploy/instrumentation/files/php/otel_init.php
Normal 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());
|
||||
}
|
||||
5
deploy/instrumentation/files/python/bootstrap.sh
Normal file
5
deploy/instrumentation/files/python/bootstrap.sh
Normal 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"
|
||||
3
deploy/instrumentation/files/python/requirements.txt
Normal file
3
deploy/instrumentation/files/python/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
opentelemetry-distro>=0.43b0
|
||||
opentelemetry-exporter-otlp>=1.22.0
|
||||
opentelemetry-instrumentation>=0.43b0
|
||||
@@ -1,18 +1,38 @@
|
||||
version: '3.8'
|
||||
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
# 🐍 OPHION - Docker Compose
|
||||
# Observability Platform with ClickHouse, PostgreSQL, Redis
|
||||
# 🐍 OPHION - Full Observability Stack
|
||||
# Single docker compose up for complete observability platform
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
x-ophion-common: &ophion-common
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- ophion
|
||||
|
||||
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:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: deploy/docker/Dockerfile.server
|
||||
container_name: ophion-server
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
@@ -20,101 +40,40 @@ services:
|
||||
- DATABASE_URL=postgres://ophion:ophion@postgres:5432/ophion?sslmode=disable
|
||||
- CLICKHOUSE_URL=clickhouse://default:@clickhouse:9000/ophion
|
||||
- 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:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
clickhouse:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- ophion
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
<<: *ophion-common
|
||||
|
||||
# ─────────────────────────────────────────────────────────
|
||||
# OPHION Dashboard (Next.js)
|
||||
# 🖥️ OPHION Dashboard (Next.js)
|
||||
# ─────────────────────────────────────────────────────────
|
||||
dashboard:
|
||||
build:
|
||||
context: ./dashboard
|
||||
dockerfile: Dockerfile
|
||||
container_name: ophion-dashboard
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_URL=http://server:8080
|
||||
- NEXT_PUBLIC_API_URL=http://localhost:8080
|
||||
- NODE_ENV=production
|
||||
depends_on:
|
||||
- server
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- ophion
|
||||
<<: *ophion-common
|
||||
|
||||
# ─────────────────────────────────────────────────────────
|
||||
# PostgreSQL (Metadata, Users, Alerts)
|
||||
# ─────────────────────────────────────────────────────────
|
||||
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)
|
||||
# 📊 OpenTelemetry Collector
|
||||
# Central receiver for all instrumented applications
|
||||
# ─────────────────────────────────────────────────────────
|
||||
otel-collector:
|
||||
image: otel/opentelemetry-collector-contrib:0.96.0
|
||||
@@ -123,17 +82,15 @@ services:
|
||||
volumes:
|
||||
- ./deploy/docker/otel-collector-config.yaml:/etc/otel-collector-config.yaml:ro
|
||||
ports:
|
||||
- "4317:4317" # OTLP gRPC receiver
|
||||
- "4318:4318" # OTLP HTTP receiver
|
||||
- "8889:8889" # Prometheus exporter metrics
|
||||
- "13133:13133" # Health check extension
|
||||
- "4317:4317" # OTLP gRPC
|
||||
- "4318:4318" # OTLP HTTP
|
||||
- "8889:8889" # Prometheus metrics
|
||||
- "13133:13133" # Health check
|
||||
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:
|
||||
- server
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- ophion
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:13133/health"]
|
||||
interval: 10s
|
||||
@@ -143,14 +100,92 @@ services:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 128M
|
||||
<<: *ophion-common
|
||||
|
||||
# ─────────────────────────────────────────────────────────
|
||||
# 🐘 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:
|
||||
ophion:
|
||||
driver: bridge
|
||||
name: ophion-network
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
clickhouse_data:
|
||||
redis_data:
|
||||
otel_agents:
|
||||
name: ophion-otel-agents
|
||||
|
||||
347
docs/QUICK_START.md
Normal file
347
docs/QUICK_START.md
Normal 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
405
instrument.sh
Executable 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)"
|
||||
Reference in New Issue
Block a user