Skip to content

Instantly share code, notes, and snippets.

@chojayr
Last active November 28, 2023 16:39
Show Gist options
  • Save chojayr/7401426 to your computer and use it in GitHub Desktop.
Save chojayr/7401426 to your computer and use it in GitHub Desktop.
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>
@andrewfraley
Copy link

Is there supposed to be an html file for the widget? I reused the default number.html and that seems to work.

Also, add the following to your Gemfile:

gem 'zabby'
gem 'active_support'

@chojayr
Copy link
Author

chojayr commented Jan 3, 2014

@andrewfraley, yup it should work for number.html I used and modify the number(widget) .scss & .coffee so the zabbix.html should be the same for the number.html(apology if i did not include it here) also any required gem would be included on the Gemfile, anyway Gratitude for adding! Thanks Mate! :)

@Doc-Savage
Copy link

I am trying to flounder my way around this - and all I can get to show up on the browser is a dot - I copied number.html and renamed it zabbix.html.

The console is not showing anything untoword - maybe i will blow it away and start over.. have you seen anything like this?

-Andy

@chojayr
Copy link
Author

chojayr commented Jan 14, 2014

Hi Andy,

I encounter this before when I messed up on modifying stuff on widgets. I also started over and poof! it works.

another thing kindly try it on webrick instead of thin

"rackup -p 3030 -s webrick"

Cheers!

@nicovs
Copy link

nicovs commented Mar 14, 2014

I have the same issue as Doc-Savage... I only get 4 dots on a white page.

When i try the rackup command i get this error:
/usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:59:in `gem_original_require': /var/lib/gems/1.8/gems/dashing-1.3.2/lib/dashing.rb:21: syntax error, unexpected ':', expecting $end (SyntaxError)
set server: 'thin', connections: [], history_file: 'history.yml'

my selected ruby version (alternative) is 1.9.1

I did not change any widgets, just created a new one (foldername widgets/zabbix), copied the .coffee and .scss into that folder, and then copied the number/number.html => zabbix/zabbix.html

@chojayr
Copy link
Author

chojayr commented Apr 2, 2014

Hi nicovs,

It shows that you still using ruby version 1.8.x can you upgrade to version 1.9.3? then re-install the dashing kindly refer to this Shopify/dashing#241

cheers!

@chojayr
Copy link
Author

chojayr commented Apr 20, 2014

I add some notes and also add the zabbix.html

@willemmerson1
Copy link

Hi Chojayr,

Please can you assist me with this - I'm also having the same issue with a blank page and 5 Bullet Points (dots) on the page: http://192.237.162.55:3030/zabbix_status

I've installed the dashboard variant by Tolleiv - https://github.com/tolleiv/dashing-zabbix

I'm using ruby-1.9.3-p547, I've added the required Gems Zabby, Dashing and Active Support to my GemFile - dashing start works without error, but I can't get anything to display other than the bullet points?

Thanks,

Will

@chojayr
Copy link
Author

chojayr commented Sep 29, 2014

Hi willemmerson1,

Just want to ask first if the zabbix account you were using had an api access to you zabbix server, to verify you can create a snippets to check if you can extract data or if you have access to the zabbix api, once there's is try to re-create you dashing working directory. btw, this version of zabbix-dashing is so awesome https://github.com/tolleiv/dashing-zabbix, props to tolleiv for improving the zabbix-dashing

Regards,

@Greyegreye
Copy link

So I am currently having a problem to where the dashboard doesn't display the numbers below the "Warning", "High", "Disaster" areas nor the "last checked". Previously it worked, but after trying to install a new pingdom widget, having it break things and removing it this occurred. Also the text fields displaying the names of the Zabbix hosts will not display.
Does anyone have any ideas as to what I messed up?

@chojayr
Copy link
Author

chojayr commented Jun 3, 2015

Hey mate, are you talking about this version of dashing-zabbix? https://github.com/tolleiv/dashing-zabbix. any error prompted upon running?

@maxdrs
Copy link

maxdrs commented Jun 17, 2015

Hi chojayr, nice work!
Do you think is possible to insert on the dashboard the zabbix group and after divided the alert by gruup?

thank you

@chojayr
Copy link
Author

chojayr commented Jun 22, 2016

@maxdrs, sorry mate did not visit this page almost a year sorry for the late response. with regards to your query yup its possible. we just need some modifications on zabbix_trigger.rb or probably you already figure it out 😄

@6LYTH3
Copy link

6LYTH3 commented Sep 12, 2016

@chojayr, Now expandData was removed out of the Zabbix api 3.0
For easy way to fix i think we can replace expandData with 'selectHosts' => 'extend' and change hostnme to res['hosts'][0]['name']

@socialstijn
Copy link

Is still still working with the latest Zabbix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment