Class: Profiler::Collectors::DatabaseCollector

Inherits:
BaseCollector show all
Defined in:
lib/profiler/collectors/database_collector.rb

Instance Attribute Summary

Attributes inherited from BaseCollector

#profile

Instance Method Summary collapse

Methods inherited from BaseCollector

descendants, #has_data?, inherited, #name, #panel_content, #render_html, #render_mode

Constructor Details

#initialize(profile) ⇒ DatabaseCollector

Returns a new instance of DatabaseCollector.



9
10
11
12
13
# File 'lib/profiler/collectors/database_collector.rb', line 9

def initialize(profile)
  super
  @queries = []
  @subscription = nil
end

Instance Method Details

#collectObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/profiler/collectors/database_collector.rb', line 57

def collect
  # Unsubscribe from notifications
  ActiveSupport::Notifications.unsubscribe(@subscription) if @subscription

  data = {
    total_queries: @queries.size,
    total_duration: @queries.sum(&:duration).round(2),
    slow_queries: @queries.select { |q| q.slow?(Profiler.configuration.slow_query_threshold) }.size,
    cached_queries: @queries.count(&:cached?),
    queries: @queries.map(&:to_h)
  }

  store_data(data)
end

#iconObject



15
16
17
# File 'lib/profiler/collectors/database_collector.rb', line 15

def icon
  "🗄️"
end

#priorityObject



19
20
21
# File 'lib/profiler/collectors/database_collector.rb', line 19

def priority
  20
end

#subscribeObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/profiler/collectors/database_collector.rb', line 34

def subscribe
  return unless defined?(ActiveSupport::Notifications)

  @subscription = ActiveSupport::Notifications.monotonic_subscribe("sql.active_record") do |name, started, finished, unique_id, payload|
    duration = ((finished - started) * 1000).round(2) # milliseconds

    # Skip schema queries and internal Rails queries
    next if payload[:name] == "SCHEMA"
    next if payload[:sql] =~ /^(BEGIN|COMMIT|ROLLBACK|SAVEPOINT)/i

    query = Models::SqlQuery.new(
      sql: payload[:sql],
      duration: duration,
      binds: extract_binds(payload[:binds]),
      name: payload[:name],
      connection: payload[:connection],
      backtrace: extract_backtrace
    )

    @queries << query
  end
end

#tab_configObject



23
24
25
26
27
28
29
30
31
32
# File 'lib/profiler/collectors/database_collector.rb', line 23

def tab_config
  {
    key: "database",
    label: "Database",
    icon: icon,
    priority: priority,
    enabled: true,
    default_active: true
  }
end

#toolbar_summaryObject



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/profiler/collectors/database_collector.rb', line 72

def toolbar_summary
  total = @queries.size
  slow = @queries.select { |q| q.slow?(Profiler.configuration.slow_query_threshold) }.size
  duration = @queries.sum(&:duration).round(2)

  color = if slow > 0
            "red"
          elsif total > Profiler.configuration.max_queries_warning
            "orange"
          else
            "green"
          end

  {
    text: "#{total} queries (#{duration}ms)",
    color: color,
    slow_queries: slow
  }
end