/
bacula_job
166 lines (134 loc) · 4.66 KB
/
bacula_job
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/python
# Copyright (C) 2009 Andreas Thienemann <andreas@bawue.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as published by
# the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# Munin Plugin to get job throughput for Bacula by parsing the bconsole
# output.
#
# Parameters:
#
# config (required)
# autoconf (optional - only used by munin-config)
#
# Magic markers (optional - only used by munin-config and some
# installation scripts):
#
#%# family=contrib
#%# capabilities=autoconf
import subprocess
import time
import sys
import re
import os
def parse_running_jobs():
""" Parse the bconsole output once to get the running jobs """
bconsole = subprocess.Popen("bconsole", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stderr = bconsole.communicate("status\n1\nstatus\n3\n.")
jobs = []
clients = []
clientlist = False
# Hold the line numbers for devices
dev_line = []
input = stdout.split("\n")
for line, i in zip(input, range(0, len(input))):
if line.startswith("Connecting to Director "):
hostname = line.split()[-1].split(":")[0]
if line.endswith(" is running"):
jobs.append(line.split()[2].split(".")[0])
# Parse the clientlist, warning, order of statements is important
if line.startswith("Select Client (File daemon) resource"):
clientlist = False
if clientlist is True:
client_id, client_name = line.split()
client_clean = re.sub("^[^A-Za-z_]", "_", client_name, 1)
client_clean = re.sub("[^A-Za-z0-9_]", "_", client_clean, 0)
clients.append((client_name, client_clean, client_id[:-1]))
if line.startswith("The defined Client resources are:"):
clientlist = True
return hostname, jobs, clients
def parse(clients):
""" Parse the bconsole output """
query_str = ""
for client in clients:
query_str = query_str + "status\n3\n" + client[1] + "\n"
query_str = query_str + "quit"
bconsole = subprocess.Popen("bconsole", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stderr = bconsole.communicate(query_str)
input = stdout.split("\n")
jobstats = []
for line, pos in zip(input, range(0, len(input))):
# Get the client name
if line.startswith("Connecting to Client "):
# client_name = input[pos].split()[3].split(".")[0]
client_name = line.split()[3]
client_clean = re.sub("^[^A-Za-z_]", "_", client_name, 1)
client_clean = re.sub("[^A-Za-z0-9_]", "_", client_clean, 0)
# Get the current bytes
if line.endswith(" is running."):
bytes = long(input[pos+2].split()[1].split("=")[1].replace(",", ""))
jobstats.append([client_name, client_clean, bytes])
job_dict = {}
for job in jobstats:
job_dict[job[0].split("-")[0]] = job
return job_dict
def print_config():
hostname, jobs, clients = parse_running_jobs()
print "graph_title Bacula Job throughput"
print "graph_vlabel bytes per ${graph_period}"
print "graph_args --base 1024 -l 0"
print "graph_scale yes"
print "graph_info Bacula Job measurement."
print "graph_category Bacula"
print "graph_order",
for fd in clients:
print fd[1],
print
if os.getenv("report_hostname") is not None and \
os.getenv("report_hostname").upper() in ["YES", "TRUE", "1", "Y"]:
print "host_name", hostname
for client in clients:
print "%s.label %s" % (client[1], client[0])
print "%s.type DERIVE" % (client[1])
print "%s.min 0" % (client[1])
# print "%s.max %s" % (client[1], str(1024*1024*1024*16))
# print "%s.cdef up,8,*" (client[1])
sys.exit(0)
if "config" in sys.argv[1:]:
print_config()
elif "autoconf" in sys.argv[1:]:
for dir in os.getenv("PATH").split(":"):
for root, dirs, files in os.walk(dir):
if "bconsole" in files:
print "yes"
sys.exit(0)
print "no"
sys.exit(1)
elif "suggest" in sys.argv[1:]:
sys.exit(1)
else:
hostname, jobs, clients = parse_running_jobs()
str = []
for client in clients:
if client[0].split("-")[0] in jobs:
str.append((client[0], client[2]))
client_values = parse(str)
for client in clients:
client_name_short = client[0].split("-")[0]
if client_name_short in client_values:
print "%s.value %s" % (client_values[client_name_short][1], client_values[client_name_short][2])
else:
print "%s.value %s" % (client[1], "0")
sys.exit(0)