Skip to content

Instantly share code, notes, and snippets.

@wyattwalter
Created October 15, 2014 21:38
Show Gist options
  • Save wyattwalter/b84292cb2987439ec077 to your computer and use it in GitHub Desktop.
Save wyattwalter/b84292cb2987439ec077 to your computer and use it in GitHub Desktop.
Grafana backup script. Adapted from https://gist.github.com/jaimegago/11229750
#! /usr/bin/env python
# borrowed and adapted from https://gist.github.com/jaimegago/11229750
import datetime
import json
import logging
import logging.handlers
import optparse
import os
import re
import shutil
import sys
import tarfile
import tempfile
import urllib2
def grafana_dashboards_backup():
parser = optparse.OptionParser()
parser.add_option('-D', '--debug',
action = 'store_true',
default = False,
dest = 'debug',
help = 'Debug output (very noisy)')
parser.add_option('-e', '--grafana-elasticsearch-host',
dest = 'elastic_host',
help = 'The elastic search host FQDN used by grafana',
metavar = 'ELASTIC_SEARCH_HOST')
parser.add_option('-i', '--index',
default = 'grafana-dash',
dest = 'elastic_index',
help = 'Index containing dashboards (defaults to grafana-dash)',
metavar = 'ELASTIC_INDEX')
parser.add_option('-p', '--grafana-elasticsearch-port',
default = '9200',
dest = 'elastic_port',
help = 'The elastic search port used by grafana',
metavar = 'ELASTIC_SEARCH_PORT')
parser.add_option('-t', '--dest-dir',
default = '/var/opt/grafana-dashboards-backups',
dest = 'dest_dir',
help = 'The destination directory where dashboards will be saved',
metavar = 'DEST_DIR')
(options, args) = parser.parse_args()
if not options.elastic_host:
parser.error('An elastic search host is required')
elastic_host = options.elastic_host
elastic_index = options.elastic_index
elastic_port = options.elastic_port
dest_dir = options.dest_dir
debug = options.debug
#Set Logging to syslog
try:
logger = logging.getLogger(__name__)
if debug:
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.ERROR)
formatter = logging.Formatter('%(pathname)s: %(message)s')
syslog_handler = logging.handlers.SysLogHandler(address = 'localhost')
syslog_handler.setFormatter(formatter)
logger.addHandler(syslog_handler)
except Exception:
logging.info('Could not set syslog logging handler')
def cam_case_convert(name):
'''strips spaces and replace CamCasing.cam with cam_casing_cam'''
s1 = re.sub('([^._])([A-Z][a-z]+)', r'\1_\2', name.replace(' ',''))
s1 = s1.replace('.','_')
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
# Conveniance vars
# XXX: arbitrarily set size to 100, should be a scan and search if it gets large
dashboards_url = 'http://%s:%s/%s/dashboard/_search/?size=100' % (elastic_host,
elastic_port, elastic_index)
work_tmp_dir = tempfile.mkdtemp()
utc_datetime = datetime.datetime.utcnow()
formatted_time = utc_datetime.strftime("%Y-%m-%d-%H%MZ")
try:
elastic_response = urllib2.urlopen(dashboards_url, timeout=5)
except urllib2.URLError as e:
if debug:
logger.critical('Failed accessing: %s \n' % dashboards_url)
logger.critical(e)
sys.exit(1)
if debug:
logger.info('Grabbing grafana dashboards from: %s \n' % dashboards_url)
try:
data = json.load(elastic_response)
if debug:
print 'Elastic Search raw json:\n'
print '-----------------------'
print json.dumps(data, sort_keys = False, indent = 4)
except Exception as e:
logger.critical(e)
sys.exit(1)
# Create a tarball with all the dashboards and move to target dir
tarball = os.path.join(work_tmp_dir, 'grafana_dashboards_backup_' +
formatted_time + '.tar.gz')
tar = tarfile.open(tarball, 'w:gz')
try:
for hit in data['hits']['hits']:
dashboard_definition = json.loads(hit['_source']['dashboard'])
dashboard_file_name = cam_case_convert(hit['_id']) + '_' + formatted_time + '.json'
dashboard_file_path = os.path.join(work_tmp_dir, dashboard_file_name)
dashboard_file = open(dashboard_file_path, 'w')
json.dump(dashboard_definition, dashboard_file, sort_keys = True,
indent = 2, ensure_ascii=False)
logger.info('Added %s to the dashboards backup tarball' % hit['_id'])
dashboard_file.close()
tar.add(dashboard_file_path, arcname=cam_case_convert(hit['_id']) + '_' + formatted_time + '.json')
tar.close()
except Exception as e:
logging.critical(e)
sys.exit(1)
try:
tarball_file = os.path.basename(tarball)
tarball_dest = os.path.join(dest_dir, tarball_file)
shutil.move(tarball,tarball_dest)
logger.info('New grafana dashboards backup at %s' % tarball_dest)
except Exception as e:
logging.critical('Failed to move tarball to %s' % dest_dir)
logging.critical(e)
sys.exit(1)
# Clean up
try:
shutil.rmtree(work_tmp_dir)
except Exception as e:
logging.critical(e)
sys.exit(1)
if __name__ == '__main__':
grafana_dashboards_backup()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment