add plattform services

This commit is contained in:
Marcel Arndt
2026-01-05 16:01:40 +01:00
parent e25d8dd5d9
commit 193319fa52
65 changed files with 4240 additions and 39 deletions
+33
View File
@@ -0,0 +1,33 @@
networks:
traefik_public:
external: true
services:
dockge:
image: louislam/dockge:1
environment:
- DOCKGE_STACKS_DIR=/opt/stacks
- DOCKGE_DATA_DIR=/app/data
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- '/mnt/cephfs/dockge/data:/app/data'
- '/mnt/cephfs/dockge/stacks:/opt/stacks'
networks:
- traefik_public
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
restart_policy:
condition: on-failure
labels:
- 'traefik.enable=true'
- 'traefik.swarm.network=traefik_public'
# --- Router für Dockge ---
- 'traefik.http.routers.dockge.rule=Host(`dockge.genius.ceo`)'
- 'traefik.http.routers.dockge.entrypoints=https'
- 'traefik.http.routers.dockge.tls.certresolver=main'
# --- Service für Dockge ---
- 'traefik.http.services.dockge.loadbalancer.server.port=5001'
+22
View File
@@ -0,0 +1,22 @@
services:
sd_server:
image: socheatsok78/dockerswarm_sd_server:latest
networks:
- sd_network
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
monitoring:
driver: overlay
attachable: true
ipam:
config:
- subnet: 172.16.201.0/24
sd_network:
driver: overlay
attachable: true
ipam:
config:
- subnet: 172.16.202.0/24
@@ -0,0 +1,139 @@
faro.receiver "stage_app_agent_receiver" {
server {
listen_address = "0.0.0.0"
listen_port = 12347
cors_allowed_origins = ["*"]
// cors_allowed_origins = ["https://avicenna.genius.ceo"]
api_key = "t3stK3y"
max_allowed_payload_size = "10MiB"
rate_limiting {
rate = 100
}
}
sourcemaps {}
output {
logs = [loki.process.logs_process_client.receiver]
traces = [otelcol.exporter.otlp.tempo.input]
}
}
loki.process "logs_process_client" {
forward_to = [loki.write.to_loki.receiver]
stage.logfmt {
mapping = { "kind" = "", "service_name" = "", "app_name" = "", "namespace" = "" }
}
stage.labels {
values = { "kind" = "kind", "service_name" = "service_name", "app" = "app_name", "namespace" = "namespace" }
}
}
otelcol.receiver.otlp "otel_collector" {
grpc {
endpoint = "0.0.0.0:4317"
}
http {
endpoint = "0.0.0.0:4318"
cors {
allowed_origins = ["https://avicenna.genius.ceo/"]
}
}
// Definiert, wohin die empfangenen Daten weitergeleitet werden
output {
metrics = [otelcol.exporter.prometheus.otel_metrics.input]
logs = [otelcol.exporter.loki.otel_logs.input]
traces = [otelcol.exporter.otlp.tempo.input]
}
}
loki.write "to_loki" {
endpoint {
url = "http://loki:3100/loki/api/v1/push"
}
}
prometheus.remote_write "to_prometheus" {
endpoint {
url = "http://prometheus:9090/api/v1/write"
}
}
// Docker-Container auf dem Host entdecken
discovery.docker "logs_integration_docker" {
host = "unix:///var/run/docker.sock"
refresh_interval = "5s"
}
discovery.relabel "logs_integration_docker" {
targets = []
rule {
action = "labelmap"
regex = "__meta_docker_container_label_com_docker_swarm_node_id"
replacement = "node_id"
}
rule {
action = "labelmap"
regex = "__meta_docker_container_label_com_docker_stack_namespace"
replacement = "namespace"
}
rule {
action = "labelmap"
regex = "__meta_docker_container_label_com_docker_swarm_service_name"
replacement = "service_name"
}
rule {
action = "labelmap"
regex = "__meta_docker_container_name"
replacement = "container_name"
}
}
loki.source.docker "logs_from_containers" {
host = "unix:///var/run/docker.sock"
targets = discovery.docker.logs_integration_docker.targets // Nutzt die entdeckten Container
relabel_rules = discovery.relabel.logs_integration_docker.rules
// Leitet die gesammelten Logs an den definierten Loki-Endpunkt weiter
forward_to = [loki.write.to_loki.receiver]
}
otelcol.exporter.otlp "tempo" { // Name kann variieren
client {
endpoint = "tempo:4317" // Ziel: Tempo Service auf Port 4317
tls {
insecure = true // Interne Kommunikation ohne TLS
}
}
}
otelcol.exporter.prometheus "otel_metrics" {
forward_to = [prometheus.remote_write.to_prometheus.receiver]
}
otelcol.exporter.loki "otel_logs" {
forward_to = [loki.write.to_loki.receiver]
}
// Logging für Alloy selbst konfigurieren
logging {
level = "info"
format = "logfmt"
}
// prometheus.scrape "alloy_self" {
// targets = [
// prometheus.target_group {
// targets = [{"__address__" = "localhost:12345"}]
// }
// ]
// forward_to = [...] // An Prometheus Remote Write oder lokalen Agent
// }
@@ -0,0 +1,76 @@
auth_enabled: false # Einfachste Konfiguration ohne Authentifizierung
analytics:
reporting_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096 # Standard gRPC Port für Loki
common:
instance_addr: 127.0.0.1 # Adresse, unter der sich die Instanz meldet
path_prefix: /loki # Wo Loki seine Daten speichert (im Volume)
storage:
filesystem: # Lokales Dateisystem für Indizes und Chunks
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1 # Keine Replikation bei Einzelinstanz
ring:
kvstore:
store: inmemory # Einfachster Ring-Speicher für Einzelinstanz
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
pattern_ingester:
enabled: true
metric_aggregation:
loki_address: localhost:3100
frontend:
encoding: protobuf
limits_config:
metric_aggregation_enabled: true
reject_old_samples: true
reject_old_samples_max_age: 168h # 7 Tage
ingestion_rate_mb: 15 # Erlaube 15 MiB/Sekunde pro Tenant (Standard war 4)
ingestion_burst_size_mb: 30 # Erlaube kurzfristige Bursts bis 30 MiB (Standard war 6)
# Optional: Maximale Anzahl aktiver Log-Streams pro Tenant (Standard ist 10000)
# max_global_streams_per_user: 10000
# Optional: Maximale Größe einer Log-Zeile (Standard 256kB)
# max_line_size: 262144
# --- Optional: Compactor (Bereinigt alte Daten) ---
# compactor:
# working_directory: /loki/compactor
# shared_store: filesystem
# compaction_interval: 10m
# retention_enabled: true
# retention_delete_delay: 2h
# retention_delete_worker_count: 150
# --- Optional: Ruler (für Alerts basierend auf Logs) ---
# ruler:
# alertmanager_url: http://alertmanager:9093 # Pfad zu deinem Alertmanager
# storage:
# type: local
# local:
# directory: /loki/rules
# rule_path: /tmp/loki/rules-temp
# ring:
# kvstore:
# store: inmemory
# enable_api: true
@@ -0,0 +1,57 @@
global:
scrape_interval: 15s # Wie oft Ziele abgefragt werden
evaluation_interval: 15s # Wie oft Regeln ausgewertet werden
scrape_configs:
- job_name: 'prometheus'
# Prometheus überwacht sich selbst
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
# Docker Swarm Service Discovery für den Node Exporter
dockerswarm_sd_configs:
- host: unix:///var/run/docker.sock
role: tasks
port: 9100 # Standard-Port vom Node Exporter
relabel_configs:
# Nur Tasks im Zustand 'running' verwenden
- source_labels: [__meta_dockerswarm_task_desired_state]
regex: running
action: keep
# Nur Tasks des 'node-exporter' Services aus diesem Stack auswählen
# Passe den Regex ggf. an, wenn dein Stack anders heißt (hier Annahme: Stack-Name enthält 'monitoring')
- source_labels: [__meta_dockerswarm_service_name]
regex: ^monitoring_node-exporter$ # Regex an Stack-Namen anpassen!
action: keep
# Verwende den Hostnamen des Swarm Nodes als Instance Label
- source_labels: [__meta_dockerswarm_node_hostname]
target_label: instance
# Setze die Zieladresse korrekt auf IP:Port
- source_labels: [__address__]
regex: '(.*):.*' # Extrahiere die IP-Adresse
replacement: '${1}:9100' # Setze den korrekten Port (9100)
target_label: __address__
- job_name: 'cadvisor'
dockerswarm_sd_configs:
- host: unix:///var/run/docker.sock
role: tasks
port: 8080 # Standard-Port von cAdvisor
relabel_configs:
# Nur Tasks im Zustand 'running' verwenden
- source_labels: [__meta_dockerswarm_task_desired_state]
regex: running
action: keep
# Nur Tasks des 'cadvisor' Services aus diesem Stack auswählen
# Passe den Regex an deinen Stack-Namen an!
- source_labels: [__meta_dockerswarm_service_name]
regex: .*(monitoring|mon)_cadvisor.* # Regex an Stack-Namen anpassen!
action: keep
# Verwende den Hostnamen des Swarm Nodes als Instance Label
- source_labels: [__meta_dockerswarm_node_hostname]
target_label: instance
# WICHTIG: Setze den Metrik-Pfad, da cAdvisor ihn unter /metrics bereitstellt
- action: replace
target_label: __metrics_path__
replacement: /metrics
@@ -0,0 +1,38 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /mnt/promtail/positions.yaml # Pfad im gemounteten Volume
clients:
- url: http://loki:3100/loki/api/v1/push # Sendet Logs an den Loki-Service
scrape_configs:
- job_name: docker_containers
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
# Extrahiere Container-Name (ohne '/')
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container_name'
# Behalte den Log-Stream (stdout/stderr) als Label
- source_labels: ['__meta_docker_container_log_stream']
target_label: 'logstream'
# Extrahiere Service-Name aus Swarm-Label
- source_labels: ['__meta_docker_container_label_com_docker_swarm_service_name']
target_label: 'service_name'
# Extrahiere Task-Name aus Swarm-Label
- source_labels: ['__meta_docker_container_label_com_docker_swarm_task_name']
target_label: 'task_name'
# Füge 'instance'-Label mit dem Hostnamen des Tasks hinzu (Annäherung an Node-Namen)
- action: replace
source_labels: ['container_name'] # Braucht ein existierendes Label als Quelle
target_label: 'instance'
replacement: ${HOSTNAME} # Nutzt Swarm HOSTNAME Variable
# Verwerfe Logs von Promtail selbst (Regex ggf. an Stacknamen anpassen)
- source_labels: ['container_name']
regex: 'monitoring_promtail.*' # Passe 'monitoring' an deinen Stack-Namen an!
action: drop
@@ -0,0 +1,36 @@
server:
http_listen_port: 3200 # Standard API/UI Port
distributor:
receivers: # OTLP receiver aktivieren (Tempo kann auch direkt empfangen)
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
# Grundlegende Konfiguration für Datenverarbeitung (meist ok für Start)
ingester:
trace_idle_period: 10s
max_block_bytes: 1048576 # 1MB
max_block_duration: 5m
compactor:
compaction:
block_retention: 1h # Wie lange Blöcke mindestens aufheben (geringer Wert für Test)
# WICHTIG: Storage explizit definieren!
storage:
trace:
backend: local # Backend-Typ: lokales Dateisystem
# Write Ahead Log (WAL) configuration.
wal:
path: /tmp/tempo/wal # Directory to store the the WAL locally.
# Local configuration for filesystem storage.
local:
path: /tmp/tempo/blocks # Directory to store the TSDB blocks.
# Pool used for finding trace IDs.
pool:
max_workers: 100 # Worker pool determines the number of parallel requests to the object store backend.
queue_depth: 10000 # Maximum depth for the querier queue jobs. A job is required for each block searched.
@@ -0,0 +1,226 @@
configs:
alloy-config-v3:
file: /srv/monitoring/config/alloy.v3.alloy
loki-config-v1:
file: /srv/monitoring/config/loki.v1.yml
prometheus-config-v3:
file: /srv/monitoring/config/prometheus.v3.yml
tempo-config-v1:
file: /srv/monitoring/config/tempo.v1.yml
volumes:
prometheus-data:
driver: local
grafana-data:
driver: local
loki-data:
driver: local
alloy-data:
driver: local
tempo-data:
driver: local
networks:
monitoring-net: # Internes Overlay-Netzwerk für die Monitoring-Komponenten
driver: overlay
attachable: true # Erlaubt anderen Containern/Stacks ggf. den Zugriff
traefik_public: # Das externe Netzwerk, auf dem Traefik lauscht
external: true # Wichtig: Dieses Netzwerk wird NICHT von diesem Stack erstellt
services:
prometheus:
image: prom/prometheus:latest
user: "65534:988"
volumes:
- prometheus-data:/prometheus
- /var/run/docker.sock:/var/run/docker.sock:ro
configs:
- source: prometheus-config-v3 # Versionierte Config
target: /etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
- '--web.enable-lifecycle'
- '--web.enable-remote-write-receiver'
networks:
- monitoring-net
- traefik_public # Nur wenn Traefik direkt auf Prometheus zugreifen soll (optional)
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager # Optional: An Manager-Nodes binden
labels:
- "traefik.enable=true"
# --- Router für Prometheus UI ---
- "traefik.http.routers.prometheus.rule=Host(`prometheus.genius.ceo`)"
- "traefik.http.routers.prometheus.entrypoints=https" # Entrypoint anpassen, falls anders
- "traefik.http.routers.prometheus.tls.certresolver=main" # CertResolver anpassen!
# --- Service für Prometheus UI ---
- "traefik.http.services.prometheus.loadbalancer.server.port=9090"
# --- Middleware (optional, z.B. für Authentifizierung) ---
# - "traefik.http.routers.prometheus.middlewares=my-auth-middleware"
# --- Netzwerk für Traefik ---
# WICHTIG: Das Netzwerk muss existieren und Traefik muss darauf lauschen.
- "traefik.swarm.network=traefik_public" # Traefik Netzwerkname anpassen!
loki:
image: grafana/loki:latest
volumes:
- loki-data:/loki
configs:
- source: loki-config-v1
target: /etc/loki/local-config.yaml
command: "-config.file=/etc/loki/local-config.yaml"
networks:
- monitoring-net
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
tempo:
image: grafana/tempo:latest # Aktuelles Tempo Image
volumes:
- tempo-data:/tmp/tempo # Persistenter Speicher für Traces (Standardpfad)
configs:
- source: tempo-config-v1
target: /etc/tempo/tempo.yaml
command: [ "-config.file=/etc/tempo/tempo.yaml" ]
user: root
# Tempo lauscht intern auf verschiedenen Ports für verschiedene Protokolle:
# - 4317 (OTLP gRPC - wird von Alloy genutzt)
# - 4318 (OTLP HTTP)
# - 14268 (Jaeger gRPC)
# - 3200 (Tempo HTTP Frontend/API - für Grafana & UI)
# Wir mappen sie vorerst nicht nach außen.
networks:
- monitoring-net
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager # Optional: An Manager-Nodes binden
grafana:
image: grafana/grafana:latest
volumes:
- grafana-data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin # Besser über Docker Secrets lösen!
# Weitere Grafana env vars nach Bedarf
networks:
- monitoring-net
- traefik_public # Nur wenn Traefik direkt auf Grafana zugreifen soll (optional)
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager # Optional: An Manager-Nodes binden
labels:
- "traefik.enable=true"
# --- Router für Grafana ---
- "traefik.http.routers.grafana.rule=Host(`grafana.genius.ceo`)"
- "traefik.http.routers.grafana.entrypoints=https" # Entrypoint anpassen, falls anders
- "traefik.http.routers.grafana.tls.certresolver=main" # CertResolver anpassen!
# --- Service für Grafana ---
- "traefik.http.services.grafana.loadbalancer.server.port=3000"
# --- Middleware (optional) ---
# - "traefik.http.routers.grafana.middlewares=my-auth-middleware"
# --- Netzwerk für Traefik ---
- "traefik.swarm.network=traefik_public" # Traefik Netzwerkname anpassen!
alloy:
image: grafana/alloy:latest # Offizielles Alloy Image
volumes:
- alloy-data:/var/lib/alloy/data # Persistenter Speicher für Alloy (WAL etc.)
- /var/run/docker.sock:/var/run/docker.sock:ro # Für Docker Discovery
configs:
- source: alloy-config-v3
target: /etc/alloy/config.alloy # S3-Pfad für Alloy Config
environment:
- HOSTNAME=${HOSTNAME}
# Start mit root wegen Docker Socket / Volume Permissions, kann später optimiert werden (Socket Proxy)
# user: root
command: [
"run",
"--server.http.listen-addr=0.0.0.0:12345",
"/etc/alloy/config.alloy",
]
networks:
- monitoring-net
- traefik_public
deploy:
mode: global # WICHTIG: Alloy muss auf jedem Node laufen!
labels: # Traefik Labels für Alloy UI
- "traefik.enable=true"
# --- Router für Alloy UI ---
- "traefik.http.routers.alloy-ui.rule=Host(`otlp.genius.ceo`)"
- "traefik.http.routers.alloy-ui.entrypoints=https"
- "traefik.http.routers.alloy-ui.tls.certresolver=main"
- "traefik.http.routers.alloy-ui.service=alloy-ui@swarm"
# --- Service für Alloy UI ---
- "traefik.http.services.alloy-ui.loadbalancer.server.port=12345" # Ziel-Port ist 12345 (Alloy UI Standard)
# # --- Router für OTLP HTTP ---
# - "traefik.http.routers.otlp-http.rule=Host(`alloy.genius.ceo`)"
# - "traefik.http.routers.otlp-http.entrypoints=https"
# - "traefik.http.routers.otlp-http.tls.certresolver=main"
# - "traefik.http.routers.otlp-http.service=otlp-http@swarm"
# # --- Service für OTLP HTTP ---
# - "traefik.http.services.otlp-http.loadbalancer.server.port=4318" # Ziel-Port ist 4318 (OTLP HTTP Standard)
# --- Router für FARO RECEIVER ---
- "traefik.http.routers.faro-receiver.rule=Host(`alloy.genius.ceo`)"
- "traefik.http.routers.faro-receiver.entrypoints=https"
- "traefik.http.routers.faro-receiver.tls.certresolver=main"
- "traefik.http.routers.faro-receiver.service=faro-receiver@swarm"
# --- Service für FARO RECEIVER ---
- "traefik.http.services.faro-receiver.loadbalancer.server.port=12347" # Ziel-Port ist 12347 (FARO RECEIVER Standard)
# # --- Middlewares ---
# - "traefik.http.routers.otlp-http.middlewares=alloy-ratelimit@swarm"
# - "traefik.http.middlewares.alloy-ratelimit.ratelimit.average=100" # z.B. 100 Anfragen pro Sekunde
# - "traefik.http.middlewares.alloy-ratelimit.ratelimit.burst=50" # kurzfristig 50 mehr erlaubt
# --- Netzwerk für Traefik ---
- "traefik.swarm.network=traefik_public" # Traefik Netzwerkname prüfen/anpassen!
node-exporter:
image: quay.io/prometheus/node-exporter:latest # Aktuelles Image verwenden
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)'
networks:
- monitoring-net # Nur internes Netzwerk nötig
deploy:
mode: global # Läuft auf JEDEM Node im Swarm
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest # Google's cAdvisor Image
volumes:
# cAdvisor braucht Zugriff auf Host-System-Infos und Docker
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- monitoring-net # Nur internes Netzwerk nötig
deploy:
mode: global # Läuft auf JEDEM Node im Swarm
resources: # Optional: Limitiert Ressourcen, cAdvisor kann hungrig sein
limits:
memory: 512M
reservations:
memory: 256M
@@ -0,0 +1,102 @@
receivers:
hostmetrics:
collection_interval: 30s
root_path: /hostfs
scrapers:
cpu: {}
load: {}
memory: {}
disk: {}
filesystem: {}
network: {}
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
prometheus:
config:
global:
scrape_interval: 60s
scrape_configs:
- job_name: otel-agent
static_configs:
- targets:
- localhost:8888
labels:
job_name: otel-agent
tcplog/docker:
listen_address: "0.0.0.0:2255"
operators:
- type: regex_parser
regex: '^<([0-9]+)>[0-9]+ (?P<timestamp>[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?) (?P<container_id>\S+) (?P<container_name>\S+) [0-9]+ - -( (?P<body>.*))?'
timestamp:
parse_from: attributes.timestamp
layout: '%Y-%m-%dT%H:%M:%S.%LZ'
- type: move
from: attributes["body"]
to: body
- type: remove
field: attributes.timestamp
# please remove names from below if you want to collect logs from them
- type: filter
id: signoz_logs_filter
expr: 'attributes.container_name matches "^(signoz_(logspout|signoz|otel-collector|clickhouse|zookeeper))|(infra_(logspout|otel-agent|otel-metrics)).*"'
processors:
batch:
send_batch_size: 10000
send_batch_max_size: 11000
timeout: 10s
resourcedetection:
# Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels.
detectors:
# - ec2
# - gcp
# - azure
- env
- system
timeout: 2s
extensions:
health_check:
endpoint: 0.0.0.0:13133
pprof:
endpoint: 0.0.0.0:1777
exporters:
otlp:
endpoint: ${env:SIGNOZ_COLLECTOR_ENDPOINT}
tls:
insecure: true
headers:
signoz-access-token: ${env:SIGNOZ_ACCESS_TOKEN}
# debug: {}
service:
telemetry:
logs:
encoding: json
metrics:
address: 0.0.0.0:8888
extensions:
- health_check
- pprof
pipelines:
traces:
receivers: [otlp]
processors: [resourcedetection, batch]
exporters: [otlp]
metrics:
receivers: [otlp]
processors: [resourcedetection, batch]
exporters: [otlp]
metrics/hostmetrics:
receivers: [hostmetrics]
processors: [resourcedetection, batch]
exporters: [otlp]
metrics/prometheus:
receivers: [prometheus]
processors: [resourcedetection, batch]
exporters: [otlp]
logs:
receivers: [otlp, tcplog/docker]
processors: [resourcedetection, batch]
exporters: [otlp]
@@ -0,0 +1,103 @@
receivers:
prometheus:
config:
global:
scrape_interval: 60s
scrape_configs:
- job_name: otel-metrics
static_configs:
- targets:
- localhost:8888
labels:
job_name: otel-metrics
# For Docker daemon metrics to be scraped, it must be configured to expose
# Prometheus metrics, as documented here: https://docs.docker.com/config/daemon/prometheus/
# - job_name: docker-daemon
# dockerswarm_sd_configs:
# - host: unix:///var/run/docker.sock
# role: nodes
# relabel_configs:
# - source_labels: [__meta_dockerswarm_node_address]
# target_label: __address__
# replacement: $1:9323
- job_name: "dockerswarm"
dockerswarm_sd_configs:
- host: unix:///var/run/docker.sock
role: tasks
relabel_configs:
- action: keep
regex: running
source_labels:
- __meta_dockerswarm_task_desired_state
- action: keep
regex: true
source_labels:
- __meta_dockerswarm_service_label_signoz_io_scrape
- regex: ([^:]+)(?::\d+)?
replacement: $1
source_labels:
- __address__
target_label: swarm_container_ip
- separator: .
source_labels:
- __meta_dockerswarm_service_name
- __meta_dockerswarm_task_slot
- __meta_dockerswarm_task_id
target_label: swarm_container_name
- target_label: __address__
source_labels:
- swarm_container_ip
- __meta_dockerswarm_service_label_signoz_io_port
separator: ":"
- source_labels:
- __meta_dockerswarm_service_label_signoz_io_path
target_label: __metrics_path__
- source_labels:
- __meta_dockerswarm_service_label_com_docker_stack_namespace
target_label: namespace
- source_labels:
- __meta_dockerswarm_service_name
target_label: service_name
- source_labels:
- __meta_dockerswarm_task_id
target_label: service_instance_id
- source_labels:
- __meta_dockerswarm_node_hostname
target_label: host_name
processors:
batch:
send_batch_size: 10000
send_batch_max_size: 11000
timeout: 10s
resourcedetection:
detectors:
- env
- system
timeout: 2s
extensions:
health_check:
endpoint: 0.0.0.0:13133
pprof:
endpoint: 0.0.0.0:1777
exporters:
otlp:
endpoint: ${env:SIGNOZ_COLLECTOR_ENDPOINT}
tls:
insecure: true
headers:
signoz-access-token: ${env:SIGNOZ_ACCESS_TOKEN}
# debug: {}
service:
telemetry:
logs:
encoding: json
metrics:
address: 0.0.0.0:8888
extensions:
- health_check
- pprof
pipelines:
metrics:
receivers: [prometheus]
processors: [resourcedetection, batch]
exporters: [otlp]
@@ -0,0 +1,78 @@
version: "3"
x-common: &common
networks:
- signoz-net
extra_hosts:
- host.docker.internal:host-gateway
logging:
options:
max-size: 50m
max-file: "3"
deploy:
mode: global
restart_policy:
condition: on-failure
services:
otel-agent:
<<: *common
image: otel/opentelemetry-collector-contrib:0.111.0
command:
- --config=/etc/otel-collector-config.yaml
configs:
- source: otel-agent-config-v1
target: /etc/otel-collector-config.yaml
volumes:
- /:/hostfs:ro
environment:
- SIGNOZ_COLLECTOR_ENDPOINT=http://host.docker.internal:4317 # In case of external SigNoz or cloud, update the endpoint and access token
- OTEL_RESOURCE_ATTRIBUTES=host.name={{.Node.Hostname}},os.type={{.Node.Platform.OS}}
# - SIGNOZ_ACCESS_TOKEN="<your-access-token>"
# Before exposing the ports, make sure the ports are not used by other services
# ports:
# - "4317:4317"
# - "4318:4318"
otel-metrics:
<<: *common
image: otel/opentelemetry-collector-contrib:0.111.0
user: 0:0 # If you have security concerns, you can replace this with your `UID:GID` that has necessary permissions to docker.sock
command:
- --config=/etc/otel-collector-config.yaml
configs:
- source: otel-metrics-config-v1
target: /etc/otel-collector-config.yaml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- SIGNOZ_COLLECTOR_ENDPOINT=http://host.docker.internal:4317 # In case of external SigNoz or cloud, update the endpoint and access token
- OTEL_RESOURCE_ATTRIBUTES=host.name={{.Node.Hostname}},os.type={{.Node.Platform.OS}}
# - SIGNOZ_ACCESS_TOKEN="<your-access-token>"
# Before exposing the ports, make sure the ports are not used by other services
# ports:
# - "4317:4317"
# - "4318:4318"
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
logspout:
<<: *common
image: "gliderlabs/logspout:v3.2.14"
command: syslog+tcp://otel-agent:2255
user: root
volumes:
- /etc/hostname:/etc/host_hostname:ro
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- otel-agent
networks:
signoz-net:
name: signoz-net
external: true
configs:
otel-metrics-config-v1:
file: /mnt/cephfs/signoz-infra/config/otel-metrics-config.v1.yaml
otel-agent-config-v1:
file: /mnt/cephfs/signoz-infra/config/otel-agent-config.v1.yaml
@@ -0,0 +1,75 @@
<?xml version="1.0"?>
<clickhouse>
<!-- ZooKeeper is used to store metadata about replicas, when using Replicated tables.
Optional. If you don't use replicated tables, you could omit that.
See https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/replication/
-->
<zookeeper>
<node index="1">
<host>zookeeper-1</host>
<port>2181</port>
</node>
<!-- <node index="2">
<host>zookeeper-2</host>
<port>2181</port>
</node>
<node index="3">
<host>zookeeper-3</host>
<port>2181</port>
</node> -->
</zookeeper>
<!-- Configuration of clusters that could be used in Distributed tables.
https://clickhouse.com/docs/en/operations/table_engines/distributed/
-->
<remote_servers>
<cluster>
<!-- Inter-server per-cluster secret for Distributed queries
default: no secret (no authentication will be performed)
If set, then Distributed queries will be validated on shards, so at least:
- such cluster should exist on the shard,
- such cluster should have the same secret.
And also (and which is more important), the initial_user will
be used as current user for the query.
Right now the protocol is pretty simple and it only takes into account:
- cluster name
- query
Also it will be nice if the following will be implemented:
- source hostname (see interserver_http_host), but then it will depends from DNS,
it can use IP address instead, but then the you need to get correct on the initiator node.
- target hostname / ip address (same notes as for source hostname)
- time-based security tokens
-->
<!-- <secret></secret> -->
<shard>
<!-- Optional. Whether to write data to just one of the replicas. Default: false (write data to all replicas). -->
<!-- <internal_replication>false</internal_replication> -->
<!-- Optional. Shard weight when writing data. Default: 1. -->
<!-- <weight>1</weight> -->
<replica>
<host>clickhouse</host>
<port>9000</port>
<!-- Optional. Priority of the replica for load_balancing. Default: 1 (less value has more priority). -->
<!-- <priority>1</priority> -->
</replica>
</shard>
<!-- <shard>
<replica>
<host>clickhouse-2</host>
<port>9000</port>
</replica>
</shard>
<shard>
<replica>
<host>clickhouse-3</host>
<port>9000</port>
</replica>
</shard> -->
</cluster>
</remote_servers>
</clickhouse>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
<functions>
<function>
<type>executable</type>
<name>histogramQuantile</name>
<return_type>Float64</return_type>
<argument>
<type>Array(Float64)</type>
<name>buckets</name>
</argument>
<argument>
<type>Array(Float64)</type>
<name>counts</name>
</argument>
<argument>
<type>Float64</type>
<name>quantile</name>
</argument>
<format>CSV</format>
<command>./histogramQuantile</command>
</function>
</functions>
@@ -0,0 +1,41 @@
<?xml version="1.0"?>
<clickhouse>
<storage_configuration>
<disks>
<default>
<keep_free_space_bytes>10485760</keep_free_space_bytes>
</default>
<s3>
<type>s3</type>
<!-- For S3 cold storage,
if region is us-east-1, endpoint can be https://<bucket-name>.s3.amazonaws.com
if region is not us-east-1, endpoint should be https://<bucket-name>.s3-<region>.amazonaws.com
For GCS cold storage,
endpoint should be https://storage.googleapis.com/<bucket-name>/data/
-->
<endpoint>https://BUCKET-NAME.s3-REGION-NAME.amazonaws.com/data/</endpoint>
<access_key_id>ACCESS-KEY-ID</access_key_id>
<secret_access_key>SECRET-ACCESS-KEY</secret_access_key>
<!-- In case of S3, uncomment the below configuration in case you want to read
AWS credentials from the Environment variables if they exist. -->
<!-- <use_environment_credentials>true</use_environment_credentials> -->
<!-- In case of GCS, uncomment the below configuration, since GCS does
not support batch deletion and result in error messages in logs. -->
<!-- <support_batch_delete>false</support_batch_delete> -->
</s3>
</disks>
<policies>
<tiered>
<volumes>
<default>
<disk>default</disk>
</default>
<s3>
<disk>s3</disk>
<perform_ttl_move_on_insert>0</perform_ttl_move_on_insert>
</s3>
</volumes>
</tiered>
</policies>
</storage_configuration>
</clickhouse>
@@ -0,0 +1,123 @@
<?xml version="1.0"?>
<clickhouse>
<!-- See also the files in users.d directory where the settings can be overridden. -->
<!-- Profiles of settings. -->
<profiles>
<!-- Default settings. -->
<default>
<!-- Maximum memory usage for processing single query, in bytes. -->
<max_memory_usage>10000000000</max_memory_usage>
<!-- How to choose between replicas during distributed query processing.
random - choose random replica from set of replicas with minimum number of errors
nearest_hostname - from set of replicas with minimum number of errors, choose replica
with minimum number of different symbols between replica's hostname and local hostname
(Hamming distance).
in_order - first live replica is chosen in specified order.
first_or_random - if first replica one has higher number of errors, pick a random one from replicas with minimum number of errors.
-->
<load_balancing>random</load_balancing>
</default>
<!-- Profile that allows only read queries. -->
<readonly>
<readonly>1</readonly>
</readonly>
</profiles>
<!-- Users and ACL. -->
<users>
<!-- If user name was not specified, 'default' user is used. -->
<default>
<!-- See also the files in users.d directory where the password can be overridden.
Password could be specified in plaintext or in SHA256 (in hex format).
If you want to specify password in plaintext (not recommended), place it in 'password' element.
Example: <password>qwerty</password>.
Password could be empty.
If you want to specify SHA256, place it in 'password_sha256_hex' element.
Example: <password_sha256_hex>65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5</password_sha256_hex>
Restrictions of SHA256: impossibility to connect to ClickHouse using MySQL JS client (as of July 2019).
If you want to specify double SHA1, place it in 'password_double_sha1_hex' element.
Example: <password_double_sha1_hex>e395796d6546b1b65db9d665cd43f0e858dd4303</password_double_sha1_hex>
If you want to specify a previously defined LDAP server (see 'ldap_servers' in the main config) for authentication,
place its name in 'server' element inside 'ldap' element.
Example: <ldap><server>my_ldap_server</server></ldap>
If you want to authenticate the user via Kerberos (assuming Kerberos is enabled, see 'kerberos' in the main config),
place 'kerberos' element instead of 'password' (and similar) elements.
The name part of the canonical principal name of the initiator must match the user name for authentication to succeed.
You can also place 'realm' element inside 'kerberos' element to further restrict authentication to only those requests
whose initiator's realm matches it.
Example: <kerberos />
Example: <kerberos><realm>EXAMPLE.COM</realm></kerberos>
How to generate decent password:
Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
In first line will be password and in second - corresponding SHA256.
How to generate double SHA1:
Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha1sum | tr -d '-' | xxd -r -p | sha1sum | tr -d '-'
In first line will be password and in second - corresponding double SHA1.
-->
<password></password>
<!-- List of networks with open access.
To open access from everywhere, specify:
<ip>::/0</ip>
To open access only from localhost, specify:
<ip>::1</ip>
<ip>127.0.0.1</ip>
Each element of list has one of the following forms:
<ip> IP-address or network mask. Examples: 213.180.204.3 or 10.0.0.1/8 or 10.0.0.1/255.255.255.0
2a02:6b8::3 or 2a02:6b8::3/64 or 2a02:6b8::3/ffff:ffff:ffff:ffff::.
<host> Hostname. Example: server01.clickhouse.com.
To check access, DNS query is performed, and all received addresses compared to peer address.
<host_regexp> Regular expression for host names. Example, ^server\d\d-\d\d-\d\.clickhouse\.com$
To check access, DNS PTR query is performed for peer address and then regexp is applied.
Then, for result of PTR query, another DNS query is performed and all received addresses compared to peer address.
Strongly recommended that regexp is ends with $
All results of DNS requests are cached till server restart.
-->
<networks>
<ip>::/0</ip>
</networks>
<!-- Settings profile for user. -->
<profile>default</profile>
<!-- Quota for user. -->
<quota>default</quota>
<!-- User can create other users and grant rights to them. -->
<!-- <access_management>1</access_management> -->
</default>
</users>
<!-- Quotas. -->
<quotas>
<!-- Name of quota. -->
<default>
<!-- Limits for time interval. You could specify many intervals with different limits. -->
<interval>
<!-- Length of interval. -->
<duration>3600</duration>
<!-- No limits. Just calculate resource usage for time interval. -->
<queries>0</queries>
<errors>0</errors>
<result_rows>0</result_rows>
<read_rows>0</read_rows>
<execution_time>0</execution_time>
</interval>
</default>
</quotas>
</clickhouse>
@@ -0,0 +1,140 @@
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
cors:
allowed_origins:
- https://*.genius.ceo
- https://*.avicenna.hamburg
prometheus:
config:
global:
scrape_interval: 60s
scrape_configs:
- job_name: otel-collector
static_configs:
- targets:
- localhost:8888
labels:
job_name: otel-collector
docker_stats:
endpoint: unix:///var/run/docker.sock
metrics:
container.cpu.utilization:
enabled: true
container.memory.percent:
enabled: true
container.network.io.usage.rx_bytes:
enabled: true
container.network.io.usage.tx_bytes:
enabled: true
container.network.io.usage.rx_dropped:
enabled: true
container.network.io.usage.tx_dropped:
enabled: true
container.memory.usage.limit:
enabled: true
container.memory.usage.total:
enabled: true
container.blockio.io_service_bytes_recursive:
enabled: true
processors:
batch:
send_batch_size: 10000
send_batch_max_size: 11000
timeout: 10s
resourcedetection:
# Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels.
detectors: [env, system]
timeout: 2s
resourcedetection/docker:
detectors: [env, docker]
timeout: 2s
override: false
signozspanmetrics/delta:
metrics_exporter: clickhousemetricswrite, signozclickhousemetrics
metrics_flush_interval: 60s
latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ]
dimensions_cache_size: 100000
aggregation_temporality: AGGREGATION_TEMPORALITY_DELTA
enable_exp_histogram: true
dimensions:
- name: service.namespace
default: default
- name: deployment.environment
default: default
# This is added to ensure the uniqueness of the timeseries
# Otherwise, identical timeseries produced by multiple replicas of
# collectors result in incorrect APM metrics
- name: signoz.collector.id
- name: service.version
- name: browser.platform
- name: browser.mobile
- name: k8s.cluster.name
- name: k8s.node.name
- name: k8s.namespace.name
- name: host.name
- name: host.type
- name: container.name
extensions:
health_check:
endpoint: 0.0.0.0:13133
pprof:
endpoint: 0.0.0.0:1777
exporters:
clickhousetraces:
datasource: tcp://clickhouse:9000/signoz_traces
low_cardinal_exception_grouping: ${env:LOW_CARDINAL_EXCEPTION_GROUPING}
use_new_schema: true
clickhousemetricswrite:
endpoint: tcp://clickhouse:9000/signoz_metrics
resource_to_telemetry_conversion:
enabled: true
disable_v2: true
clickhousemetricswrite/prometheus:
endpoint: tcp://clickhouse:9000/signoz_metrics
disable_v2: true
signozclickhousemetrics:
dsn: tcp://clickhouse:9000/signoz_metrics
clickhouselogsexporter:
dsn: tcp://clickhouse:9000/signoz_logs
timeout: 10s
use_new_schema: true
otlp:
endpoint: http://otel-collector:4317
tls:
insecure: true
# debug: {}
service:
telemetry:
logs:
encoding: json
metrics:
address: 0.0.0.0:8888
extensions:
- health_check
- pprof
pipelines:
traces:
receivers: [otlp]
processors: [signozspanmetrics/delta, batch]
exporters: [clickhousetraces]
metrics/docker:
receivers: [docker_stats]
processors: [resourcedetection/docker]
exporters: [otlp]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [clickhousemetricswrite, signozclickhousemetrics]
metrics/prometheus:
receivers: [prometheus]
processors: [batch]
exporters: [clickhousemetricswrite/prometheus, signozclickhousemetrics]
logs:
receivers: [otlp]
processors: [batch]
exporters: [clickhouselogsexporter]
@@ -0,0 +1 @@
server_endpoint: ws://signoz:4320/v1/opamp
@@ -0,0 +1,25 @@
# my global config
global:
scrape_interval: 5s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files: []
# - "first_rules.yml"
# - "second_rules.yml"
# - 'alerts.yml'
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs: []
remote_read:
- url: tcp://clickhouse:9000/signoz_metrics
+243
View File
@@ -0,0 +1,243 @@
version: '3'
x-common: &common
networks:
- signoz-net
deploy:
restart_policy:
condition: on-failure
logging:
options:
max-size: 50m
max-file: '3'
x-clickhouse-defaults: &clickhouse-defaults
!!merge <<: *common
image: clickhouse/clickhouse-server:24.1.2-alpine
tty: true
user: "1000:1000"
deploy:
placement:
constraints: [node.hostname == manager-node-3]
labels:
signoz.io/scrape: 'true'
signoz.io/port: '9363'
signoz.io/path: '/metrics'
depends_on:
- init-clickhouse
- zookeeper-1
healthcheck:
test:
- CMD
- wget
- --spider
- -q
- 0.0.0.0:8123/ping
interval: 30s
timeout: 5s
retries: 3
ulimits:
nproc: 65535
nofile:
soft: 262144
hard: 262144
x-zookeeper-defaults: &zookeeper-defaults
!!merge <<: *common
image: bitnami/zookeeper:3.7.1
user: root
deploy:
placement:
constraints: [node.hostname == manager-node-1]
labels:
signoz.io/scrape: 'true'
signoz.io/port: '9141'
signoz.io/path: '/metrics'
healthcheck:
test:
- CMD-SHELL
- curl -s -m 2 http://localhost:8080/commands/ruok | grep error | grep null
interval: 30s
timeout: 5s
retries: 3
x-db-depend: &db-depend
!!merge <<: *common
depends_on:
- clickhouse
- schema-migrator
services:
init-clickhouse:
!!merge <<: *common
image: clickhouse/clickhouse-server:24.1.2-alpine
command:
- bash
- -c
- |
version="v0.0.1"
node_os=$$(uname -s | tr '[:upper:]' '[:lower:]')
node_arch=$$(uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/)
echo "Fetching histogram-binary for $${node_os}/$${node_arch}"
cd /tmp
wget -O histogram-quantile.tar.gz "https://github.com/SigNoz/signoz/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
tar -xvzf histogram-quantile.tar.gz
mv histogram-quantile /var/lib/clickhouse/user_scripts/histogramQuantile
deploy:
restart_policy:
condition: on-failure
volumes:
- /mnt/cephfs/signoz/data/clickhouse/user_scripts:/var/lib/clickhouse/user_scripts/
zookeeper-1:
!!merge <<: *zookeeper-defaults
# ports:
# - "2181:2181"
# - "2888:2888"
# - "3888:3888"
volumes:
- /mnt/cephfs/signoz/data/zookeeper-1:/bitnami/zookeeper
environment:
- ZOO_SERVER_ID=1
- ALLOW_ANONYMOUS_LOGIN=yes
- ZOO_AUTOPURGE_INTERVAL=1
- ZOO_ENABLE_PROMETHEUS_METRICS=yes
- ZOO_PROMETHEUS_METRICS_PORT_NUMBER=9141
clickhouse:
!!merge <<: *clickhouse-defaults
# TODO: needed for clickhouse TCP connectio
hostname: clickhouse
# ports:
# - "9000:9000"
# - "8123:8123"
# - "9181:9181"
configs:
- source: clickhouse-config-v1
target: /etc/clickhouse-server/config.xml
- source: clickhouse-users-v1
target: /etc/clickhouse-server/users.xml
- source: clickhouse-custom-function-v1
target: /etc/clickhouse-server/custom-function.xml
- source: clickhouse-cluster-v1
target: /etc/clickhouse-server/config.d/cluster.xml
volumes:
- /mnt/cephfs/signoz/data/clickhouse/data/user_scripts:/var/lib/clickhouse/user_scripts/
- /mnt/cephfs/signoz/data/clickhouse/data:/var/lib/clickhouse/
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:v0.86.1
command:
- --config=/root/config/prometheus.yml
# ports:
# - "8080:8080" # signoz port
# - "6060:6060" # pprof port
configs:
- source: signoz-prometheus-config-v1
target: /root/config/prometheus.yml
volumes:
- /mnt/cephfs/signoz/data/dashboards:/root/config/dashboards
- /mnt/cephfs/signoz/data/sqlite:/var/lib/signoz/
environment:
- SIGNOZ_ALERTMANAGER_PROVIDER=signoz
- SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_SQLSTORE_SQLITE_PATH=/var/lib/signoz/signoz.db
- DASHBOARDS_PATH=/root/config/dashboards
- STORAGE=clickhouse
- GODEBUG=netdns=go
- TELEMETRY_ENABLED=true
- DEPLOYMENT_TYPE=docker-swarm
healthcheck:
test:
- CMD
- wget
- --spider
- -q
- localhost:8080/api/v1/health
interval: 30s
timeout: 5s
retries: 3
networks:
- signoz-net
- traefik_public
deploy:
labels:
- 'traefik.enable=true'
# --- Router für Signoz UI ---
- 'traefik.http.routers.signoz.rule=Host(`signoz.genius.ceo`)'
- 'traefik.http.routers.signoz.entrypoints=https'
- 'traefik.http.routers.signoz.tls.certresolver=main'
# --- Service für Signoz UI ---
- 'traefik.http.services.signoz.loadbalancer.server.port=8080'
# --- Netzwerk für Traefik ---
- 'traefik.swarm.network=traefik_public'
otel-collector:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:v0.111.42
user: root
command:
- --config=/etc/otel-collector-config.yaml
- --manager-config=/etc/manager-config.yaml
- --copy-path=/var/tmp/collector-config.yaml
- --feature-gates=-pkg.translator.prometheus.NormalizeName
configs:
- source: otel-collector-config-v4
target: /etc/otel-collector-config.yaml
- source: otel-collector-manager-config-v1
target: /etc/manager-config.yaml
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- OTEL_RESOURCE_ATTRIBUTES=host.name={{.Node.Hostname}},os.type={{.Node.Platform.OS}}
- LOW_CARDINAL_EXCEPTION_GROUPING=false
ports:
# - "1777:1777" # pprof extension
- '4317:4317' # OTLP gRPC receiver
- '4318:4318' # OTLP HTTP receiver
deploy:
replicas: 3
labels:
- 'traefik.enable=true'
# --- Router für Signoz Collector UI ---
- 'traefik.http.routers.signoz-collector.rule=Host(`collector.genius.ceo`)'
- 'traefik.http.routers.signoz-collector.entrypoints=https'
- 'traefik.http.routers.signoz-collector.tls.certresolver=main'
# --- Service für Signoz Collector UI ---
- 'traefik.http.services.signoz-collector.loadbalancer.server.port=4318'
# --- Netzwerk für Traefik ---
- 'traefik.swarm.network=traefik_public'
depends_on:
- clickhouse
- schema-migrator
- signoz
networks:
- signoz-net
- traefik_public
schema-migrator:
!!merge <<: *common
image: signoz/signoz-schema-migrator:v0.111.42
deploy:
restart_policy:
condition: on-failure
delay: 5s
entrypoint: sh
command:
- -c
- '/signoz-schema-migrator sync --dsn=tcp://clickhouse:9000 --up= && /signoz-schema-migrator async --dsn=tcp://clickhouse:9000 --up='
depends_on:
- clickhouse
networks:
signoz-net:
name: signoz-net
attachable: true
traefik_public:
external: true
configs:
otel-collector-config-v4:
file: /mnt/cephfs/signoz/config/otel-collector-config.v4.yaml
otel-collector-manager-config-v1:
file: /mnt/cephfs/signoz/config/signoz/otel-collector-opamp-config.yaml
clickhouse-config-v1:
file: /mnt/cephfs/signoz/config/clickhouse/config.v1.xml
clickhouse-users-v1:
file: /mnt/cephfs/signoz/config/clickhouse/users.v1.xml
clickhouse-custom-function-v1:
file: /mnt/cephfs/signoz/config/clickhouse/custom-function.v1.xml
clickhouse-cluster-v1:
file: /mnt/cephfs/signoz/config/clickhouse/cluster.v1.xml
signoz-prometheus-config-v1:
file: /mnt/cephfs/signoz/config/signoz/prometheus.v1.yml