def __init__(self, header, loglevel, loglevel_type, name, filter_exp): super(self.__class__, self).__init__(header) self.loglevel = loglevel self.loglevel_type = loglevel_type self.name = name self.filter_expression = filter_exp dbg._pdebug('server enable command {}'.format(self.__dict__))
def _handle_server_cmd_list(self, server_cmd): dbg._pdebug(self._debug('got "list" server command')) names = logging.Logger.manager.loggerDict.keys() dbg._pdebug(self._debug('found {} loggers'.format(len(names)))) cmd_reply = lttngust.cmd._ClientCmdReplyList(names=names) return cmd_reply
def _handle_server_cmd_list(self, server_cmd): dbg._pdebug(self._debug('got "list" server command')) names = logging.Logger.manager.loggerDict.keys() dbg._pdebug(self._debug("found {} loggers".format(len(names)))) cmd_reply = lttngust.cmd._ClientCmdReplyList(names=names) return cmd_reply
def _server_cmd_header_from_data(data): try: data_size, cmd_id, cmd_version = _server_cmd_header_struct.unpack(data) except (Exception) as e: dbg._pdebug('cannot decode command header: {}'.format(e)) return None return _ServerCmdHeader(data_size, cmd_id, cmd_version)
def from_data(cls, header, data): try: name = data.rstrip(b'\0').decode() return cls(header, name) except (Exception) as e: dbg._pdebug('cannot decode disable command: {}'.format(e)) return None
def from_data(cls, header, data): try: loglevel, loglevel_type = cls._loglevel_struct.unpack_from(data) data_name = data[cls._loglevel_struct.size:] name = data_name.rstrip(b'\0').decode() return cls(header, loglevel, loglevel_type, name) except (Exception) as e: dbg._pdebug('cannot decode enable command: {}'.format(e)) return None
def _recv_server_cmd_header(self): data = self._sessiond_sock.recv(lttngust.cmd._SERVER_CMD_HEADER_SIZE) if not data: dbg._pdebug(self._debug("received empty server command header")) return None assert len(data) == lttngust.cmd._SERVER_CMD_HEADER_SIZE dbg._pdebug(self._debug("received server command header ({} bytes)".format(len(data)))) return lttngust.cmd._server_cmd_header_from_data(data)
def _recv_server_cmd_header(self): data = self._sessiond_sock.recv(lttngust.cmd._SERVER_CMD_HEADER_SIZE) if not data: dbg._pdebug(self._debug('received empty server command header')) return None assert (len(data) == lttngust.cmd._SERVER_CMD_HEADER_SIZE) dbg._pdebug( self._debug('received server command header ({} bytes)'.format( len(data)))) return lttngust.cmd._server_cmd_header_from_data(data)
def _handle_server_cmd_reg_done(self, server_cmd): dbg._pdebug(self._debug('got "registration done" server command')) if self._reg_queue is not None: dbg._pdebug(self._debug('notifying _init_threads()')) try: self._reg_queue.put(True) except (Exception) as e: # read side could be closed by now; ignore it pass self._reg_queue = None
def _handle_server_cmd_reg_done(self, server_cmd): dbg._pdebug(self._debug('got "registration done" server command')) if self._reg_queue is not None: dbg._pdebug(self._debug("notifying _init_threads()")) try: self._reg_queue.put(True) except (Exception) as e: # read side could be closed by now; ignore it pass self._reg_queue = None
def _get_port_from_file(path): port = None dbg._pdebug('reading port from file "{}"'.format(path)) try: f = open(path) r_port = int(f.readline()) f.close() if r_port > 0 or r_port <= 65535: port = r_port except: pass return port
def _handle_server_cmd(self, server_cmd): cmd_reply = None if server_cmd is None: dbg._pdebug(self._debug("bad server command")) status = lttngust.cmd._CLIENT_CMD_REPLY_STATUS_INVALID_CMD cmd_reply = lttngust.cmd._ClientCmdReply(status) elif type(server_cmd) in self._server_cmd_handlers: cmd_reply = self._server_cmd_handlers[type(server_cmd)](server_cmd) else: dbg._pdebug(self._debug("unknown server command")) status = lttngust.cmd._CLIENT_CMD_REPLY_STATUS_INVALID_CMD cmd_reply = lttngust.cmd._ClientCmdReply(status) if cmd_reply is not None: self._send_cmd_reply(cmd_reply)
def _handle_server_cmd(self, server_cmd): cmd_reply = None if server_cmd is None: dbg._pdebug(self._debug('bad server command')) status = lttngust.cmd._CLIENT_CMD_REPLY_STATUS_INVALID_CMD cmd_reply = lttngust.cmd._ClientCmdReply(status) elif type(server_cmd) in self._server_cmd_handlers: cmd_reply = self._server_cmd_handlers[type(server_cmd)](server_cmd) else: dbg._pdebug(self._debug('unknown server command')) status = lttngust.cmd._CLIENT_CMD_REPLY_STATUS_INVALID_CMD cmd_reply = lttngust.cmd._ClientCmdReply(status) if cmd_reply is not None: self._send_cmd_reply(cmd_reply)
def from_data(cls, header, data): try: loglevel, loglevel_type = cls._loglevel_struct.unpack_from(data) name_start = cls._loglevel_struct.size name_end = name_start + _LTTNG_SYMBOL_NAME_LEN data_name = data[name_start:name_end] name = data_name.rstrip(b'\0').decode() filter_exp_start = name_end + cls._filter_exp_len_struct.size filter_exp_len, = cls._filter_exp_len_struct.unpack_from( data[name_end:filter_exp_start]) filter_exp_end = filter_exp_start + filter_exp_len filter_exp = data[filter_exp_start:filter_exp_end].rstrip( b'\0').decode() return cls(header, loglevel, loglevel_type, name, filter_exp) except (Exception) as e: dbg._pdebug('cannot decode enable command: {}'.format(e)) return None
def _handle_server_cmd_enable(self, server_cmd): dbg._pdebug(self._debug('got "enable" server command')) self._ref_count += 1 if self._ref_count == 1: dbg._pdebug(self._debug("adding our handler to the root logger")) self._root_logger.addHandler(self._log_handler) dbg._pdebug(self._debug("ref count is {}".format(self._ref_count))) return lttngust.cmd._ClientCmdReplyEnable()
def _handle_server_cmd_enable(self, server_cmd): dbg._pdebug(self._debug('got "enable" server command')) self._ref_count += 1 if self._ref_count == 1: dbg._pdebug(self._debug('adding our handler to the root logger')) self._root_logger.addHandler(self._log_handler) dbg._pdebug(self._debug('ref count is {}'.format(self._ref_count))) return lttngust.cmd._ClientCmdReplyEnable()
def run(self): while True: try: # connect to the session daemon dbg._pdebug(self._debug("connecting to session daemon")) self._connect_to_sessiond() # register to the session daemon after a successful connection dbg._pdebug(self._debug("registering to session daemon")) self._register() # wait for commands from the session daemon self._wait_server_cmd() except (Exception) as e: # Whatever happens here, we have to close the socket and # retry to connect to the session daemon since either # the socket was closed, a network timeout occured, or # invalid data was received. dbg._pdebug(self._debug("got exception: {}".format(e))) self._cleanup_socket() dbg._pdebug(self._debug("sleeping for {} s".format(_RETRY_REG_DELAY))) time.sleep(_RETRY_REG_DELAY)
def _handle_server_cmd_disable(self, server_cmd): dbg._pdebug(self._debug('got "disable" server command')) self._ref_count -= 1 if self._ref_count < 0: # disable command could be sent again when a session is destroyed self._ref_count = 0 if self._ref_count == 0: dbg._pdebug(self._debug("removing our handler from the root logger")) self._root_logger.removeHandler(self._log_handler) dbg._pdebug(self._debug("ref count is {}".format(self._ref_count))) return lttngust.cmd._ClientCmdReplyDisable()
def _handle_server_cmd_disable(self, server_cmd): dbg._pdebug(self._debug('got "disable" server command')) self._ref_count -= 1 if self._ref_count < 0: # disable command could be sent again when a session is destroyed self._ref_count = 0 if self._ref_count == 0: dbg._pdebug( self._debug('removing our handler from the root logger')) self._root_logger.removeHandler(self._log_handler) dbg._pdebug(self._debug('ref count is {}'.format(self._ref_count))) return lttngust.cmd._ClientCmdReplyDisable()
def run(self): while True: try: # connect to the session daemon dbg._pdebug(self._debug('connecting to session daemon')) self._connect_to_sessiond() # register to the session daemon after a successful connection dbg._pdebug(self._debug('registering to session daemon')) self._register() # wait for commands from the session daemon self._wait_server_cmd() except (Exception) as e: # Whatever happens here, we have to close the socket and # retry to connect to the session daemon since either # the socket was closed, a network timeout occured, or # invalid data was received. dbg._pdebug(self._debug('got exception: {}'.format(e))) self._cleanup_socket() dbg._pdebug( self._debug('sleeping for {} s'.format(_RETRY_REG_DELAY))) time.sleep(_RETRY_REG_DELAY)
def _recv_server_cmd(self): server_cmd_header = self._recv_server_cmd_header() if server_cmd_header is None: return None dbg._pdebug(self._debug("server command header: data size: {} bytes".format(server_cmd_header.data_size))) dbg._pdebug(self._debug("server command header: command ID: {}".format(server_cmd_header.cmd_id))) dbg._pdebug(self._debug("server command header: command version: {}".format(server_cmd_header.cmd_version))) data = bytes() if server_cmd_header.data_size > 0: data = self._sessiond_sock.recv(server_cmd_header.data_size) assert len(data) == server_cmd_header.data_size return lttngust.cmd._server_cmd_from_data(server_cmd_header, data)
def _recv_server_cmd(self): server_cmd_header = self._recv_server_cmd_header() if server_cmd_header is None: return None dbg._pdebug( self._debug('server command header: data size: {} bytes'.format( server_cmd_header.data_size))) dbg._pdebug( self._debug('server command header: command ID: {}'.format( server_cmd_header.cmd_id))) dbg._pdebug( self._debug('server command header: command version: {}'.format( server_cmd_header.cmd_version))) data = bytes() if server_cmd_header.data_size > 0: data = self._sessiond_sock.recv(server_cmd_header.data_size) assert (len(data) == server_cmd_header.data_size) return lttngust.cmd._server_cmd_from_data(server_cmd_header, data)
def _init_threads(): global _initialized dbg._pdebug("entering") if _initialized: dbg._pdebug("agent is already initialized") return # This makes sure that the appropriate modules for encoding and # decoding strings/bytes are imported now, since no import should # happen within a thread at import time (our case). "lttng".encode().decode() _initialized = True sys_port = _get_port_from_file("/var/run/lttng/agent.port") user_port_file = os.path.join(_get_user_home_path(), ".lttng", "agent.port") user_port = _get_port_from_file(user_port_file) reg_queue = queue.Queue() reg_expecting = 0 dbg._pdebug("system session daemon port: {}".format(sys_port)) dbg._pdebug("user session daemon port: {}".format(user_port)) if sys_port == user_port and sys_port is not None: # The two session daemon ports are the same. This is not normal. # Connect to only one. dbg._pdebug("both user and system session daemon have the same port") sys_port = None try: if sys_port is not None: dbg._pdebug("creating system client thread") t = threading.Thread(target=_client_thread_target, args=("system", sys_port, reg_queue)) t.name = "system" t.daemon = True t.start() dbg._pdebug("created and started system client thread") reg_expecting += 1 if user_port is not None: dbg._pdebug("creating user client thread") t = threading.Thread(target=_client_thread_target, args=("user", user_port, reg_queue)) t.name = "user" t.daemon = True t.start() dbg._pdebug("created and started user client thread") reg_expecting += 1 except: # cannot create threads for some reason; stop this initialization dbg._pwarning("cannot create client threads") return if reg_expecting == 0: # early exit: looks like there's not even one valid port dbg._pwarning("no valid LTTng session daemon port found (is the session daemon started?)") return cur_timeout = _REG_TIMEOUT # We block here to make sure the agent is properly registered to # the session daemon. If we timeout, the client threads will still # continue to try to connect and register to the session daemon, # but there is no guarantee that all following logging statements # will make it to LTTng-UST. # # When a client thread receives a "registration done" confirmation # from the session daemon it's connected to, it puts True in # reg_queue. while True: try: dbg._pdebug( "waiting for registration done (expecting {}, timeout is {} s)".format(reg_expecting, cur_timeout) ) t1 = time.clock() reg_queue.get(timeout=cur_timeout) t2 = time.clock() reg_expecting -= 1 dbg._pdebug("unblocked") if reg_expecting == 0: # done! dbg._pdebug("successfully registered to session daemon(s)") break cur_timeout -= t2 - t1 if cur_timeout <= 0: # timeout dbg._pdebug("ran out of time") break except queue.Empty: dbg._pdebug("ran out of time") break dbg._pdebug("leaving")
def _send_cmd_reply(self, cmd_reply): data = cmd_reply.get_data() dbg._pdebug(self._debug("sending command reply ({} bytes)".format(len(data)))) self._sessiond_sock.sendall(data)
def _client_thread_target(name, port, reg_queue): dbg._pdebug('creating client "{}" using TCP port {}'.format(name, port)) client = _TcpClient(name, _SESSIOND_HOST, port, reg_queue) dbg._pdebug('starting client "{}"'.format(name)) client.run()
def _send_cmd_reply(self, cmd_reply): data = cmd_reply.get_data() dbg._pdebug( self._debug('sending command reply ({} bytes)'.format(len(data)))) self._sessiond_sock.sendall(data)
def _init_threads(): global _initialized dbg._pdebug('entering') if _initialized: dbg._pdebug('agent is already initialized') return # This makes sure that the appropriate modules for encoding and # decoding strings/bytes are imported now, since no import should # happen within a thread at import time (our case). 'lttng'.encode().decode() _initialized = True sys_port = _get_port_from_file('/var/run/lttng/agent.port') user_port_file = os.path.join(_get_user_home_path(), '.lttng', 'agent.port') user_port = _get_port_from_file(user_port_file) reg_queue = queue.Queue() reg_expecting = 0 dbg._pdebug('system session daemon port: {}'.format(sys_port)) dbg._pdebug('user session daemon port: {}'.format(user_port)) if sys_port == user_port and sys_port is not None: # The two session daemon ports are the same. This is not normal. # Connect to only one. dbg._pdebug('both user and system session daemon have the same port') sys_port = None try: if sys_port is not None: dbg._pdebug('creating system client thread') t = threading.Thread(target=_client_thread_target, args=('system', sys_port, reg_queue)) t.name = 'system' t.daemon = True t.start() dbg._pdebug('created and started system client thread') reg_expecting += 1 if user_port is not None: dbg._pdebug('creating user client thread') t = threading.Thread(target=_client_thread_target, args=('user', user_port, reg_queue)) t.name = 'user' t.daemon = True t.start() dbg._pdebug('created and started user client thread') reg_expecting += 1 except: # cannot create threads for some reason; stop this initialization dbg._pwarning('cannot create client threads') return if reg_expecting == 0: # early exit: looks like there's not even one valid port dbg._pwarning( 'no valid LTTng session daemon port found (is the session daemon started?)' ) return cur_timeout = _REG_TIMEOUT # We block here to make sure the agent is properly registered to # the session daemon. If we timeout, the client threads will still # continue to try to connect and register to the session daemon, # but there is no guarantee that all following logging statements # will make it to LTTng-UST. # # When a client thread receives a "registration done" confirmation # from the session daemon it's connected to, it puts True in # reg_queue. while True: try: dbg._pdebug( 'waiting for registration done (expecting {}, timeout is {} s)' .format(reg_expecting, cur_timeout)) t1 = lttngust.compat._clock() reg_queue.get(timeout=cur_timeout) t2 = lttngust.compat._clock() reg_expecting -= 1 dbg._pdebug('unblocked') if reg_expecting == 0: # done! dbg._pdebug('successfully registered to session daemon(s)') break cur_timeout -= (t2 - t1) if cur_timeout <= 0: # timeout dbg._pdebug('ran out of time') break except queue.Empty: dbg._pdebug('ran out of time') break dbg._pdebug('leaving')