Skip to content

Instantly share code, notes, and snippets.

@visibilityspots
Last active February 9, 2016 07:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save visibilityspots/c28ec9f53fb2753a3c85 to your computer and use it in GitHub Desktop.
Save visibilityspots/c28ec9f53fb2753a3c85 to your computer and use it in GitHub Desktop.
A dashing widget to show the state of your bacula backups

Bacula widget

We have a dashing dashboard to give an overview of our infrastructure. Icinga, jenkins, foreman, web-services, traffic times.. Almost everything is been captured.. Only for bacula I could not find an existing one.

So I decided to write one myself. The first idea was to scrape the bacula-web overview site and use that output in a dashing screen. Mainly because a missing API for bacula or bacula-web. Nevertheless scraping a website isn't the best idea if that layout changes your quite fucked up..

screenshot

After googling around I came across an exampling of using mysql with ruby. So I decided to use this approach to have an overview of the bacula state since we configured bacula using a mysql database.

In you dashing root directory you have to add those gems into the Gemfile.

gem 'dbi'
    gem 'dbd-mysql'
    gem 'mysql2'
    gem 'mysql'
    gem 'pg'

And install them using

$ bundle install

Now copy the bacula.rb into the jobs directory and fill in the database details of your bacula director machine. I created a special db user which only can execute the select command from the dashing server to the mysql database.

Next step is to insert the html code in your dashing file dashingRootDir/dashboards/####.erb

<li data-row="1" data-col="2" data-sizex="1" data-sizey="1">
      <div data-id="bacula" data-view="List" data-unordered="true" data-title="Backup state" onclick="window.open('http://your.bacula-web.instance/','Bacula');";></div>
</li>

So now you have an overview of the backup jobs of the last 24hrs in your dashing setup.

<li data-row="1" data-col="2" data-sizex="1" data-sizey="1">
<div data-id="bacula" data-view="List" data-unordered="true" data-title="Backup state" onclick="window.open('http://your.bacula-web.instance/','Bacula');";></div>
</li>
require 'rubygems'
require 'pg'
require 'dbi'
db_driver = 'postgres'
db_name = 'bacula'
db_user = ''
db_password = ''
db_host = ''
db_port = '5432'
SCHEDULER.every '4s' do
if db_driver == 'postgres'
# Gathering Data from Postgres database
conn=PGconn.connect( :hostaddr=>db_host, :port=>db_port, :dbname=>db_name, :user=>db_user, :password=>db_password)
completed = conn.exec("select count(*) as Completed from Job WHERE RealEndTime >= NOW() - INTERVAL '24' HOUR AND JobStatus = 'T';")
failing = conn.exec("select count(*) as Failed from Job WHERE RealEndTime >= NOW() - INTERVAL '24' HOUR AND JobStatus IN ('f', 'E');")
cancelled = conn.exec("select count(*) as Cancelled from Job WHERE RealEndTime >= NOW() - INTERVAL '24' HOUR AND JobStatus = 'A';")
running = conn.exec("select count(*) as Running from Job WHERE JobStatus = 'R';")
waiting = conn.exec("select count(*) as Waiting from Job WHERE JobStatus IN ('F','S','M','m','s','j','c','d','t','p','C');")
completedJobs = Integer(completed.getvalue(0,0))
failingJobs = Integer(failing.getvalue(0,0))
cancelledJobs = Integer(cancelled.getvalue(0,0))
waitingJobs = Integer(waiting.getvalue(0,0))
runningJobs = Integer(running.getvalue(0,0))
completed.clear
failing.clear
cancelled.clear
running.clear
waiting.clear
conn.close
elsif db_driver == 'mysql'
# Gathering Data from MySQL database
dbh=DBI.connect('DBI:Mysql:db_name:db_host',db_user,db_password)
completed = "select count(*) as Completed from Job WHERE `RealEndTime` >= DATE_SUB(NOW(),INTERVAL 24 HOUR) AND JobStatus = 'T';"
failing = "select count(*) as Failed from Job WHERE `RealEndTime` >= DATE_SUB(NOW(),INTERVAL 24 HOUR) AND DATE(NOW()) AND JobStatus IN ('f', 'E');"
cancelled = "select count(*) as Cancelled from Job WHERE `RealEndTime` >= DATE_SUB(NOW(),INTERVAL 24 HOUR) AND JobStatus = 'A';"
running = "select count(*) as Running from Job WHERE JobStatus = 'R';"
waiting = "select count(*) as Waiting from Job WHERE JobStatus IN ('F','S','M','m','s','j','c','d','t','p','C');"
completedJobs = dbh.select_one(completed)
completedJobs = Integer(completedJobs[0])
failingJobs = dbh.select_one(failing)
failingJobs = Integer(failingJobs[0])
cancelledJobs = dbh.select_one(cancelled)
cancelledJobs = Integer(cancelledJobs[0])
runningJobs = dbh.select_one(running)
runningJobs = Integer(runningJobs[0])
waitingJobs = dbh.select_one(waiting)
waitingJobs = Integer(waitingJobs[0])
dbh.disconnect if dbh
end
# If statement to declare color according to state
if failingJobs > 0
value = failingJobs
color = 'red' + "-blink"
elsif waitingJobs > 0
value = waitingJobs
color = 'yellow'
else
value = completedJobs
color = 'green'
end
# Update the simplemon widget
send_event('bacula', {
value: value,
color: color
})
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment