diff --git a/Gemfile b/Gemfile index 36935daf..5e9f6938 100644 --- a/Gemfile +++ b/Gemfile @@ -54,9 +54,6 @@ gem 'kredis' # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby] -# Exposes Metrics -gem 'prometheus_exporter' - # vault for secrets management gem 'vault' diff --git a/Gemfile.lock b/Gemfile.lock index 26ac948e..e7abd417 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -211,8 +211,6 @@ GEM parser (3.3.5.0) ast (~> 2.4.1) racc - prometheus_exporter (2.1.1) - webrick pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) @@ -375,7 +373,6 @@ DEPENDENCIES money-rails newrelic_rpm overcommit - prometheus_exporter pry puma (~> 6.4) rack-cors diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2aff0f00..07321f17 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -17,7 +17,7 @@ def validate_jwt_token decoded_token = (JWT.decode token, JwtOptions.secret, true, { algorithm: JwtOptions.algorithm })[0] @current_user = decoded_token['user_id'].to_i rescue JWT::VerificationError, JWT::InvalidJtiError - Metrics.jwt_verification_error_counter.increment + Metrics.increment('jwt_verification_error_counter') render json: { error: ErrorCodes::INVALID_TOKEN }, status: :unauthorized rescue JWT::ExpiredSignature render json: { error: ErrorCodes::EXPIRED_TOKEN }, status: :unauthorized @@ -37,7 +37,7 @@ def performance_profile(&) end def render_error(http_status, error, data = nil) - Metrics.registration_validation_errors_counter.increment + Metrics.increment('registration_validation_errors_counter') if data.present? render json: { error: error, data: data }, status: http_status else diff --git a/app/controllers/registration_controller.rb b/app/controllers/registration_controller.rb index 22874f87..c325cffa 100644 --- a/app/controllers/registration_controller.rb +++ b/app/controllers/registration_controller.rb @@ -71,7 +71,7 @@ def update render json: { status: 'ok', registration: process_update(params) } rescue Dynamoid::Errors::Error => e Rails.logger.debug e - Metrics.registration_dynamodb_errors_counter.increment + Metrics.increment('registration_dynamodb_errors_counter') render json: { error: "Error Updating Registration: #{e.message}" }, status: :internal_server_error end @@ -179,7 +179,7 @@ def list rescue Dynamoid::Errors::Error => e # Render an error response Rails.logger.debug e - Metrics.registration_dynamodb_errors_counter.increment + Metrics.increment('registration_dynamodb_errors_counter') render json: { error: "Error getting registrations #{e}" }, status: :internal_server_error end @@ -193,7 +193,7 @@ def mine rescue Dynamoid::Errors::Error => e # Render an error response Rails.logger.debug e - Metrics.registration_dynamodb_errors_counter.increment + Metrics.increment('registration_dynamodb_errors_counter') render json: { error: "Error getting registrations #{e}" }, status: :internal_server_error end @@ -212,7 +212,7 @@ def list_admin render json: add_waiting_list(@competition_id, registrations_with_pii) rescue Dynamoid::Errors::Error => e Rails.logger.debug e - Metrics.registration_dynamodb_errors_counter.increment + Metrics.increment('registration_dynamodb_errors_counter') render json: { error: "Error getting registrations #{e}" }, status: :internal_server_error end diff --git a/app/jobs/registration_processor.rb b/app/jobs/registration_processor.rb index 5af03be2..ef267d6b 100644 --- a/app/jobs/registration_processor.rb +++ b/app/jobs/registration_processor.rb @@ -16,6 +16,7 @@ def perform(message) message[:created_at]) end Rails.cache.delete("#{message[:user_id]}-registrations-by-user") + Metrics.increment('registrations_processed') end private diff --git a/config/initializers/prometheus.rb b/config/initializers/prometheus.rb deleted file mode 100644 index 7c51f780..00000000 --- a/config/initializers/prometheus.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require 'prometheus_exporter/client' -require 'prometheus_exporter/instrumentation' -require 'prometheus_exporter/metric' - -PrometheusExporter::Client.default = PrometheusExporter::Client.new(host: ENV.fetch('PROMETHEUS_EXPORTER'), port: 9091) - -if Rails.env.production? && !EnvConfig.REGISTRATION_LIVE_SITE? - PrometheusExporter::Instrumentation::Process.start(type: 'wca-registration-handler-staging', labels: { process: '1' }) - suffix = '-staging' -else - PrometheusExporter::Instrumentation::Process.start(type: 'wca-registration-handler', labels: { process: '1' }) - suffix = '' -end - -unless Rails.env.test? - require 'prometheus_exporter/middleware' - - # This reports stats per request like HTTP status and timings - Rails.application.middleware.unshift PrometheusExporter::Middleware -end - -# Create our Metric Counters -Rails.application.config.to_prepare do - Metrics.registration_dynamodb_errors_counter = PrometheusExporter::Client.default.register('counter', "registration_dynamodb_errors_counter#{suffix}", 'The number of times interacting with dynamodb fails') - Metrics.registration_competition_api_error_counter = PrometheusExporter::Client.default.register('counter', "registration_competition_api_error_counter#{suffix}", 'The number of times interacting with the competition API failed') - Metrics.registration_competitor_api_error_counter = PrometheusExporter::Client.default.register('counter', "registration_competitor_api_error_counter#{suffix}", 'The number of times interacting with the user API failed') - Metrics.registration_validation_errors_counter = PrometheusExporter::Client.default.register('counter', "registration_validation_errors_counter#{suffix}", 'The number of times validation fails when an attendee tries to register') - Metrics.jwt_verification_error_counter = PrometheusExporter::Client.default.register('counter', "jwt_verification_error_counter#{suffix}", 'The number of times JWT verification failed') - Metrics.registration_impersonation_attempt_counter = PrometheusExporter::Client.default.register('counter', "registration_impersonation_attempt_counter#{suffix}", 'The number of times a Person tries to register as someone else') -end diff --git a/docker-compose.backend-test.yml b/docker-compose.backend-test.yml index 95923dbc..563a692a 100644 --- a/docker-compose.backend-test.yml +++ b/docker-compose.backend-test.yml @@ -8,7 +8,6 @@ services: - "3001:3000" environment: LOCALSTACK_ENDPOINT: "http://localstack:4566" - PROMETHEUS_EXPORTER: "prometheus_exporter" REDIS_URL: "redis://redis:6379" RAILS_ENV: test QUEUE_NAME: "registrations.fifo" @@ -23,7 +22,6 @@ services: - wca-registration depends_on: - localstack - - prometheus_exporter - redis - wca_registration_worker healthcheck: @@ -32,17 +30,6 @@ services: # Set the DNS server to be the LocalStack container - 10.0.2.20 - - prometheus_exporter: - build: - context: . - dockerfile: dockerfile.metrics - tty: true - ports: - - "9090:9090" - networks: - - wca-registration - wca_registration_worker: container_name: wca_registration_worker build: @@ -53,7 +40,6 @@ services: AWS_REGION: "us-east-1" AWS_ACCESS_KEY_ID: "fake-key" AWS_SECRET_ACCESS_KEY: "fake-access-key" - PROMETHEUS_EXPORTER: "prometheus_exporter" DYNAMO_REGISTRATIONS_TABLE: "registrations-development" QUEUE_NAME: "registrations.fifo" volumes: diff --git a/docker-compose.yml b/docker-compose.yml index 5951597b..e78a4c69 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,6 @@ services: - "8000:3000" environment: LOCALSTACK_ENDPOINT: "http://localstack:4566" - PROMETHEUS_EXPORTER: "prometheus_exporter" REDIS_URL: "redis://redis:6379" RAILS_ENV: development QUEUE_NAME: "registrations.fifo" @@ -27,7 +26,6 @@ services: - wca-main depends_on: - localstack - - prometheus_exporter - redis healthcheck: test: curl --fail http://localhost:3000/healthcheck @@ -35,17 +33,6 @@ services: # Set the DNS server to be the LocalStack container - 10.0.2.20 - prometheus_exporter: - container_name: prometheus_exporter - build: - context: . - dockerfile: dockerfile.metrics - tty: true - ports: - - "9091:9091" - networks: - - wca-registration - wca_registration_worker: container_name: wca_registration_worker @@ -57,7 +44,6 @@ services: AWS_REGION: "us-east-1" AWS_ACCESS_KEY_ID: "fake-key" AWS_SECRET_ACCESS_KEY: "fake-access-key" - PROMETHEUS_EXPORTER: "prometheus_exporter" DYNAMO_REGISTRATIONS_TABLE: "registrations-development" REGISTRATION_HISTORY_DYNAMO_TABLE: "registration-history-development" CODE_ENVIRONMENT: "development" diff --git a/dockerfile.metrics b/dockerfile.metrics deleted file mode 100644 index 4a3af34c..00000000 --- a/dockerfile.metrics +++ /dev/null @@ -1,8 +0,0 @@ -FROM ruby:3.3.0-alpine - -RUN gem install prometheus_exporter - -CMD ["-v","-b", "0.0.0.0", "-p", "9091"] - - -ENTRYPOINT ["/usr/local/bundle/bin/prometheus_exporter"] diff --git a/env_config.rb b/env_config.rb index 48aeee65..4532e8cf 100644 --- a/env_config.rb +++ b/env_config.rb @@ -23,7 +23,6 @@ end # We even need the AWS_REGION in dev because we fake authenticate with localstack mandatory :AWS_REGION, :string - mandatory :PROMETHEUS_EXPORTER, :string mandatory :DYNAMO_REGISTRATIONS_TABLE, :string mandatory :REGISTRATION_HISTORY_DYNAMO_TABLE, :string mandatory :WAITING_LIST_DYNAMO_TABLE, :string diff --git a/infra/handler/main.tf b/infra/handler/main.tf index c6f8ba6b..6e159deb 100644 --- a/infra/handler/main.tf +++ b/infra/handler/main.tf @@ -48,10 +48,6 @@ locals { name = "QUEUE_NAME", value = var.shared_resources.queue.name }, - { - name = "PROMETHEUS_EXPORTER" - value = var.prometheus_address - }, { name = "REDIS_URL" value = "redis://${var.shared_resources.aws_elasticache_cluster.cache_nodes.0.address}:${var.shared_resources.aws_elasticache_cluster.cache_nodes.0.port}" diff --git a/infra/handler/variables.tf b/infra/handler/variables.tf index 7ef51e10..406733f2 100644 --- a/infra/handler/variables.tf +++ b/infra/handler/variables.tf @@ -10,12 +10,6 @@ variable "vault_address" { default = "http://vault.worldcubeassociation.org:8200" } -variable "prometheus_address" { - type = string - description = "The Address that prometheus is running at" - default = "prometheus.worldcubeassociation.org" -} - variable "name_prefix" { type = string description = "Prefix for naming resources" diff --git a/infra/staging/main.tf b/infra/staging/main.tf index 9f84d446..fdd70b9e 100644 --- a/infra/staging/main.tf +++ b/infra/staging/main.tf @@ -48,10 +48,6 @@ locals { name = "WAITING_LIST_DYNAMO_TABLE", value = aws_dynamodb_table.waiting_list.name }, - { - name = "PROMETHEUS_EXPORTER" - value = var.prometheus_address - }, { name = "REDIS_URL" value = "redis://${aws_elasticache_cluster.this.cache_nodes.0.address}:${aws_elasticache_cluster.this.cache_nodes.0.port}" diff --git a/infra/staging/variables.tf b/infra/staging/variables.tf index 968198fb..65f9342e 100644 --- a/infra/staging/variables.tf +++ b/infra/staging/variables.tf @@ -22,12 +22,6 @@ variable "vault_address" { default = "http://vault.worldcubeassociation.org:8200" } -variable "prometheus_address" { - type = string - description = "The Address that prometheus is running at" - default = "prometheus.worldcubeassociation.org" -} - variable "region" { type = string description = "The region to operate in" diff --git a/infra/worker/main.tf b/infra/worker/main.tf index d3ef0ded..b427de6c 100644 --- a/infra/worker/main.tf +++ b/infra/worker/main.tf @@ -32,10 +32,6 @@ locals { name = "REGISTRATION_LIVE_SITE", value = "true" }, - { - name = "PROMETHEUS_EXPORTER" - value = var.prometheus_address - }, { name = "TASK_ROLE" value = aws_iam_role.task_role.name diff --git a/infra/worker/variables.tf b/infra/worker/variables.tf index 223b4bbe..d1d97cfe 100644 --- a/infra/worker/variables.tf +++ b/infra/worker/variables.tf @@ -27,11 +27,6 @@ variable "region" { description = "The region to operate in" default = "us-west-2" } -variable "prometheus_address" { - type = string - description = "The Address that prometheus is running at" - default = "prometheus.worldcubeassociation.org" -} variable "availability_zones" { type = list(string) diff --git a/lib/competition_api.rb b/lib/competition_api.rb index 3bf9d9f3..2d3acfca 100644 --- a/lib/competition_api.rb +++ b/lib/competition_api.rb @@ -29,10 +29,10 @@ def self.fetch_qualifications(competition_id) @status = 200 response.parsed_response when 404 - Metrics.registration_competition_api_error_counter.increment + Metrics.increment('registration_competition_api_404_counter') raise RegistrationError.new(404, ErrorCodes::COMPETITION_NOT_FOUND) else - Metrics.registration_competition_api_error_counter.increment + Metrics.increment('registration_competition_api_error_counter') raise RegistrationError.new(response.code.to_i, ErrorCodes::COMPETITION_API_5XX) end end @@ -45,10 +45,10 @@ def self.fetch_qualifications(competition_id) when 200 response.parsed_response when 404 - Metrics.registration_competition_api_error_counter.increment + Metrics.increment('registration_competition_api_404_counter') raise RegistrationError.new(404, ErrorCodes::COMPETITION_NOT_FOUND) else - Metrics.registration_competition_api_error_counter.increment + Metrics.increment('registration_competition_api_error_counter') raise RegistrationError.new(response.code.to_i, ErrorCodes::COMPETITION_API_5XX) end end diff --git a/lib/metrics.rb b/lib/metrics.rb index f1348ce3..64415861 100644 --- a/lib/metrics.rb +++ b/lib/metrics.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module Metrics - class << self - attr_accessor :registration_validation_errors_counter, :registration_dynamodb_errors_counter, :registrations_counter, :registration_competition_api_error_counter, :registration_competitor_api_error_counter, - :registration_impersonation_attempt_counter, :jwt_verification_error_counter + def self.increment(metric) + return if Rails.env.local? + ::NewRelic::Agent.increment_metric("Custom/Registration/#{metric}") end end