Improved monitoring controller with amount_check (e. g. monitoring will alert about unusual amount of ticket creation).

This commit is contained in:
Martin Edenhofer 2018-11-02 07:35:28 +01:00
parent 385d6e69da
commit a97e261ac7
3 changed files with 229 additions and 1 deletions

View file

@ -1,7 +1,7 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class MonitoringController < ApplicationController
prepend_before_action -> { authentication_check(permission: 'admin.monitoring') }, except: %i[health_check status]
prepend_before_action -> { authentication_check(permission: 'admin.monitoring') }, except: %i[health_check status amount_check]
skip_before_action :verify_csrf_token
=begin
@ -239,6 +239,112 @@ curl http://localhost/api/v1/monitoring/status?token=XXX
render json: status
end
=begin
get counts about created ticket in certain time slot. s, m, h and d possible.
Resource:
GET /api/v1/monitoring/amount_check?token=XXX&max_warning=2000&max_critical=3000&periode=1h
GET /api/v1/monitoring/amount_check?token=XXX&min_warning=2000&min_critical=3000&periode=1h
GET /api/v1/monitoring/amount_check?token=XXX&periode=1h
Response:
{
"state": "ok",
"message": "",
"count": 123,
}
{
"state": "warning",
"message": "limit of 2000 tickets in 1h reached",
"count": 123,
}
{
"state": "critical",
"message": "limit of 3000 tickets in 1h reached",
"count": 123,
}
Test:
curl http://localhost/api/v1/monitoring/amount_check?token=XXX&max_warning=2000&max_critical=3000&periode=1h
curl http://localhost/api/v1/monitoring/amount_check?token=XXX&min_warning=2000&min_critical=3000&periode=1h
curl http://localhost/api/v1/monitoring/amount_check?token=XXX&periode=1h
=end
def amount_check
token_or_permission_check
raise Exceptions::UnprocessableEntity, 'periode is missing!' if params[:periode].blank?
scale = params[:periode][-1, 1]
raise Exceptions::UnprocessableEntity, 'periode need to have s, m, h or d as last!' if scale !~ /^(s|m|h|d)$/
periode = params[:periode][0, params[:periode].length - 1]
raise Exceptions::UnprocessableEntity, 'periode need to be an integer!' if periode.to_i.zero?
if scale == 's'
created_at = Time.zone.now - periode.to_i.seconds
elsif scale == 'm'
created_at = Time.zone.now - periode.to_i.minutes
elsif scale == 'h'
created_at = Time.zone.now - periode.to_i.hours
elsif scale == 'd'
created_at = Time.zone.now - periode.to_i.days
end
map = [
{ param: :max_critical, notice: 'critical', type: 'gt' },
{ param: :min_critical, notice: 'critical', type: 'lt' },
{ param: :max_warning, notice: 'warning', type: 'gt' },
{ param: :min_warning, notice: 'warning', type: 'lt' },
]
result = {}
map.each do |row|
next if params[row[:param]].blank?
raise Exceptions::UnprocessableEntity, "#{row[:param]} need to be an integer!" if params[row[:param]].to_i.zero?
count = Ticket.where('created_at >= ?', created_at).count
if row[:type] == 'gt'
if count > params[row[:param]].to_i
result = {
state: row[:notice],
message: "The limit of #{params[row[:param]]} was exceeded with #{count} in the last #{params[:periode]}",
count: count,
}
break
end
next
end
next if count > params[row[:param]].to_i
result = {
state: row[:notice],
message: "The minimum of #{params[row[:param]]} was undercut by #{count} in the last #{params[:periode]}",
count: count,
}
break
end
if result.blank?
result = {
state: 'ok',
message: '',
count: Ticket.where('created_at >= ?', created_at).count,
}
end
render json: result
end
def token
access_check
token = SecureRandom.urlsafe_base64(40)

View file

