Added: stderr for mapping scripts
Change-Id: If40ea86db849f09ffc2e9936483a2dee3776e65e (cherry picked from commit ee44efcd4948590ea99b837d3baaccf9589bd177)
This commit is contained in:
parent
cc8b3e0868
commit
33327b6d2d
@ -44,7 +44,7 @@ def analyze(node_manager):
|
|||||||
module.register(fn_mapping)
|
module.register(fn_mapping)
|
||||||
|
|
||||||
results = {}
|
results = {}
|
||||||
for node in node_manager.nodes.values():
|
for node in node_manager.sorted_nodes():
|
||||||
if not node.mapscr:
|
if not node.mapscr:
|
||||||
node.generate_mapscr()
|
node.generate_mapscr()
|
||||||
for script, param in node.mapscr.items():
|
for script, param in node.mapscr.items():
|
||||||
@ -53,13 +53,28 @@ def analyze(node_manager):
|
|||||||
logger.warning('File %s does not exist'
|
logger.warning('File %s does not exist'
|
||||||
% param['output_path'])
|
% param['output_path'])
|
||||||
continue
|
continue
|
||||||
|
try:
|
||||||
with open(param['output_path'], 'r') as f:
|
with open(param['output_path'], 'r') as f:
|
||||||
data = [l.rstrip() for l in f.readlines()]
|
stdout = f.read()
|
||||||
health, details = fn_mapping[script](data, script, node)
|
if os.path.exists(param['stderr_path']):
|
||||||
|
with open(param['stderr_path'], 'r') as f:
|
||||||
|
stderr = f.read()
|
||||||
|
exitcode = stderr.splitlines()[0]
|
||||||
|
exitcode = exitcode.rstrip().split()[1]
|
||||||
|
else:
|
||||||
|
stderr = None
|
||||||
|
exitcode = 0
|
||||||
|
except IOError as e:
|
||||||
|
logger.warning('Could not read from %s' % e.filename)
|
||||||
|
health, details = fn_mapping[script](stdout, script, node,
|
||||||
|
stderr=stderr,
|
||||||
|
exitcode=exitcode)
|
||||||
if node.repr not in results:
|
if node.repr not in results:
|
||||||
results[node.repr] = []
|
results[node.repr] = []
|
||||||
results[node.repr].append({'script': script,
|
results[node.repr].append({'script': script,
|
||||||
'output_file': param['output_path'],
|
'output_file': param['output_path'],
|
||||||
|
'stderr_file': param['stderr_path'],
|
||||||
|
'exitcode': exitcode,
|
||||||
'health': health,
|
'health': health,
|
||||||
'details': details})
|
'details': details})
|
||||||
node_manager.analyze_results = results
|
node_manager.analyze_results = results
|
||||||
@ -72,7 +87,7 @@ def analyze_print_results(node_manager):
|
|||||||
RED: ['RED', '\033[91m']}
|
RED: ['RED', '\033[91m']}
|
||||||
color_end = '\033[0m'
|
color_end = '\033[0m'
|
||||||
print('Nodes health analysis:')
|
print('Nodes health analysis:')
|
||||||
for node, result in node_manager.analyze_results.items():
|
for node, result in sorted(node_manager.analyze_results.items()):
|
||||||
node_health = max([x['health'] for x in result])
|
node_health = max([x['health'] for x in result])
|
||||||
node_color = code_colors[node_health][1]
|
node_color = code_colors[node_health][1]
|
||||||
health_repr = code_colors[node_health][0]
|
health_repr = code_colors[node_health][0]
|
||||||
@ -85,8 +100,13 @@ def analyze_print_results(node_manager):
|
|||||||
color = code_colors[r['health']][1]
|
color = code_colors[r['health']][1]
|
||||||
sys.stdout.write(color)
|
sys.stdout.write(color)
|
||||||
health_repr = code_colors[r['health']][0]
|
health_repr = code_colors[r['health']][0]
|
||||||
print(' %s: %s' % (r['script'], health_repr))
|
print('%s%s: %s' % (8*' ', r['script'], health_repr))
|
||||||
print(' %s: %s' % ('output_file', r['output_file']))
|
print('%s%s: %s' % (12*' ', 'output_file', r['output_file']))
|
||||||
|
if ((r['stderr_file'] is not None) and
|
||||||
|
(os.path.exists(r['stderr_file']))):
|
||||||
|
print('%s%s: %s' % (12*' ', 'stderr_file', r['stderr_file']))
|
||||||
|
if r['exitcode'] != 0:
|
||||||
|
print('%s%s: %s' % (12*' ', 'exit code', r['exitcode']))
|
||||||
if len(r['details']) > 1:
|
if len(r['details']) > 1:
|
||||||
print(' details:')
|
print(' details:')
|
||||||
for d in r['details']:
|
for d in r['details']:
|
||||||
|
@ -50,12 +50,14 @@ def register(function_mapping):
|
|||||||
function_mapping['script-basename'] = parsing_function
|
function_mapping['script-basename'] = parsing_function
|
||||||
|
|
||||||
|
|
||||||
def parsing_function(data, script, node):
|
def parsing_function(stdout, script, node, stderr=None, exitcode=None):
|
||||||
'''
|
'''
|
||||||
each analyzing function should have 3 arguments:
|
each analyzing function should have 3 arguments:
|
||||||
data - list of strings aquired by reading the output file
|
stdout - string aquired by reading the output file
|
||||||
script - path to the script file
|
script - path to the script file
|
||||||
node - node object
|
node - node object
|
||||||
|
stderr - optional string with error file content
|
||||||
|
exitcode - optional int with script exit code
|
||||||
|
|
||||||
return should contain 2 values:
|
return should contain 2 values:
|
||||||
health - set to one of the imported constants according to the analysis
|
health - set to one of the imported constants according to the analysis
|
||||||
@ -63,7 +65,8 @@ def parsing_function(data, script, node):
|
|||||||
lines which were indicative of the issue
|
lines which were indicative of the issue
|
||||||
'''
|
'''
|
||||||
health = UNKNOWN
|
health = UNKNOWN
|
||||||
line = data[0] # in this example we only look at the first line
|
# in this example we only look at the first line
|
||||||
|
line = stdout.splitlines()[0]
|
||||||
details = [line]
|
details = [line]
|
||||||
if line.find('error'):
|
if line.find('error'):
|
||||||
health = RED
|
health = RED
|
||||||
|
@ -30,12 +30,13 @@ def register(function_mapping):
|
|||||||
function_mapping['df-i'] = parse_df_i
|
function_mapping['df-i'] = parse_df_i
|
||||||
|
|
||||||
|
|
||||||
def parse_df_m(data, script, node):
|
def parse_df_m(stdout, script, node, stderr=None, exitcode=None):
|
||||||
column_use = "Use%"
|
column_use = "Use%"
|
||||||
full = 100
|
full = 100
|
||||||
near_full = 80
|
near_full = 80
|
||||||
health = GREEN
|
health = GREEN
|
||||||
details = []
|
details = []
|
||||||
|
data = [l.rstrip() for l in stdout.splitlines()]
|
||||||
if column_use not in data[0]:
|
if column_use not in data[0]:
|
||||||
logger.warning(col_msg % (column_use, script, node.repr))
|
logger.warning(col_msg % (column_use, script, node.repr))
|
||||||
health = UNKNOWN
|
health = UNKNOWN
|
||||||
@ -59,12 +60,13 @@ def parse_df_m(data, script, node):
|
|||||||
return health, details
|
return health, details
|
||||||
|
|
||||||
|
|
||||||
def parse_df_i(data, script, node):
|
def parse_df_i(stdout, script, node, stderr=None, exitcode=None):
|
||||||
column_use = "IUse%"
|
column_use = "IUse%"
|
||||||
full = 100
|
full = 100
|
||||||
near_full = 80
|
near_full = 80
|
||||||
health = GREEN
|
health = GREEN
|
||||||
details = []
|
details = []
|
||||||
|
data = [l.rstrip() for l in stdout.splitlines()]
|
||||||
if column_use not in data[0]:
|
if column_use not in data[0]:
|
||||||
logger.warning(col_msg % (column_use, script, node.repr))
|
logger.warning(col_msg % (column_use, script, node.repr))
|
||||||
health = UNKNOWN
|
health = UNKNOWN
|
||||||
|
@ -30,11 +30,12 @@ def register(function_mapping):
|
|||||||
function_mapping['rabbitmqctl-status'] = parse_status
|
function_mapping['rabbitmqctl-status'] = parse_status
|
||||||
|
|
||||||
|
|
||||||
def parse_list_queues(data, script, node):
|
def parse_list_queues(stdout, script, node, stderr=None, exitcode=None):
|
||||||
warning = 100
|
warning = 100
|
||||||
error = 1000
|
error = 1000
|
||||||
health = GREEN
|
health = GREEN
|
||||||
details = []
|
details = []
|
||||||
|
data = [l.rstrip() for l in stdout.splitlines()]
|
||||||
for line in data[1:]:
|
for line in data[1:]:
|
||||||
elements = line.rstrip().split()
|
elements = line.rstrip().split()
|
||||||
if len(elements) < 2:
|
if len(elements) < 2:
|
||||||
@ -47,8 +48,8 @@ def parse_list_queues(data, script, node):
|
|||||||
return health, details
|
return health, details
|
||||||
|
|
||||||
|
|
||||||
def prepare_status(data):
|
def prepare_status(stdout):
|
||||||
bad_yaml = ''.join(data[1:])
|
bad_yaml = ''.join(stdout.splitlines()[1:])
|
||||||
# quoting string elements
|
# quoting string elements
|
||||||
bad_yaml = re.sub(r'([,{])([a-z_A-Z]+)([,}])', r'\1"\2"\3', bad_yaml)
|
bad_yaml = re.sub(r'([,{])([a-z_A-Z]+)([,}])', r'\1"\2"\3', bad_yaml)
|
||||||
# changing first element int a key - replacing , with :
|
# changing first element int a key - replacing , with :
|
||||||
@ -116,8 +117,13 @@ def squash_dicts(input_data):
|
|||||||
return input_data
|
return input_data
|
||||||
|
|
||||||
|
|
||||||
def parse_status(data, script, node):
|
def parse_status(stdout, script, node, stderr=None, exitcode=None):
|
||||||
status = prepare_status(data)
|
status = prepare_status(stdout)
|
||||||
|
if not status or exitcode:
|
||||||
|
health = RED
|
||||||
|
details = ['Failed on getting data from status']
|
||||||
|
return health, details
|
||||||
|
|
||||||
health = GREEN
|
health = GREEN
|
||||||
details = []
|
details = []
|
||||||
|
|
||||||
|
@ -212,12 +212,14 @@ class Node(object):
|
|||||||
self.logger.debug('%s, exec: %s' % (self.repr, script_path))
|
self.logger.debug('%s, exec: %s' % (self.repr, script_path))
|
||||||
output_path = os.path.join(self.scripts_ddir,
|
output_path = os.path.join(self.scripts_ddir,
|
||||||
os.path.basename(script_path))
|
os.path.basename(script_path))
|
||||||
|
stderr_path = "%s.stderr" % output_path
|
||||||
if self.outputs_timestamp:
|
if self.outputs_timestamp:
|
||||||
output_path += self.outputs_timestamp_str
|
output_path += self.outputs_timestamp_str
|
||||||
self.logger.debug('outfile: %s' % output_path)
|
self.logger.debug('outfile: %s' % output_path)
|
||||||
mapscr[scr] = {'env_vars': env_vars,
|
mapscr[scr] = {'env_vars': env_vars,
|
||||||
'script_path': script_path,
|
'script_path': script_path,
|
||||||
'output_path': output_path}
|
'output_path': output_path,
|
||||||
|
'stderr_path': stderr_path}
|
||||||
self.mapscr = mapscr
|
self.mapscr = mapscr
|
||||||
|
|
||||||
def exec_cmd(self, fake=False, ok_codes=None):
|
def exec_cmd(self, fake=False, ok_codes=None):
|
||||||
@ -232,6 +234,8 @@ class Node(object):
|
|||||||
for c in self.cmds:
|
for c in self.cmds:
|
||||||
for cmd in c:
|
for cmd in c:
|
||||||
dfile = os.path.join(ddir, cmd)
|
dfile = os.path.join(ddir, cmd)
|
||||||
|
errf = '%s.stderr' % dfile
|
||||||
|
|
||||||
if self.outputs_timestamp:
|
if self.outputs_timestamp:
|
||||||
dfile += self.outputs_timestamp_str
|
dfile += self.outputs_timestamp_str
|
||||||
self.logger.info('outfile: %s' % dfile)
|
self.logger.info('outfile: %s' % dfile)
|
||||||
@ -244,13 +248,22 @@ class Node(object):
|
|||||||
env_vars=self.env_vars,
|
env_vars=self.env_vars,
|
||||||
timeout=self.timeout,
|
timeout=self.timeout,
|
||||||
prefix=self.prefix)
|
prefix=self.prefix)
|
||||||
self.check_code(code, 'exec_cmd', c[cmd], errs, ok_codes)
|
ec = self.check_code(code, 'exec_cmd',
|
||||||
|
c[cmd], errs, ok_codes)
|
||||||
try:
|
try:
|
||||||
with open(dfile, 'w') as df:
|
with open(dfile, 'w') as df:
|
||||||
df.write(outs.encode('utf-8'))
|
df.write(outs.encode('utf-8'))
|
||||||
except:
|
except IOError:
|
||||||
self.logger.error("can't write to file %s" %
|
self.logger.error("can't write to file %s" %
|
||||||
dfile)
|
dfile)
|
||||||
|
if ec:
|
||||||
|
try:
|
||||||
|
with open(errf, 'w') as ef:
|
||||||
|
ef.write('exitcode: %s\n' % code)
|
||||||
|
ef.write(errs.encode('utf-8'))
|
||||||
|
except IOError:
|
||||||
|
self.logger.error("can't write to file %s" %
|
||||||
|
errf)
|
||||||
if self.scripts:
|
if self.scripts:
|
||||||
self.generate_mapscr()
|
self.generate_mapscr()
|
||||||
tools.mdir(self.scripts_ddir)
|
tools.mdir(self.scripts_ddir)
|
||||||
@ -263,14 +276,23 @@ class Node(object):
|
|||||||
env_vars=param['env_vars'],
|
env_vars=param['env_vars'],
|
||||||
timeout=self.timeout,
|
timeout=self.timeout,
|
||||||
prefix=self.prefix)
|
prefix=self.prefix)
|
||||||
self.check_code(code, 'exec_cmd',
|
ec = self.check_code(code, 'exec_cmd',
|
||||||
'script %s' % param['script_path'], errs, ok_codes)
|
('script %s' % param['script_path']),
|
||||||
|
errs, ok_codes)
|
||||||
try:
|
try:
|
||||||
with open(param['output_path'], 'w') as df:
|
with open(param['output_path'], 'w') as df:
|
||||||
df.write(outs.encode('utf-8'))
|
df.write(outs.encode('utf-8'))
|
||||||
except:
|
except IOError:
|
||||||
self.logger.error("can't write to file %s"
|
self.logger.error("can't write to file %s" %
|
||||||
% param['output_path'])
|
param['output_path'])
|
||||||
|
if not ec:
|
||||||
|
try:
|
||||||
|
with open(param['stderr_path'], 'w') as ef:
|
||||||
|
ef.write('exitcode: %s\n' % code)
|
||||||
|
ef.write(errs.encode('utf-8'))
|
||||||
|
except IOError:
|
||||||
|
self.logger.error("can't write to file %s" %
|
||||||
|
param['stderr_path'])
|
||||||
return mapcmds, self.mapscr
|
return mapcmds, self.mapscr
|
||||||
|
|
||||||
def exec_simple_cmd(self, cmd, timeout=15, infile=None, outfile=None,
|
def exec_simple_cmd(self, cmd, timeout=15, infile=None, outfile=None,
|
||||||
@ -380,7 +402,7 @@ class Node(object):
|
|||||||
for line in df:
|
for line in df:
|
||||||
if not line.isspace() and line[0] != '#':
|
if not line.isspace() and line[0] != '#':
|
||||||
data += line
|
data += line
|
||||||
except:
|
except IOError:
|
||||||
self.logger.error('could not read file: %s' % fname)
|
self.logger.error('could not read file: %s' % fname)
|
||||||
self.logger.debug('%s: data:\n%s' % (self.repr, data))
|
self.logger.debug('%s: data:\n%s' % (self.repr, data))
|
||||||
if data:
|
if data:
|
||||||
@ -496,6 +518,8 @@ class Node(object):
|
|||||||
self.logger.warning("%s: func: %s: "
|
self.logger.warning("%s: func: %s: "
|
||||||
"cmd: '%s' exited %d, error: %s" %
|
"cmd: '%s' exited %d, error: %s" %
|
||||||
(self.repr, func_name, cmd, code, err))
|
(self.repr, func_name, cmd, code, err))
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def get_results(self, result_map):
|
def get_results(self, result_map):
|
||||||
# result_map should be either mapcmds or mapscr
|
# result_map should be either mapcmds or mapscr
|
||||||
@ -796,7 +820,7 @@ class NodeManager(object):
|
|||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
fs = int(outs.rstrip('\n'))
|
fs = int(outs.rstrip('\n'))
|
||||||
except:
|
except ValueError:
|
||||||
self.logger.error("can't get free space\nouts: %s" %
|
self.logger.error("can't get free space\nouts: %s" %
|
||||||
outs)
|
outs)
|
||||||
return False
|
return False
|
||||||
@ -842,7 +866,7 @@ class NodeManager(object):
|
|||||||
return self.conf['logs_speed_default']
|
return self.conf['logs_speed_default']
|
||||||
try:
|
try:
|
||||||
speed = int(out)
|
speed = int(out)
|
||||||
except:
|
except ValueError:
|
||||||
speed = self.conf['logs_speed_default']
|
speed = self.conf['logs_speed_default']
|
||||||
return speed
|
return speed
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user