module Stasher

Constants

VERSION

Public Class Methods

add_custom_fields(&block) click to toggle source
# File lib/stasher.rb, line 41
def self.add_custom_fields(&block)
  ActionController::Metal.send(:define_method, :stasher_add_custom_fields_to_scope, &block)
end
add_default_fields_to_scope(scope, request) click to toggle source
# File lib/stasher.rb, line 37
def self.add_default_fields_to_scope(scope, request)
  scope[:uuid] = request.uuid
end
format_exception(type_name, message, backtrace) click to toggle source
# File lib/stasher.rb, line 80
def self.format_exception(type_name, message, backtrace)
  {
    :exception => { 
      :name => type_name,
      :message => message,
      :backtrace => backtrace
    }
  }
end
hostname() click to toggle source
# File lib/stasher.rb, line 120
def self.hostname
  require 'socket'

  Socket.gethostname
end
log(severity, msg) click to toggle source
# File lib/stasher.rb, line 90
def self.log(severity, msg)
  if self.logger && self.logger.send("#{severity.to_s.downcase}?")
    data = {
      :severity => severity.upcase
    }
    tags = ['log']

    if msg.is_a? Exception
      data.merge! self.format_exception(msg.class.name, msg.message, msg.backtrace.join("\n"))
      msg = "#{msg.class.name}: #{msg.message}"
      tags << 'exception'
    else        
      # Strip ANSI codes from the message
      msg.gsub!(/\u001B\[[0-9;]+m/, '')
    end

    return true if msg.empty?
    data.merge! CurrentScope.fields

    tags << severity.downcase

    event = LogStash::Event.new(
      '@fields' => data, 
      '@tags' => tags,
      '@message' => msg,
      '@source' => Stasher.source)
    self.logger << event.to_json + "\n"
  end
end
remove_existing_log_subscriptions() click to toggle source
# File lib/stasher.rb, line 13
def self.remove_existing_log_subscriptions
  ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
    case subscriber
      when ActionView::LogSubscriber
        unsubscribe(:action_view, subscriber)
      when ActiveRecord::LogSubscriber
        unsubscribe(:active_record, subscriber)
      when ActionController::LogSubscriber
        unsubscribe(:action_controller, subscriber)
    end
  end
end
setup(app) click to toggle source
# File lib/stasher.rb, line 45
def self.setup(app)
  app.config.action_dispatch.rack_cache[:verbose] = false if app.config.action_dispatch.rack_cache

  # Compose source
  self.source = "rails://#{hostname}/#{app.class.name.deconstantize.underscore}"

  # Initialize & set up instrumentation
  require 'stasher/rails_ext/action_controller/metal/instrumentation'
  require 'logstash/event'      
  self.suppress_app_logs(app) if app.config.stasher.suppress_app_log

  # Redirect Rails' logger if requested
  Rails.logger = Stasher::Logger.new  if app.config.stasher.redirect_logger

  # Subscribe to configured events
  app.config.stasher.attach_to.each do |target|
    Stasher::LogSubscriber.attach_to target
  end

  # Initialize internal logger
  self.logger = app.config.stasher.logger || Logger.new("#{Rails.root}/log/logstash_#{Rails.env}.log")
  level = ::Logger.const_get(app.config.stasher.log_level.to_s.upcase) if app.config.stasher.log_level
  self.logger.level = level || Logger::WARN

  self.enabled = true
end
suppress_app_logs(app) click to toggle source
# File lib/stasher.rb, line 72
def self.suppress_app_logs(app)   
  require 'stasher/rails_ext/rack/logger'
  Stasher.remove_existing_log_subscriptions

  # Disable ANSI colorization
  app.config.colorize_logging = false
end
unsubscribe(component, subscriber) click to toggle source
# File lib/stasher.rb, line 26
def self.unsubscribe(component, subscriber)
  events = subscriber.public_methods(false).reject{ |method| method.to_s == 'call' }
  events.each do |event|
    ActiveSupport::Notifications.notifier.listeners_for("#{event}.#{component}").each do |listener|
      if listener.instance_variable_get('@delegate') == subscriber
        ActiveSupport::Notifications.unsubscribe listener
      end
    end
  end
end