@ -3,6 +3,7 @@ Zammad::Application.routes.draw do
match api_path + '/monitoring/health_check', to: 'monitoring#health_check', via: :get
match api_path + '/monitoring/status', to: 'monitoring#status', via: :get
match api_path + '/monitoring/amount_check', to: 'monitoring#amount_check', via: :get
match api_path + '/monitoring/token', to: 'monitoring#token', via: :post
match api_path + '/monitoring/restart_failed_jobs', to: 'monitoring#restart_failed_jobs', via: :post

View file

@ -692,4 +692,125 @@ class MonitoringControllerTest < ActionDispatch::IntegrationTest
# cleanup
Delayed::Job.delete_all
end
test '11 check amount' do
Ticket.destroy_all
# amount_check - ok
get "/api/v1/monitoring/amount_check?token=#{@token}&periode=1h", params: {}, headers: @headers
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('ok', result['state'])
assert_equal('', result['message'])
assert_equal(0, result['count'])
Ticket.destroy_all
(1..6).each do |i|
Ticket.create!(
title: "Ticket-#{i}",
group: Group.lookup(name: 'Users'),
customer_id: 1,
state: Ticket::State.lookup(name: 'new'),
priority: Ticket::Priority.lookup(name: '2 normal'),
updated_by_id: 1,
created_by_id: 1,
)
travel 10.seconds
end
get "/api/v1/monitoring/amount_check?token=#{@token}&periode=1h&min_warning=10&min_critical=8", params: {}, headers: @headers
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('critical', result['state'])
assert_equal('The minimum of 8 was undercut by 6 in the last 1h', result['message'])
assert_equal(6, result['count'])
get "/api/v1/monitoring/amount_check?token=#{@token}&periode=1h&min_warning=7&min_critical=2", params: {}, headers: @headers
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('warning', result['state'])
assert_equal('The minimum of 7 was undercut by 6 in the last 1h', result['message'])
assert_equal(6, result['count'])
get "/api/v1/monitoring/amount_check?token=#{@token}&periode=1h&max_warning=10&max_critical=20", params: {}, headers: @headers
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('ok', result['state'])
assert_equal('', result['message'])
assert_equal(6, result['count'])
(1..6).each do |i|
Ticket.create!(
title: "Ticket-#{i}",
group: Group.lookup(name: 'Users'),
customer_id: 1,
state: Ticket::State.lookup(name: 'new'),
priority: Ticket::Priority.lookup(name: '2 normal'),
updated_by_id: 1,
created_by_id: 1,
)
travel 1.second
end
get "/api/v1/monitoring/amount_check?token=#{@token}&periode=1h&max_warning=10&max_critical=20", params: {}, headers: @headers
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('warning', result['state'])
assert_equal('The limit of 10 was exceeded with 12 in the last 1h', result['message'])
assert_equal(12, result['count'])
(1..10).each do |i|
Ticket.create!(
title: "Ticket-#{i}",
group: Group.lookup(name: 'Users'),
customer_id: 1,
state: Ticket::State.lookup(name: 'new'),
priority: Ticket::Priority.lookup(name: '2 normal'),
updated_by_id: 1,
created_by_id: 1,
)
travel 1.second
end
get "/api/v1/monitoring/amount_check?token=#{@token}&periode=1h&max_warning=10&max_critical=20", params: {}, headers: @headers
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('critical', result['state'])
assert_equal('The limit of 20 was exceeded with 22 in the last 1h', result['message'])
assert_equal(22, result['count'])
get "/api/v1/monitoring/amount_check?token=#{@token}&periode=1h", params: {}, headers: @headers
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('ok', result['state'])
assert_equal('', result['message'])
assert_equal(22, result['count'])
travel 2.hours
get "/api/v1/monitoring/amount_check?token=#{@token}&periode=1h", params: {}, headers: @headers
assert_response(200)
result = JSON.parse(@response.body)
assert_equal(Hash, result.class)
assert_equal('ok', result['state'])
assert_equal('', result['message'])
assert_equal(0, result['count'])
end
end