Skip to content

Commit fe4ae74

Browse files
committed
feat: implement monitoring sources
1 parent c07c8f2 commit fe4ae74

8 files changed

Lines changed: 201 additions & 2 deletions

File tree

config/database.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ default: &default
2020
# Supabase transaction pooler (port 6543) does not support prepared statements.
2121
# Disabling here prevents PG::DuplicatePstatement errors across all envs.
2222
prepared_statements: false
23+
# PgBouncer transaction mode doesn't support session-level advisory locks.
24+
# Disabling prevents ConcurrentMigrationError on container restarts.
25+
advisory_locks: false
2326
# For details on connection pooling, see Rails configuration guide
2427
# https://guides.rubyonrails.org/configuring.html#database-pooling
2528
# DB_POOL lets you set a higher pool for Sidekiq without raising Puma threads.

config/initializers/cors.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Rails.application.config.middleware.insert_before 0, Rack::Cors do
44
allow do
55
# The fallback (second argument) must be a single string separated by commas
6-
origins ENV.fetch('CORS_ORIGINS', 'http://localhost:3000,http://localhost:5173,http://localhost:8888,http://localhost:4444,https://prostaff.gg,https://www.prostaff.gg,https://api.prostaff.gg,https://status.prostaff.gg,https://docs.prostaff.gg,https://scrims.lol,https://www.scrims.lol,https://arena-br.vercel.app').split(',')
6+
origins ENV.fetch('CORS_ORIGINS', 'http://localhost:3000,http://localhost:5173,http://localhost:5555,http://localhost:8888,http://localhost:4444,https://prostaff.gg,https://www.prostaff.gg,https://api.prostaff.gg,https://status.prostaff.gg,https://docs.prostaff.gg,https://scrims.lol,https://www.scrims.lol,https://arena-br.vercel.app').split(',')
77

88
resource '*',
99
headers: :any,

config/initializers/rack_attack.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ class Attack
3737
end
3838

3939
# Allow localhost and Docker bridge in development and test environments
40+
# Docker uses 172.16.0.0/12 range for bridge networks (172.16–172.31)
4041
safelist('allow from localhost') do |req|
4142
next false unless Rails.env.development? || Rails.env.test?
4243

4344
ip = req.ip.to_s
44-
ip == '127.0.0.1' || ip == '::1' || ip.start_with?('172.18.', '172.17.')
45+
ip == '127.0.0.1' || ip == '::1' ||
46+
(ip.start_with?('172.') && (ip.split('.')[1].to_i >= 16 && ip.split('.')[1].to_i <= 31))
4547
end
4648

4749
# Block known malicious bots and scrapers

docker-compose.monitoring.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
services:
2+
node-exporter:
3+
image: prom/node-exporter:latest
4+
restart: unless-stopped
5+
pid: host
6+
networks:
7+
- monitoring
8+
ports:
9+
- "127.0.0.1:9100:9100"
10+
volumes:
11+
- /proc:/host/proc:ro
12+
- /sys:/host/sys:ro
13+
- /:/rootfs:ro
14+
command:
15+
- '--path.procfs=/host/proc'
16+
- '--path.sysfs=/host/sys'
17+
- '--path.rootfs=/rootfs'
18+
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
19+
20+
cadvisor:
21+
image: gcr.io/cadvisor/cadvisor:latest
22+
restart: unless-stopped
23+
privileged: true
24+
networks:
25+
- monitoring
26+
ports:
27+
- "127.0.0.1:9200:8080"
28+
volumes:
29+
- /:/rootfs:ro
30+
- /var/run:/var/run:ro
31+
- /sys:/sys:ro
32+
- /var/lib/docker:/var/lib/docker:ro
33+
- /dev/disk:/dev/disk:ro
34+
35+
prometheus:
36+
image: prom/prometheus:latest
37+
restart: unless-stopped
38+
networks:
39+
- monitoring
40+
ports:
41+
- "127.0.0.1:9090:9090"
42+
volumes:
43+
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
44+
- prometheus-data:/prometheus
45+
command:
46+
- '--config.file=/etc/prometheus/prometheus.yml'
47+
- '--storage.tsdb.path=/prometheus'
48+
- '--storage.tsdb.retention.time=30d'
49+
- '--web.enable-lifecycle'
50+
51+
grafana:
52+
image: grafana/grafana:latest
53+
restart: unless-stopped
54+
networks:
55+
- monitoring
56+
ports:
57+
- "127.0.0.1:3001:3000"
58+
volumes:
59+
- grafana-data:/var/lib/grafana
60+
- ./monitoring/grafana/provisioning:/etc/grafana/provisioning:ro
61+
environment:
62+
GF_SECURITY_ADMIN_USER: '${GRAFANA_ADMIN_USER:-admin}'
63+
GF_SECURITY_ADMIN_PASSWORD: '${GRAFANA_ADMIN_PASSWORD}'
64+
GF_PATHS_PROVISIONING: '/etc/grafana/provisioning'
65+
GF_USERS_ALLOW_SIGN_UP: 'false'
66+
GF_SERVER_ROOT_URL: '${GRAFANA_ROOT_URL:-http://localhost:3001}'
67+
depends_on:
68+
- prometheus
69+
70+
volumes:
71+
prometheus-data:
72+
driver: local
73+
grafana-data:
74+
driver: local
75+
76+
networks:
77+
monitoring:
78+
driver: bridge

