commit 9966851e7503f3aa1a9e2663d41843cf71caad07 Author: Egutierrez Date: Mon Oct 6 00:52:31 2025 +0200 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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..899bead --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv + +data \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/README.md b/README.md new file mode 100644 index 0000000..7ec0c3c --- /dev/null +++ b/README.md @@ -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 +``` \ No newline at end of file diff --git a/config/alloy/alloy.river b/config/alloy/alloy.river new file mode 100644 index 0000000..44dc10f --- /dev/null +++ b/config/alloy/alloy.river @@ -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" +} diff --git a/config/grafana/grafana.ini b/config/grafana/grafana.ini new file mode 100644 index 0000000..2b73a84 --- /dev/null +++ b/config/grafana/grafana.ini @@ -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 \ No newline at end of file diff --git a/config/grafana/provisioning/dashboards.yml b/config/grafana/provisioning/dashboards.yml new file mode 100644 index 0000000..55e7290 --- /dev/null +++ b/config/grafana/provisioning/dashboards.yml @@ -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 \ No newline at end of file diff --git a/config/grafana/provisioning/datasources.yml b/config/grafana/provisioning/datasources.yml new file mode 100644 index 0000000..9e2e24a --- /dev/null +++ b/config/grafana/provisioning/datasources.yml @@ -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 \ No newline at end of file diff --git a/config/loki/loki.yaml b/config/loki/loki.yaml new file mode 100644 index 0000000..286f75b --- /dev/null +++ b/config/loki/loki.yaml @@ -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 \ No newline at end of file diff --git a/config/prometheus/prometheus.yml b/config/prometheus/prometheus.yml new file mode 100644 index 0000000..b09d87c --- /dev/null +++ b/config/prometheus/prometheus.yml @@ -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 \ No newline at end of file diff --git a/config/tempo/tempo.yaml b/config/tempo/tempo.yaml new file mode 100644 index 0000000..bede4c8 --- /dev/null +++ b/config/tempo/tempo.yaml @@ -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 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a71b660 --- /dev/null +++ b/docker-compose.yml @@ -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 diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..95adb6e --- /dev/null +++ b/init.sh @@ -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 "" \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..1f73f74 --- /dev/null +++ b/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from suite-logs!") + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a73d11a --- /dev/null +++ b/pyproject.toml @@ -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", +] diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..c282174 --- /dev/null +++ b/uv.lock @@ -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" }]