Class: ActiveTracker::Plugin::Request

Inherits:
Base
  • Object
show all
Defined in:
lib/active_tracker/plugin/request.rb

Class Method Summary collapse

Methods inherited from Base

nav_url

Class Method Details

.app_nameObject



99
100
101
# File 'lib/active_tracker/plugin/request.rb', line 99

def self.app_name
  ENV["APP_NAME"] || Rails.application.class.parent.to_s
end

.apply_redactions(value) ⇒ Object



155
156
157
158
159
160
# File 'lib/active_tracker/plugin/request.rb', line 155

def self.apply_redactions(value)
  (@redactions || []).each do |redaction|
    value = value.gsub(redaction, "[REDACTED]")
  end
  value
end

.clear_contextObject



82
83
84
85
# File 'lib/active_tracker/plugin/request.rb', line 82

def self.clear_context
  @tags = {}
  @redactions = []
end

.current_tagsObject



91
92
93
# File 'lib/active_tracker/plugin/request.rb', line 91

def self.current_tags
  @tags || {}
end

.filter_request?(path) ⇒ Boolean

Returns:

  • (Boolean)


139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/active_tracker/plugin/request.rb', line 139

def self.filter_request?(path)
  ActiveTracker::Plugin::Request.filters.each do |filter|
    if filter.is_a?(Regexp)
      if filter.match(path)
        return true
      end
    else
      if path.start_with?(filter)
        return true
      end
    end
  end

  false
end

.filtersObject



78
79
80
# File 'lib/active_tracker/plugin/request.rb', line 78

def self.filters
  @filters ||= ["/#{ActiveTracker::Configuration.mountpoint}"]
end

.filters=(value) ⇒ Object



74
75
76
# File 'lib/active_tracker/plugin/request.rb', line 74

def self.filters=(value)
  @filters = value
end


34
35
36
37
38
39
40
41
# File 'lib/active_tracker/plugin/request.rb', line 34

def self.nav_svg
  svg = <<~EOF
    <svg width="16" height="16" viewBox="0 0 16 16" class="fill-current" xmlns="http://www.w3.org/2000/svg">
    <path d="M16 1.5V10.5C16 11.3281 15.3281 12 14.5 12H13V5.5C13 4.12187 11.8781 3 10.5 3H4V1.5C4 0.671875 4.67188 0 5.5 0H14.5C15.3281 0 16 0.671875 16 1.5ZM12 5.5V14.5C12 15.3281 11.3281 16 10.5 16H1.5C0.671875 16 0 15.3281 0 14.5V5.5C0 4.67188 0.671875 4 1.5 4H10.5C11.3281 4 12 4.67188 12 5.5ZM9.875 6.375C9.875 6.16875 9.70625 6 9.5 6H2.375C2.16875 6 2 6.16875 2 6.375V8H9.875V6.375Z" />
    </svg>
  EOF
  svg.html_safe
end


43
44
45
# File 'lib/active_tracker/plugin/request.rb', line 43

def self.nav_title
  "Requests"
end

.output_capture(output, content_type) ⇒ Object



111
112
113
114
# File 'lib/active_tracker/plugin/request.rb', line 111

def self.output_capture(output, content_type)
  @output = output
  @content_type = content_type
end

.record_duration(duration) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/active_tracker/plugin/request.rb', line 116

def self.record_duration(duration)
  return if ActiveTracker::Plugin::Request.current_tags[:url] && filter_request?(ActiveTracker::Plugin::Request.current_tags[:url])

  @duration = duration
  log = @logger.lines[0, 65535] rescue ""

  _, status, duration = (@logger&.lines || "").force_encoding("UTF-8").match(/Completed (\d+) .*? in (\d+)ms/m).to_a
  tag_current status: status
  tag_current duration: "#{duration.to_i}ms"

  log = apply_redactions(log)
  @output = apply_redactions(@output)

  ActiveTracker::Model.save("Request", {log: log, output: @output, content_type: @content_type},
    tags: ActiveTracker::Plugin::Request.current_tags,
    data_type: "full",
    expiry: 7.days,
    log_at: Time.now
  ) if ActiveTracker::Plugin::Request.current_tags.any? && ActiveTracker::Plugin::Request.current_tags[:id].present?

  clear_context
end

.redact(value) ⇒ Object



95
96
97
# File 'lib/active_tracker/plugin/request.rb', line 95

def self.redact(value)
  @redactions << value
end

.registerObject



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/active_tracker/plugin/request.rb', line 4

def self.register
  @logger = ActiveTracker::RailsLogger.new
  @logger.level = Rails.logger.level
  Rails.logger.extend(ActiveSupport::Logger.broadcast(@logger))

  ActiveSupport::Notifications.subscribe "start_processing.action_controller" do |event|
    clear_context
    @logger.reset
    tag_current(id: SecureRandom.uuid)
    @output = ""
  end

  ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
    event = ActiveSupport::Notifications::Event.new(*args)
    request_processed(event)
  end

  Rails.application.middleware.insert_before Rack::Sendfile, ActiveTracker::OutputCapturer

  @@registered = true
end

.registered?Boolean

Returns:

  • (Boolean)


26
27
28
# File 'lib/active_tracker/plugin/request.rb', line 26

def self.registered?
  @@registered rescue false
end

.request_processed(event) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/active_tracker/plugin/request.rb', line 103

def self.request_processed(event)
  tag_current status: event.payload[:status]
  tag_current duration: "#{@duration.to_i}ms"
  tag_current url: event.payload[:path]
  tag_current method: event.payload[:method]
  tag_current app: app_name
end

.resources_nameObject



30
31
32
# File 'lib/active_tracker/plugin/request.rb', line 30

def self.resources_name
  :requests
end

.statisticsObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/active_tracker/plugin/request.rb', line 47

def self.statistics
  ret = []
  @requests = ActiveTracker::Model.all("Request")
  @requests = @requests.select {|e| e.log_at >= 60.minutes.ago}

  num_requests = @requests.count

  percentage_error = 0
  avg_milliseconds = 0
  if num_requests > 0
    num_errors = @requests.map {|r| r.tags[:status][0]}.select {|s| s=="4" || s=="5"}.count
    percentage_error = num_errors / @requests.count.to_f * 100.0
    avg_milliseconds = @requests.map {|r| r.tags[:duration].to_i}.sum / num_requests
  end


  ret << {plugin: self, label: "Requests/hour", value: num_requests}
  if percentage_error < 1.0
    ret << {plugin: self, label: "Error percentage", value: "%.1f%%" % percentage_error}
  else
    ret << {plugin: self, label: "Error percentage", value: "%.1f%%" % percentage_error, error: true}
  end
  ret << {plugin: self, label: "Avg time/request", value: "#{avg_milliseconds}ms"} if avg_milliseconds

  ret
end

.tag_current(tags = {}) ⇒ Object



87
88
89
# File 'lib/active_tracker/plugin/request.rb', line 87

def self.tag_current(tags = {})
  @tags = current_tags.merge(tags)
end