{"record":{"id":"fa3aaabd357b4553","repo":"ankane/pghero","slug":"system-stats-not-enabled","errorCode":null,"errorMessage":"System stats not enabled","messagePattern":"System stats not enabled","errorType":"exception","errorClass":"PgHero::NotEnabled","httpStatus":null,"severity":"warning","filePath":"lib/pghero/methods/system.rb","lineNumber":74,"sourceCode":"          resp = client.get_metric_statistics(\n            namespace: \"AWS/RDS\",\n            metric_name: metric_name,\n            dimensions: [{name: \"DBInstanceIdentifier\", value: aws_db_instance_identifier}],\n            start_time: start_time.iso8601,\n            end_time: end_time.iso8601,\n            period: period,\n            statistics: [\"Average\"]\n          )\n          data = {}\n          resp[:datapoints].sort_by { |d| d[:timestamp] }.each do |d|\n            data[d[:timestamp]] = d[:average]\n          end\n\n          add_missing_data(data, start_time, end_time, period) if series\n\n          data\n        else\n          raise NotEnabled, \"System stats not enabled\"\n        end\n      end\n\n      private\n\n      def gcp_stats(metric_name, duration: nil, period: nil, offset: nil, series: false)\n        # TODO DRY with RDS stats\n        duration = (duration || 1.hour).to_i\n        period = (period || 1.minute).to_i\n        offset = (offset || 0).to_i\n        end_time = Time.at(((Time.now - offset).to_f / period).ceil * period)\n        start_time = end_time - duration\n\n        # validate input since we need to interpolate below\n        raise Error, \"Invalid metric name\" unless /\\A[a-z\\/_]+\\z/i.match?(metric_name)\n        raise Error, \"Invalid database id\" unless /\\A[a-z0-9\\-:]+\\z/i.match?(gcp_database_id)\n\n        # we handle three situations:","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/ankane/pghero/blob/7edb57986ffd36f9d64f0830c4ccc90a5eac46d6/lib/pghero/methods/system.rb#L56-L92","documentation":"PgHero raises this from PgHero::Methods::System#rds_stats when system_stats_enabled? is false, i.e. system_stats_provider is nil because neither aws_db_instance_identifier nor gcp_database_id is configured for the database in config/pghero.yml. rds_stats fetches CloudWatch metrics (AWS/RDS namespace) via Aws::CloudWatch::Client, so without an RDS instance identifier PgHero refuses the call rather than querying CloudWatch blindly.","triggerScenarios":"Calling PgHero.rds_stats(\"CPUUtilization\", ...) directly, or reaching it through cpu_usage/connection_stats/replication_lag_stats/read_iops_stats/write_iops_stats/free_space_stats when the AWS identifier is missing; typical when pghero.yml has no aws: section or the database entry uses DATABASE_URL without aws_db_instance_identifier.","commonSituations":"Self-hosted or non-RDS Postgres where system stats are simply unsupported; pghero.yml deployed with the aws keys commented out; per-database config listing a second database without its own aws settings; missing aws-cloudwatch gem surfacing later as a different failure after the config is fixed.","solutions":["In config/pghero.yml, set the database's aws: block: db_instance_identifier (PgHero's key is aws_db_instance_identifier via `aws: db_instance_identifier: ...`), aws_region, and optionally aws_access_key_id/aws_secret_access_key (otherwise IAM instance profile is used).","Add the `aws-cloudwatch` gem to the Gemfile so Aws::CloudWatch::Client can be loaded.","If not on RDS but on Cloud SQL, configure gcp_database_id instead so the provider becomes :gcp and calls route to gcp_stats rather than rds_stats.","Guard with `PgHero.system_stats_enabled?` (and system_stats_provider == :aws) or rescue PgHero::NotEnabled."],"exampleFix":"# before - raises PgHero::NotEnabled: System stats not enabled\nPgHero.cpu_usage(duration: 1.hour)\n\n# after\n# Gemfile: gem \"aws-cloudwatch\"\n# config/pghero.yml:\n#   databases:\n#     main:\n#       aws:\n#         db_instance_identifier: my-prod-instance\n#         region: us-east-1\nusage = PgHero.cpu_usage(duration: 1.hour) if PgHero.system_stats_provider == :aws","handlingStrategy":"validation","validationCode":"return unless PgHero.system_stats_enabled? && PgHero.system_stats_provider == :aws\ncpu = PgHero.rds_stats(\"CPUUtilization\", duration: 1.hour)","typeGuard":"def rds_stats_available?\n  PgHero.system_stats_provider == :aws\nend","tryCatchPattern":"begin\n  PgHero.rds_stats(metric, duration: 1.hour)\nrescue PgHero::NotEnabled\n  Rails.logger.info(\"Configure aws db_instance_identifier in pghero.yml for RDS stats\")\n  {}\nend","preventionTips":["Store the AWS identifier and region in env vars referenced from pghero.yml so every environment gets them via ERB.","Add the aws-cloudwatch gem whenever the aws: block is present.","Prefer the public wrappers (cpu_usage etc.) over rds_stats; they dispatch on the configured provider."],"tags":["pghero","aws","rds","cloudwatch","rails","configuration","not-enabled"],"backgroundTag":"optional-feature-not-enabled","analyzedSha":"7edb57986ffd36f9d64f0830c4ccc90a5eac46d6","analyzedAt":"2026-08-21T17:33:54.942Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}