Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@

# Ignore master key for decrypting credentials and more.
/config/master.key
.idea
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ruby 3.2.9
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ gem "jbuilder"

gem "yabeda-rails"
gem "yabeda-prometheus"
gem "lograge"
gem "redis"
gem "logster"

# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
# gem "bcrypt", "~> 3.1.7"
Expand Down
16 changes: 16 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ GEM
language_server-protocol (3.17.0.5)
lint_roller (1.1.0)
logger (1.7.0)
lograge (0.14.0)
actionpack (>= 4)
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
logster (2.20.1)
loofah (2.24.1)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
Expand Down Expand Up @@ -247,9 +253,15 @@ GEM
erb
psych (>= 4.0.0)
tsort
redis (5.4.1)
redis-client (>= 0.22.0)
redis-client (0.26.1)
connection_pool
regexp_parser (2.11.3)
reline (0.6.2)
io-console (~> 0.5)
request_store (1.7.0)
rack (>= 1.4)
rexml (3.4.4)
rubocop (1.81.1)
json (~> 2.3)
Expand Down Expand Up @@ -366,6 +378,7 @@ GEM
PLATFORMS
aarch64-linux
arm64-darwin-24
arm64-darwin-25
x86_64-linux

DEPENDENCIES
Expand All @@ -376,9 +389,12 @@ DEPENDENCIES
importmap-rails
jbuilder
kamal
lograge
logster
propshaft
puma (>= 5.0)
rails (~> 8.0.3)
redis
rubocop-rails-omakase
selenium-webdriver
solid_cable
Expand Down
48 changes: 48 additions & 0 deletions alertmanager/alertmanager.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
global:
resolve_timeout: 5m

route:
group_by: ['alertname', 'cluster', 'service']
group_wait: 10s
group_interval: 10s
repeat_interval: 12h
receiver: 'default-receiver'
routes:
- match:
severity: critical
receiver: 'critical-receiver'
repeat_interval: 1h
- match:
severity: warning
receiver: 'warning-receiver'
repeat_interval: 3h

receivers:
- name: 'default-receiver'
# Для продакшна здесь можно настроить email, slack, pagerduty и т.д.
# Пример с webhook:
# webhook_configs:
# - url: 'http://example.com/webhook'

- name: 'critical-receiver'
# Критичные алерты - можно отправлять в Slack, PagerDuty
# slack_configs:
# - api_url: 'YOUR_SLACK_WEBHOOK_URL'
# channel: '#alerts-critical'
# title: 'Critical Alert'
# text: '{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}'

- name: 'warning-receiver'
# Предупреждения - можно отправлять в Slack
# slack_configs:
# - api_url: 'YOUR_SLACK_WEBHOOK_URL'
# channel: '#alerts-warning'
# title: 'Warning Alert'
# text: '{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}'

inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'cluster', 'service']
2 changes: 1 addition & 1 deletion app/controllers/hello_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def index
end

def refresh_online
users_online_count = rand(100..1000)
users_online_count = params['manual_count'].presence || rand(100..1000)
Yabeda.top_shop.user_online.set({}, users_online_count)
render plain: "#{users_online_count} users online now"
end
Expand Down
2 changes: 2 additions & 0 deletions config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@

# Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
# config.generators.apply_rubocop_autocorrect_after_generate!

config.hosts.clear
end
5 changes: 5 additions & 0 deletions config/initializers/lograge.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Rails.application.configure do
# Configure lograge
config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Json.new
end
4 changes: 4 additions & 0 deletions config/initializers/logster.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Rails.application.config.to_prepare do
Logster.store.level = Logger::INFO
Logster.config.application_version = Rails.application.class.module_parent_name
end
7 changes: 7 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
Rails.application.routes.draw do
mount Yabeda::Prometheus::Exporter, at: "/metrics"
mount(
Rack::Auth::Basic.new(Logster::Web) do |username, password|
username == ENV.fetch('LOGSTER_USERNAME', 'admin') &&
password == ENV.fetch('LOGSTER_PASSWORD', 'admin')
end,
at: "/logs"
)
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
Expand Down
88 changes: 88 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
version: '3.8'

services:
web:
build:
context: .
dockerfile: Dockerfile
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails server -b 0.0.0.0"
volumes:
- .:/app
- bundle_cache:/usr/local/bundle
ports:
- "3000:3000"
environment:
RAILS_ENV: development
RAILS_DEVELOPMENT_HOSTS: .web
REDIS_URL: redis://redis:6379/0
depends_on:
- redis

prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- ./prometheus/alert_rules.yml:/etc/prometheus/alert_rules.yml
- prometheus_data:/prometheus
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'
depends_on:
- web
- alertmanager

grafana:
image: grafana/grafana:latest
ports:
- "3001:3000"
environment:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: admin
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
depends_on:
- prometheus

node_exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro

alertmanager:
image: prom/alertmanager:latest
ports:
- "9093:9093"
volumes:
- ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
- alertmanager_data:/alertmanager
command:
- '--config.file=/etc/alertmanager/alertmanager.yml'
- '--storage.path=/alertmanager'

redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
command: redis-server --appendonly yes

volumes:
bundle_cache:
prometheus_data:
grafana_data:
alertmanager_data:
redis_data:
12 changes: 12 additions & 0 deletions grafana/provisioning/dashboards/dashboard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: 1

providers:
- name: 'Default'
orgId: 1
folder: ''
type: file
disableDeletion: false
updateIntervalSeconds: 10
allowUiUpdates: true
options:
path: /etc/grafana/provisioning/dashboards
Loading