diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr index 6dc9860eb..c103e484a 100644 --- a/src/invidious/helpers/helpers.cr +++ b/src/invidious/helpers/helpers.cr @@ -225,3 +225,11 @@ def get_playback_statistic return tracker.as(Hash(String, Int64 | Float64)) end + +def to_prometheus_metrics(metrics_struct : Hash(String, Number)) : String + return String.build do |str| + metrics_struct.each.each do |key, value| + str << key << " " << value << "\n" + end + end +end diff --git a/src/invidious/jobs/statistics_refresh_job.cr b/src/invidious/jobs/statistics_refresh_job.cr index 72d1ce882..431fb8294 100644 --- a/src/invidious/jobs/statistics_refresh_job.cr +++ b/src/invidious/jobs/statistics_refresh_job.cr @@ -27,6 +27,11 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob "playback" => {} of String => Int64 | Float64, } + STATISTICS_PROMETHEUS = { + "invidious_updated_at" => Time.utc.to_unix, + "invidious_last_channel_refreshed_at" => 0_i64, + } + private getter db : DB::Database def initialize(@db, @software_config : Hash(String, String)) @@ -59,6 +64,9 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob users["activeHalfyear"] = Invidious::Database::Statistics.count_users_active_1m users["activeMonth"] = Invidious::Database::Statistics.count_users_active_6m + STATISTICS_PROMETHEUS["invidious_updated_at"] = Time.utc.to_unix + STATISTICS_PROMETHEUS["invidious_last_channel_refreshed_at"] = Invidious::Database::Statistics.channel_last_update.try &.to_unix || 0_i64 + STATISTICS["metadata"] = { "updatedAt" => Time.utc.to_unix, "lastChannelRefreshedAt" => Invidious::Database::Statistics.channel_last_update.try &.to_unix || 0_i64, diff --git a/src/invidious/routes/api/v1/misc.cr b/src/invidious/routes/api/v1/misc.cr index b42ecd1ac..d4e65655d 100644 --- a/src/invidious/routes/api/v1/misc.cr +++ b/src/invidious/routes/api/v1/misc.cr @@ -26,6 +26,11 @@ module Invidious::Routes::API::V1::Misc end end + def self.metrics(env) + env.response.content_type = "text/plain" + return to_prometheus_metrics(Invidious::Jobs::StatisticsRefreshJob::STATISTICS_PROMETHEUS) + end + # APIv1 currently uses the same logic for both # user playlists and Invidious playlists. This means that we can't # reasonably split them yet. This should be addressed in APIv2 diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index d6bd991c5..27c3d1994 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -310,6 +310,9 @@ module Invidious::Routing # Misc get "/api/v1/stats", {{namespace}}::Misc, :stats + if CONFIG.statistics_enabled + get "/api/v1/metrics", {{namespace}}::Misc, :metrics + end get "/api/v1/playlists/:plid", {{namespace}}::Misc, :get_playlist get "/api/v1/auth/playlists/:plid", {{namespace}}::Misc, :get_playlist get "/api/v1/mixes/:rdid", {{namespace}}::Misc, :mixes