Browse Source

add metrics collector

main
Lerk 6 months ago
parent
commit
4eff51e0a2
  1. 2
      Gemfile
  2. 4
      Gemfile.lock
  3. 1
      Procfile
  4. 1
      Procfile.dev
  5. 76
      bin/metrics-collector
  6. 15
      dist/mastodon-metrics-collector.service

2
Gemfile

@ -159,3 +159,5 @@ gem 'xorcist', '~> 1.1'
gem 'resolv', '~> 0.1.0'
gem "rexml", "~> 3.2"
gem "prometheus_exporter", "~> 0.8.0"

4
Gemfile.lock

@ -419,6 +419,8 @@ GEM
actionmailer (>= 3)
premailer (~> 1.7, >= 1.7.9)
private_address_check (0.5.0)
prometheus_exporter (0.8.0)
webrick
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
@ -658,6 +660,7 @@ GEM
webpush (0.3.8)
hkdf (~> 0.2)
jwt (~> 2.0)
webrick (1.7.0)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
@ -750,6 +753,7 @@ DEPENDENCIES
posix-spawn
premailer-rails
private_address_check (~> 0.5)
prometheus_exporter (~> 0.8.0)
pry-byebug (~> 3.9)
pry-rails (~> 0.3)
puma (~> 5.3)

1
Procfile

@ -1,5 +1,6 @@
web: bin/heroku-web
worker: bundle exec sidekiq
metrics-collector: ./bin/metrics-collector
# For the streaming API, you need a separate app that shares Postgres and Redis:
#

1
Procfile.dev

@ -2,3 +2,4 @@ web: env PORT=3000 RAILS_ENV=development bundle exec puma -C config/puma.rb
sidekiq: env PORT=3000 RAILS_ENV=development bundle exec sidekiq
stream: env PORT=4000 yarn run start
webpack: ./bin/webpack-dev-server --listen-host 0.0.0.0
metrics-collector: ./bin/metrics-collector

76
bin/metrics-collector

@ -0,0 +1,76 @@
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../config/application', __dir__)
require "bundler/setup"
require 'sidekiq/api'
require 'prometheus_exporter'
require 'prometheus_exporter/client'
require_relative '../config/boot'
require_relative '../config/environment'
scrape_interval = 2.seconds
ActiveRecord::Base.logger = Logger.new('/dev/null')
def collect_metric(gauge, value)
gauge.observe(value, instance: Rails.configuration.x.local_domain, version: Mastodon::Version)
end
begin
client = PrometheusExporter::Client.default
PrometheusExporter::Instrumentation::Process.start(client: client, type: "metrics-collector")
instance_presenter = InstancePresenter.new
logins_gauge = client.register(:gauge, "mastodon_logins_week", "Logins this week")
users_gauge = client.register(:gauge, "mastodon_users_total", "Total users")
active_users_gauge = client.register(:gauge, "mastodon_users_active_4w", "Active users in the last four weeks")
pending_gauge = client.register(:gauge, "mastodon_users_pending", "Pending users")
unresolved_gauge = client.register(:gauge, "mastodon_reports_unresolved", "Unresolved reports")
dbsize_gauge = client.register(:gauge, "mastodon_database_size_bytes", "Database size in bytes")
enqueued_gauge = client.register(:gauge, "sidekiq_jobs_enqueud", "Enquequed Sidekiq Jobs")
registrations_gauge = client.register(:gauge, "mastodon_registrations_1w", "Registrations this week")
relay_gauge = client.register(:gauge, "mastodon_relay_enabled", "Relay enabled")
registration_gauge = client.register(:gauge, "mastodon_registrations_enabled", "Registrations enabled")
fetch_duration_gauge = client.register(:gauge, "mastodon_metrics_collect_duration_millis", "Mastodon metric collection duration in milliseconds")
pending_tags_gauge = client.register(:gauge, "mastodon_pending_tags", "Pending Tags")
status_count_gauge = client.register(:gauge, "mastodon_status_count", "Number of statuses")
domain_count_gauge = client.register(:gauge, "mastodon_domain_count", "Number of known domains")
while true do
# This should come first!
start_time = DateTime.now.strftime("%Q").to_i
logins_value = Redis.current.pfcount("activity:logins:#{Time.now.utc.to_date.cweek}")
users_value = User.count
pending_value = User.pending.count
unresolved_value = Report.unresolved.count
dbsize_value = ActiveRecord::Base.connection.execute('SELECT pg_database_size(current_database())').first['pg_database_size']
enqueued_value = Sidekiq::Stats.new.enqueued
registrations_value = Redis.current.get("activity:accounts:local:#{Time.now.utc.to_date.cweek}") || 0
relay_value = Relay.enabled.exists? ? 1 : 0
registration_value = Setting.registrations_mode != 'none' ? 1 : 0
pending_tags_value = Tag.pending_review.count
status_count_value = instance_presenter.status_count
active_users_value = instance_presenter.active_user_count
domain_count_value = instance_presenter.domain_count
collect_metric(relay_gauge, relay_value)
collect_metric(users_gauge, users_value)
collect_metric(dbsize_gauge, dbsize_value)
collect_metric(logins_gauge, logins_value)
collect_metric(pending_gauge, pending_value)
collect_metric(enqueued_gauge, enqueued_value)
collect_metric(unresolved_gauge, unresolved_value)
collect_metric(registration_gauge, registration_value)
collect_metric(pending_tags_gauge, pending_tags_value)
collect_metric(status_count_gauge, status_count_value)
collect_metric(active_users_gauge, active_users_value)
collect_metric(domain_count_gauge, domain_count_value)
collect_metric(registrations_gauge, registrations_value)
# This should come last!
fetch_duration_gauge.observe(DateTime.now.strftime("%Q").to_i - start_time)
sleep(scrape_interval)
end
rescue Interrupt
exit(130)
end

15
dist/mastodon-metrics-collector.service

@ -0,0 +1,15 @@
[Unit]
Description=mastodon-metrics
After=network.target
[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec bin/metrics-collector
TimeoutSec=15
Restart=always
[Install]
WantedBy=multi-user.target
Loading…
Cancel
Save