diff --git a/Gemfile b/Gemfile index ea6548a8b..60d1729cf 100644 --- a/Gemfile +++ b/Gemfile @@ -56,6 +56,7 @@ gem "rbtrace" gem "good_job" gem "crass" gem "public_suffix" +gem "elastic-apm" group :development do gem 'rubocop', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 308b0f8f5..9a1635c9b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -166,6 +166,9 @@ GEM railties (>= 3.2) e2mmap (0.1.0) ed25519 (1.3.0) + elastic-apm (4.5.0) + concurrent-ruby (~> 1.0) + http (>= 3.0) erubi (1.10.0) et-orbi (1.2.7) tzinfo @@ -535,6 +538,7 @@ DEPENDENCIES dotenv-rails dtext_rb! ed25519 + elastic-apm factory_bot ffaker ffi diff --git a/app/logical/danbooru_logger.rb b/app/logical/danbooru_logger.rb index 51f2624d5..a96937c35 100644 --- a/app/logical/danbooru_logger.rb +++ b/app/logical/danbooru_logger.rb @@ -42,10 +42,10 @@ class DanbooruLogger # @param session the Rails session # @param user [User] the current user def self.add_session_attributes(request, session, user) - add_attributes("request", { path: request.path }) - add_attributes("request.headers", header_params(request)) - add_attributes("request.params", request_params(request)) - add_attributes("session.params", session_params(session)) + #add_attributes("request", { path: request.path }) + #add_attributes("request.headers", header_params(request)) + add_attributes("param", request_params(request)) + add_attributes("session", session_params(session)) add_attributes("user", user_params(request, user)) end @@ -70,10 +70,10 @@ class DanbooruLogger id: user&.id, name: user&.name, level: user&.level_string, - ip: request.remote_ip, - country: CurrentUser.country, - safe_mode: CurrentUser.safe_mode?, - bot: UserAgent.new(request.headers["HTTP_USER_AGENT"]).is_bot?, + #ip: request.remote_ip, + #country: CurrentUser.country, + #safe_mode: CurrentUser.safe_mode?, + #bot: UserAgent.new(request.headers["HTTP_USER_AGENT"]).is_bot?, } end @@ -86,12 +86,18 @@ class DanbooruLogger private_class_method def self.log_attributes(attributes) + attributes.each do |key, value| + ElasticAPM.set_label(key, value) + end end def self.log_exception(exception, expected: false, custom_params: {}) + ElasticAPM.report(exception, handled: expected) end def self.log_event(level, message: nil, **params) + ElasticAPM.set_custom_context(params) + ElasticAPM.report_message(message) end # flatten_hash({ foo: { bar: { baz: 42 } } }) diff --git a/app/logical/session_loader.rb b/app/logical/session_loader.rb index 3cdbcb724..438172d4f 100644 --- a/app/logical/session_loader.rb +++ b/app/logical/session_loader.rb @@ -117,7 +117,7 @@ class SessionLoader def authenticate_basic_auth credentials = ::Base64.decode64(request.authorization.split(' ', 2).last || '') login, api_key = credentials.split(/:/, 2) - DanbooruLogger.add_attributes("request.params", login: login) + DanbooruLogger.add_attributes("param", login: login) authenticate_api_key(login, api_key) end diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index 68b3c8333..c37d225ac 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -547,6 +547,13 @@ module Danbooru # "redis://localhost:6379" end + # Optional. The URL of the Elastic APM server. Used for application performance monitoring. + # + # https://www.elastic.co/observability/application-performance-monitoring + def elastic_apm_server_url + # "http://localhost:8200" + end + # True if the Winter Sale is active. def is_promotion? false diff --git a/config/initializers/00_elastic_apm.rb b/config/initializers/00_elastic_apm.rb new file mode 100644 index 000000000..11fa86e24 --- /dev/null +++ b/config/initializers/00_elastic_apm.rb @@ -0,0 +1,10 @@ +if Danbooru.config.elastic_apm_server_url.present? + require "elastic_apm" + + # https://www.elastic.co/guide/en/apm/agent/ruby/4.x/api.html#api-agent-start + # https://www.elastic.co/guide/en/apm/agent/ruby/4.x/configuration.html + ElasticAPM::Rails.start( + server_url: Danbooru.config.elastic_apm_server_url, + service_name: "Danbooru", + ) +end