From d099ed1efa6b55d7a43eadfcddf5805d01798df8 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 3 Apr 2025 13:18:28 +0300 Subject: [PATCH] Add Prometheus integration #60181 --- Gemfile | 6 ++ Gemfile.lock | 75 +++++++++++++++++++ config.ru | 5 ++ config/puma.rb | 6 ++ .../configuration/environment/README.md | 1 + .../operation/monitoring/README.md | 9 +++ 6 files changed, 102 insertions(+) diff --git a/Gemfile b/Gemfile index 4ce4a6a1b7d..cc9cd73df38 100644 --- a/Gemfile +++ b/Gemfile @@ -223,6 +223,12 @@ gem "store_attribute", "~> 2.0" # Appsignal integration gem "appsignal", "~> 3.10.0", require: false +# Yabeda integration +gem "yabeda-activerecord" +gem "yabeda-prometheus-mmap" +gem "yabeda-puma-plugin" +gem "yabeda-rails" + gem "view_component" # Lookbook gem "lookbook", "~> 2.3.4" diff --git a/Gemfile.lock b/Gemfile.lock index 68eb413d58d..2c77e8936ec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -343,6 +343,8 @@ GEM airbrake-ruby (6.2.2) rbtree3 (~> 0.6) android_key_attestation (0.3.0) + anyway_config (2.7.2) + ruby-next-core (~> 1.0) appsignal (3.10.0) rack ast (2.4.3) @@ -905,9 +907,44 @@ GEM prawn (>= 1.3.0, < 3.0.0) prettyprint (0.2.0) prism (1.4.0) + prometheus-client-mmap (1.2.9) + base64 + bigdecimal + logger + rb_sys (~> 0.9.109) + prometheus-client-mmap (1.2.9-aarch64-linux-gnu) + base64 + bigdecimal + logger + rb_sys (~> 0.9.109) + prometheus-client-mmap (1.2.9-aarch64-linux-musl) + base64 + bigdecimal + logger + rb_sys (~> 0.9.109) + prometheus-client-mmap (1.2.9-arm64-darwin) + base64 + bigdecimal + logger + rb_sys (~> 0.9.109) + prometheus-client-mmap (1.2.9-x86_64-darwin) + base64 + bigdecimal + logger + rb_sys (~> 0.9.109) + prometheus-client-mmap (1.2.9-x86_64-linux-gnu) + base64 + bigdecimal + logger + rb_sys (~> 0.9.109) + prometheus-client-mmap (1.2.9-x86_64-linux-musl) + base64 + bigdecimal + logger pry (0.15.2) coderay (~> 1.1) method_source (~> 1.0) + rb_sys (~> 0.9.109) pry-byebug (3.11.0) byebug (~> 12.0) pry (>= 0.13, < 0.16) @@ -1106,6 +1143,7 @@ GEM activesupport (>= 3.0.0) i18n iso8601 + ruby-next-core (1.1.1) ruby-ole (1.2.13.1) ruby-prof (1.7.1) ruby-progressbar (1.13.0) @@ -1256,6 +1294,25 @@ GEM zeitwerk (>= 2.6) xpath (3.2.0) nokogiri (~> 1.8) + yabeda (0.13.1) + anyway_config (>= 1.0, < 3) + concurrent-ruby + dry-initializer + yabeda-activerecord (0.1.1) + activerecord (>= 6.0) + yabeda (~> 0.6) + yabeda-prometheus-mmap (0.4.0) + prometheus-client-mmap + yabeda (~> 0.10) + yabeda-puma-plugin (0.7.1) + json + puma + yabeda (~> 0.5) + yabeda-rails (0.9.0) + activesupport + anyway_config (>= 1.3, < 3) + railties + yabeda (~> 0.8) yard (0.9.37) zeitwerk (2.7.2) @@ -1485,6 +1542,10 @@ DEPENDENCIES webmock (~> 3.12) will_paginate (~> 4.0.0) with_advisory_lock (~> 5.1.0) + yabeda-activerecord + yabeda-prometheus-mmap + yabeda-puma-plugin + yabeda-rails CHECKSUMS Ascii85 (2.0.1) sha256=15cb5d941808543cbb9e7e6aea3c8ec3877f154c3461e8b3673e97f7ecedbe5a @@ -1513,6 +1574,7 @@ CHECKSUMS airbrake (13.0.5) sha256=901f5074c25d5ef77ed87f5bde7a28400a7324f5d7013a8a12d07e0099cc31b6 airbrake-ruby (6.2.2) sha256=293e34fb36e763e1b6d67ab584cce7c5b6fe9eea1a70c26d8c13c0f5d7de2fbc android_key_attestation (0.3.0) sha256=467eb01a99d2bb48ef9cf24cc13712669d7056cba5a52d009554ff037560570b + anyway_config (2.7.2) sha256=30f6b087c0b41afdd43fe46c81d65a16f052a8489dab453abaeb4ea67aa74bad appsignal (3.10.0) sha256=2a18f3253afdf2fc2d7f9e43d5118976c05a614934abcbb29bb84000d047b61b ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 attr_required (1.0.2) sha256=f0ebfc56b35e874f4d0ae799066dbc1f81efefe2364ca3803dc9ea6a4de6cb99 @@ -1787,6 +1849,13 @@ CHECKSUMS prawn-table (0.2.2) sha256=336d46e39e003f77bf973337a958af6a68300b941c85cb22288872dc2b36addb prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 prism (1.4.0) sha256=dc0e3e00e93160213dc2a65519d9002a4a1e7b962db57d444cf1a71565bb703e + prometheus-client-mmap (1.2.9) sha256=20ff9ef443767bc45d338882fbc6a9a853cdae190ec68cfd9395a5ac44384004 + prometheus-client-mmap (1.2.9-aarch64-linux-gnu) sha256=e2a52234bed534fbce8185b781f49e2a584808a3713fb77287fb3017ae4e8dad + prometheus-client-mmap (1.2.9-aarch64-linux-musl) sha256=4d09f7c011cba48ca119515988e1683c4a99fc4310fb33145817541043556f55 + prometheus-client-mmap (1.2.9-arm64-darwin) sha256=2d5277fe916d76e92a2801685d02bb7da4c8d62ba32e9bb83eb1edc9ad8bb165 + prometheus-client-mmap (1.2.9-x86_64-darwin) sha256=aab97474ccc96cc707af4be5b26f8d2fe89f4d67013ad996ae10f17712f527ff + prometheus-client-mmap (1.2.9-x86_64-linux-gnu) sha256=f17f2b069f73a976b421cf6730974d3addf196656b8437deca9c36845f658f9e + prometheus-client-mmap (1.2.9-x86_64-linux-musl) sha256=e2af29e954f40fda4c3acb5c3b9722dbfc724d8d67a28e01904233e558c4ce1d pry (0.15.2) sha256=12d54b8640d3fa29c9211dd4ffb08f3fd8bf7a4fd9b5a73ce5b59c8709385b6b pry-byebug (3.11.0) sha256=0b0abb7d309bc7f00044d512a3c8567274f7012b944b38becc8440439a1cea72 pry-rails (0.3.11) sha256=a69e28e24a34d75d1f60bcf241192a54253f8f7ef8a62cba1e75750a9653593d @@ -1857,6 +1926,7 @@ CHECKSUMS rubocop-rspec (3.6.0) sha256=c0e4205871776727e54dee9cc91af5fd74578001551ba40e1fe1a1ab4b404479 rubocop-rspec_rails (2.31.0) sha256=775375e18a26a1184a812ef3054b79d218e85601b9ae897f38f8be24dddf1f45 ruby-duration (3.2.3) sha256=eb3d13b1df85067a015a8fb2ed8f1eec842a3b721e47c9b6fd74d2f356069784 + ruby-next-core (1.1.1) sha256=37886d41cf91072a0f14fa53b3e7e650adce1fe3b1227842bae32034dcce1d5f ruby-ole (1.2.13.1) sha256=578d10dd2a797a2b35a1286c6fb2c9525f67c24791346fc8015d39f0ffa3cb72 ruby-prof (1.7.1) sha256=026393448cf92fd24a91739bf71ccd2bfe88fe8a1401ee8afc4948a16d62ea24 ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 @@ -1932,6 +2002,11 @@ CHECKSUMS will_paginate (4.0.1) sha256=107b226ebe1d393d274575956a7c472e1eefdd97d8828e01b72d425d15a875b9 with_advisory_lock (5.1.0) sha256=0692cd82013b271c59aa5e1f603b741ab94926dbce098990fbace5dd5412fed7 xpath (3.2.0) sha256=6dfda79d91bb3b949b947ecc5919f042ef2f399b904013eb3ef6d20dd3a4082e + yabeda (0.13.1) sha256=3213025f22b7746602c8a4c41e2ed82d73a90bdc5489f6ef472142b06c1cf954 + yabeda-activerecord (0.1.1) sha256=ae338213c264f20d8642e8bf47ac6058c49a6f7c8c00c892cd5765332914f45f + yabeda-prometheus-mmap (0.4.0) sha256=1a66120756d6f931f03a7784e08e79060d71681ff83a9f5287df2ff756e9e2c9 + yabeda-puma-plugin (0.7.1) sha256=a41d72053b8eb5b9db92c59bfb4a95f1988bafd2fdc9f4f13836849af073b17b + yabeda-rails (0.9.0) sha256=6011bfa1e282456dbb4f0d6571267ad57108b54fab0de37ae3b70653fa9582da yard (0.9.37) sha256=a6e910399e78e613f80ba9add9ba7c394b1a935f083cccbef82903a3d2a26992 zeitwerk (2.7.2) sha256=842e067cb11eb923d747249badfb5fcdc9652d6f20a1f06453317920fdcd4673 diff --git a/config.ru b/config.ru index f72d7c70572..94f20f17a13 100644 --- a/config.ru +++ b/config.ru @@ -28,6 +28,11 @@ # This file is used by Rack-based servers to start the application. +if ENV["OPENPROJECT_PROMETHEUS_EXPORT"] == "true" + require "yabeda/prometheus/mmap" + use Yabeda::Prometheus::Exporter +end + require File.expand_path("config/environment", __dir__) subdir = OpenProject::Configuration.rails_relative_url_root.presence diff --git a/config/puma.rb b/config/puma.rb index 8f225b55914..0a15ae87026 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -36,6 +36,12 @@ plugin :tmp_restart unless ENV["RAILS_ENV"] == "production" plugin :appsignal if ENV["APPSIGNAL_ENABLED"] == "true" +if ENV["OPENPROJECT_PROMETHEUS_EXPORT"] == "true" + activate_control_app + plugin :yabeda + plugin :yabeda_prometheus +end + # activate statsd plugin only if a host is configured explicitly if OpenProject::Configuration.statsd_host.present? module ConfigurationViaOpenProject diff --git a/docs/installation-and-operations/configuration/environment/README.md b/docs/installation-and-operations/configuration/environment/README.md index 80d57a7cf1a..85bd0445e7f 100644 --- a/docs/installation-and-operations/configuration/environment/README.md +++ b/docs/installation-and-operations/configuration/environment/README.md @@ -275,6 +275,7 @@ OPENPROJECT_PLUGIN__OPENPROJECT__STORAGES (default=nil) OPENPROJECT_PLUGIN__OPENPROJECT__TEAM__PLANNER (default=nil) OPENPROJECT_PLUGIN__OPENPROJECT__TWO__FACTOR__AUTHENTICATION (default={"active_strategies"=>[], "enforced"=>false, "allow_remember_for_days"=>0}) OPENPROJECT_PROJECT__GANTT__QUERY (default=nil) Project portfolio Gantt view +OPENPROJECT_PROMETHEUS_EXPORT (default: nil) Enable Prometheus export endpoint OPENPROJECT_RAILS__ASSET__HOST (default=nil) Custom asset hostname for serving assets (e.g., Cloudfront) OPENPROJECT_RAILS__CACHE__STORE (default=:file_store) Set cache store implemenation to use with OpenProject OPENPROJECT_RAILS__RELATIVE__URL__ROOT (default="") Set a URL prefix / base path to run OpenProject under, e.g., host.tld/openproject diff --git a/docs/installation-and-operations/operation/monitoring/README.md b/docs/installation-and-operations/operation/monitoring/README.md index 9c47269029b..730cca092c6 100644 --- a/docs/installation-and-operations/operation/monitoring/README.md +++ b/docs/installation-and-operations/operation/monitoring/README.md @@ -102,6 +102,15 @@ service openproject restart For Docker-based installations, add the ENV variable to your env file and restart the containers. +## Prometheus metrics + +OpenProject can give metrics suitable to use with Prometheus. + +To enable this option the [environment variable](../../configuration/environment/#environment-variables) `OPENPROJECT_PROMETHEUS_EXPORT` has to be set to `true`. +[Yabeda Prometheus gem](https://github.com/yabeda-rb/yabeda-prometheus-mmap) is used with [ActiveRecord](https://github.com/yabeda-rb/yabeda-activerecord/), [Rails](https://github.com/yabeda-rb/yabeda-rails/) and [Puma](https://github.com/yabeda-rb/yabeda-puma-plugin/) plugins. + +Listening address is configured via `PROMETHEUS_EXPORTER_BIND` env variable with default 0.0.0.0. Port is configured by `PROMETHEUS_EXPORTER_PORT` variable with default 9394. Both provided by Prometheus gem. + ## Health checks OpenProject uses the [okcomputer gem](https://github.com/sportngin/okcomputer) to provide built-in health checks on database, web, and background workers.