Class: Errsight::Railtie

Inherits:
Rails::Railtie
  • Object
show all
Defined in:
lib/errsight/railtie.rb

Constant Summary collapse

HOSTNAME =

Captured once at boot — Socket.gethostname does a DNS lookup on some platforms and is called on the hot exception-capture path.

begin
  Socket.gethostname
rescue StandardError
  nil
end.freeze

Class Method Summary collapse

Class Method Details

.build_tags(payload, request) ⇒ Object

Top-level tags the UI uses for filtering. Rails env info is free at capture time and makes “errors on this controller/action/host” filters work without any app-side setup.



185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/errsight/railtie.rb', line 185

def self.build_tags(payload, request)
  tags = {
    "controller"     => payload[:controller],
    "action"         => payload[:action],
    "request_method" => request&.request_method,
    "status"         => payload[:status]&.to_s,
    "ruby_version"   => RUBY_VERSION,
    "rails_version"  => Rails.version
  }
  tags["hostname"] = HOSTNAME if HOSTNAME
  tags.compact.reject { |_, v| v.to_s.strip.empty? }
end

.build_user_context(request) ⇒ Object

Extracts a top-level user context the API stores in user_context / user_identifier. Falls through to just the request IP when no user is signed in so anonymous errors still carry some identity.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/errsight/railtie.rb', line 149

def self.build_user_context(request)
  ctx = {}

  # Warden-backed auth (Devise, ActiveAdmin, etc.). Walks every authenticated
  # scope in the session rather than hard-coding :user.
  begin
    warden = request&.env&.fetch("warden", nil)
    if warden
      session = request.env["rack.session"] || {}
      scopes  = session.keys
                       .grep(/\Awarden\.user\.(.+)\.key\z/) { $1.to_sym }
                       .then { |s| s.any? ? s : [ :user ] }

      user = scopes.lazy.filter_map { |scope| warden.user(scope) rescue nil }.first

      if user
        ctx[:id]       = user.id.to_s       if user.respond_to?(:id)       && !user.id.to_s.strip.empty?
        ctx[:email]    = user.email.to_s    if user.respond_to?(:email)    && !user.email.to_s.strip.empty?
        ctx[:username] = user.username.to_s if user.respond_to?(:username) && !user.username.to_s.strip.empty?
      end
    end
  rescue StandardError
    # never let user-lookup failures suppress the event
  end

  if request.respond_to?(:remote_ip)
    ip = request.remote_ip.to_s
    ctx[:ip_address] = ip unless ip.empty?
  end

  ctx.empty? ? nil : ctx
end