Module: Blazer

Defined in:
lib/blazer.rb,
lib/blazer/engine.rb,
lib/blazer/version.rb,
lib/blazer/data_source.rb,
app/models/blazer/audit.rb,
app/models/blazer/check.rb,
app/models/blazer/query.rb,
app/models/blazer/dashboard.rb,
app/models/blazer/connection.rb,
app/helpers/blazer/base_helper.rb,
app/mailers/blazer/check_mailer.rb,
app/models/blazer/dashboard_query.rb,
app/controllers/blazer/base_controller.rb,
lib/generators/blazer/install_generator.rb,
app/controllers/blazer/checks_controller.rb,
app/controllers/blazer/queries_controller.rb,
app/controllers/blazer/dashboards_controller.rb

Defined Under Namespace

Modules: BaseHelper, Generators Classes: Audit, BaseController, Check, CheckMailer, ChecksController, Connection, Dashboard, DashboardQuery, DashboardsController, DataSource, Engine, QueriesController, Query, TimeoutNotSupported

Constant Summary collapse

TIMEOUT_MESSAGE =
"Query timed out :("
TIMEOUT_ERRORS =
[
  "canceling statement due to statement timeout", # postgres
  "cancelled on user's request", # redshift
  "system requested abort" # redshift
]
VERSION =
"1.3.1"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.auditObject

Returns the value of attribute audit.



12
13
14
# File 'lib/blazer.rb', line 12

def audit
  @audit
end

.before_actionObject

Returns the value of attribute before_action.



17
18
19
# File 'lib/blazer.rb', line 17

def before_action
  @before_action
end

.cacheObject

Returns the value of attribute cache.



19
20
21
# File 'lib/blazer.rb', line 19

def cache
  @cache
end

.check_schedulesObject

Returns the value of attribute check_schedules.



21
22
23
# File 'lib/blazer.rb', line 21

def check_schedules
  @check_schedules
end

.from_emailObject

Returns the value of attribute from_email.



18
19
20
# File 'lib/blazer.rb', line 18

def from_email
  @from_email
end

.time_zoneObject

Returns the value of attribute time_zone.



13
14
15
# File 'lib/blazer.rb', line 13

def time_zone
  @time_zone
end

.transform_statementObject

Returns the value of attribute transform_statement.



20
21
22
# File 'lib/blazer.rb', line 20

def transform_statement
  @transform_statement
end

.user_classObject

Returns the value of attribute user_class.



15
16
17
# File 'lib/blazer.rb', line 15

def user_class
  @user_class
end

.user_methodObject

Returns the value of attribute user_method.



16
17
18
# File 'lib/blazer.rb', line 16

def user_method
  @user_method
end

.user_nameObject

Returns the value of attribute user_name.



14
15
16
# File 'lib/blazer.rb', line 14

def user_name
  @user_name
end

Class Method Details

.data_sourcesObject



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/blazer.rb', line 49

def self.data_sources
  @data_sources ||= begin
    ds = Hash[
      settings["data_sources"].map do |id, s|
        [id, Blazer::DataSource.new(id, s)]
      end
    ]
    ds.default = ds.values.first
    ds
  end
end

.run_checks(schedule: nil) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/blazer.rb', line 61

def self.run_checks(schedule: nil)
  checks = Blazer::Check.includes(:query)
  checks = checks.where(schedule: schedule) if schedule
  checks.find_each do |check|
    rows = nil
    error = nil
    tries = 1

    ActiveSupport::Notifications.instrument("run_check.blazer", check_id: check.id, query_id: check.query.id, state_was: check.state) do |instrument|
      # try 3 times on timeout errors
      while tries <= 3
        rows, error, cached_at = data_sources[check.query.data_source].run_statement(check.query.statement, refresh_cache: true)
        if error == Blazer::TIMEOUT_MESSAGE
          Rails.logger.info "[blazer timeout] query=#{check.query.name}"
          tries += 1
          sleep(10)
        else
          break
        end
      end
      check.update_state(rows, error)
      # TODO use proper logfmt
      Rails.logger.info "[blazer check] query=#{check.query.name} state=#{check.state} rows=#{rows.try(:size)} error=#{error}"

      instrument[:state] = check.state
      instrument[:rows] = rows.try(:size)
      instrument[:error] = error
      instrument[:tries] = tries
    end

  end
end

.send_failing_checksObject



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/blazer.rb', line 94

def self.send_failing_checks
  emails = {}
  Blazer::Check.includes(:query).where(state: %w[failing error]).find_each do |check|
    check.split_emails.each do |email|
      (emails[email] ||= []) << check
    end
  end

  emails.each do |email, checks|
    Blazer::CheckMailer.failing_checks(email, checks).deliver_later
  end
end

.settingsObject



38
39
40
41
42
43
44
45
46
47
# File 'lib/blazer.rb', line 38

def self.settings
  @settings ||= begin
    path = Rails.root.join("config", "blazer.yml").to_s
    if File.exist?(path)
      YAML.load(ERB.new(File.read(path)).result)
    else
      {}
    end
  end
end