def handleFrontAgentData(self, client, type, body): content = body.decode('utf-8') try: TCLogger.debug(content) stack = json.loads(content) except Exception as e: TCLogger.error("json is crash") return if 'appid' not in stack: TCLogger.warning(" drop %s, as no appid", content) return else: appid = stack['appid'] if 'appname' not in stack: TCLogger.warning(" drop %s, as no appname", content) return else: appname = stack['appname'] if 'FT' not in stack: TCLogger.warning(" drop %s, as no FT", content) return else: ft = stack['FT'] app = self.findApp(appid, appname, ft) app.asynSendSpan(stack, body) self.recv_count += 1
def _handleCommand(self): handshake = PCmdServiceHandshake() handshake.supportCommandServiceKey.append(PCommandType.PING) handshake.supportCommandServiceKey.append(PCommandType.PONG) handshake.supportCommandServiceKey.append( PCommandType.ACTIVE_THREAD_COUNT) handshake.supportCommandServiceKey.append( PCommandType.ACTIVE_THREAD_DUMP) handshake.supportCommandServiceKey.append( PCommandType.ACTIVE_THREAD_LIGHT_DUMP) cmd = PCmdMessage(handshakeMessage=handshake) while self.task_running: self.cmd_pipe = GrpcAgent.HandStreamIterator(cmd) # while self.task_running: msg_iter = self.cmd_sub.HandleCommand(self.cmd_pipe, metadata=self.profile_meta) try: for msg in msg_iter: TCLogger.debug("command channel %s", msg) self._handleCmd(msg, self.cmd_pipe) TCLogger.debug('iter_response is over') except Exception as e: TCLogger.error("handleCommand channel %s error", e) finally: with self.exit_cv: if self.exit_cv.wait(self.timeout): break
def getAndSendSpan(self): self.task_running = True spans = [] def get_n_span(queue, N): i = 0 try: while N > i: spans.append(queue.get(timeout=0.005)) i += 1 except Empty as e: pass return True if i > 0 else False while self.task_running: try: if not get_n_span(self.queue, 10240): with self.exit_cv: if self.exit_cv.wait(5): break continue self.send_span_count += len(spans) self.span_stub.SendSpan(iter(spans)) except Exception as e: TCLogger.error("span channel, can't work:exception:%s", e) traceback.print_exc() finally: spans.clear()
def loopTheQueue(self): while True: try: body = self.mpQueue.get() except KeyboardInterrupt: break if body == None: TCLogger.info("agent: %s stopping", self.agent_meta) break else: content = body.decode('utf-8') try: stack = json.loads(content) except Exception as e: TCLogger.error("json is crash:[%s]", content) return super().sendSpan(stack, body) try: pSpan = self.span_factory.makeSpan(stack) spanMesg = PSpanMessage(span=pSpan) except Exception as e: TCLogger.warn("interrupted by %s", e) continue self.span_helper.sendSpan(spanMesg)
def _registerAgent(self): while self.task_running: try: TCLogger.debug("sending agentinfo %s", self.agentinfo) self.stub.RequestAgentInfo(self.agentinfo) except Exception as e: TCLogger.warn( " pinpoint collector is not available. Try it again [%s] ", self.agentinfo) continue finally: with self.exit_cv: if self.exit_cv.wait(self.timeout): break iter_response = self.stub.PingSession(self._pingPPing(), metadata=self.ping_meta) try: for response in iter_response: TCLogger.debug('get ping response:%s agentinfo:%s', response, self.meta) except Exception as e: TCLogger.error("ping response abort with exception: [%s] %s", self.agentinfo, e) TCLogger.debug('agent thread exit: %s', self.task_running)
def _send_thread_count(self, requestId): channel = grpc.insecure_channel(self.address) stub = Service_pb2_grpc.ProfilerCommandServiceStub(channel) def generator_cmd(): i = 0 while True: try: cmd_response = PCmdStreamResponse(responseId=requestId, sequenceId=i) cmd_response.message.value = 'hello' threadCountRes = PCmdActiveThreadCountRes( commonStreamResponse=cmd_response) threadCountRes.histogramSchemaType = 2 for stat in self.get_req_stat(): threadCountRes.activeThreadCount.append(stat) threadCountRes.timeStamp = int(time.time()) i += 1 yield threadCountRes with self.exit_cv: if self.exit_cv.wait(1): break except Exception as e: TCLogger.warning("catch exception %s", e) break try: stub.CommandStreamActiveThreadCount(generator_cmd(), metadata=self.profile_meta) TCLogger.debug("send req state requestId: %d done", requestId) except Exception as e: TCLogger.error( "CommandStreamActiveThreadCount, catch exception %s", e)
def _send_thread_count(self, requestId): channel = grpc.insecure_channel(self.address) stub = Service_pb2_grpc.ProfilerCommandServiceStub(channel) def generator_cmd(): i = 0 while self.task_running: try: cmd_response = PCmdStreamResponse(responseId=requestId, sequenceId=i) cmd_response.message.value = 'hello' threadCountRes = PCmdActiveThreadCountRes( commonStreamResponse=cmd_response) threadCountRes.histogramSchemaType = 2 for stat in self.get_req_stat(): threadCountRes.activeThreadCount.append(stat) threadCountRes.timeStamp = int(time.time()) i += 1 yield threadCountRes ## it's a templated task, don't use exit_cv time.sleep(1) except Exception as e: TCLogger.warning("catch exception %s", e) break try: TCLogger.debug("new a thread for activeThreadCound %d", requestId) stub.CommandStreamActiveThreadCount(generator_cmd(), metadata=self.profile_meta) TCLogger.debug("send activeThreadCound requestId: %d is done", requestId) channel.close() except Exception as e: TCLogger.error( "CommandStreamActiveThreadCount, catch exception %s", e)
def getAndSendSpan(self): self.task_running = True spans = [] def get_n_span(queue, N): i = 0 try: while N > i: spans.append(queue.get(timeout=0.005)) i += 1 except Empty as e: pass return True if i > 0 else False client = GrpcSpan.SpanClient(self.address, self.meta) while self.task_running: try: if not get_n_span(self.queue, 10240): with self.exit_cv: if not self.task_running or self.exit_cv.wait(5): TCLogger.info("span send thread is done") break continue self.send_span_count += len(spans) client.sendSpans(iter(spans)) TCLogger.debug("send %d", self.send_span_count) except Exception as e: TCLogger.error("span channel catches an exception:%s", e) client.reconnect() finally: spans.clear()
def _actionTimeOut(self, time): if self.state == E_CONNETING: TCLogger.info("connecting state:%d timeout:%ds", self.state, time) self.close() elif self.state & E_WRITING == E_WRITING: TCLogger.info("waiting writing %d timeout:%ds", self.state, time) else: TCLogger.error("unhandled state:%d", self.state)
def sendSpan(self, spanMesg): try: self.span_queue.put(spanMesg, False) except Full as e: self.dropped_span_count+=1 return False except Exception as e: TCLogger.error("send span failed: %s", e) return False return True
def _sendData(self): try: ret = self.socket.send(self.send_buf) except asy_socket.error as e: TCLogger.error("_sendData %s", e) self.close() return ### not ready try next time if ret != len(self.send_buf): self.send_buf = self.send_buf[ret:] # self.sendData() return TCLogger.debug("send %d", ret) self._write_watcher.stop()
def _sendData(self): try: ret = self.socket.send(self.send_buf) except asy_socket.error as e: TCLogger.error("_sendData %s", e) self.close() return if ret != len(self.send_buf): self.send_buf = self.send_buf[ret:] self.sendData() return TCLogger.debug("send %d", ret) ## write is done self.state &= (~E_WRITING) self._write_watcher.stop() self.send_buf = b''
def handleFrontAgentData(self, client, type, body): content = body.decode('utf-8') try: stack = json.loads(content) except Exception as e: TCLogger.error("json is crash") return if 'appid' not in stack: appid = self.default_appid else: appid = stack['appid'] if 'appname' not in stack: appname = self.default_appname else: appname = stack['appname'] ft = stack['FT'] app = self.findApp(appid, appname, ft) app.sendSpan(stack, body) self.recv_count += 1
def _handleCmd(self, msg, cmdIter): try: if msg.HasField('commandEcho'): pass elif msg.HasField('commandActiveThreadCount'): self.thread_count = threading.Thread( target=self._send_thread_count, args=(msg.requestId, )) self.thread_count.start() elif msg.HasField('commandActiveThreadDump'): pass elif msg.HasField('commandActiveThreadLightDump'): lightDumpRes = PCmdActiveThreadLightDumpRes() lightDumpRes.commonResponse.responseId = msg.requestId lightDumpRes.type = 'java' lightDumpRes.subType = 'oracle' lightDumpRes.version = '1.8.105' self.cmd_sub.CommandActiveThreadLightDump(lightDumpRes) else: TCLogger.warn("msg type not support:%s", msg) except Exception as e: TCLogger.error(e)
def createSpan(self, stackMap): tSpan = PSpan() tSpan.apiId = self.agent.updateApiMeta(stackMap['name'], API_WEB_REQUEST) tSpan.version = 1 if 'stp' in stackMap: tSpan.serviceType = int(stackMap['stp']) tSpan.applicationServiceType = int(stackMap['stp']) else: tSpan.serviceType = PHP tSpan.applicationServiceType = PHP if 'psid' in stackMap: tSpan.parentSpanId = int(stackMap['psid']) else: tSpan.parentSpanId = -1 if 'tid' in stackMap: agentId, startTime, id = stackMap['tid'].split('^') tSpan.transactionId.agentId = agentId tSpan.transactionId.agentStartTime = int(startTime) tSpan.transactionId.sequence = int(id) if 'sid' in stackMap: tSpan.spanId = int(stackMap['sid']) if 'S' in stackMap: tSpan.startTime = stackMap['S'] if 'E' in stackMap: tSpan.elapsed = stackMap['E'] accept = tSpan.acceptEvent if 'uri' in stackMap: accept.rpc = stackMap['uri'] if 'server' in stackMap: accept.endPoint = stackMap['server'] if 'client' in stackMap: accept.remoteAddr = stackMap['client'] parent_info = accept.parentInfo if 'pname' in stackMap: parent_info.parentApplicationName = stackMap['pname'] if 'ptype' in stackMap: parent_info.parentApplicationType = int(stackMap['ptype']) if 'Ah' in stackMap: parent_info.acceptorHost = stackMap['Ah'] if 'ERR' in stackMap: tSpan.err = 1 id = self.agent.updateStringMeta('ERR') value = StringValue(value=stackMap['ERR']['msg']) tSpan.exceptionInfo.intValue = id tSpan.exceptionInfo.stringValue.CopyFrom(value) if 'EXP' in stackMap: id = self.agent.updateStringMeta('EXP') value = StringValue(value=stackMap['EXP']) tSpan.exceptionInfo.intValue = id tSpan.exceptionInfo.stringValue.CopyFrom(value) if 'clues' in stackMap: for annotation in stackMap['clues']: # list id, value = annotation.split(':', 1) ann = PAnnotation(key=int(id), value=PAnnotationValue(stringValue=value)) tSpan.annotation.append(ann) try: value = None if 'NP' in stackMap: ## nginx value = PLongIntIntByteByteStringValue() arr = ThriftProtocolUtil._parseStrField(stackMap['NP']) value.intValue1 = 2 if 'D' in arr: value.intValue2 = ThriftProtocolUtil._parseDotFormat(arr['D']) if 't' in arr: value.longValue = ThriftProtocolUtil._parseDotFormat(arr['t']) elif 'AP' in stackMap: ## apache value = PLongIntIntByteByteStringValue() arr = ThriftProtocolUtil._parseStrField(stackMap['AP']) value.intValue1 = 3 if 'i' in arr: value.byteValue1 = int(arr['i']) if 'b' in arr: value.byteValue2 = int(arr['b']) if 'D' in arr: value.intValue2 = int(arr['D']) if 't' in arr: value.longValue = int(int(arr['t']) / 1000) if value is not None: ann = PAnnotation(key=PROXY_HTTP_HEADER, value=PAnnotationValue(longIntIntByteByteStringValue=value)) tSpan.annotation.append(ann) except Exception as e: TCLogger.error("input is illegal,Exception %s", e) return tSpan
def createSpan(self, stackMap): tSpan = TSpan() tSpan.apiId = self.agent.updateApiMeta(stackMap['name'], API_WEB_REQUEST).apiId tSpan.agentStartTime = self.agent.startTimeStamp if 'appid' in stackMap: tSpan.agentId = stackMap['appid'] else: tSpan.agentId = self.agent.app_id if 'appname' in stackMap: tSpan.applicationName = stackMap['appname'] else: tSpan.applicationName = self.agent.app_name if 'stp' in stackMap: tSpan.serviceType = int(stackMap['stp']) tSpan.applicationServiceType = int(stackMap['stp']) else: tSpan.serviceType = PHP tSpan.applicationServiceType = PHP if 'psid' in stackMap: tSpan.parentSpanId = int(stackMap['psid']) if 'tid' in stackMap: tSpan.transactionId = TransactionId( encoded_str=stackMap['tid']).getBytes() if 'sid' in stackMap: tSpan.spanId = int(stackMap['sid']) if 'S' in stackMap: tSpan.startTime = stackMap['S'] if 'E' in stackMap: tSpan.elapsed = stackMap['E'] if 'uri' in stackMap: tSpan.rpc = stackMap['uri'] if 'pname' in stackMap: tSpan.parentApplicationName = stackMap['pname'] if 'ptype' in stackMap: tSpan.parentApplicationType = int(stackMap['ptype']) if 'client' in stackMap: tSpan.remoteAddr = stackMap['client'] if 'server' in stackMap: tSpan.endPoint = stackMap['server'] if 'ERR' in stackMap: tSpan.err = 1 id = self.agent.updateStringMeta('ERR').apiId tSpan.exceptionInfo = TIntStringValue(id, stackMap['ERR']['msg']) if 'Ah' in stackMap: tSpan.acceptorHost = stackMap['Ah'] tSpan.spanEventList = [] tSpan.annotations = [] if 'clues' in stackMap: for annotation in stackMap['clues']: # list id, value = annotation.split(':', 1) ann = TAnnotation(int(id), TAnnotationValue(stringValue=value)) tSpan.annotations.append(ann) try: value = TLongIntIntByteByteStringValue() if 'NP' in stackMap: ## nginx arr = ThriftProtocolUtil._parseStrField(stackMap['NP']) value.intValue1 = 2 if 'D' in arr: value.intValue2 = ThriftProtocolUtil._parseDotFormat( arr['D']) if 't' in arr: value.longValue = ThriftProtocolUtil._parseDotFormat( arr['t']) elif 'AP' in stackMap: ## apache arr = ThriftProtocolUtil._parseStrField(stackMap['AP']) value.intValue1 = 3 if 'i' in arr: value.byteValue1 = int(arr['i']) if 'b' in arr: value.byteValue2 = int(arr['b']) if 'D' in arr: value.intValue2 = int(arr['D']) if 't' in arr: value.longValue = int(int(arr['t']) / 1000) ann = TAnnotation( PROXY_HTTP_HEADER, TAnnotationValue(longIntIntByteByteStringValue=value)) tSpan.annotations.append(ann) except Exception as e: TCLogger.error("input is illegal,Exception %s", e) return tSpan