Skip to content

Instantly share code, notes, and snippets.

@welsh
Last active November 2, 2020 18:05
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save welsh/9588819 to your computer and use it in GitHub Desktop.
Save welsh/9588819 to your computer and use it in GitHub Desktop.
Server Status Squares: A Dashing Dashboard Widget to represent a Server Status as a Colored Square.

Server Status Squares

A Dashing widget that checks whether a server is responding to either an http or ping request using smaller squares to represent its status.

This is based off of the Server Status widget that willjohnson developed but modified to work across multiple squares rather than be one square with a list.

Description

The widget updates the appropriate squares color upon determining its status. Statuses are as follows:

  • Blue represents a new square that hasn't had any data sent to it yet.
  • Green represents that the square is responding properly
  • Red represents that there is an issue. (Ping failed, non 200 response, etc.)

Example:

Setup - Manual

  1. Move server_status_squares.erb into your dashboards directory.

  2. Create a directory called server_status_squares under your widgets directory and move the following under it:

    • server_status_squares.coffee
    • server_status_squares.html
    • server_status_squares.scss
  3. Move server_status_squares.rb into your jobs directory.

  4. Run Dashing and navigate to http://localhost:3030/server_status_squares which will show this example dashboard:

Setup - Auto

  1. Within your dashing project do dashing install 9588819

  2. Move server_status_squares.erb into your dashboards directory.

  3. Run Dashing and navigate to http://localhost:3030/server_status_squares which will show the above example dashboard.

Adjusting

To add a new server, add the following into your dashboard:

<li data-row="2" data-col="4" data-sizex="1" data-sizey="1">
    <div data-id="sss-mynewserver" data-view="ServerStatusSquares" data-title="My Server"></div>
</li>

Then in your server_status_squares.rb file within the jobs directory adjust the servers array to add a new entry:

{name: 'sss-mynewserver', url: '192.168.1.150', method: 'ping'},

You need to ensure that the data-id of the dashboard entry matches the name in the new servers array entry.

I use the sss- prefix so I know its a Server Status Squares entry.

Notes

Managing large number of servers
Depending on the number of squares you want to manage and the polling duration you may want to create multiple Server Status Squares jobs.

For example if you have say 60 servers listed and it runs every 60 seconds you may run into issues with jobs overlapping.

Adjusting polling duration
To adjust the polling duration, open up the server_status_squares.rb job file and modify the main scheduler line which is currently set at 60 seconds. The line is:

SCHEDULER.every '60s', :first_in => 0 do |job|

You can modify the '60s' to be any number for seconds. To configure it to 5 minutes you can do '5m'.

Cube Sizing
I've found that doing a Dashing.widget_base_dimensions = [170, 170] works best to fit an optimal number of Squares on a 1080p Dashboard as you can do 10 across and 6 down for a total of 60 Squares.

This can provide you a quick glance system to see if there are any issues with any of the servers as the Red Square will stand out in the sea (of hopefully) Green Squares.

You can still create squares that are almost the same size as the Example dashboards base squares by setting data-sizex="2" data-sizey="2" for the li entry. You can see this in the server_status_squares.erb file for the Clock. (It will be shorter vertically by 30px.)

API
To manually update the data of the widget, you can update via HTTP as described in the Dashing Data section. To do this, find the data-id of the ServerStatusSquares widget and send it "result": 1 if its up or "result": 0 if its down.

For example with the server_status_squares dashboard that was provided, the New Server square isn't hooked up to the server_status_squares.rb job.

You can update it to show that is is up with:

curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "result": 1 }' http://localhost:3030/widgets/sss-newserver

Or that it is down with:

curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "result": 0 }' http://localhost:3030/widgets/sss-newserver
class Dashing.ServerStatusSquares extends Dashing.Widget
onData: (data) ->
$(@node).fadeOut().fadeIn()
color = if data.result == 1 then "#96BF48" else "#BF4848"
$(@get('node')).css('background-color', "#{color}")
<script type='text/javascript'>
$(function() {
Dashing.widget_base_dimensions = [170, 170]
Dashing.numColumns = 10
});
</script>
<% content_for :title do %>Status Status Squares<% end %>
<div class="gridster">
<ul>
<li data-row="2" data-col="1" data-sizex="2" data-sizey="2">
<div data-view="Clock" style="background-color: #4b4b4b"></div>
<i class="icon-time icon-background"></i>
</li>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
<div data-id="welcome" data-view="Text" data-title="Server Status Squares" style="background-color: #4b4b4b"></div>
</li>
<li data-row="1" data-col="3" data-sizex="1" data-sizey="1">
<div data-id="sss-gateway" data-view="ServerStatusSquares" data-title="Gateway"></div>
</li>
<li data-row="1" data-col="4" data-sizex="1" data-sizey="1">
<div data-id="sss-reddit" data-view="ServerStatusSquares" data-title="Reddit"></div>
</li>
<li data-row="1" data-col="5" data-sizex="1" data-sizey="1">
<div data-id="sss-github" data-view="ServerStatusSquares" data-title="Github"></div>
</li>
<li data-row="2" data-col="3" data-sizex="1" data-sizey="1">
<div data-id="sss-brokenserver" data-view="ServerStatusSquares" data-title="Broken Server"></div>
</li>
<li data-row="2" data-col="4" data-sizex="1" data-sizey="1">
<div data-id="sss-newserver" data-view="ServerStatusSquares" data-title="New Server"></div>
</li>
</ul>
</div>
<h1 class="title" data-bind="title"></h1>
<p class="updated-at" data-bind="updatedAtMessage"></p>
#!/usr/bin/env ruby
require 'net/http'
require 'uri'
#
### Global Config
#
# httptimeout => Number in seconds for HTTP Timeout. Set to ruby default of 60 seconds.
# ping_count => Number of pings to perform for the ping method
#
httptimeout = 60
ping_count = 10
#
# Check whether a server is Responding you can set a server to
# check via http request or ping
#
# Server Options
# name
# => The name of the Server Status Tile to Update
# url
# => Either a website url or an IP address. Do not include https:// when using ping method.
# method
# => http
# => ping
#
# Notes:
# => If the server you're checking redirects (from http to https for example)
# the check will return false
#
servers = [
{name: 'sss-gateway', url: '192.168.1.1', method: 'ping'},
{name: 'sss-reddit', url: 'http://www.reddit.com/', method: 'http'},
{name: 'sss-github', url: 'https://github.com/', method: 'http'},
{name: 'sss-brokenserver', url: '192.168.1.100', method: 'ping'},
]
SCHEDULER.every '1m', :first_in => 0 do |job|
servers.each do |server|
if server[:method] == 'http'
begin
uri = URI.parse(server[:url])
http = Net::HTTP.new(uri.host, uri.port)
http.read_timeout = httptimeout
if uri.scheme == "https"
http.use_ssl=true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
if response.code == "200"
result = 1
else
result = 0
end
rescue Timeout::Error
result = 0
rescue Errno::ETIMEDOUT
result = 0
rescue Errno::EHOSTUNREACH
result = 0
rescue Errno::ECONNREFUSED
result = 0
rescue SocketError => e
result = 0
end
elsif server[:method] == 'ping'
result = `ping -q -c #{ping_count} #{server[:url]}`
if ($?.exitstatus == 0)
result = 1
else
result = 0
end
end
send_event(server[:name], result: result)
end
end
// ----------------------------------------------------------------------------
// Widget Styles
// ----------------------------------------------------------------------------
.widget-server-status-squares {
background-color: #12b0c5;
vertical-align: top;
.title {
color: rgba(255, 255, 255, 0.7);
font-size: 25px;
}
.updated-at {
color: rgba(0, 0, 0, 0.3);
}
}
@MartynKeigher
Copy link

Hey man!

Great job on this widget!! I do have one feature request if possible.. ;)

Is there any way that I can change the TEXT in the tile to say "Online" or "Offline" based on the result. Right now the tile just flips between red/green, but changing the text also... would be awesome!!

Thank you so much for your work on this!

Martyn.

@Mukish
Copy link

Mukish commented Aug 13, 2014

Hey dude, awesome widget - for some reason the ping boxes never appear green. Not sure if it is working correctly? I can ping using cmd prompt perfectly.

