Module: ThreeScale::Backend::Alerts

Extended by:
Alerts, KeyHelpers
Includes:
Memoizer::Decorator
Included in:
Alerts
Defined in:
lib/3scale/backend/alerts.rb

Defined Under Namespace

Modules: KeyHelpers Classes: UsagesChecked

Constant Summary collapse

ALERT_TTL =

1 day (only one message per day)

24*3600
ALERT_BINS =

zero must be here and sorted, yes or yes

[0, 50, 80, 90, 100, 120, 150, 200, 300].freeze
FIRST_ALERT_BIN =
ALERT_BINS.first
RALERT_BINS =
ALERT_BINS.reverse.freeze

Instance Method Summary collapse

Methods included from Memoizer::Decorator

included

Instance Method Details

#allowed_set_for_service(service_id) ⇒ Object



169
170
171
# File 'lib/3scale/backend/alerts.rb', line 169

def allowed_set_for_service(service_id)
  storage.smembers(key_allowed_set(service_id)).map(&:to_i) # Redis returns strings always
end

#can_raise_more_alerts?(service_id, app_id) ⇒ Boolean

Returns:

  • (Boolean)


122
123
124
125
126
127
128
129
130
# File 'lib/3scale/backend/alerts.rb', line 122

def can_raise_more_alerts?(service_id, app_id)
  allowed_bins = allowed_set_for_service(service_id).sort

  return false if allowed_bins.empty?

  # If the bin with the highest value has already been notified, there's
  # no need to notify anything else.
  not notified?(service_id, app_id, allowed_bins.last)
end

#notified?(service_id, app_id, bin) ⇒ Boolean

Returns:

  • (Boolean)


174
175
176
# File 'lib/3scale/backend/alerts.rb', line 174

def notified?(service_id, app_id, bin)
  storage.get(key_already_notified(service_id, app_id, bin))
end

#storageObject



179
180
181
# File 'lib/3scale/backend/alerts.rb', line 179

def storage
  Storage.instance
end

#update_utilization(service_id, app_id, utilization) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/3scale/backend/alerts.rb', line 132

def update_utilization(service_id, app_id, utilization)
  discrete = utilization_discrete(utilization.ratio)

  keys = alert_keys(service_id, app_id, discrete)

  already_alerted, allowed = storage.pipelined do
    storage.get(keys[:already_notified])
    storage.sismember(keys[:allowed], discrete)
  end

  if already_alerted.nil? && allowed && discrete.to_i > 0
    next_id, _, _ = storage.pipelined do
      storage.incr(keys[:current_id])
      storage.setex(keys[:already_notified], ALERT_TTL, "1")
      UsagesChecked.invalidate(service_id, app_id)
    end

    alert = { :id => next_id,
              :utilization => discrete,
              :max_utilization => utilization.ratio,
              :application_id => app_id,
              :service_id => service_id,
              :timestamp => Time.now.utc,
              :limit => utilization.to_s }

    Backend::EventStorage::store(:alert, alert)
  end
end

#utilization_discrete(utilization) ⇒ Object



161
162
163
164
165
166
167
# File 'lib/3scale/backend/alerts.rb', line 161

def utilization_discrete(utilization)
  u = utilization * 100.0
  # reverse search
  RALERT_BINS.find do |b|
    u >= b
  end || FIRST_ALERT_BIN
end