mirror of
https://github.com/System-End/identity-vault.git
synced 2026-04-19 16:28:21 +00:00
rails_pulse delenda est
This commit is contained in:
parent
f5e98c1b69
commit
69c2507793
11 changed files with 1 additions and 393 deletions
1
Gemfile
1
Gemfile
|
|
@ -153,4 +153,3 @@ gem "premailer-rails", "~> 1.12"
|
|||
|
||||
gem "openssl", "~> 3.3"
|
||||
|
||||
gem "rails_pulse"
|
||||
|
|
|
|||
20
Gemfile.lock
20
Gemfile.lock
|
|
@ -162,7 +162,6 @@ GEM
|
|||
countries (7.1.1)
|
||||
unaccent (~> 0.3)
|
||||
crass (1.0.6)
|
||||
css-zero (1.1.15)
|
||||
css_parser (1.21.1)
|
||||
addressable
|
||||
csv (3.3.5)
|
||||
|
|
@ -250,8 +249,6 @@ GEM
|
|||
fugit (>= 1.11.0)
|
||||
railties (>= 6.1.0)
|
||||
thor (>= 1.0.0)
|
||||
groupdate (6.7.0)
|
||||
activesupport (>= 7.1)
|
||||
hashid-rails (1.4.1)
|
||||
activerecord (>= 4.0)
|
||||
hashids (~> 1.0)
|
||||
|
|
@ -368,9 +365,6 @@ GEM
|
|||
nokogiri (~> 1.13)
|
||||
openssl (3.3.2)
|
||||
ostruct (0.6.1)
|
||||
pagy (43.2.2)
|
||||
json
|
||||
yaml
|
||||
paper_trail (16.0.0)
|
||||
activerecord (>= 6.1)
|
||||
request_store (~> 1.4)
|
||||
|
|
@ -453,14 +447,6 @@ GEM
|
|||
rails-html-sanitizer (1.6.2)
|
||||
loofah (~> 2.21)
|
||||
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
||||
rails_pulse (0.2.4)
|
||||
css-zero (~> 1.1, >= 1.1.4)
|
||||
groupdate (~> 6.0)
|
||||
pagy (>= 8, < 44)
|
||||
rails (>= 7.1.0, < 9.0.0)
|
||||
ransack (~> 4.0)
|
||||
request_store (~> 1.5)
|
||||
turbo-rails (~> 2.0.11)
|
||||
rails_semantic_logger (4.17.0)
|
||||
rack
|
||||
railties (>= 5.1)
|
||||
|
|
@ -475,10 +461,6 @@ GEM
|
|||
zeitwerk (~> 2.6)
|
||||
rainbow (3.1.1)
|
||||
rake (13.2.1)
|
||||
ransack (4.4.1)
|
||||
activerecord (>= 7.2)
|
||||
activesupport (>= 7.2)
|
||||
i18n
|
||||
rdoc (6.14.0)
|
||||
erb
|
||||
psych (>= 4.0.0)
|
||||
|
|
@ -610,7 +592,6 @@ GEM
|
|||
websocket-extensions (0.1.5)
|
||||
wicked (2.0.0)
|
||||
railties (>= 3.0.7)
|
||||
yaml (0.4.0)
|
||||
zeitwerk (2.7.3)
|
||||
|
||||
PLATFORMS
|
||||
|
|
@ -677,7 +658,6 @@ DEPENDENCIES
|
|||
pundit (~> 2.5)
|
||||
rack-attack (~> 6.7)
|
||||
rails (~> 8.0.2)
|
||||
rails_pulse
|
||||
rails_semantic_logger (~> 4.17)
|
||||
redcarpet (~> 3.6)
|
||||
rexml
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ module Shortcodes
|
|||
Shortcode.new(code: "USRS", label: "Backend users", controller: "backend/users", action: "index", icon: "⭢", role: :super_admin, path_override: nil),
|
||||
Shortcode.new(code: "JOBS", label: "Job queue", controller: "good_job/jobs", action: "index", icon: "⭢", role: :super_admin, path_override: "/backend/good_job"),
|
||||
Shortcode.new(code: "FLIP", label: "Feature flags", controller: "flipper/features", action: "index", icon: "⭢", role: :super_admin, path_override: "/backend/flipper"),
|
||||
Shortcode.new(code: "ORWL", label: "Console audit", controller: "audits1984/audits", action: "index", icon: "⭢", role: :super_admin, path_override: "/backend/console_audit"),
|
||||
Shortcode.new(code: "PLSE", label: "Rails Pulse", controller: "rails_pulse/dashboard", action: "index", icon: "⭢", role: :super_admin, path_override: "/backend/rails_pulse")
|
||||
Shortcode.new(code: "ORWL", label: "Console audit", controller: "audits1984/audits", action: "index", icon: "⭢", role: :super_admin, path_override: "/backend/console_audit")
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,6 @@
|
|||
<p class="shortcode"> [ JOBS ]</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<div data-navigable-item>
|
||||
<%= render Components::Backend::Item.new(icon: "⭢", href: "/backend/rails_pulse") do %>
|
||||
<b>Rails Pulse</b>
|
||||
<p class="shortcode"> [ PLSE ]</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<div data-navigable-item>
|
||||
<%= render Components::Backend::Item.new(icon: "⭢", href: backend_users_path) do %>
|
||||
<b>Manage users</b>
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ development:
|
|||
primary:
|
||||
<<: *default
|
||||
database: identity_vault_development
|
||||
rails_pulse:
|
||||
<<: *default
|
||||
database: identity_vault_rails_pulse_development
|
||||
migrations_paths: db/rails_pulse_migrate
|
||||
|
||||
# The specified database role being used to connect to PostgreSQL.
|
||||
# To create additional roles in PostgreSQL see `$ createuser --help`.
|
||||
|
|
@ -64,10 +60,6 @@ test:
|
|||
primary:
|
||||
<<: *default
|
||||
database: identity_vault_test
|
||||
rails_pulse:
|
||||
<<: *default
|
||||
database: identity_vault_rails_pulse_test
|
||||
migrations_paths: db/rails_pulse_migrate
|
||||
|
||||
# As with config/credentials.yml, you never want to store sensitive information,
|
||||
# like your database password, in your source code. If your source code is
|
||||
|
|
@ -93,16 +85,8 @@ production:
|
|||
primary:
|
||||
<<: *default
|
||||
database: identity_vault_prod
|
||||
rails_pulse:
|
||||
<<: *default
|
||||
database: identity_vault_rails_pulse_production
|
||||
migrations_paths: db/rails_pulse_migrate
|
||||
|
||||
staging:
|
||||
primary:
|
||||
<<: *default
|
||||
database: identity_vault_staging
|
||||
rails_pulse:
|
||||
<<: *default
|
||||
database: identity_vault_rails_pulse_staging
|
||||
migrations_paths: db/rails_pulse_migrate
|
||||
|
|
|
|||
|
|
@ -3,14 +3,6 @@ Rails.application.configure do
|
|||
expire_draft_aadhaar_verifications: {
|
||||
cron: "*/5 * * * *", # Run every 5 minutes
|
||||
class: "Verification::ExpireDraftAadhaarVerificationsJob"
|
||||
},
|
||||
rails_pulse_summary: {
|
||||
cron: "5 * * * *", # Run 5 minutes past every hour
|
||||
class: "RailsPulse::SummaryJob"
|
||||
},
|
||||
rails_pulse_cleanup: {
|
||||
cron: "0 1 * * *", # Run daily at 1:00 AM
|
||||
class: "RailsPulse::CleanupJob"
|
||||
}
|
||||
}
|
||||
config.good_job.enable_cron = true
|
||||
|
|
|
|||
|
|
@ -1,208 +0,0 @@
|
|||
RailsPulse.configure do |config|
|
||||
# ====================================================================================================
|
||||
# GLOBAL CONFIGURATION
|
||||
# ====================================================================================================
|
||||
|
||||
# Enable or disable Rails Pulse
|
||||
config.enabled = true
|
||||
|
||||
# ====================================================================================================
|
||||
# THRESHOLDS
|
||||
# ====================================================================================================
|
||||
# These thresholds are used to determine if a route, request, or query is slow, very slow, or critical.
|
||||
# Values are in milliseconds (ms). Adjust these based on your application's performance requirements.
|
||||
|
||||
# Thresholds for an individual route
|
||||
config.route_thresholds = {
|
||||
slow: 500,
|
||||
very_slow: 1500,
|
||||
critical: 3000
|
||||
}
|
||||
|
||||
# Thresholds for an individual request
|
||||
config.request_thresholds = {
|
||||
slow: 700,
|
||||
very_slow: 2000,
|
||||
critical: 4000
|
||||
}
|
||||
|
||||
# Thresholds for an individual database query
|
||||
config.query_thresholds = {
|
||||
slow: 100,
|
||||
very_slow: 500,
|
||||
critical: 1000
|
||||
}
|
||||
|
||||
# ====================================================================================================
|
||||
# FILTERING
|
||||
# ====================================================================================================
|
||||
|
||||
# Asset Tracking Configuration
|
||||
# By default, Rails Pulse ignores asset requests (images, CSS, JS files) to focus on application performance.
|
||||
# Set track_assets to true if you want to monitor asset delivery performance.
|
||||
config.track_assets = false
|
||||
|
||||
# Custom asset patterns to ignore (in addition to the built-in defaults)
|
||||
# Only applies when track_assets is false. Add patterns for app-specific asset paths.
|
||||
config.custom_asset_patterns = [
|
||||
# Example: ignore specific asset directories
|
||||
# %r{^/uploads/},
|
||||
# %r{^/media/},
|
||||
# "/special-assets/"
|
||||
]
|
||||
|
||||
# Rails Pulse Mount Path (optional)
|
||||
# If Rails Pulse is mounted at a custom path, specify it here to prevent
|
||||
# Rails Pulse from tracking its own requests. Leave as nil for default '/rails_pulse'.
|
||||
# Examples:
|
||||
# config.mount_path = "/admin/monitoring"
|
||||
config.mount_path = "/backend/rails_pulse"
|
||||
|
||||
# Manual route filtering
|
||||
# Specify additional routes, requests, or queries to ignore from performance tracking.
|
||||
# Each array can include strings (exact matches) or regular expressions.
|
||||
#
|
||||
# Examples:
|
||||
# config.ignored_routes = ["/health_check", %r{^/admin}]
|
||||
# config.ignored_requests = ["GET /status", %r{POST /api/v1/.*}]
|
||||
# config.ignored_queries = ["SELECT 1", %r{FROM \"schema_migrations\"}]
|
||||
|
||||
config.ignored_routes = []
|
||||
config.ignored_requests = []
|
||||
config.ignored_queries = []
|
||||
|
||||
# ====================================================================================================
|
||||
# TAGGING
|
||||
# ====================================================================================================
|
||||
# Define custom tags for categorizing routes, requests, and queries.
|
||||
# You can add any custom tags you want for filtering and organization.
|
||||
#
|
||||
# Tag names should be in present tense and describe the current state or category.
|
||||
# Examples of good tag names:
|
||||
# - "critical" (for high-priority endpoints)
|
||||
# - "experimental" (for routes under development)
|
||||
# - "deprecated" (for routes being phased out)
|
||||
# - "external" (for third-party API calls)
|
||||
# - "background" (for async job-related operations)
|
||||
# - "admin" (for administrative routes)
|
||||
# - "public" (for public-facing routes)
|
||||
#
|
||||
# Example configuration:
|
||||
# config.tags = ["ignored", "critical", "experimental", "deprecated", "external", "admin"]
|
||||
|
||||
config.tags = [ "ignored", "critical", "experimental" ]
|
||||
|
||||
# ====================================================================================================
|
||||
# DATABASE CONFIGURATION
|
||||
# ====================================================================================================
|
||||
# Configure Rails Pulse to use a separate database for performance monitoring data.
|
||||
# This is optional but recommended for production applications to isolate performance
|
||||
# data from your main application database.
|
||||
#
|
||||
# Uncomment and configure one of the following patterns:
|
||||
|
||||
# Option 1: Separate single database for Rails Pulse
|
||||
config.connects_to = {
|
||||
database: { writing: :rails_pulse, reading: :rails_pulse }
|
||||
}
|
||||
|
||||
# Option 2: Primary/replica configuration for Rails Pulse
|
||||
# config.connects_to = {
|
||||
# database: { writing: :rails_pulse_primary, reading: :rails_pulse_replica }
|
||||
# }
|
||||
|
||||
# Don't forget to add the database configuration to config/database.yml:
|
||||
#
|
||||
# production:
|
||||
# # ... your main database config ...
|
||||
# rails_pulse:
|
||||
# adapter: postgresql # or mysql2, sqlite3
|
||||
# database: myapp_rails_pulse_production
|
||||
# username: rails_pulse_user
|
||||
# password: <%= Rails.application.credentials.dig(:rails_pulse, :database_password) %>
|
||||
# host: localhost
|
||||
# pool: 5
|
||||
|
||||
# ====================================================================================================
|
||||
# AUTHENTICATION
|
||||
# ====================================================================================================
|
||||
# Configure authentication to secure access to the Rails Pulse dashboard.
|
||||
# Authentication is ENABLED BY DEFAULT in production environments for security.
|
||||
#
|
||||
# If no authentication method is configured, Rails Pulse will use HTTP Basic Auth
|
||||
# with credentials from RAILS_PULSE_USERNAME (default: 'admin') and RAILS_PULSE_PASSWORD
|
||||
# environment variables. Set RAILS_PULSE_PASSWORD to enable this fallback.
|
||||
#
|
||||
# Uncomment and configure one of the following patterns based on your authentication system:
|
||||
|
||||
# Enable/disable authentication (enabled by default in production)
|
||||
config.authentication_enabled = false
|
||||
# we have SuperAdminConstraint in routes/
|
||||
|
||||
# Where to redirect unauthorized users
|
||||
# config.authentication_redirect_path = "/"
|
||||
|
||||
# Custom authentication method - choose one of the examples below:
|
||||
|
||||
# Example 1: Devise with admin role check
|
||||
# config.authentication_method = proc {
|
||||
# unless user_signed_in? && current_user.admin?
|
||||
# redirect_to main_app.root_path, alert: "Access denied"
|
||||
# end
|
||||
# }
|
||||
|
||||
# Example 2: Custom session-based authentication
|
||||
# config.authentication_method = proc {
|
||||
# unless session[:user_id] && User.find_by(id: session[:user_id])&.admin?
|
||||
# redirect_to main_app.login_path, alert: "Please log in as an admin"
|
||||
# end
|
||||
# }
|
||||
|
||||
# Example 3: Warden authentication
|
||||
# config.authentication_method = proc {
|
||||
# warden.authenticate!(:scope => :admin)
|
||||
# }
|
||||
|
||||
# Example 4: Basic HTTP authentication
|
||||
# config.authentication_method = proc {
|
||||
# authenticate_or_request_with_http_basic do |username, password|
|
||||
# username == ENV['RAILS_PULSE_USERNAME'] && password == ENV['RAILS_PULSE_PASSWORD']
|
||||
# end
|
||||
# }
|
||||
|
||||
# Example 5: Custom authorization check
|
||||
# config.authentication_method = proc {
|
||||
# current_user = User.find_by(id: session[:user_id])
|
||||
# unless current_user&.can_access_rails_pulse?
|
||||
# render plain: "Forbidden", status: :forbidden
|
||||
# end
|
||||
# }
|
||||
|
||||
# ====================================================================================================
|
||||
# DATA CLEANUP
|
||||
# ====================================================================================================
|
||||
# Configure automatic cleanup of old performance data to manage database size.
|
||||
# Rails Pulse provides two cleanup mechanisms that work together:
|
||||
#
|
||||
# 1. Time-based cleanup: Delete records older than the retention period
|
||||
# 2. Count-based cleanup: Keep only the specified number of records per table
|
||||
#
|
||||
# Cleanup order respects foreign key constraints:
|
||||
# operations → requests → queries/routes
|
||||
|
||||
# Enable or disable automatic data cleanup
|
||||
config.archiving_enabled = true
|
||||
|
||||
# Time-based retention - delete records older than this period
|
||||
config.full_retention_period = 2.weeks
|
||||
|
||||
# Count-based retention - maximum records to keep per table
|
||||
# After time-based cleanup, if tables still exceed these limits,
|
||||
# the oldest remaining records will be deleted to stay under the limit
|
||||
config.max_table_records = {
|
||||
rails_pulse_requests: 10000, # HTTP requests (moderate volume)
|
||||
rails_pulse_operations: 50000, # Operations within requests (high volume)
|
||||
rails_pulse_routes: 1000, # Unique routes (low volume)
|
||||
rails_pulse_queries: 500 # Normalized SQL queries (low volume)
|
||||
}
|
||||
end
|
||||
|
|
@ -185,7 +185,6 @@ Rails.application.routes.draw do
|
|||
mount GoodJob::Engine => "good_job"
|
||||
mount Audits1984::Engine => "/console_audit"
|
||||
mount Flipper::UI.app(Flipper) => "/flipper", as: :flipper
|
||||
mount RailsPulse::Engine => "rails_pulse"
|
||||
end
|
||||
resources :audit_logs, only: [ :index ]
|
||||
get "dashboard", to: "dashboard#show", as: :dashboard
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
class InstallRailsPulseTables < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
schema_file = Rails.root.join("db", "rails_pulse_schema.rb")
|
||||
|
||||
unless File.exist?(schema_file)
|
||||
raise "Rails Pulse schema file not found at #{schema_file}"
|
||||
end
|
||||
|
||||
say_with_time "Loading Rails Pulse schema from #{schema_file}" do
|
||||
load schema_file
|
||||
say "Rails Pulse tables created successfully"
|
||||
say "The schema file #{schema_file} remains as your single source of truth"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
#
|
||||
# This file is the source Rails uses to define your schema when running `bin/rails
|
||||
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
|
||||
# be faster and is potentially less error prone than running all of your
|
||||
# migrations from scratch. Old migrations may fail to apply correctly if those
|
||||
# migrations use external dependencies or application code.
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_12_22_190545) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_catalog.plpgsql"
|
||||
|
||||
create_table "rails_pulse_operations", force: :cascade do |t|
|
||||
t.bigint "request_id", null: false, comment: "Link to the request"
|
||||
t.bigint "query_id", comment: "Link to the normalized SQL query"
|
||||
t.string "operation_type", null: false, comment: "Type of operation (e.g., database, view, gem_call)"
|
||||
t.string "label", null: false, comment: "Descriptive name (e.g., SELECT FROM users WHERE id = 1, render layout)"
|
||||
t.decimal "duration", precision: 15, scale: 6, null: false, comment: "Operation duration in milliseconds"
|
||||
t.string "codebase_location", comment: "File and line number (e.g., app/models/user.rb:25)"
|
||||
t.float "start_time", default: 0.0, null: false, comment: "Operation start time in milliseconds"
|
||||
t.datetime "occurred_at", precision: nil, null: false, comment: "When the request started"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["created_at", "query_id"], name: "idx_operations_for_aggregation"
|
||||
t.index ["created_at"], name: "idx_operations_created_at"
|
||||
t.index ["occurred_at", "duration", "operation_type"], name: "index_rails_pulse_operations_on_time_duration_type"
|
||||
t.index ["occurred_at"], name: "index_rails_pulse_operations_on_occurred_at"
|
||||
t.index ["operation_type"], name: "index_rails_pulse_operations_on_operation_type"
|
||||
t.index ["query_id", "duration", "occurred_at"], name: "index_rails_pulse_operations_query_performance"
|
||||
t.index ["query_id", "occurred_at"], name: "index_rails_pulse_operations_on_query_and_time"
|
||||
t.index ["query_id"], name: "index_rails_pulse_operations_on_query_id"
|
||||
t.index ["request_id"], name: "index_rails_pulse_operations_on_request_id"
|
||||
end
|
||||
|
||||
create_table "rails_pulse_queries", force: :cascade do |t|
|
||||
t.string "normalized_sql", limit: 1000, null: false, comment: "Normalized SQL query string (e.g., SELECT * FROM users WHERE id = ?)"
|
||||
t.datetime "analyzed_at", comment: "When query analysis was last performed"
|
||||
t.text "explain_plan", comment: "EXPLAIN output from actual SQL execution"
|
||||
t.text "issues", comment: "JSON array of detected performance issues"
|
||||
t.text "metadata", comment: "JSON object containing query complexity metrics"
|
||||
t.text "query_stats", comment: "JSON object with query characteristics analysis"
|
||||
t.text "backtrace_analysis", comment: "JSON object with call chain and N+1 detection"
|
||||
t.text "index_recommendations", comment: "JSON array of database index recommendations"
|
||||
t.text "n_plus_one_analysis", comment: "JSON object with enhanced N+1 query detection results"
|
||||
t.text "suggestions", comment: "JSON array of optimization recommendations"
|
||||
t.text "tags", comment: "JSON array of tags for filtering and categorization"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["normalized_sql"], name: "index_rails_pulse_queries_on_normalized_sql", unique: true
|
||||
end
|
||||
|
||||
create_table "rails_pulse_requests", force: :cascade do |t|
|
||||
t.bigint "route_id", null: false, comment: "Link to the route"
|
||||
t.decimal "duration", precision: 15, scale: 6, null: false, comment: "Total request duration in milliseconds"
|
||||
t.integer "status", null: false, comment: "HTTP status code (e.g., 200, 500)"
|
||||
t.boolean "is_error", default: false, null: false, comment: "True if status >= 500"
|
||||
t.string "request_uuid", null: false, comment: "Unique identifier for the request (e.g., UUID)"
|
||||
t.string "controller_action", comment: "Controller and action handling the request (e.g., PostsController#show)"
|
||||
t.datetime "occurred_at", precision: nil, null: false, comment: "When the request started"
|
||||
t.text "tags", comment: "JSON array of tags for filtering and categorization"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["created_at", "route_id"], name: "idx_requests_for_aggregation"
|
||||
t.index ["created_at"], name: "idx_requests_created_at"
|
||||
t.index ["occurred_at"], name: "index_rails_pulse_requests_on_occurred_at"
|
||||
t.index ["request_uuid"], name: "index_rails_pulse_requests_on_request_uuid", unique: true
|
||||
t.index ["route_id", "occurred_at"], name: "index_rails_pulse_requests_on_route_id_and_occurred_at"
|
||||
t.index ["route_id"], name: "index_rails_pulse_requests_on_route_id"
|
||||
end
|
||||
|
||||
create_table "rails_pulse_routes", force: :cascade do |t|
|
||||
t.string "method", null: false, comment: "HTTP method (e.g., GET, POST)"
|
||||
t.string "path", null: false, comment: "Request path (e.g., /posts/index)"
|
||||
t.text "tags", comment: "JSON array of tags for filtering and categorization"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["method", "path"], name: "index_rails_pulse_routes_on_method_and_path", unique: true
|
||||
end
|
||||
|
||||
create_table "rails_pulse_summaries", force: :cascade do |t|
|
||||
t.datetime "period_start", null: false, comment: "Start of the aggregation period"
|
||||
t.datetime "period_end", null: false, comment: "End of the aggregation period"
|
||||
t.string "period_type", null: false, comment: "Aggregation period type: hour, day, week, month"
|
||||
t.string "summarizable_type", null: false
|
||||
t.bigint "summarizable_id", null: false, comment: "Link to Route or Query"
|
||||
t.integer "count", default: 0, null: false, comment: "Total number of requests/operations"
|
||||
t.float "avg_duration", comment: "Average duration in milliseconds"
|
||||
t.float "min_duration", comment: "Minimum duration in milliseconds"
|
||||
t.float "max_duration", comment: "Maximum duration in milliseconds"
|
||||
t.float "p50_duration", comment: "50th percentile duration"
|
||||
t.float "p95_duration", comment: "95th percentile duration"
|
||||
t.float "p99_duration", comment: "99th percentile duration"
|
||||
t.float "total_duration", comment: "Total duration in milliseconds"
|
||||
t.float "stddev_duration", comment: "Standard deviation of duration"
|
||||
t.integer "error_count", default: 0, comment: "Number of error responses (5xx)"
|
||||
t.integer "success_count", default: 0, comment: "Number of successful responses"
|
||||
t.integer "status_2xx", default: 0, comment: "Number of 2xx responses"
|
||||
t.integer "status_3xx", default: 0, comment: "Number of 3xx responses"
|
||||
t.integer "status_4xx", default: 0, comment: "Number of 4xx responses"
|
||||
t.integer "status_5xx", default: 0, comment: "Number of 5xx responses"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["created_at"], name: "index_rails_pulse_summaries_on_created_at"
|
||||
t.index ["period_type", "period_start"], name: "index_rails_pulse_summaries_on_period"
|
||||
t.index ["summarizable_type", "summarizable_id", "period_type", "period_start"], name: "idx_pulse_summaries_unique", unique: true
|
||||
t.index ["summarizable_type", "summarizable_id"], name: "index_rails_pulse_summaries_on_summarizable"
|
||||
end
|
||||
|
||||
add_foreign_key "rails_pulse_operations", "rails_pulse_queries", column: "query_id"
|
||||
add_foreign_key "rails_pulse_operations", "rails_pulse_requests", column: "request_id"
|
||||
add_foreign_key "rails_pulse_requests", "rails_pulse_routes", column: "route_id"
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue