Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Dashboard(Dashing) Zabbix Triggers

Dashing dashboard for zabbix trigger

zabbix trigger zabbix trigger

This will provide the total number of alerts on triggers status

  • flash when there's an alert/triggers (color based on the zabbix trigger color format)
  • trigger = Warning, Average, High & Disaster
  • unacknowledge triggers
  • triggers within 1 hour( you can adjust the number of hour or min )
  • if the alerts are already okay you need to acknowledge(on zabbix) the alerts with the "OK" status so it will also clear on the dashboard (the purpose of these is so you can monitor closely all the alerts)

Some notes to avoid issues:

  • Ruby version should be 1.9.x
  • Replace the "username" & "password" with your credentials set :user => "username" set :password => "password"
  • You can use api keys but you have to modify the script(zabbix_trigger.rb)
  • Your zabbix account should have a privilege to access the Zabbix api
  • also thanks to andrewfraley for the reminder of adding this to your gemfile
    • gem 'zabby'
    • gem 'active_support'

-- @chojayr

class Dashing.Zabbix extends Dashing.Widget
@accessor 'current', Dashing.AnimatedValue
onData: (data) ->
if data.status
# clear existing "status-*" classes
$(@get('node')).attr 'class', (i,c) ->
c.replace /\bstatus-\S+/g, ''
# add new class
$(@get('node')).addClass "status-#{data.status}"
<h1 class="title" data-bind="title"></h1>
<h2 class="value" data-bind="current | shortenedNumber | prepend prefix | append suffix"></h2>
<h3 class="titl" data-bind="titl"></h3>
<p class="change-rate">
<i data-bind-class="arrow"></i><span data-bind="difference"></span>
</p>
<p class="more-info" data-bind="moreinfo | raw"></p>
<p class="updated-at" data-bind="updatedAtMessage"></p>
/*
//=require_directory .
//=require_tree ../../widgets
*/
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #222;
$text-color: #fff;
$background-average-color-1: #A0522D;
$background-average-color-2: #FFA07A;
$text-average-color: #fff;
$background-warn-color-1: #FFFF66;
$background-warn-color-2: #FF9618;
$text-warn-color: #fff;
$background-high-color-1: #CD5C5C;
$background-high-color-2: #FF9999;
$text-high-color: #fff;
$background-disaster-color-1: #E82711;
$background-disaster-color-2: #9B2D23;
$text-disaster-color: #fff;
@-webkit-keyframes status-average-background {
0% { background-color: $background-average-color-1; }
50% { background-color: $background-average-color-2; }
100% { background-color: $background-average-color-1; }
}
@-webkit-keyframes status-warn-background {
0% { background-color: $background-warn-color-1; }
50% { background-color: $background-warn-color-2; }
100% { background-color: $background-warn-color-1; }
}
@-webkit-keyframes status-high-background {
0% { background-color: $background-high-color-1; }
50% { background-color: $background-high-color-2; }
100% { background-color: $background-high-color-1; }
}
@-webkit-keyframes status-disaster-background {
0% { background-color: $background-disaster-color-1; }
50% { background-color: $background-disaster-color-2; }
100% { background-color: $background-disaster-color-1; }
}
@mixin animation($animation-name, $duration, $function, $animation-iteration-count:""){
-webkit-animation: $animation-name $duration $function #{$animation-iteration-count};
-moz-animation: $animation-name $duration $function #{$animation-iteration-count};
-ms-animation: $animation-name $duration $function #{$animation-iteration-count};
}
// ----------------------------------------------------------------------------
// Base styles
// ----------------------------------------------------------------------------
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
body {
margin: 0;
background-color: $background-color;
font-size: 20px;
color: $text-color;
font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
}
b, strong {
font-weight: bold;
}
a {
text-decoration: none;
color: inherit;
}
img {
border: 0;
-ms-interpolation-mode: bicubic;
vertical-align: middle;
}
img, object {
max-width: 100%;
}
iframe {
max-width: 100%;
}
table {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
}
td {
vertical-align: middle;
}
ul, ol {
padding: 0;
margin: 0;
}
h1, h2, h3, h4, h5, p {
padding: 0;
margin: 0;
}
h1 {
margin-bottom: 12px;
text-align: center;
font-size: 30px;
font-weight: 400;
}
h2 {
text-transform: uppercase;
font-size: 76px;
font-weight: 700;
color: $text-color;
}
h3 {
font-size: 25px;
font-weight: 600;
color: $text-color;
}
// ----------------------------------------------------------------------------
// Base widget styles
// ----------------------------------------------------------------------------
.gridster {
margin: 0px auto;
}
.icon-background {
width: 100%!important;
height: 100%;
position: absolute;
left: 0;
top: 0;
opacity: 0.1;
font-size: 275px;
}
.list-nostyle {
list-style: none;
}
.gridster ul {
list-style: none;
}
.gs_w {
width: 100%;
display: table;
cursor: pointer;
}
.widget {
padding: 25px 12px;
text-align: center;
width: 100%;
display: table-cell;
vertical-align: middle;
}
.widget.status-average {
color: $text-average-color;
background-color: $background-average-color-1;
@include animation(status-average-background, 2s, ease, infinite);
.icon-average-sign {
display: inline-block;
}
.title, .more-info {
color: $text-average-color;
}
}
.widget.status-warn {
color: $text-warn-color;
background-color: $background-warn-color-1;
@include animation(status-warn-background, 2s, ease, infinite);
.icon-warn-sign {
display: inline-block;
}
.title, .more-info {
color: $text-warn-color;
}
}
.widget.status-high {
color: $text-high-color;
background-color: $background-high-color-1;
@include animation(status-high-background, 2s, ease, infinite);
.icon-high-sign {
display: inline-block;
}
.title, .more-info {
color: $text-high-color;
}
}
.widget.status-disaster {
color: $text-disaster-color;
background-color: $background-disaster-color-1;
@include animation(status-disaster-background, 2s, ease, infinite);
.icon-disaster-sign {
display: inline-block;
}
.title, .more-info {
color: $text-disaster-color;
}
}
.more-info {
font-size: 15px;
position: absolute;
bottom: 32px;
left: 0;
right: 0;
}
.updated-at {
font-size: 15px;
position: absolute;
bottom: 12px;
left: 0;
right: 0;
}
#save-gridster {
display: none;
position: fixed;
top: 0;
margin: 0px auto;
left: 50%;
z-index: 1000;
background: black;
width: 190px;
text-align: center;
border: 1px solid white;
border-top: 0px;
margin-left: -95px;
padding: 15px;
}
#save-gridster:hover {
padding-top: 25px;
}
#saving-instructions {
display: none;
padding: 10px;
width: 500px;
height: 122px;
z-index: 1000;
background: white;
top: 100px;
color: black;
font-size: 15px;
padding-bottom: 4px;
textarea {
white-space: nowrap;
width: 494px;
height: 80px;
}
}
#lean_overlay {
position: fixed;
z-index:100;
top: 0px;
left: 0px;
height:100%;
width:100%;
background: #000;
display: none;
}
#container {
padding-top: 5px;
}
// ----------------------------------------------------------------------------
// Clearfix
// ----------------------------------------------------------------------------
.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; }
.clearfix:after { clear: both; }
.clearfix { zoom: 1; }
require 'zabby'
require 'json'
require 'active_support/core_ext/numeric/time'
swarn = []
savrg = []
shgh = []
sdis = []
twarn = 0
tavrg = 0
thgh = 0
tdis = 0
lav_warn = 0
lav_avrg = 0
lav_hgh = 0
lav_dis = 0
SCHEDULER.every '10s' do
serv = Zabby.init do
set :server => "http://example.zabbix.com/zabbix"
set :user => "username"
set :password => "password"
login
end
env = serv.run { Zabby::Trigger.get "filter" => { "priority" => [ 2, 3, 4, 5 ] }, "output" => "extend", "only_true" => "true", "monitored" => 1, "withUnacknowledgedEvents" => 1, "skipDependent" => 1, "expandData" => "host" }
pas = JSON.parse(env.to_json)
pas.each do |res|
prio = res["priority"]
lstchnge = res["lastchange"]
hostnme = res["hostname"]
alertime = Time.at(lstchnge.to_i)
#adjust the pref. time
timelapse = Time.now - 1.hours
if alertime >= timelapse
case prio
when '2' then
swarn << hostnme
when '3' then
savrg << hostnme
when '4' then
shgh << hostnme
when '5' then
sdis << hostnme
end
end
end
lav_warn = twarn
lav_avrg = tavrg
lav_hgh = thgh
lav_dis = tdis
twarn = swarn.count
tavrg = savrg.count
thgh = shgh.count
tdis = sdis.count
warn = twarn - lav_warn
avrg = tavrg - lav_avrg
hgh = thgh - lav_hgh
dis = tdis - lav_dis
if warn > 0 then warnstats = "warn" else warnstats = "ok" end
if avrg > 0 then avrgstats = "average" else avrgstats = "ok" end
if hgh > 0 then hghstats = "high" else hghstats = "ok" end
if dis > 0 then disstats = "disaster" else disstats = "ok" end
send_event( 'outwarn', { current: warn, last: lav_warn, status: warnstats } )
send_event( 'outavrg', { current: avrg, last: lav_avrg, status: avrgstats } )
send_event( 'outhigh', { current: hgh, last: lav_hgh, status: hghstats } )
send_event( 'outdis', { current: dis, last: lav_dis, status: disstats } )
end
<% content_for :title do %>Zabbix Trigger<% end %>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
<div data-id="outwarn" data-view="Zabbix" data-title="warning" style="background-color:#96bf48;"></div>
</li>
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
<div data-id="outavrg" data-view="Zabbix" data-title="average" style="background-color:#96bf48;"></div>
</li>
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
<div data-id="outhigh" data-view="Zabbix" data-title="high" style="background-color:#96bf48;"></div>
</li>
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
<div data-id="outdis" data-view="Zabbix" data-title="disaster" style="background-color:#96bf48;"></div>
</li>
</ul>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.