def _save_key(key_string, zone_name, key_path): with open(key_path, 'wb') as f: f.write(unicode_to_bytes(key_string)) cprint('%s OK the key is saved as file %s' % (CHARACTERS.check, key_path)) # Try to send the information to the agent, so it can reload the key try: get_opsbro_json('/agent/zones-keys/reload/%s' % zone_name) except get_request_errors(): cprint( ' | The agent seems to not be started. Skipping hot key reload.', color='grey') return
def do_docker_show(): d = get_opsbro_json('/docker/stats') scontainers = d.get('containers') simages = d.get('images') print_info_title('Docker Stats') if not scontainers: cprint("No running containers", color='grey') for (cid, stats) in scontainers.items(): print_info_title('Container:%s' % cid) keys = stats.keys() keys.sort() e = [] for k in keys: sd = stats[k] e.append((k, sd['value'])) # Normal agent information print_2tab(e, capitalize=False, col_size=30) for (cid, stats) in simages.items(): print_info_title('Image:%s (sum)' % cid) keys = stats.keys() keys.sort() e = [] for k in keys: sd = stats[k] e.append((k, sd['value'])) # Normal agent information print_2tab(e, capitalize=False, col_size=30)
def do_agent_parameters_remove(parameter_name, str_value): if parameter_name not in list_type_parameters: cprint( 'Error: the parameter %s is not a list. Cannot use the add/remove. Please use set instead' % parameter_name) sys.exit(2) parameters_file_path = DEFAULT_CFG_FILE yml_parameter_remove(parameters_file_path, parameter_name, str_value, file_display='agent.%s' % parameter_name) # Groups is a bit special as it can be load directly by the agent if parameter_name == 'groups': try: did_change = get_opsbro_json('/agent/parameters/remove/groups/%s' % str_value) except get_request_errors(): cprint( ' | The agent seems to not be started. Skipping hot group removing.', color='grey') return if did_change: cprint( " | The agent groups are updated too. You don't need to restart your daemon.", color='grey') return cprint( 'NOTE: only the yml configuration file is modified. You need to restart your agent to use this modification', color='grey') return
def do_detect_wait_group(group_name, timeout=30): import itertools spinners = itertools.cycle(CHARACTERS.spinners) for i in range(timeout): uri = '/agent/detectors/state' try: detected_groups = get_opsbro_json(uri) except get_request_errors() as exp: logger.error(exp) return if group_name in detected_groups: cprint('\n %s ' % CHARACTERS.arrow_left, color='grey', end='') cprint('%s ' % CHARACTERS.check, color='green', end='') cprint('The group ', end='') cprint('%s' % group_name, color='magenta', end='') cprint(' is ', end='') cprint('detected', color='green') sys.exit(0) # Not detected? increase loop cprint('\r %s ' % next(spinners), color='blue', end='') # next=> python3 cprint('%s' % group_name, color='magenta', end='') cprint(' is ', end='') cprint('NOT DETECTED', color='magenta', end='') cprint(' (%d/%d)' % (i, timeout), end='') # As we did not \n, we must flush stdout to print it sys.stdout.flush() time.sleep(1) cprint("\nThe group %s was not detected after %s seconds" % (group_name, timeout)) sys.exit(2)
def do_collectors_history(): try: history_entries = get_opsbro_json('/agent/collectors/history') except get_request_errors() as exp: logger.error(exp) return print_h1('History') for history_entry in history_entries: epoch_date = history_entry['date'] entries = history_entry['entries'] print_h2( ' Date: %s ' % time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(epoch_date))) for entry in entries: name = entry['name'] cprint(' * ', end='') cprint('%s ' % (name.ljust(20)), color='magenta', end='') old_state = entry['old_state'] c = COLLECTORS_STATE_COLORS.get(old_state, 'cyan') cprint('%s' % old_state.ljust(10), color=c, end='') cprint(' %s ' % CHARACTERS.arrow_left, color='grey', end='') state = entry['state'] c = COLLECTORS_STATE_COLORS.get(state, 'cyan') cprint('%s' % state.ljust(10), color=c) # Now print output the line under log = entry['log'] if log: cprint(' ' * 4 + '| ' + log, color='grey')
def do_node_uuid(): try: d = get_opsbro_json('/agent/info') except get_request_errors() as exp: logger.error('Cannot join opsbro agent for info: %s' % exp) sys.exit(1) _uuid = d.get('uuid') cprint(_uuid)
def do_node_public_addr(): try: d = get_opsbro_json('/agent/info') except get_request_errors() as exp: logger.error('Cannot join opsbro agent for info: %s' % exp) sys.exit(1) public_addr = d.get('public_addr') cprint(public_addr)
def do_list_follow_log(): try: parts = get_opsbro_json('/log/parts/') except get_request_errors() as exp: logger.error('Cannot join opsbro agent to list logs: %s' % exp) sys.exit(1) parts.sort() cprint("Available parts to follow logs:") for p in parts: cprint(" * %s" % p)
def do_collectors_state(): print_h1('Collectors') try: collectors = get_opsbro_json('/collectors') except get_request_errors() as exp: logger.error(exp) return cnames = list(collectors.keys()) cnames.sort() for cname in cnames: d = collectors[cname] __print_collector_state(d)
def do_exec(group='*', cmd='uname -a'): if cmd == '': logger.error('Missing command') return # The information is available only if the agent is started wait_for_agent_started(visual_wait=True) cmd_64 = bytes_to_unicode(base64.b64encode(unicode_to_bytes(cmd))) try: r = get_opsbro_json('/exec/%s?cmd=%s' % (group, cmd_64)) except get_request_errors() as exp: cprint('ERROR: cannot launch the command: %s' % exp, color='red') sys.exit(2) cid = r print("Command group launch as cid", cid) time.sleep(5) # TODO: manage a real way to get the result.. try: r = get_opsbro_json('/exec-get/%s' % cid) except get_request_errors() as exp: cprint('ERROR: cannot get execution results: %s' % exp, color='red') sys.exit(2) res = r['res'] print('Launched at: %s' % res) for (uuid, e) in res.items(): node = e['node'] nname = node['name'] color = {'alive': 'green', 'dead': 'red', 'suspect': 'yellow', 'leave': 'cyan'}.get(node['state'], 'cyan') cprint(nname, color=color) cprint('Return code for [%s]:' % e['cmd'], end='') color = {0: 'green', 1: 'yellow', 2: 'red'}.get(e['rc'], 'cyan') cprint(e['rc'], color=color) cprint('Output:', end='') cprint(e['output'].strip(), color=color) if e['err']: cprint('Error:', end='') cprint(e['err'].strip(), color='red') cprint('')
def do_ping(node): # The information is available only if the agent is started wait_for_agent_started(visual_wait=True) try: node_obj = get_opsbro_json('/agent/query/guess/%s' % node) except get_request_errors() as exp: logger.error('Cannot query the node: %s' % exp) sys.exit(2) if node_obj is None: cprint('FAILED: cannot find the node %s' % node, color='red') sys.exit(2) node_uuid = node_obj['uuid'] try: ping_result = get_opsbro_json('/agent/ping/%s' % node_uuid) except get_request_errors() as exp: logger.error('Cannot launch the node ping: %s' % exp) sys.exit(2) if 'error' in ping_result: cprint('FAILED: %s' % ping_result['error'], color='red') sys.exit(2) node_state = ping_result['state'] display_name = node_obj['display_name'] if not display_name: display_name = node_obj['name'] state_color = NODE_STATE_COLORS.get(node_state) state_char = NODE_STATE_PREFIXS.get(node_state) cprint(' %s ' % state_char, color=state_color, end='') cprint('%-15s ' % display_name, color='magenta', end='') cprint('is: ', end='') cprint(node_state, color=state_color) # If not alive, it's an error if node_state != NODE_STATES.ALIVE: sys.exit(2)
def do_members_history(): # The information is available only if the agent is started wait_for_agent_started(visual_wait=True) try: history_entries = get_opsbro_json('/agent/members/history') except get_request_errors() as exp: logger.error('Cannot join opsbro agent to show member history: %s' % exp) sys.exit(1) print_h1('History') for history_entry in history_entries: epoch_date = history_entry['date'] # We want only group type events entries = [ entry for entry in history_entry['entries'] if entry['type'] == 'node-state-change' ] if not entries: continue print_h2( ' Date: %s ' % time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(epoch_date))) for entry in entries: name = entry['name'] if entry.get('display_name', ''): name = '[ ' + entry.get('display_name') + ' ]' old_state = entry['old_state'] new_state = entry['state'] old_color = NODE_STATE_COLORS.get(old_state, 'cyan') old_state_prefix = NODE_STATE_PREFIXS.get( old_state, CHARACTERS.double_exclamation) new_color = NODE_STATE_COLORS.get(new_state, 'cyan') new_state_prefix = NODE_STATE_PREFIXS.get( new_state, CHARACTERS.double_exclamation) cprint('%s ' % name.ljust(20), color='magenta', end='') cprint(('%s %s' % (old_state_prefix, old_state)).ljust(9), color=old_color, end='') # 7 for the maximum state string + 2 for prefix cprint(' %s ' % CHARACTERS.arrow_left, color='grey', end='') cprint(('%s %s' % (new_state_prefix, new_state)).ljust(9), color=new_color ) # 7 for the maximum state string + 2 for prefix
def do_zone_list(): print_h1('Known zones') try: zones = get_opsbro_json('/agent/zones') except get_request_errors() as exp: logger.error(exp) return # We are building the zone tree, so link real object in other zone for zone in zones.values(): sub_zones = {} for sub_zone_name in zone.get('sub-zones', []): sub_zone = zones.get(sub_zone_name, None) sub_zones[sub_zone_name] = sub_zone zone['sub-zones'] = sub_zones # Set if the zone is top/lower if not our own zone for zone in zones.values(): zone['type'] = _ZONE_TYPES.OTHER # And finally delete the zone that are not in top level to_del = set() for (zname, zone) in zones.items(): for sub_zname in zone['sub-zones']: to_del.add(sub_zname) for zname in to_del: del zones[zname] for zone in zones.values(): _flag_top_lower_zone(zone) # Now print it zone_names = zones.keys() zone_names.sort() for zname in zone_names: zone = zones[zname] _print_zone(zname, zone, 0) cprint('') print_h1('Zones types legend') for zone_type in _ALL_ZONE_TYPES: label = _ZONE_TYPE_LABEL[zone_type] color = _ZONE_TYPE_COLORS[zone_type] description = _ZONE_TYPE_DESCRIPTION[zone_type] cprint(' - ', end='') cprint('%-15s' % label, color=color, end='') cprint(' : %s' % description)
def do_zone_list(): print_h1('Known zones') try: zones = get_opsbro_json('/agent/zones') except get_request_errors() as exp: logger.error(exp) return for (zname, zone) in zones.items(): cprint(' * ', end='') cprint(zname, color='magenta') sub_zones = zone.get('sub-zones', []) if not sub_zones: continue cprint(' Sub zones:') for sub_zname in sub_zones: cprint(' - ', end='') cprint(sub_zname, color='cyan')
def do_wait_event(event_type, timeout=30): # The information is available only if the agent is started wait_for_agent_started(visual_wait=True) import itertools spinners = itertools.cycle(CHARACTERS.spinners) for i in range(timeout): uri = '/agent/event/%s' % event_type logger.debug('ASK FOR EVENT %s' % event_type) try: evt = get_opsbro_json( uri, timeout=1) # slow timeout to allow fast looping # Timemouts: just loop except get_not_critical_request_errors() as exp: logger.debug( 'Asking for event: get timeout (%s), skiping this turn' % exp) evt = None except get_request_errors() as exp: logger.error( 'Cannot ask for event %s because there is a critical error: %s' % (event_type, exp)) sys.exit(2) if evt is not None: cprint('\n %s ' % CHARACTERS.arrow_left, color='grey', end='') cprint('%s ' % CHARACTERS.check, color='green', end='') cprint('The event ', end='') cprint('%s' % event_type, color='magenta', end='') cprint(' is ', end='') cprint('detected', color='green') sys.exit(0) # Not detected? increase loop cprint('\r %s ' % next(spinners), color='blue', end='') cprint('%s' % event_type, color='magenta', end='') cprint(' is ', end='') cprint('NOT DETECTED', color='magenta', end='') cprint(' (%d/%d)' % (i, timeout), end='') # As we did not \n, we must flush stdout to print it sys.stdout.flush() time.sleep(1) cprint("\nThe event %s was not detected after %s seconds" % (event_type, timeout)) sys.exit(2)
def do_collectors_show(name='', all=False): try: collectors = get_opsbro_json('/collectors') except get_request_errors() as exp: logger.error(exp) return disabled = [] for (cname, d) in collectors.items(): if name and not name == cname: continue if not name and not d['active'] and not all: disabled.append(d) continue print_info_title('Collector %s' % cname) pretty_print(d) if len(disabled) > 0: print_info_title('Disabled collectors') cprint(','.join([d['name'] for d in disabled]), color='grey')
def do_modules_state(): try: d = get_opsbro_json('/agent/info') except get_request_errors() as exp: logger.error('Cannot join opsbro agent for module state: %s' % exp) sys.exit(1) modules = d.get('modules', {}) print_info_title('Modules') modules_types = {} for (module_name, module) in modules.items(): module_type = module['module_type'] if module_type not in modules_types: modules_types[module_type] = {} modules_types[module_type][module_name] = module modules_type_names = list(modules_types.keys()) modules_type_names.sort() for (module_type, _modules) in modules_types.items(): cprint(' - [', end='') cprint(' %-10s ' % module_type.capitalize(), color='magenta', end='') cprint(' ]: ', end='') cprint(TYPES_DESCRIPTIONS.get(module_type, 'unknown module type'), color='grey') module_names = list(_modules.keys()) module_names.sort() for module_name in module_names: module = _modules[module_name] state = module['state'] state_color = MODULE_STATE_COLORS.get(state, 'grey') log = module['log'] kwcolor = {'color': 'grey'} if state == 'DISABLED' else {} cprint(' * ', end='', **kwcolor) cprint('%-20s ' % module_name, color=state_color, end='') cprint(state, color=state_color) if state != 'DISABLED' and log: cprint(' | Log: %s' % log, color='grey') cprint( ' | Note: you can look at modules configuration with the command opsbro packs show', color='grey')
def do_leave(nuuid=''): # The information is available only if the agent is started wait_for_agent_started(visual_wait=True) # Lookup at the localhost name first if not nuuid: try: nuuid = get_opsbro_json('/agent/uuid') except get_request_errors() as exp: logger.error('Cannot join opsbro agent to get our uuid: %s' % exp) sys.exit(2) uri = '/agent/leave/%s' % nuuid try: (code, r) = get_opsbro_local(uri) except get_request_errors() as exp: logger.error(exp) return if code != 200: logger.error('Node %s is missing (return=%s)' % (nuuid, r)) return cprint('Node %s is set to leave state' % nuuid, end='') cprint(': OK', color='green')
def do_collectors_wait_ok(collector_name, timeout=30): import itertools spinners = itertools.cycle(CHARACTERS.spinners) current_state = 'PENDING' for i in range(timeout): try: collectors = get_opsbro_json('/collectors') except get_request_errors() as exp: logger.error(exp) return collector = None for (cname, c) in collectors.items(): if cname == collector_name: collector = c if not collector: logger.error("Cannot find the collector '%s'" % collector_name) sys.exit(2) current_state = collector['state'] cprint('\r %s ' % next(spinners), color='blue', end='') cprint('%s' % collector_name, color='magenta', end='') cprint(' is ', end='') cprint('%15s ' % current_state, color=COLLECTORS_STATE_COLORS.get(current_state, 'cyan'), end='') cprint(' (%d/%d)' % (i, timeout), end='') # As we did not \n, we must flush stdout to print it sys.stdout.flush() if current_state == 'OK': cprint("\nThe collector %s is OK" % collector_name) sys.exit(0) logger.debug("Current state %s" % current_state) time.sleep(1) cprint("\nThe collector %s is not OK after %s seconds (currently %s)" % (collector_name, timeout, current_state)) sys.exit(2)
def do_wait_members(name='', display_name='', group='', count=1, timeout=30): # The information is available only if the agent is started wait_for_agent_started(visual_wait=True) import itertools spinners = itertools.cycle(CHARACTERS.spinners) for i in range(timeout): try: members = get_opsbro_json('/agent/members').values() except get_request_errors() as exp: logger.error(exp) sys.exit(2) if name: for m in members: if m['name'] == name: cprint('\n %s ' % CHARACTERS.arrow_left, color='grey', end='') cprint('%s ' % CHARACTERS.check, color='green', end='') cprint('The member ', end='') cprint('%s' % name, color='magenta', end='') cprint(' is ', end='') cprint('detected', color='green') sys.exit(0) elif display_name: for m in members: if m['display_name'] == display_name: cprint('\n %s ' % CHARACTERS.arrow_left, color='grey', end='') cprint('%s ' % CHARACTERS.check, color='green', end='') cprint('The member ', end='') cprint('%s' % display_name, color='magenta', end='') cprint(' is ', end='') cprint('detected', color='green') sys.exit(0) elif group: founded = [] for m in members: if group in m['groups']: founded.append(m) if len(founded) > count: cprint('\n %s ' % CHARACTERS.arrow_left, color='grey', end='') cprint('%s ' % CHARACTERS.check, color='green', end='') cprint('The group ', end='') cprint('%s' % group, color='magenta', end='') cprint(' is ', end='') cprint('detected', color='green') cprint(' with %d members' % len(founded), end='') sys.exit(0) # Not detected? increase loop cprint('\r %s ' % next(spinners), color='blue', end='') if name: cprint('%s' % name, color='magenta', end='') elif display_name: cprint('%s' % display_name, color='magenta', end='') else: cprint('%s' % group, color='magenta', end='') cprint(' is ', end='') cprint('NOT DETECTED', color='magenta', end='') cprint(' (%d/%d)' % (i, timeout), end='') # As we did not \n, we must flush stdout to print it sys.stdout.flush() time.sleep(1) cprint("\nThe name/display_name/group was not detected after %s seconds" % (timeout)) sys.exit(2)
def do_members(detail=False): # The information is available only if the agent is started wait_for_agent_started(visual_wait=True) try: members = get_opsbro_json('/agent/members').values() except get_request_errors() as exp: logger.error('Cannot join opsbro agent to list members: %s' % exp) sys.exit(1) members = my_sort(members, cmp_f=__sorted_members) pprint = libstore.get_pprint() logger.debug('Raw members: %s' % (pprint.pformat(members))) # If there is a display_name, use it max_name_size = max([ max(len(m['name']), len(m.get('display_name', '')) + 4) for m in members ]) max_addr_size = max( [len(m['addr']) + len(str(m['port'])) + 1 for m in members]) zones = set() for m in members: mzone = m.get('zone', '') if mzone == '': mzone = NO_ZONE_DEFAULT m['zone'] = mzone # be sure to fix broken zones zones.add(mzone) zones = list(zones) zones.sort() for z in zones: z_display = z if not z: z_display = NO_ZONE_DEFAULT z_display = z_display.ljust(15) title_s = '%s: %s' % (sprintf('Zone', color='yellow', end=''), sprintf(z_display, color='blue', end='')) print_h1(title_s, raw_title=True) for m in members: zone = m.get('zone', NO_ZONE_DEFAULT) if zone != z: continue name = m['name'] if m.get('display_name', ''): name = '[ ' + m.get('display_name') + ' ]' groups = m.get('groups', []) groups.sort() port = m['port'] addr = m['addr'] state = m['state'] is_proxy = m.get('is_proxy', False) if not detail: cprint(' - %s > ' % zone, color='blue', end='') cprint('%s ' % name.ljust(max_name_size), color='magenta', end='') else: cprint(' %s %s ' % (m['uuid'], name.ljust(max_name_size)), end='') c = NODE_STATE_COLORS.get(state, 'cyan') state_prefix = NODE_STATE_PREFIXS.get( state, CHARACTERS.double_exclamation) cprint(('%s %s' % (state_prefix, state)).ljust(9), color=c, end='') # 7 for the maximum state string + 2 for prefix s = ' %s:%s ' % (addr, port) s = s.ljust(max_addr_size + 2) # +2 for the spaces cprint(s, end='') if is_proxy: cprint('proxy ', end='') else: cprint(' ', end='') if detail: cprint('%5d' % m['incarnation'], end='') cprint(' %s ' % ','.join(groups))
def do_detect_nodes(auto_join, timeout=5): # The information is available only if the agent is started wait_for_agent_started(visual_wait=True) print_h1('UDP broadcast LAN detection') print( "Trying to detect other nodes on the network thanks to a UDP broadcast. Will last %ds." % timeout) cprint(' * The detection scan will be ', end='') cprint('%ds' % timeout, color='magenta', end='') cprint(' long.') threader.create_and_launch(__print_detection_spinner, (timeout, ), 'spinner', essential=False) # Send UDP broadcast packets from the daemon try: network_nodes = get_opsbro_json('/agent/detect?timeout=%d' % timeout, timeout=timeout + 10) except get_request_errors() as exp: logger.error('Cannot join opsbro agent to detect network nodes: %s' % exp) sys.exit(1) cprint(" * Detection is DONE") print_h1('Detection result') if len(network_nodes) == 0: cprint(' ERROR: ', color='red', end='') cprint("cannot detect (broadcast UDP) other nodes") sys.exit(1) cprint("Other network nodes detected on this network:") cprint( ' Name Zone Address:port Proxy Groups' ) for node in network_nodes: cprint(' %-35s %-10s %s:%d %5s %s' % (node['name'], node['zone'], node['addr'], node['port'], node['is_proxy'], ','.join(node['groups']))) if not auto_join: cprint('NOTICE: ', color='blue', end='') cprint( "Auto join (--auto-join) is not enabled, so don't try to join theses nodes" ) return # try to join theses nodes so :) # NOTE: sort by uuid so we are always joining the same nodes # and so we don't have split network if possible (common node) all_proxys = sorted([node for node in network_nodes if node['is_proxy']], key=lambda n: n['uuid']) not_proxys = sorted( [node for node in network_nodes if not node['is_proxy']], key=lambda n: n['uuid']) if all_proxys: node = all_proxys.pop() cprint("A proxy node is detected, using it: %s (%s:%d)" % (node['name'], node['addr'], node['port'])) to_connect = '%s:%d' % (node['addr'], node['port']) else: node = not_proxys.pop() cprint("No proxy node detected. Using a standard one: %s (%s:%d)" % (node['name'], node['addr'], node['port'])) to_connect = '%s:%d' % (node['addr'], node['port']) do_join(to_connect)
def do_info(show_logs): try: d = get_opsbro_json('/agent/info') except get_request_errors() as exp: logger.error('Cannot join opsbro agent for info: %s' % exp) sys.exit(1) logs = d.get('logs') version = d.get('version') cpu_consumption = d.get('cpu_consumption') memory_consumption = d.get('memory_consumption') name = d.get('name') display_name = d.get('display_name', '') # A failback to display name is the name (hostname) if not display_name: display_name = name else: # show it's a display name display_name = '[ ' + display_name + ' ]' port = d.get('port') local_addr = d.get('local_addr') public_addr = d.get('public_addr') zone = d.get('zone') zone_color = 'green' if not zone: zone = NO_ZONE_DEFAULT zone_color = 'red' is_managed_system = d.get('is_managed_system') system_distro = d.get('system_distro') system_distroversion = d.get('system_distroversion') is_zone_protected = d.get('is_zone_protected') is_zone_protected_display = ('%s zone have a gossip key' % CHARACTERS.check, 'green') if is_zone_protected else ( '%s zone do not have a gossip key' % CHARACTERS.double_exclamation, 'yellow') nb_threads = d.get('threads')['nb_threads'] hosting_drivers_state = d.get('hosting_drivers_state', []) httpservers = d.get('httpservers', {'internal': None, 'external': None}) socket_path = d.get('socket') _uuid = d.get('uuid') # Modules groking modules = d.get('modules', {}) topics = d.get('topics', {}) # Get groups as sorted groups = d.get('groups') groups.sort() groups = ','.join(groups) collectors = d.get('collectors') monitoring = d.get('monitoring') compliance = d.get('compliance') generators = d.get('generators') kv_store = d.get('kv') ################### Generic __print_topic_header(TOPIC_GENERIC) # print_info_title('OpsBro Daemon') __print_key_val('Name', name, topic=TOPIC_GENERIC) display_name_color = 'green' if (name != display_name) else 'grey' __print_key_val('Display name', display_name, color=display_name_color, topic=TOPIC_GENERIC) __print_key_val('System', '%s (version %s) ' % (system_distro, system_distroversion), color='green', topic=TOPIC_GENERIC, end_line='') if is_managed_system: cprint(' %s managed' % CHARACTERS.check, color='grey') else: cprint(' %s this system is not managed' % CHARACTERS.double_exclamation, color='yellow') __print_more( ' Not managed means that configuration automation & system compliance will not be available' ) # We will print modules by modules types # cprint(' - Modules: '.ljust(DEFAULT_INFO_COL_SIZE), end='', color='blue') modules_by_states = {} for module_state in MODULE_STATES: modules_by_states[module_state] = [] for (module_name, module) in modules.items(): modules_by_states[module['state']].append(module) strs = [] for module_state in MODULE_STATES: nb = len(modules_by_states[module_state]) state_color = MODULE_STATE_COLORS.get(module_state, 'grey') color = 'grey' if nb == 0 else state_color _s = sprintf('%d %s ' % (nb, module_state), color=color, end='') strs.append(_s) module_string = sprintf(' / ', color='grey', end='').join(strs) __print_key_val('Modules', module_string, topic=TOPIC_GENERIC) __print_topic_picto(TOPIC_GENERIC) __print_more('opsbro agent modules state') ################### Service Discovery cprint('') __print_topic_header(TOPIC_SERVICE_DISCOVERY) __print_key_val('UUID', _uuid, topic=TOPIC_SERVICE_DISCOVERY) __print_key_val('Local addr', local_addr, topic=TOPIC_SERVICE_DISCOVERY) __print_key_val('Public addr', public_addr, topic=TOPIC_SERVICE_DISCOVERY) __print_key_val('UDP port', port, topic=TOPIC_SERVICE_DISCOVERY) # Normal agent information ext_server = httpservers.get('external') int_server = httpservers.get('internal') ext_threads = '%d/%d' % (ext_server['nb_threads'] - ext_server['idle_threads'], ext_server['nb_threads']) if int_server: int_threads = '%d/%d' % (int_server['nb_threads'] - int_server['idle_threads'], int_server['nb_threads']) else: # windows case int_threads = '(not available on windows)' __print_key_val('HTTP threads', 'LAN:%s Private socket:%s' % (ext_threads, int_threads), topic=TOPIC_SERVICE_DISCOVERY) __print_topic_picto(TOPIC_SERVICE_DISCOVERY) __print_note( ' Listen on the TCP port %s Listen on the unix socket %s' % (port, socket_path)) __print_key_val('Zone', zone, color=zone_color, topic=TOPIC_SERVICE_DISCOVERY, end_line=False) cprint(' (%s)' % is_zone_protected_display[0], color=is_zone_protected_display[1]) __print_topic_picto(TOPIC_SERVICE_DISCOVERY) __print_more('opsbro gossip members') ################################## Automatic Detection cprint('') __print_topic_header(TOPIC_AUTOMATIC_DECTECTION) __print_key_val('Groups', groups, topic=TOPIC_AUTOMATIC_DECTECTION) __print_topic_picto(TOPIC_AUTOMATIC_DECTECTION) __print_more('opsbro detectors state') # Show hosting drivers, and why we did chose this one main_driver_founded = False strs = [] for driver_entry in hosting_drivers_state: driver_name = driver_entry['name'] driver_is_active = driver_entry['is_active'] _name = driver_name if not main_driver_founded and driver_is_active: strs.append( sprintf('[', color='magenta') + sprintf(_name, color='green') + sprintf(']', color='magenta')) main_driver_founded = True elif driver_is_active: strs.append(sprintf(_name, color='green')) else: strs.append(sprintf(_name, color='grey')) _hosting_drivers_state_string = sprintf(' %s ' % CHARACTERS.arrow_left, color='grey').join(strs) __print_key_val('Hosting drivers', _hosting_drivers_state_string, topic=TOPIC_AUTOMATIC_DECTECTION) __print_topic_picto(TOPIC_AUTOMATIC_DECTECTION) __print_note( 'first founded valid driver is used as main hosting driver (give uuid, public/private ip, %s)' % CHARACTERS.three_dots) ################################## Monitoring cprint('') __print_topic_header(TOPIC_MONITORING) monitoring_strings = [] for check_state in CHECK_STATES: count = monitoring[check_state] color = STATE_COLORS.get(check_state) if count != 0 else 'grey' s = ('%d %s' % (count, check_state.upper())).ljust(15) s = sprintf(s, color=color, end='') monitoring_strings.append(s) monitoring_string = sprintf(' / ', color='grey', end='').join(monitoring_strings) __print_key_val('Check states', monitoring_string, topic=TOPIC_MONITORING) __print_topic_picto(TOPIC_MONITORING) __print_more('opsbro monitoring state') ################################## Metrology # Now collectors part cprint('') __print_topic_header(TOPIC_METROLOGY) cnames = list(collectors.keys()) cnames.sort() collectors_states = {} for collector_state in COLLECTORS_STATES: collectors_states[collector_state] = [] for cname in cnames: v = collectors[cname] collector_state = v['state'] collectors_states[collector_state].append(cname) strs = [] for collector_state in COLLECTORS_STATES: nb = len(collectors_states[collector_state]) state_color = COLLECTORS_STATE_COLORS.get(collector_state, 'grey') color = 'grey' if nb == 0 else state_color _s = ('%d %s' % (nb, collector_state)).ljust(15) _s = sprintf(_s, color=color, end='') strs.append(_s) collector_string = sprintf(' / ', color='grey', end='').join(strs) __print_key_val('Collectors', collector_string, topic=TOPIC_METROLOGY) __print_topic_picto(TOPIC_METROLOGY) __print_more('opsbro collectors state') ################################## configuration automation cprint('') __print_topic_header(TOPIC_CONFIGURATION_AUTOMATION) strs = [] for state in GENERATOR_STATES: nb = generators[state] state_color = GENERATOR_STATE_COLORS.get(state, 'grey') color = 'grey' if nb == 0 else state_color _s = ('%d %s' % (nb, state)).ljust(15) _s = sprintf(_s, color=color, end='') strs.append(_s) generator_string = sprintf(' / ', color='grey', end='').join(strs) __print_key_val('Generators', generator_string, topic=TOPIC_CONFIGURATION_AUTOMATION) __print_topic_picto(TOPIC_CONFIGURATION_AUTOMATION) __print_more('opsbro generators state') ################################## system compliance cprint('') __print_topic_header(TOPIC_SYSTEM_COMPLIANCE) strs = [] for state in ALL_COMPLIANCE_STATES: nb = compliance[state] state_color = COMPLIANCE_STATE_COLORS.get(state, 'grey') color = 'grey' if nb == 0 else state_color _s = ('%d %s' % (nb, state)).ljust(15) _s = sprintf(_s, color=color, end='') strs.append(_s) collector_string = sprintf(' / ', color='grey', end='').join(strs) __print_key_val('Compliance rules', collector_string, topic=TOPIC_SYSTEM_COMPLIANCE) __print_topic_picto(TOPIC_SYSTEM_COMPLIANCE) __print_more('opsbro compliance state') ############### Logs: Show errors logs if any cprint('') print_info_title('Technical info') cprint(' - Job threads: '.ljust(DEFAULT_INFO_COL_SIZE), end='', color='blue') cprint(nb_threads, color='green') if memory_consumption != 0: mo_memory_consumption = int(memory_consumption / 1024.0 / 1024.0) s = '%dMB' % mo_memory_consumption __print_key_val('Memory usage', s) if cpu_consumption != 0: s = '%.1f%%' % cpu_consumption __print_key_val('CPU Usage', s) __print_more('opsbro agent internal show-threads') kv_store_backend = kv_store.get('backend', None) if kv_store_backend: cprint(' - KV Backend: '.ljust(DEFAULT_INFO_COL_SIZE), end='', color='blue') cprint(kv_store_backend['name'], color='green') cprint(' - size: '.ljust(DEFAULT_INFO_COL_SIZE), end='', color='blue') cprint('%.2fMB' % (kv_store['stats']['size'] / 1024.0 / 1024.0), color='green') if kv_store_backend['name'] != 'leveldb': __print_note( 'You do not have the fastest lib/backend. Please launch the command: opsbro compliance launch "Install tuning libs"' ) kv_store_error = kv_store['stats']['error'] if kv_store_error != '': cprint(' - error: '.ljust(DEFAULT_INFO_COL_SIZE), color='blue', end='') cprint(kv_store_error, color='red') cprint(' - Version: '.ljust(DEFAULT_INFO_COL_SIZE), end='', color='blue') cprint(version, color='green') errors = logs.get('ERROR') warnings = logs.get('WARNING') cprint(' - Logs: '.ljust(DEFAULT_INFO_COL_SIZE), end='', color='blue') # Put warning and errors in red/yellow if need only error_color = 'red' if len(errors) > 0 else 'grey' warning_color = 'yellow' if len(warnings) > 0 else 'grey' cprint('%d errors ' % len(errors), color=error_color, end='') cprint('%d warnings ' % len(warnings), color=warning_color) # If there are errors or warnings, help the user to know it can print them if not show_logs and (len(errors) > 0 or len(warnings) > 0): __print_note( 'you can show error & warning logs with the --show-logs options') if show_logs: if len(errors) > 0: print_info_title('Error logs') for s in errors: cprint(s, color='red') if len(warnings) > 0: print_info_title('Warning logs') for s in warnings: cprint(s, color='yellow') logger.debug('Raw information: %s' % d)
def do_show_threads(): try: data = get_opsbro_json('/threads/') except get_request_errors() as exp: logger.error('Cannot join opsbro agent to show threads: %s' % exp) sys.exit(1) all_threads = data['threads'] process = data['process'] age = data['age'] # Cut the threads into 2 lists: always here, and the others all_daemon_threads = [t for t in all_threads if t['essential']] all_not_daemon_threads = [t for t in all_threads if not t['essential']] # Put essential ones into part threads_into_parts = {} for t in all_daemon_threads: part = t['part'].capitalize() if not t: part = '(unknown)' if part not in threads_into_parts: threads_into_parts[part] = { 'name': part, 'user_time': 0.0, 'system_time': 0.0, 'threads': [] } e = threads_into_parts[part] e['user_time'] += t['user_time'] e['system_time'] += t['system_time'] e['threads'].append(t) # Sort threads inside the parts for (pname, e) in threads_into_parts.items(): e['threads'].sort(_sort_threads) # Now have parts sort by their times (from bigger to min) parts_sorts_by_cpu_usage = threads_into_parts.values() parts_sorts_by_cpu_usage = sorted(parts_sorts_by_cpu_usage, key=lambda e: -e['user_time']) # Then by name parts_sorts_by_name = threads_into_parts.values() parts_sorts_by_name = sorted(parts_sorts_by_name, key=lambda e: e['name']) all_daemon_threads.sort(_sort_threads) all_not_daemon_threads.sort(_sort_threads) upercent, syspercent = __get_cpu_time_percent_display(process, age) cprint('Total process CPU consumption: ', color='blue', end='') cprint('cpu(user):%s%% ' % upercent, color='magenta', end='') cprint('cpu(system):%s%%' % syspercent) cprint("\n") cprint("Summary of CPU consumption based on opsbro parts:") for p in parts_sorts_by_cpu_usage: upercent, syspercent = __get_cpu_time_percent_display(p, age) cprint(' * [ ', end='') cprint('%-15s' % p['name'], color='blue', end='') cprint(' ] ', end='') cprint('cpu(user):%s%% ' % upercent, color='magenta', end='') cprint('cpu(system):%s%%' % syspercent) cprint("") cprint("Daemon threads (persistent):") for p in parts_sorts_by_name: cprint('[ ', end='') cprint('%-15s' % p['name'], color='blue', end='') cprint(' ] ') for t in p['threads']: upercent, syspercent = __get_cpu_time_percent_display(t, age) cprint( ' * %-55s thread id:%5d cpu(user):%s%% cpu(system):%s%%' % (t['name'], t['tid'], upercent, syspercent)) if all_not_daemon_threads: cprint("\nTemporary threads:") for t in all_not_daemon_threads: upercent, syspercent = __get_cpu_time_percent_display(t, age) cprint(' Name:%-55s id:%d cpu(user):%s%% cpu(system):%s%%' % (t['name'], t['tid'], upercent, syspercent))