@Noble7ven
Copy link

@Mukish, did you ever get the ping command to work on this widget? I'm experiencing the same problem as you are.

@stenknz
Copy link

stenknz commented Jul 28, 2015

This is a very good widget. Currently using to monitor a few DCs around the country. Just one question how can I stop the 'squares' from blinking every 10 seconds? I'm using ping.

@mandelbrotmedia
Copy link

Hi guys,

i solved the ping problem by changing this line in the server_status.rb:

result = ping -n #{ping_count} #{server[:url]}

Works for me on a windows maschine

cheers

@guenther-rafal
Copy link

Uhm, doesn't seem to work. All I get inside the tile is:
"["str", [Tilt::StringTemplate]]["erb", [Tilt::ErubisTemplate, Tilt::ERBTemplate]]["rhtml", [Tilt::ErubisTemplate, Tilt::ERBTemplate]]["erubis", [Tilt::ErubisTemplate]]["etn", [Tilt::EtanniTemplate]]["etanni", [Tilt::EtanniTemplate]]["haml", [Tilt::HamlTemplate]]["mab", [Tilt::MarkabyTemplate]]["liquid", [Tilt::LiquidTemplate]]["radius", [Tilt::RadiusTemplate]]["markdown", [Tilt::RedcarpetTemplate, Tilt::RedcarpetTemplate::Redcarpet2, Tilt::RedcarpetTemplate::Redcarpet1, Tilt::RDiscountTemplate, Tilt::BlueClothTemplate, Tilt::KramdownTemplate, Tilt::MarukuTemplate]]["mkd", [Tilt::RedcarpetTemplate, Tilt::RedcarpetTemplate::Redcarpet2, Tilt::RedcarpetTemplate::Redcarpet1, Tilt::RDiscountTemplate, Tilt::BlueClothTemplate, Tilt::KramdownTemplate, Tilt::MarukuTemplate]]["md", [Tilt::RedcarpetTemplate, Tilt::RedcarpetTemplate::Redcarpet2, Tilt::RedcarpetTemplate::Redcarpet1, Tilt::RDiscountTemplate, Tilt::BlueClothTemplate, Tilt::KramdownTemplate, Tilt::MarukuTemplate]]["textile", [Tilt::RedClothTemplate]]["rdoc", [Tilt::RDocTemplate]]["wiki", [Tilt::WikiClothTemplate, Tilt::CreoleTemplate]]["creole", [Tilt::CreoleTemplate]]["mediawiki", [Tilt::WikiClothTemplate]]["mw", [Tilt::WikiClothTemplate]]["ad", [Tilt::AsciidoctorTemplate]]["adoc", [Tilt::AsciidoctorTemplate]]["asciidoc", [Tilt::AsciidoctorTemplate]]["html", [Tilt::PlainTemplate]]"

I'm using exact same code as example. Well, at least the colour changes :P

@simonmd
Copy link

simonmd commented Feb 2, 2016

I get exactly the same output as @Rufix . I've used this widget a year back and it worked. Any idea what changed?

@moosemedia
Copy link

Awesome, I have one question the sites I want to monitor have binary logins when you browse to them it looks like it shows as a failure even though I can browse the site. Is there a way to input the credentials for the site so it will load and show as online?

@twest283
Copy link

twest283 commented Sep 9, 2016

Amazing app. Any advice on where to adjust the "Last updated" text on the tiles? I'd like it to use the 12-hour clock and maybe have the date as well.

@henryp007
Copy link

Hi - thanks for the code!
For some reason the squares only ever show as Red even if the IP is pingable. is there a fix for this?
image

@kylezero
Copy link

kylezero commented Mar 8, 2018

I am using this widget and I love it. However, I'd like to change the "okay" green color to a different shade. When I edit the coffee file (which seems like the obvious place) it doesn't take effect no matter what I try. The only thing I haven't tried is a full reboot of the dashing server. Any idea how to edit those colors and make it stick? Here's my edit-

onData: (data) ->
$(@node).fadeOut().fadeIn()
color = if data.result == 1 then "#00C176" else "#BF4848"
$(@get('node')).css('background-color', "#{color}")

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