Add initial project structure and configuration for monitoring suite
- Create .gitignore to exclude Python-generated files and virtual environments - Add .python-version for Python version management - Initialize README.md with project description and usage instructions - Implement alloy.river configuration for Grafana Alloy observability - Set up grafana.ini for Grafana configuration - Configure dashboards.yml for automatic dashboard loading in Grafana - Define datasources.yml for connecting Grafana to Prometheus, Loki, and Tempo - Establish loki.yaml configuration for Loki logging - Set up prometheus.yml for Prometheus metrics collection - Configure tempo.yaml for Tempo tracing - Create docker-compose.yml for orchestrating services - Develop init.sh script for initializing project directories and services - Implement main.py as the entry point for the application - Define pyproject.toml for project metadata and dependencies - Update uv.lock for dependency management
This commit is contained in:
+12
@@ -0,0 +1,12 @@
|
||||
# Python-generated files
|
||||
__pycache__/
|
||||
*.py[oc]
|
||||
build/
|
||||
dist/
|
||||
wheels/
|
||||
*.egg-info
|
||||
|
||||
# Virtual environments
|
||||
.venv
|
||||
|
||||
data
|
||||
@@ -0,0 +1 @@
|
||||
3.13
|
||||
@@ -0,0 +1,147 @@
|
||||
# Suite de Monitoreo con Grafana, Prometheus y Mimir
|
||||
|
||||
Esta configuraci�n incluye un stack completo de monitoreo con:
|
||||
- **Prometheus**: Recolecci�n de m�tricas
|
||||
- **Mimir**: Almacenamiento de m�tricas a largo plazo
|
||||
- **Grafana**: Visualizaci�n y dashboards
|
||||
|
||||
## Estructura de Archivos
|
||||
|
||||
|
||||
## Uso
|
||||
|
||||
### Iniciar los servicios
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Verificar estado
|
||||
```bash
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
### Ver logs
|
||||
```bash
|
||||
# Todos los servicios
|
||||
docker-compose logs -f
|
||||
|
||||
# Servicio espec�fico
|
||||
docker-compose logs -f grafana
|
||||
docker-compose logs -f prometheus
|
||||
docker-compose logs -f mimir
|
||||
```
|
||||
|
||||
### Detener los servicios
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
## Acceso a los Servicios
|
||||
|
||||
- **Grafana**: http://localhost:3000
|
||||
- Usuario: `admin`
|
||||
- Contrase�a: `admin`
|
||||
|
||||
- **Prometheus**: http://localhost:9090
|
||||
|
||||
- **Mimir**: http://localhost:9009
|
||||
|
||||
## Configuraci�n
|
||||
|
||||
### Modificar Configuraciones
|
||||
|
||||
Todos los archivos de configuraci�n est�n en la carpeta `config/` y pueden editarse directamente:
|
||||
|
||||
1. **Prometheus** (`config/prometheus/prometheus.yml`):
|
||||
- Agregar nuevos targets de scraping
|
||||
- Configurar reglas de alertas
|
||||
- Modificar intervalos de recolecci�n
|
||||
|
||||
2. **Mimir** (`config/mimir/mimir.yml`):
|
||||
- Ajustar l�mites de series
|
||||
- Configurar almacenamiento
|
||||
- Modificar configuraci�n de cluster
|
||||
|
||||
3. **Grafana** (`config/grafana/grafana.ini`):
|
||||
- Cambiar configuraci�n de seguridad
|
||||
- Configurar autenticaci�n
|
||||
- Ajustar configuraci�n de la base de datos
|
||||
|
||||
### Aplicar Cambios
|
||||
|
||||
Despu�s de modificar las configuraciones:
|
||||
|
||||
```bash
|
||||
# Reiniciar servicios espec�ficos
|
||||
docker-compose restart prometheus
|
||||
docker-compose restart mimir
|
||||
docker-compose restart grafana
|
||||
|
||||
# O reiniciar todo
|
||||
docker-compose restart
|
||||
```
|
||||
|
||||
### Agregar Fuentes de Datos
|
||||
|
||||
Edita `config/grafana/provisioning/datasources/datasources.yml` para agregar nuevas fuentes de datos autom�ticamente.
|
||||
|
||||
### Cargar Dashboards
|
||||
|
||||
Coloca archivos JSON de dashboards en `data/grafana/dashboards/` y se cargar�n autom�ticamente.
|
||||
|
||||
## Flujo de Datos
|
||||
|
||||
1. **Prometheus** recolecta m�tricas de los targets configurados
|
||||
2. **Prometheus** env�a las m�tricas a **Mimir** via remote_write
|
||||
3. **Grafana** consulta tanto **Prometheus** (datos recientes) como **Mimir** (datos hist�ricos)
|
||||
|
||||
## Personalizaci�n
|
||||
|
||||
### Agregar Node Exporter
|
||||
|
||||
Descomenta las l�neas en `config/prometheus/prometheus.yml` y agrega al docker-compose:
|
||||
|
||||
```yaml
|
||||
node-exporter:
|
||||
image: prom/node-exporter:latest
|
||||
container_name: node-exporter
|
||||
ports:
|
||||
- "9100:9100"
|
||||
networks:
|
||||
- monitoring
|
||||
```
|
||||
|
||||
### Agregar Alertmanager
|
||||
|
||||
Descomenta las l�neas en `config/prometheus/prometheus.yml` y agrega al docker-compose:
|
||||
|
||||
```yaml
|
||||
alertmanager:
|
||||
image: prom/alertmanager:latest
|
||||
container_name: alertmanager
|
||||
ports:
|
||||
- "9093:9093"
|
||||
networks:
|
||||
- monitoring
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Verificar conectividad
|
||||
```bash
|
||||
# Ping entre contenedores
|
||||
docker exec prometheus ping mimir
|
||||
docker exec grafana ping prometheus
|
||||
```
|
||||
|
||||
### Verificar configuraci�n de Prometheus
|
||||
```bash
|
||||
# Verificar sintaxis de configuraci�n
|
||||
docker exec prometheus promtool check config /etc/prometheus/prometheus.yml
|
||||
```
|
||||
|
||||
### Verificar configuraci�n de Mimir
|
||||
```bash
|
||||
# Ver configuraci�n activa
|
||||
curl http://localhost:9009/config
|
||||
```
|
||||
@@ -0,0 +1,207 @@
|
||||
//=============================================================================
|
||||
// GRAFANA ALLOY - PUERTA DE ENTRADA ÚNICA DE OBSERVABILIDAD
|
||||
//=============================================================================
|
||||
|
||||
//=============================================================================
|
||||
// PROMETHEUS - MÉTRICAS
|
||||
//=============================================================================
|
||||
|
||||
// Scraping del propio Alloy
|
||||
prometheus.scrape "alloy" {
|
||||
targets = [{"__address__" = "localhost:12345"}]
|
||||
forward_to = [prometheus.remote_write.prometheus.receiver]
|
||||
scrape_interval = "15s"
|
||||
metrics_path = "/metrics"
|
||||
job_name = "alloy"
|
||||
}
|
||||
|
||||
// Scraping de Prometheus
|
||||
prometheus.scrape "prometheus" {
|
||||
targets = [{"__address__" = "prometheus:9090"}]
|
||||
forward_to = [prometheus.remote_write.prometheus.receiver]
|
||||
scrape_interval = "15s"
|
||||
metrics_path = "/metrics"
|
||||
job_name = "prometheus"
|
||||
}
|
||||
|
||||
// Scraping de Grafana
|
||||
prometheus.scrape "grafana" {
|
||||
targets = [{"__address__" = "grafana:3000"}]
|
||||
forward_to = [prometheus.remote_write.prometheus.receiver]
|
||||
scrape_interval = "30s"
|
||||
metrics_path = "/metrics"
|
||||
job_name = "grafana"
|
||||
}
|
||||
|
||||
// Scraping de Loki
|
||||
prometheus.scrape "loki" {
|
||||
targets = [{"__address__" = "loki:3100"}]
|
||||
forward_to = [prometheus.remote_write.prometheus.receiver]
|
||||
scrape_interval = "15s"
|
||||
metrics_path = "/metrics"
|
||||
job_name = "loki"
|
||||
}
|
||||
|
||||
// Scraping de Tempo
|
||||
prometheus.scrape "tempo" {
|
||||
targets = [{"__address__" = "tempo:3200"}]
|
||||
forward_to = [prometheus.remote_write.prometheus.receiver]
|
||||
scrape_interval = "15s"
|
||||
metrics_path = "/metrics"
|
||||
job_name = "tempo"
|
||||
}
|
||||
|
||||
// Receptor para métricas externas (aplicaciones que envían métricas)
|
||||
prometheus.receive_http "external_metrics" {
|
||||
http {
|
||||
listen_address = "0.0.0.0"
|
||||
listen_port = 9999
|
||||
}
|
||||
forward_to = [prometheus.remote_write.prometheus.receiver]
|
||||
}
|
||||
|
||||
// Remote write a Prometheus
|
||||
prometheus.remote_write "prometheus" {
|
||||
endpoint {
|
||||
url = "http://prometheus:9090/api/v1/write"
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// LOKI - LOGS
|
||||
//=============================================================================
|
||||
|
||||
// Descubrimiento de contenedores Docker
|
||||
discovery.docker "docker_logs" {
|
||||
host = "unix:///var/run/docker.sock"
|
||||
refresh_interval = "5s"
|
||||
}
|
||||
|
||||
// Fuente de logs de contenedores Docker
|
||||
loki.source.docker "containers" {
|
||||
host = "unix:///var/run/docker.sock"
|
||||
targets = discovery.docker.docker_logs.targets
|
||||
refresh_interval = "5s"
|
||||
forward_to = [loki.relabel.docker.receiver]
|
||||
}
|
||||
|
||||
// Relabel para contenedores Docker
|
||||
loki.relabel "docker" {
|
||||
forward_to = [loki.write.loki.receiver]
|
||||
|
||||
rule {
|
||||
source_labels = ["__meta_docker_container_name"]
|
||||
target_label = "container"
|
||||
}
|
||||
|
||||
rule {
|
||||
source_labels = ["__meta_docker_container_image"]
|
||||
target_label = "image"
|
||||
}
|
||||
}
|
||||
|
||||
// Receptor HTTP para logs externos
|
||||
loki.source.api "external_logs" {
|
||||
http {
|
||||
listen_address = "0.0.0.0"
|
||||
listen_port = 3101
|
||||
}
|
||||
forward_to = [loki.write.loki.receiver]
|
||||
}
|
||||
|
||||
// Receptor Syslog para logs del sistema
|
||||
loki.source.syslog "system_logs" {
|
||||
listener {
|
||||
address = "0.0.0.0:1514"
|
||||
protocol = "tcp"
|
||||
}
|
||||
forward_to = [loki.relabel.syslog.receiver]
|
||||
}
|
||||
|
||||
// Relabel para logs del sistema
|
||||
loki.relabel "syslog" {
|
||||
forward_to = [loki.write.loki.receiver]
|
||||
|
||||
rule {
|
||||
source_labels = ["__syslog_message_hostname"]
|
||||
target_label = "hostname"
|
||||
}
|
||||
}
|
||||
|
||||
// Cliente Loki - destino final
|
||||
loki.write "loki" {
|
||||
endpoint {
|
||||
url = "http://loki:3100/loki/api/v1/push"
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// TEMPO - TRAZAS
|
||||
//=============================================================================
|
||||
|
||||
// Receptor OTLP
|
||||
otelcol.receiver.otlp "tempo" {
|
||||
grpc {
|
||||
endpoint = "0.0.0.0:4317"
|
||||
}
|
||||
http {
|
||||
endpoint = "0.0.0.0:4318"
|
||||
}
|
||||
output {
|
||||
traces = [otelcol.processor.batch.tempo.input]
|
||||
}
|
||||
}
|
||||
|
||||
// Receptor Jaeger
|
||||
otelcol.receiver.jaeger "jaeger_traces" {
|
||||
protocols {
|
||||
grpc {
|
||||
endpoint = "0.0.0.0:14250"
|
||||
}
|
||||
thrift_http {
|
||||
endpoint = "0.0.0.0:14268"
|
||||
}
|
||||
thrift_compact {
|
||||
endpoint = "0.0.0.0:6831"
|
||||
}
|
||||
}
|
||||
output {
|
||||
traces = [otelcol.processor.batch.tempo.input]
|
||||
}
|
||||
}
|
||||
|
||||
// Receptor Zipkin
|
||||
otelcol.receiver.zipkin "zipkin_traces" {
|
||||
endpoint = "0.0.0.0:9411"
|
||||
output {
|
||||
traces = [otelcol.processor.batch.tempo.input]
|
||||
}
|
||||
}
|
||||
|
||||
// Procesador batch
|
||||
otelcol.processor.batch "tempo" {
|
||||
send_batch_size = 1024
|
||||
timeout = "1s"
|
||||
output {
|
||||
traces = [otelcol.exporter.otlp.tempo.input]
|
||||
}
|
||||
}
|
||||
|
||||
// Exportador a Tempo
|
||||
otelcol.exporter.otlp "tempo" {
|
||||
client {
|
||||
endpoint = "http://tempo:4317"
|
||||
tls {
|
||||
insecure = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// CONFIGURACIÓN GENERAL
|
||||
//=============================================================================
|
||||
|
||||
logging {
|
||||
level = "info"
|
||||
format = "logfmt"
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
# Configuración principal de Grafana
|
||||
# Puedes editar este archivo para personalizar Grafana
|
||||
|
||||
[server]
|
||||
# Puerto HTTP
|
||||
http_port = 3000
|
||||
# Dominio de la aplicación
|
||||
domain = localhost
|
||||
# URL raíz
|
||||
root_url = http://localhost:3000/
|
||||
|
||||
[database]
|
||||
# Tipo de base de datos (sqlite3, mysql, postgres)
|
||||
type = sqlite3
|
||||
# Ruta de la base de datos SQLite
|
||||
path = /var/lib/grafana/grafana.db
|
||||
|
||||
[security]
|
||||
# Usuario administrador por defecto
|
||||
admin_user = admin
|
||||
# Contraseña administrador por defecto
|
||||
admin_password = admin123
|
||||
# Clave secreta para cookies
|
||||
secret_key = your_secret_key_here
|
||||
|
||||
[users]
|
||||
# Permitir registro de usuarios
|
||||
allow_sign_up = false
|
||||
# Permitir que los usuarios creen organizaciones
|
||||
allow_org_create = false
|
||||
# Asignación automática de organización
|
||||
auto_assign_org = true
|
||||
# Rol por defecto para nuevos usuarios
|
||||
auto_assign_org_role = Viewer
|
||||
|
||||
[auth.anonymous]
|
||||
# Habilitar acceso anónimo
|
||||
enabled = false
|
||||
|
||||
[logging]
|
||||
# Nivel de logging (debug, info, warn, error)
|
||||
level = info
|
||||
# Formato de logging (console, json)
|
||||
format = console
|
||||
|
||||
[metrics]
|
||||
# Habilitar métricas internas de Grafana
|
||||
enabled = true
|
||||
# Intervalo de recolección de métricas
|
||||
interval_seconds = 10
|
||||
|
||||
[unified_alerting]
|
||||
# Habilitar nuevo sistema de alertas
|
||||
enabled = true
|
||||
|
||||
[explore]
|
||||
# Habilitar el modo Explore
|
||||
enabled = true
|
||||
|
||||
[feature_toggles]
|
||||
# Habilitar características experimentales
|
||||
enable = newPanelChromeUI
|
||||
|
||||
[panels]
|
||||
# Deshabilitar sanitización de HTML en paneles de texto
|
||||
disable_sanitize_html = false
|
||||
|
||||
[plugins]
|
||||
# Permitir carga de plugins sin firma
|
||||
allow_loading_unsigned_plugins = false
|
||||
# Habilitar plugins por defecto
|
||||
enable_alpha = false
|
||||
@@ -0,0 +1,29 @@
|
||||
# Configuración de dashboards para Grafana
|
||||
# Puedes editar este archivo para configurar la carga automática de dashboards
|
||||
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
# Proveedor principal de dashboards
|
||||
- name: 'default'
|
||||
orgId: 1
|
||||
folder: ''
|
||||
type: file
|
||||
disableDeletion: false
|
||||
editable: true
|
||||
updateIntervalSeconds: 10
|
||||
allowUiUpdates: true
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards
|
||||
|
||||
# Proveedor para dashboards de sistema
|
||||
- name: 'system'
|
||||
orgId: 1
|
||||
folder: 'System'
|
||||
type: file
|
||||
disableDeletion: false
|
||||
editable: true
|
||||
updateIntervalSeconds: 10
|
||||
allowUiUpdates: true
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards/system
|
||||
@@ -0,0 +1,94 @@
|
||||
apiVersion: 1
|
||||
|
||||
# Configuración automática de datasources para Grafana
|
||||
# Conexión directa a Prometheus, Loki y Tempo
|
||||
datasources:
|
||||
# Prometheus para métricas
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://prometheus:9090
|
||||
uid: prometheus
|
||||
isDefault: true
|
||||
editable: false
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
prometheusType: Prometheus
|
||||
prometheusVersion: 2.40.0
|
||||
cacheLevel: 'High'
|
||||
disableRecordingRules: false
|
||||
incrementalQueryOverlapWindow: 10m
|
||||
exemplarTraceIdDestinations:
|
||||
- name: TraceID
|
||||
datasourceUid: tempo
|
||||
urlDisplayLabel: "View Trace"
|
||||
|
||||
# Loki para logs
|
||||
- name: Loki
|
||||
type: loki
|
||||
access: proxy
|
||||
url: http://loki:3100
|
||||
uid: loki
|
||||
editable: false
|
||||
jsonData:
|
||||
maxLines: 1000
|
||||
derivedFields:
|
||||
- datasourceUid: tempo
|
||||
matcherRegex: "(?:traceID|trace_id|traceid)=([A-Fa-f0-9]+)"
|
||||
name: TraceID
|
||||
url: "$${__value.raw}"
|
||||
urlDisplayLabel: "View Trace"
|
||||
|
||||
# Tempo para trazas
|
||||
- name: Tempo
|
||||
type: tempo
|
||||
access: proxy
|
||||
url: http://tempo:3200
|
||||
uid: tempo
|
||||
editable: false
|
||||
jsonData:
|
||||
httpMethod: GET
|
||||
tracesToLogs:
|
||||
datasourceUid: loki
|
||||
tags: ['job', 'instance', 'pod', 'namespace', 'container']
|
||||
mappedTags: [
|
||||
{
|
||||
key: 'service.name',
|
||||
value: 'service'
|
||||
},
|
||||
{
|
||||
key: 'container.name',
|
||||
value: 'container'
|
||||
}
|
||||
]
|
||||
mapTagNamesEnabled: true
|
||||
spanStartTimeShift: '1h'
|
||||
spanEndTimeShift: '1h'
|
||||
filterByTraceID: true
|
||||
filterBySpanID: false
|
||||
tracesToMetrics:
|
||||
datasourceUid: prometheus
|
||||
tags: [
|
||||
{
|
||||
key: 'service.name',
|
||||
value: 'service'
|
||||
},
|
||||
{
|
||||
key: 'job'
|
||||
}
|
||||
]
|
||||
queries:
|
||||
- name: 'Request Rate'
|
||||
query: 'rate(traces_service_graph_request_total{$$__tags}[5m])'
|
||||
- name: 'Error Rate'
|
||||
query: 'rate(traces_service_graph_request_failed_total{$$__tags}[5m])'
|
||||
- name: 'Duration P99'
|
||||
query: 'histogram_quantile(0.99, rate(traces_spanmetrics_latency_bucket{$$__tags}[5m]))'
|
||||
serviceMap:
|
||||
datasourceUid: prometheus
|
||||
search:
|
||||
hide: false
|
||||
nodeGraph:
|
||||
enabled: true
|
||||
lokiSearch:
|
||||
datasourceUid: loki
|
||||
@@ -0,0 +1,50 @@
|
||||
auth_enabled: false
|
||||
|
||||
server:
|
||||
http_listen_port: 3100
|
||||
grpc_listen_port: 9096
|
||||
|
||||
common:
|
||||
instance_addr: 127.0.0.1
|
||||
path_prefix: /loki
|
||||
storage:
|
||||
filesystem:
|
||||
chunks_directory: /loki/chunks
|
||||
rules_directory: /loki/rules
|
||||
replication_factor: 1
|
||||
ring:
|
||||
kvstore:
|
||||
store: inmemory
|
||||
|
||||
query_range:
|
||||
results_cache:
|
||||
cache:
|
||||
embedded_cache:
|
||||
enabled: true
|
||||
max_size_mb: 100
|
||||
|
||||
schema_config:
|
||||
configs:
|
||||
- from: 2020-10-24
|
||||
store: tsdb
|
||||
object_store: filesystem
|
||||
schema: v13
|
||||
index:
|
||||
prefix: index_
|
||||
period: 24h
|
||||
|
||||
ruler:
|
||||
alertmanager_url: http://localhost:9093
|
||||
|
||||
# By default, Loki will send anonymous, but uniquely-identifiable usage and configuration
|
||||
# analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/
|
||||
#
|
||||
# Statistics help us better understand how Loki is used, and they show us performance
|
||||
# levels for most users. This helps us prioritize features and documentation.
|
||||
# For more information on what's sent, look at
|
||||
# https://github.com/grafana/loki/blob/main/pkg/usagestats/stats.go
|
||||
# Refer to the buildReport method to see what goes into a report.
|
||||
#
|
||||
# If you would like to disable reporting, uncomment the following lines:
|
||||
analytics:
|
||||
reporting_enabled: false
|
||||
@@ -0,0 +1,23 @@
|
||||
# Configuración de Prometheus - Solo remote write desde Alloy
|
||||
# Alloy es la única puerta de entrada para métricas
|
||||
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
evaluation_interval: 15s
|
||||
external_labels:
|
||||
cluster: 'development'
|
||||
replica: 'prometheus-01'
|
||||
|
||||
# Configuración de reglas de alertas
|
||||
rule_files:
|
||||
- "rules/*.yml"
|
||||
|
||||
# Sin scrapers directos - Todo viene desde Alloy via remote_write
|
||||
scrape_configs: []
|
||||
|
||||
# Configuración de Alertmanager (descomenta si tienes Alertmanager)
|
||||
# alerting:
|
||||
# alertmanagers:
|
||||
# - static_configs:
|
||||
# - targets:
|
||||
# - alertmanager:9093
|
||||
@@ -0,0 +1,46 @@
|
||||
server:
|
||||
http_listen_port: 3200
|
||||
grpc_listen_port: 9095
|
||||
|
||||
distributor:
|
||||
receivers:
|
||||
otlp:
|
||||
protocols:
|
||||
grpc:
|
||||
endpoint: 0.0.0.0:4317
|
||||
http:
|
||||
endpoint: 0.0.0.0:4318
|
||||
|
||||
ingester:
|
||||
max_block_duration: 5m
|
||||
|
||||
compactor:
|
||||
compaction:
|
||||
block_retention: 1h
|
||||
|
||||
storage:
|
||||
trace:
|
||||
backend: local
|
||||
local:
|
||||
path: /tmp/tempo/traces
|
||||
wal:
|
||||
path: /tmp/tempo/wal
|
||||
pool:
|
||||
max_workers: 100
|
||||
queue_depth: 10000
|
||||
|
||||
query_frontend:
|
||||
search:
|
||||
duration_slo: 5s
|
||||
throughput_bytes_slo: 1.073741824e+09
|
||||
trace_by_id:
|
||||
duration_slo: 5s
|
||||
|
||||
metrics_generator:
|
||||
registry:
|
||||
external_labels:
|
||||
source: tempo
|
||||
cluster: docker-compose
|
||||
storage:
|
||||
path: /tmp/tempo/generator/wal
|
||||
# Sin remote_write directo - las métricas van a través de Alloy
|
||||
@@ -0,0 +1,118 @@
|
||||
services:
|
||||
# Prometheus para métricas
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
container_name: prometheus
|
||||
ports:
|
||||
- "9090:9090"
|
||||
volumes:
|
||||
- ./config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- ./data/prometheus:/prometheus
|
||||
command:
|
||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||
- '--storage.tsdb.path=/prometheus'
|
||||
- '--web.enable-lifecycle'
|
||||
- '--web.enable-admin-api'
|
||||
- '--web.enable-remote-write-receiver'
|
||||
user: "65534:65534"
|
||||
networks:
|
||||
- monitoring
|
||||
restart: unless-stopped
|
||||
|
||||
# Loki para logs
|
||||
loki:
|
||||
image: grafana/loki:latest
|
||||
container_name: loki
|
||||
ports:
|
||||
- "3100:3100"
|
||||
volumes:
|
||||
- ./config/loki/loki.yaml:/etc/loki/local-config.yaml
|
||||
- ./data/loki:/loki
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
networks:
|
||||
- monitoring
|
||||
restart: unless-stopped
|
||||
|
||||
# Tempo para trazas - Solo almacenamiento (Alloy maneja la recolección)
|
||||
tempo:
|
||||
image: grafana/tempo:latest
|
||||
container_name: tempo
|
||||
ports:
|
||||
- "3200:3200" # Solo puerto de consulta, sin endpoints de recepción
|
||||
volumes:
|
||||
- ./config/tempo/tempo.yaml:/etc/tempo/tempo.yaml
|
||||
- ./data/tempo:/tmp/tempo
|
||||
command:
|
||||
- -config.file=/etc/tempo/tempo.yaml
|
||||
networks:
|
||||
- monitoring
|
||||
restart: unless-stopped
|
||||
|
||||
# Grafana Alloy para colección de datos - ÚNICA PUERTA DE ENTRADA
|
||||
alloy:
|
||||
image: grafana/alloy:latest
|
||||
container_name: alloy
|
||||
ports:
|
||||
- "12345:12345" # Puerto para la UI de Alloy
|
||||
# Puertos para métricas
|
||||
- "9999:9999" # HTTP receiver para métricas externas
|
||||
# Puertos para logs
|
||||
- "3101:3101" # HTTP receiver para logs externos
|
||||
- "1514:1514" # Syslog TCP receiver
|
||||
# Puertos para trazas - OpenTelemetry
|
||||
- "4317:4317" # OTLP gRPC (ya expuesto en tempo, redirigido aquí)
|
||||
- "4318:4318" # OTLP HTTP (ya expuesto en tempo, redirigido aquí)
|
||||
# Puertos para trazas - Jaeger compatibility
|
||||
- "14250:14250" # Jaeger gRPC
|
||||
- "14268:14268" # Jaeger HTTP
|
||||
- "6831:6831/udp" # Jaeger compact thrift
|
||||
# Puertos para trazas - Zipkin compatibility
|
||||
- "9411:9411" # Zipkin HTTP
|
||||
volumes:
|
||||
- ./config/alloy/alloy.river:/etc/alloy/config.river
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- /proc:/host/proc:ro
|
||||
- /sys:/host/sys:ro
|
||||
- /:/rootfs:ro
|
||||
command:
|
||||
- run
|
||||
- --server.http.listen-addr=0.0.0.0:12345
|
||||
- /etc/alloy/config.river
|
||||
environment:
|
||||
- ALLOY_HOSTNAME=alloy
|
||||
networks:
|
||||
- monitoring
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- prometheus
|
||||
- loki
|
||||
- tempo
|
||||
|
||||
# Grafana para visualización
|
||||
grafana:
|
||||
image: grafana/grafana:latest
|
||||
container_name: grafana
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_USER=admin
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin123
|
||||
- GF_PATHS_DATA=/var/lib/grafana
|
||||
- GF_PATHS_LOGS=/var/log/grafana
|
||||
- GF_PATHS_PLUGINS=/var/lib/grafana/plugins
|
||||
- GF_PATHS_PROVISIONING=/etc/grafana/provisioning
|
||||
volumes:
|
||||
- ./config/grafana/provisioning:/etc/grafana/provisioning
|
||||
- ./data/grafana:/var/lib/grafana
|
||||
user: "472:472"
|
||||
networks:
|
||||
- monitoring
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- prometheus
|
||||
- loki
|
||||
- tempo
|
||||
|
||||
networks:
|
||||
monitoring:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,159 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script de inicialización para Suite de Monitoreo
|
||||
# Configura permisos y estructura de directorios para Prometheus, Loki, Tempo y Grafana
|
||||
|
||||
set -e # Salir si hay errores
|
||||
|
||||
echo "🚀 Iniciando configuración de Suite de Monitoreo..."
|
||||
|
||||
# Colores para output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Función para imprimir mensajes
|
||||
print_status() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[ÉXITO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[ADVERTENCIA]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Verificar que estamos en el directorio correcto
|
||||
if [ ! -f "docker-compose.yml" ]; then
|
||||
print_error "No se encontró docker-compose.yml. Ejecuta este script desde el directorio del proyecto."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Parar contenedores existentes si están corriendo
|
||||
print_status "Parando contenedores existentes..."
|
||||
docker-compose down 2>/dev/null || true
|
||||
|
||||
# Eliminar directorio data existente
|
||||
if [ -d "data" ]; then
|
||||
print_status "Eliminando directorio data existente..."
|
||||
rm -rf data/
|
||||
print_success "Directorio data eliminado"
|
||||
fi
|
||||
|
||||
# Crear estructura de directorios
|
||||
print_status "Creando estructura de directorios..."
|
||||
mkdir -p data/{prometheus,loki,tempo,grafana}
|
||||
|
||||
# Crear subdirectorios específicos necesarios
|
||||
mkdir -p data/loki/{chunks,wal,rules}
|
||||
mkdir -p data/tempo/traces
|
||||
mkdir -p data/prometheus/{data,wal}
|
||||
mkdir -p data/grafana/{data,logs,plugins}
|
||||
|
||||
print_success "Estructura de directorios creada"
|
||||
|
||||
# Configurar permisos
|
||||
print_status "Configurando permisos..."
|
||||
|
||||
# Dar permisos amplios temporalmente para permitir que los contenedores configuren sus propios permisos
|
||||
chmod -R 777 data/
|
||||
|
||||
print_success "Permisos configurados"
|
||||
|
||||
# Verificar que Docker esté disponible
|
||||
if ! command -v docker &> /dev/null; then
|
||||
print_error "Docker no está instalado o no está en el PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
print_error "Docker Compose no está instalado o no está en el PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verificar que Docker esté corriendo
|
||||
if ! docker info &> /dev/null; then
|
||||
print_error "Docker no está corriendo. Inicia Docker e intenta de nuevo."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Iniciar servicios
|
||||
print_status "Iniciando servicios..."
|
||||
docker-compose up -d
|
||||
|
||||
print_success "Servicios iniciados"
|
||||
|
||||
# Esperar a que los servicios estén listos
|
||||
print_status "Esperando a que los servicios estén listos..."
|
||||
sleep 5
|
||||
|
||||
# Verificar estado de los servicios
|
||||
print_status "Verificando estado de los servicios..."
|
||||
|
||||
# Función para verificar si un servicio está saludable
|
||||
check_service() {
|
||||
local service_name=$1
|
||||
local port=$2
|
||||
local container_name=$3
|
||||
|
||||
if docker ps | grep -q "$container_name.*Up"; then
|
||||
print_success "$service_name está ejecutándose correctamente"
|
||||
return 0
|
||||
else
|
||||
print_warning "$service_name podría tener problemas"
|
||||
echo "Logs de $service_name:"
|
||||
docker logs "$container_name" --tail 5
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Verificar cada servicio
|
||||
check_service "Prometheus" "9090" "prometheus"
|
||||
check_service "Loki" "3100" "loki"
|
||||
check_service "Tempo" "3200" "tempo"
|
||||
check_service "Grafana" "3000" "grafana"
|
||||
check_service "Alloy" "12345" "alloy"
|
||||
|
||||
echo ""
|
||||
echo "🎉 ¡Configuración completada!"
|
||||
echo ""
|
||||
echo -e "${GREEN}Servicios disponibles:${NC}"
|
||||
echo -e " 📊 Grafana Dashboard: ${BLUE}http://localhost:3000${NC} (admin/admin123)"
|
||||
echo -e " 📈 Prometheus: ${BLUE}http://localhost:9090${NC}"
|
||||
echo -e " 📋 Loki: ${BLUE}http://localhost:3100${NC}"
|
||||
echo -e " 🔍 Tempo: ${BLUE}http://localhost:3200${NC}"
|
||||
echo -e " 🤖 Alloy UI: ${BLUE}http://localhost:12345${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}🚪 Alloy - Única puerta de entrada para datos:${NC}"
|
||||
echo -e "${YELLOW}📊 Envío de métricas:${NC}"
|
||||
echo -e " • Remote Write: ${BLUE}http://localhost:9999/api/v1/write${NC}"
|
||||
echo -e " • Prometheus compatible: ${BLUE}http://localhost:9999/metrics${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}📋 Envío de logs:${NC}"
|
||||
echo -e " • HTTP API: ${BLUE}http://localhost:3101/loki/api/v1/push${NC}"
|
||||
echo -e " • Syslog TCP: ${BLUE}localhost:1514${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}🔍 Envío de trazas:${NC}"
|
||||
echo -e " • OTLP gRPC: ${BLUE}http://localhost:4317${NC}"
|
||||
echo -e " • OTLP HTTP: ${BLUE}http://localhost:4318/v1/traces${NC}"
|
||||
echo -e " • Jaeger gRPC: ${BLUE}localhost:14250${NC}"
|
||||
echo -e " • Jaeger HTTP: ${BLUE}http://localhost:14268/api/traces${NC}"
|
||||
echo -e " • Jaeger UDP: ${BLUE}localhost:6831${NC}"
|
||||
echo -e " • Zipkin: ${BLUE}http://localhost:9411/api/v2/spans${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Comandos útiles:${NC}"
|
||||
echo -e " Ver logs: ${BLUE}docker-compose logs [servicio]${NC}"
|
||||
echo -e " Parar servicios: ${BLUE}docker-compose down${NC}"
|
||||
echo -e " Reiniciar servicios: ${BLUE}docker-compose restart${NC}"
|
||||
echo -e " Estado de servicios: ${BLUE}docker-compose ps${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}✨ Configuración centralizada: Alloy recolecta todo y distribuye a Prometheus, Loki y Tempo${NC}"
|
||||
echo ""
|
||||
@@ -0,0 +1,6 @@
|
||||
def main():
|
||||
print("Hello from suite-logs!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,9 @@
|
||||
[project]
|
||||
name = "suite-logs"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"prometheus-client>=0.23.1",
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.13"
|
||||
|
||||
[[package]]
|
||||
name = "prometheus-client"
|
||||
version = "0.23.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/23/53/3edb5d68ecf6b38fcbcc1ad28391117d2a322d9a1a3eff04bfdb184d8c3b/prometheus_client-0.23.1.tar.gz", hash = "sha256:6ae8f9081eaaaf153a2e959d2e6c4f4fb57b12ef76c8c7980202f1e57b48b2ce", size = 80481, upload-time = "2025-09-18T20:47:25.043Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl", hash = "sha256:dd1913e6e76b59cfe44e7a4b83e01afc9873c1bdfd2ed8739f1e76aeca115f99", size = 61145, upload-time = "2025-09-18T20:47:23.875Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "suite-logs"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "prometheus-client" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "prometheus-client", specifier = ">=0.23.1" }]
|
||||
Reference in New Issue
Block a user