def do_subscribe(self, *args): '''Usage: subscribe [notifType|ALL] Subscribe to specific notification type. If a logger is specified, the logger's log level is changed to DEBUG. If no argument provided, the command lists all notifications grouped by listener. ''' if len(args[0].split(" ")) > 1: printError("INVALID_CL_ARGS") return arg_str = args[0].strip() try: if arg_str.upper() == "ALL": for key, listener in self.listenersDic.items(): for msgType in listener.getNotifTypes(): self.subscribeToSpecificNotifType(msgType) elif arg_str: # Subscribe to a specific notification self.subscribeToSpecificNotifType(arg_str) else: # list notifications for all listeners for listenerName, listener in self.listenersDic.items(): notifTypesList = listener.getNotifTypes() notifTypesStr = ", ".join(notifTypesList) printInfo('{0}:\n {1}\n'.format(listenerName, notifTypesStr)) except Exception as e: printError(obv=str(e)) return
def cmdloop(self): try: cmd.Cmd.cmdloop(self) except KeyboardInterrupt as e: sys.stdout.write('\n') self.cmdloop() except Exception as e: printError(obv=str(e)) self.cmdloop()
def do_logout(self, *args): '''Usage: logout Exit console. ''' try: self.quitApp() except Exception as e: printError(obv=str(e)) return True
def do_info(self, *args): ''' Usage: info Show the information of Manager, AP, APC and GPS ''' try: self.apcClient.info() except Exception as e: printError(obv=str(e)) print "Please make sure APC is running and is connected to Manager and AP" return
def do_reset(self, *args): ''' Usage: reset ap ap -- reset AP ''' iArgs = args[0].split() if len(iArgs) == 0 or not (iArgs[0].lower() in ('ap')): printError("INVALID_CL_ARGS") return try: self.apcClient.rpcResetAP() except Exception as e: printError(obv=str(e)) return
def limitQueueError(self, qsize): if len(self.trace_filter) or len(self.filters): try: printError( obv= 'Listener queue is full. Unsubscribed from all (inbox is saved): {0}' .format(' '.join(self.getSubscribedNotifs()))) except: printError( obv= 'Listener queue is full. Unsubscribed from all (inbox is saved)' ) self.trace_filter = set() self.filters = set()
def getAllLoggers(self): 'Get all loggers' try: resp = self.apcClient.send(logevent_pb2.GET_LOGGERS, "", LOGGER_SERVICE) except Exception as e: printError(obv=str(e)) return (rc, ) = struct.unpack("!L", resp[1]) if not rc: loggers_resp = logevent_pb2.GetLoggersResponse.FromString(resp[2]) return rc, loggers_resp.loggers else: return rc, []
def handleNotif(self, input_msg): '''Perform basic notification parsing, purge inbox, call processNotif. \param input_msg - Input message string ''' # separate the notification id from the notification structure # TODO: it might be better to use an instance flag to indicate whether # we should expect log message notifications notif_id = 0 try: notif_id = self.deserialize_notifid(input_msg) # Purge INBOX of this notification type self.purgeInbox(notif_id) # Listener-specific notification processing self.processNotif(notif_id, input_msg[1]) except Exception as ex: MSG_TMPL = 'Exception in {0} processNotif: notifId={1} msg={2}\n{3}' msg = MSG_TMPL.format(type(self), notif_id, input_msg, ex) printError(obv=msg)
def setLogLevel(self, loggerName, levelName, fShowResult=True): '''Unsubscribe all subscribed listeners. Keyword arguments: loggerName - Logger name levelName - Level name ''' logger_req = logevent_pb2.SetLogLevelRequest() try: logger_req.logger = loggerName levelName = "L_" + levelName logger_req.logLevel = logevent_pb2._LOGLEVEL.values_by_name[ levelName.upper()].number except KeyError: printError(obv="Invalid name '{0}'".format(levelName)) return try: self.apcClient.send_msg(logevent_pb2.SET_LOG_LEVEL, logger_req, "", LOGGER_SERVICE) except TimeoutError as exc: printError(obv=str(exc)) return except RpcError as exc: if exc.result_code == Enum_RpcResult.to_int( 'RPC_INVALID_PARAMETERS'): printRPCError('RPC_INVALID_PARAMETERS', loggerName) else: printError(obv=str(exc)) return if fShowResult: printInfo("Done")
def do_unsubscribe(self, *args): '''Usage: unsubscribe [<notifType>] [ALL] Unsubscribe from a specific message type. ALL will unsubscribe from all message type. ''' if len(args[0].split(" ")) > 1 or args[0].strip() == '': printError("INVALID_CL_ARGS") return notifType = args[0].strip() try: if notifType.upper() == 'ALL': self.unsubscribeAllListeners() else: listener = self.findListener(notifType) if not listener: printError(obv="Unknown notification name '{0}'".format( notifType)) return self.listenersDic[listener].unregisterNotifType(notifType) if self.listenersDic[listener].isFilterListEmpty(): self.stopListener(listener) except Exception as e: printError(obv=str(e)) printInfo('Done')
def subscribeToSpecificNotifType(self, notifType): '''Subscribe to a specific notification type Keyword arguments: notifType - Notification type ''' try: listener = self.findListener(notifType) if not listener: printError( obv="Notification type {0} not found".format(notifType)) return if listener == 'logListener': #Change log level to DEBUG self.setLogLevel(notifType, 'DEBUG', HIDE_RESULT) self.listenersDic[listener].registerNotifType(notifType) except KeyError as exc: printError(obv=str(exc)) return if not listener: printError( obv="Notification type '{0}' not found".format(notifType)) return if not self.listenersDic[listener].isRunning(): listener_thread = threading.Thread( target=self.listenersDic[listener].run) listener_thread.start() printInfo("Subscribed to {0}".format(notifType))
def do_stats(self, *args): '''Usage: stats <ap|manager|clear> ap -- Get statistics of APC/AP connection manager -- Get statistics of APC/Manager connection clear -- Clear APC/AP and APC/Manager statistics ''' cmdArgs = args[0].split() if len(cmdArgs) == 0: try: self.apcClient.getStats('all') except Exception as e: printError(obv=str(e)) print "Please make sure APC is running and is connected to Manager and AP" return cmd = args[0].lower() try: # partial match of command is allowed if 'ap'.find(cmd) == 0: self.apcClient.getStats('ap') elif 'manager'.find(cmd) == 0: self.apcClient.getStats('manager') elif 'clear'.find(cmd) == 0: self.apcClient.clearStats() else: printError("INVALID_CL_ARGS") except Exception as e: printError(obv=str(e)) return
def saveTraceMessage(self, traceMsg): '''Save trace message into a specific file Keyword arguments: traceMsg - Trace message to save ''' # Check if the message should be saved if not self.fSave: return # Open/create file try: traceFile = open(self.logFileName, 'a+') except IOError as exc: printError(obv='FILE_NOT_FOUND ' + str(exc)) return # Save message traceFile.write(traceMsg) # Close file traceFile.close()
def listMessages(self, args, notifyType, fPrint=True): '''List messages in the INBOX Keyword arguments: args - How many notifications to show notifType - Notificaction type to list Example: Last 10 ''' try: notifyType = self.lookupNotifId(notifyType) if not self.INBOX[notifyType]: if fPrint: print "No messages" return (0, []) rangeValues = self.parseArgs(args, notifyType) except IndexError as exc: printError(obv=str(exc)) return (1, []) except ValueError: printError(obv='INVALID_CL_ARGS') return (2, []) except KeyError: printError(obv=str(exc)) return (3, []) firstLine = rangeValues[0] lastLine = rangeValues[1] rangeIndex = firstLine outputMsgs = [] for i in range(firstLine, lastLine): queueIndex = i if fPrint: if rangeValues[2] != "RANGE": self.printNotif(queueIndex + self.base_msgId, self.INBOX[notifyType][queueIndex], notifyType) else: queueIndex = (rangeIndex - self.base_msgId) rangeIndex = rangeIndex + 1 if queueIndex < 0: continue if queueIndex >= len(self.INBOX[notifyType]): break self.printNotif(i, self.INBOX[notifyType][queueIndex], notifyType) outputMsgs.append(self.INBOX[notifyType][queueIndex]) return (0, outputMsgs)
def do_set(self, *args): ''' Usage: set <ap|loglevel> [args] ap -- set AP parameters [args] is a parameter followed by value parameter are - clkSrc - jkey - txpwr value is parameter dependent loglevel -- set loglevel for a logger [args] is a logger followed by severity logger is the output from logger command severity is - FATAL (1) - ERR (2) - WARN (3) - INFO (4) - DEBUG (5) - TRACE (6) ''' cmdArgs = args[0].split(" ") if len(cmdArgs) != 3: printError("INVALID_CL_ARGS") return cmd = cmdArgs[0].lower() numCmdArgs = len(cmdArgs) - 1 if numCmdArgs: cmdArgs = cmdArgs[1:] try: if cmd == "loglevel" and numCmdArgs == 2: self.setLogLevel(cmdArgs[0].lower(), cmdArgs[1].lower()) elif cmd == "ap" and numCmdArgs == 2: if cmdArgs[0].lower() == 'clksrc': self.apcClient.rpcSetAPClkSrc(cmdArgs) else: cmdArgs = [x.lower() for x in cmdArgs] self.apcClient.rpcAP_API_setParameter(cmdArgs) else: printError("INVALID_CL_ARGS") except Exception as e: printError(obv=str(e)) return
def do_get(self, *args): ''' Usage: get <ap|apc> [args] ap -- get AP parameters [args] are - apInfo - apStatus - clkSrc - macAddr - netid - time - txpwr apc -- get APC parameters [args] are - clientId - gpsState - managerHost - managerPort ''' cmdArgs = args[0].split(" ") if len(cmdArgs) != 2: printError("INVALID_CL_ARGS") return cmd = cmdArgs[0].lower() numCmdArgs = len(cmdArgs) - 1 if numCmdArgs: cmdArgs = cmdArgs[1:] try: if cmd == "ap" and numCmdArgs == 1: if cmdArgs[0].lower() == 'clksrc': self.apcClient.rpcGetAPClkSrc(cmdArgs) else: self.apcClient.rpcAP_API_getParameter(cmdArgs[0].lower()) elif cmd == "apc" and numCmdArgs == 1: self.apcClient.rpcAPC_getParameter(cmdArgs[0].lower()) else: printError("INVALID_CL_ARGS") except Exception as e: printError(obv=str(e)) return
for cmd in fd: cmd = cmd.strip() if cmd.startswith('#'): continue printInfo('exec: {0}'.format(cmd)) l = commander.precmd(cmd) r = commander.onecmd(l) r = commander.postcmd(r, l) fd.close() except IOError as exc: printError("FILE_NOT_FOUND", str(exc)) if not args.interactive: #To unsubscribe listeners(stop threads). commander.unsubscribeAllListeners() else: try: commander.cmdloop() except: print "Command failed, please check if APC is running" # Close listeners and RPC clients log_console.close() if __name__ == '__main__': try: main(sys.argv[1:]) except Exception as e: printError(obv=str(e))
def fatalZMQError(self, ex): printError(obv='FATAL ZMQ ERROR: {0}'.format(ex))
def fatalQueueError(self, qsize): printError(obv='\nFATAL ERROR. Listener queue overflowed.') os._exit(1)
def do_trace(self, *args): '''Usage: trace <notifType|all> <on|off> Turn on/off traces a specific notify type. ''' cmd = args[0].split(" ") if len(cmd) <= 1: # list notifications for all listeners for key, listener in self.listenersDic.items(): notifTypesList = listener.getNotifTypes() notifTypesStr = ", ".join(notifTypesList) printInfo('{0}:\n {1}\n'.format(listener.getName(), notifTypesStr)) return notifType = cmd[0] fEnable = cmd[1] if cmd[1] == 'off': fEnable = False elif cmd[1] == 'on': fEnable = True else: printError("INVALID_CL_ARGS", obv="{0} should be on or off.".format(fEnable)) return if fEnable and notifType.upper() == "ALL": printError("INVALID_CL_ARGS", obv="'all on' is not supported.") return if notifType.upper() == "ALL": try: for key, listener in self.listenersDic.items(): listener.disableTrace() printInfo("Trace disabled for all") except Exception as e: printError(obv=str(e)) return try: listener = self.findListener(notifType) if not listener: printError(obv="Invalid notify type '{0}'".format(notifType)) return if fEnable: self.subscribeListener(listener, notifType) self.listenersDic[listener].enableTrace(notifType) printInfo("Trace enabled for " + notifType) else: self.listenersDic[listener].disableTrace(notifType) printInfo("Trace disabled for " + notifType) except KeyError: printError( obv="Notification type '{0}' not subscribed".format(notifType)) except Exception as e: printError(obv=str(e))
def main(argv): # Parse command line arguments parser = commonUtils.MainCmdArgParser(APC_HOME, 'Console arguments.', 'console') parser.add_argument('--cmd', help="Execute a single command in batch mode") parser.add_argument('-f', '--filename', help="Execute all cmds inside the file") parser.add_argument('-i', '--interactive', type=bool, default=True, help="Interactive mode") parser.add_argument('-n', '--name', help="APC client-id") args = parser.parse_args() if not args: print parser.errmsg sys.exit(1) endPoints = commonUtils.ApiEndpointBuilder(APC_HOME, args.api_proto, args.api_ipcpath, args.api_host, args.api_port) if args.name: APC_ENDPOINT = endPoints.getClientEndpoint('APC_ENDPOINT_PATH', args.name) APC_LOG_ENDPOINT = endPoints.getClientEndpoint('APC_LOG_ENDPOINT_PATH', args.name) else: # if there is only one APC running, connec to it numApcRunning = 0 apcInfo = [] for proc in psutil.process_iter(): try: pInfo = proc.as_dict(attrs=['pid', 'name', 'cmdline']) if pInfo['name'] == 'apc': numApcRunning = numApcRunning + 1 apcInfo = pInfo except psutil.NoSuchProcess: pass if numApcRunning == 0: print "APC is not running, please use apcctl to start APC then try again." sys.exit(1) elif numApcRunning == 1: try: location = apcInfo['cmdline'].index('--client-id') # the APC client-id value is the next APCName = apcInfo['cmdline'][location + 1] APC_ENDPOINT = endPoints.getClientEndpoint( 'APC_ENDPOINT_PATH', APCName) APC_LOG_ENDPOINT = endPoints.getClientEndpoint( 'APC_LOG_ENDPOINT_PATH', APCName) except ValueError: print "APC is running without client-id, please check." sys.exit(1) else: print "{0} APCs are running, don't know which one to connect to. Please retry with -n option.".format( numApcRunning) sys.exit(1) ctx = zmq.Context() # Print BANNER print BANNER # apc RPC client apc = ApcClient(ctx, APC_ENDPOINT) rpcClientsDic = {APC_CLIENT_NAME: apc} # Notification listeners log_console = NoSecLogConsole(ctx, "logListener", APC_LOG_ENDPOINT, rpcClientsDic[APC_CLIENT_NAME]) listenersDic = {'logListener': log_console} commander = CommandLineHandler(rpcClientsDic, listenersDic) if args.cmd: l = commander.precmd(args.cmd) r = commander.onecmd(l) r = commander.postcmd(r, l) if not args.interactive: #To unsubscribe listeners(stop threads). commander.unsubscribeAllListeners() elif args.filename: try: fd = open(args.filename, 'r') printInfo('Loading commands from {0}'.format(args.filename)) for cmd in fd: cmd = cmd.strip() if cmd.startswith('#'): continue printInfo('exec: {0}'.format(cmd)) l = commander.precmd(cmd) r = commander.onecmd(l) r = commander.postcmd(r, l) fd.close() except IOError as exc: printError("FILE_NOT_FOUND", str(exc)) if not args.interactive: #To unsubscribe listeners(stop threads). commander.unsubscribeAllListeners() else: try: commander.cmdloop() except: print "Command failed, please check if APC is running" # Close listeners and RPC clients log_console.close()