Class: Lens::Rails::RequestsExporter

Inherits:
Object
  • Object
show all
Defined in:
lib/lens/rails/requests_exporter.rb

Overview

Subscribes to ActionController, ActionView, ActiveRecord, and ActiveJob notifications and flushes collected records to POST /v1/requests.

Constant Summary collapse

SKIP_SCHEMA =
/\A(SCHEMA|ActiveRecord::SchemaMigration|ActiveRecord::InternalMetadata)\z/
SKIP_JOB_CLASS =
/\ASolidQueue::/

Instance Method Summary collapse

Constructor Details

#initialize(url:, token:, service_name:, sql_threshold_ms: 0.0, sql_ignore: [], open_timeout: 2, read_timeout: 2) ⇒ RequestsExporter

Returns a new instance of RequestsExporter.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/lens/rails/requests_exporter.rb', line 72

def initialize(url:, token:, service_name:,
  sql_threshold_ms: 0.0, sql_ignore: [],
  open_timeout: 2, read_timeout: 2)
  @uri = URI("#{url}/v1/requests")
  @token = token
  @service_name = service_name
  @sql_threshold_ms = sql_threshold_ms
  @sql_ignore = sql_ignore
  @open_timeout = open_timeout
  @read_timeout = read_timeout
  @mutex = Mutex.new
  @requests = []
  @jobs = []
  subscribe!
  restart_flush_thread
  Lens::Rails.register_flushable(self)
end

Instance Method Details

#flushObject



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/lens/rails/requests_exporter.rb', line 90

def flush
  requests, jobs = @mutex.synchronize do
    [@requests.tap { @requests = [] }, @jobs.tap { @jobs = [] }]
  end
  return if requests.empty? && jobs.empty?

  body = JSON.generate(requests: requests, jobs: jobs,
    service: @service_name, version: Lens::Rails::VERSION)

  req = Net::HTTP::Post.new(@uri)
  req["Content-Type"] = "application/octet-stream"
  req["Authorization"] = "Bearer #{@token}"
  req.body = Zlib.gzip(body)

  Thread.current[:lens_in_export] = true
  begin
    Net::HTTP.start(@uri.host, @uri.port,
      use_ssl: @uri.scheme == "https",
      open_timeout: @open_timeout,
      read_timeout: @read_timeout) { |http| http.request(req) }
  ensure
    Thread.current[:lens_in_export] = false
  end
end

#restart_flush_threadObject



120
121
122
# File 'lib/lens/rails/requests_exporter.rb', line 120

def restart_flush_thread
  BackoffLoop.new(base: 30, max: 120, name: "lens-requests-flush").start { flush }
end

#shutdown(timeout:) ⇒ Object



115
116
117
118
# File 'lib/lens/rails/requests_exporter.rb', line 115

def shutdown(timeout:)
  Thread.new { flush }.join(timeout)
rescue
end