monitoring/README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# ProStaff Observability Stack
2+
3+
Node Exporter + cAdvisor + Prometheus + Grafana, isolado do compose principal.
4+
5+
## Setup
6+
7+
```bash
8+
cp .env.monitoring.example .env.monitoring
9+
# edite .env.monitoring e defina GRAFANA_ADMIN_PASSWORD
10+
```
11+
12+
## Subir
13+
14+
```bash
15+
docker compose -f docker-compose.monitoring.yml --env-file .env.monitoring up -d
16+
```
17+
18+
## Portas
19+
20+
| Servico | Porta local | URL |
21+
|--------------|---------------|------------------------------|
22+
| Grafana | 3001 | http://localhost:3001 |
23+
| Prometheus | 9090 | http://localhost:9090 |
24+
| Node Exporter| 9100 | http://localhost:9100/metrics|
25+
| cAdvisor | 9200 | http://localhost:9200/metrics|
26+
27+
Todas as portas estão vinculadas a `127.0.0.1` — acesse via SSH tunnel em produção:
28+
29+
```bash
30+
ssh -L 3001:localhost:3001 -L 9090:localhost:9090 user@seu-servidor
31+
```
32+
33+
## Importar dashboards prontos
34+
35+
1. Acesse Grafana → Dashboards → Import
36+
2. Cole o ID e clique em Load:
37+
38+
| Dashboard | ID |
39+
|------------------------|-------|
40+
| Node Exporter Full | 1860 |
41+
| Docker / cAdvisor | 14282 |
42+
43+
3. Selecione o datasource **Prometheus** e confirme.
44+
45+
## Habilitar métricas da API Rails
46+
47+
Descomente o job `prostaff-api` em `monitoring/prometheus.yml` após adicionar
48+
a gem `prometheus-client` e expor o endpoint `/metrics` nas rotas.
49+
50+
## Parar
51+
52+
```bash
53+
docker compose -f docker-compose.monitoring.yml down
54+
```
55+
56+
Para remover volumes (apaga histórico de métricas):
57+
58+
```bash
59+
docker compose -f docker-compose.monitoring.yml down -v
60+
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: 1
2+
3+
providers:
4+
- name: 'ProStaff'
5+
orgId: 1
6+
type: file
7+
disableDeletion: false
8+
updateIntervalSeconds: 30
9+
allowUiUpdates: true
10+
options:
11+
path: /var/lib/grafana/dashboards
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: 1
2+
3+
datasources:
4+
- name: Prometheus
5+
type: prometheus
6+
access: proxy
7+
url: http://prometheus:9090
8+
isDefault: true
9+
editable: false
10+
jsonData:
11+
timeInterval: '15s'

monitoring/prometheus.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
global:
2+
scrape_interval: 15s
3+
evaluation_interval: 15s
4+
external_labels:
5+
project: 'prostaff'
6+
env: 'production'
7+
8+
scrape_configs:
9+
- job_name: 'prometheus'
10+
static_configs:
11+
- targets: ['localhost:9090']
12+
13+
- job_name: 'node-exporter'
14+
static_configs:
15+
- targets: ['node-exporter:9100']
16+
17+
- job_name: 'cadvisor'
18+
static_configs:
19+
- targets: ['cadvisor:8080']
20+
# cAdvisor expõe métricas em /metrics por padrão
21+
22+
# Habilitar quando a gem prometheus-client for adicionada à API Rails
23+
# e o endpoint /metrics for exposto em config/routes.rb
24+
# - job_name: 'prostaff-api'
25+
# static_configs:
26+
# - targets: ['api:3000']
27+
# metrics_path: '/metrics'
28+
# scheme: http
29+
30+
# Habilitar quando o scraper expor métricas Prometheus
31+
# - job_name: 'scraper-api'
32+
# static_configs:
33+
# - targets: ['scraper-api:8000']
34+
# metrics_path: '/metrics'

0 commit comments

Comments
 (0)