def _sw_open(this: OpenerDirector, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): if isinstance(fullurl, str): fullurl = Request(fullurl, data) context = get_context() url = fullurl.selector.split("?")[0] if fullurl.selector else '/' with context.new_exit_span(op=url, peer=fullurl.host) as span: carrier = span.inject() span.layer = Layer.Http span.component = Component.General code = None [fullurl.add_header(item.key, item.val) for item in carrier] try: res = _open(this, fullurl, data, timeout) code = res.code except HTTPError as e: code = e.code raise finally: # we do this here because it may change in _open() span.tag(Tag(key=tags.HttpMethod, val=fullurl.get_method())) span.tag(Tag(key=tags.HttpUrl, val=fullurl.full_url)) if code is not None: span.tag( Tag(key=tags.HttpStatus, val=code, overridable=True)) if code >= 400: span.error_occurred = True return res
def _sw_perform_request(this: Transport, method, url, headers=None, params=None, body=None): context = get_context() peer = ",".join( [host["host"] + ":" + str(host["port"]) for host in this.hosts]) with context.new_exit_span(op="Elasticsearch/" + method + url, peer=peer, component=Component.Elasticsearch) as span: span.layer = Layer.Database res = _perform_request(this, method, url, headers=headers, params=params, body=body) span.tag(Tag(key=tags.DbType, val="Elasticsearch")) if config.elasticsearch_trace_dsl: span.tag( Tag(key=tags.DbStatement, val="" if body is None else body)) return res
def _sw_get_response(this, request): if request is None: resp = _get_response(this, request) return resp context = get_context() carrier = Carrier() for item in carrier: # Any HTTP headers in the request are converted to META keys by converting all characters to uppercase, # replacing any hyphens with underscores and adding an HTTP_ prefix to the name. # https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.HttpRequest.META sw_http_header_key = 'HTTP_%s' % item.key.upper().replace('-', '_') if sw_http_header_key in request.META: item.val = request.META[sw_http_header_key] with context.new_entry_span(op=request.path, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.Django span.peer = '%s:%s' % (request.META.get('REMOTE_ADDR'), request.META.get('REMOTE_PORT') or "80") span.tag(Tag(key=tags.HttpMethod, val=request.method)) span.tag(Tag(key=tags.HttpUrl, val=request.build_absolute_uri().split("?")[0])) # you can get request parameters by `request.GET` even though client are using POST or other methods if config.django_collect_http_params and request.GET: span.tag(Tag(key=tags.HttpParams, val=params_tostring(request.GET)[0:config.http_params_length_threshold])) resp = _get_response(this, request) span.tag(Tag(key=tags.HttpStatus, val=resp.status_code, overridable=True)) if resp.status_code >= 400: span.error_occurred = True return resp
def _sw_open(this: OpenerDirector, fullurl, data, timeout): if isinstance(fullurl, str): fullurl = Request(fullurl, data) context = get_context() carrier = Carrier() with context.new_exit_span(op=fullurl.selector or '/', peer=fullurl.host, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.General [fullurl.add_header(item.key, item.val) for item in carrier] try: res = _open(this, fullurl, data, timeout) span.tag(Tag(key=tags.HttpMethod, val=fullurl.get_method())) span.tag(Tag(key=tags.HttpUrl, val=fullurl.full_url)) span.tag(Tag(key=tags.HttpStatus, val=res.code)) if res.code >= 400: span.error_occurred = True except HTTPError as e: span.raised() raise e return res
async def _sw_handle_request(self, request, write_callback, stream_callback): req = request context = get_context() carrier = Carrier() for item in carrier: if item.key.capitalize() in req.headers: item.val = req.headers[item.key.capitalize()] with context.new_entry_span(op=req.path, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.Sanic span.peer = '%s:%s' % (req.remote_addr or req.ip, req.port) span.tag(Tag(key=tags.HttpMethod, val=req.method)) span.tag(Tag(key=tags.HttpUrl, val=req.url.split("?")[0])) if config.sanic_collect_http_params and req.args: span.tag( Tag(key=tags.HttpParams, val=params_tostring( req.args)[0:config.http_params_length_threshold])) resp = _handle_request(self, request, write_callback, stream_callback) if isawaitable(resp): result = await resp return result
def _sw_command(this: SocketInfo, dbname, spec, *args, **kwargs): # pymongo sends `ismaster` command continuously. ignore it. if spec.get("ismaster") is None: address = this.sock.getpeername() peer = "%s:%s" % address context = get_context() operation = list(spec.keys())[0] sw_op = operation.capitalize() + "Operation" with context.new_exit_span(op="MongoDB/" + sw_op, peer=peer, component=Component.MongoDB) as span: result = _command(this, dbname, spec, *args, **kwargs) span.layer = Layer.Database span.tag(Tag(key=tags.DbType, val="MongoDB")) span.tag(Tag(key=tags.DbInstance, val=dbname)) if config.pymongo_trace_parameters: # get filters filters = _get_filter(operation, spec) max_len = config.pymongo_parameters_max_length filters = filters[0:max_len] + "..." if len( filters) > max_len else filters span.tag(Tag(key=tags.DbStatement, val=filters)) else: result = _command(this, dbname, spec, *args, **kwargs) return result
def _sw_full_dispatch_request(this: Flask): import flask req = flask.request context = get_context() carrier = Carrier() for item in carrier: if item.key.capitalize() in req.headers: item.val = req.headers[item.key.capitalize()] with context.new_entry_span(op=req.path, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.Flask span.peer = '%s:%s' % (req.environ["REMOTE_ADDR"], req.environ["REMOTE_PORT"]) span.tag(Tag(key=tags.HttpMethod, val=req.method)) span.tag(Tag(key=tags.HttpUrl, val=req.url.split("?")[0])) if config.flask_collect_http_params and req.values: span.tag( Tag(key=tags.HttpParams, val=params_tostring(req.values) [0:config.http_params_length_threshold])) resp = _full_dispatch_request(this) if resp.status_code >= 400: span.error_occurred = True span.tag( Tag(key=tags.HttpStatus, val=resp.status_code, overridable=True)) return resp
def _sw_execute(this: Cursor, query, args=None): peer = "%s:%s" % (this.connection.host, this.connection.port) context = get_context() carrier = Carrier() with context.new_exit_span(op="Mysql/PyMsql/execute", peer=peer, carrier=carrier) as span: span.layer = Layer.Database span.component = Component.PyMysql res = _execute(this, query, args) span.tag(Tag(key=tags.DbType, val="mysql")) span.tag( Tag(key=tags.DbInstance, val=this.connection.db.decode("utf-8"))) span.tag(Tag(key=tags.DbStatement, val=query)) if config.mysql_trace_sql_parameters and args: parameter = ",".join([str(arg) for arg in args]) max_len = config.mysql_sql_parameters_max_length parameter = parameter[0:max_len] + "..." if len( parameter) > max_len else parameter span.tag( Tag(key=tags.DbSqlParameters, val='[' + parameter + ']')) return res
def _sw_get_response(self, *args, **kwargs): request = self.request context = get_context() carrier = Carrier() for item in carrier: if item.key.capitalize() in request.headers: item.val = request.headers[item.key.capitalize()] with context.new_entry_span(op=request.path, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.Tornado peer = request.connection.stream.socket.getpeername() span.peer = '{0}:{1}'.format(*peer) span.tag(Tag(key=tags.HttpMethod, val=request.method)) span.tag( Tag(key=tags.HttpUrl, val='{}://{}{}'.format(request.protocol, request.host, request.path))) result = yield from old_execute(self, *args, **kwargs) span.tag( Tag(key=tags.HttpStatus, val=self._status_code, overridable=True)) if self._status_code >= 400: span.error_occurred = True return result
def _sw_get_response(this: BaseHandler, request): if request is None: resp = _get_response(this, request) return resp context = get_context() carrier = Carrier() for item in carrier: if item.key.capitalize() in request.headers: item.val = request.headers[item.key.capitalize()] with context.new_entry_span(op=request.path, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.Django span.peer = '%s:%s' % (request.META.get('REMOTE_ADDR'), request.META.get('REMOTE_PORT') or "80") span.tag(Tag(key=tags.HttpMethod, val=request.method)) span.tag( Tag(key=tags.HttpUrl, val=request.build_absolute_uri())) resp = _get_response(this, request) span.tag(Tag(key=tags.HttpStatus, val=resp.status_code)) if resp.status_code >= 400: span.error_occurred = True return resp
def _sw__poll_once(this, timeout_ms, max_records, update_offsets=True): res = __poll_once(this, timeout_ms, max_records, update_offsets=update_offsets) if res: brokers = ";".join(this.config["bootstrap_servers"]) context = get_context() topics = ";".join( this._subscription.subscription or [t.topic for t in this._subscription._user_assignment]) with context.new_entry_span( op="Kafka/" + topics + "/Consumer/" + (this.config["group_id"] or "")) as span: for consumerRecords in res.values(): for record in consumerRecords: carrier = Carrier() for item in carrier: for header in record.headers: if item.key == header[0]: item.val = str(header[1]) span.extract(carrier) span.tag(Tag(key=tags.MqBroker, val=brokers)) span.tag(Tag(key=tags.MqTopic, val=topics)) span.layer = Layer.MQ span.component = Component.KafkaConsumer return res
def _sw__on_deliver(this, method_frame, header_frame, body): peer = '%s:%s' % (this.connection.params.host, this.connection.params.port) context = get_context() exchange = method_frame.method.exchange routing_key = method_frame.method.routing_key carrier = Carrier() for item in carrier: if item.key in header_frame.properties.headers: item.val = header_frame.properties.headers[item.key] with context.new_entry_span(op="RabbitMQ/Topic/" + exchange + "/Queue/" + routing_key + "/Consumer" or "", carrier=carrier) as span: span.layer = Layer.MQ span.component = Component.RabbitmqConsumer try: __on_deliver(this, method_frame, header_frame, body) span.tag(Tag(key=tags.MqBroker, val=peer)) span.tag(Tag(key=tags.MqTopic, val=exchange)) span.tag(Tag(key=tags.MqQueue, val=routing_key)) except BaseException as e: span.raised() raise e
async def _sw_request(self: ClientSession, method: str, str_or_url, **kwargs): url = URL(str_or_url).with_user(None).with_password(None) peer = '%s:%d' % (url.host or '', url.port) context = get_context() with context.new_exit_span(op=url.path or "/", peer=peer) as span: span.layer = Layer.Http span.component = Component.AioHttp span.tag(Tag(key=tags.HttpMethod, val=method.upper())) # pyre-ignore span.tag(Tag(key=tags.HttpUrl, val=url)) # pyre-ignore carrier = span.inject() headers = kwargs.get('headers') if headers is None: headers = kwargs['headers'] = CIMultiDict() elif not isinstance(headers, (MultiDictProxy, MultiDict)): headers = CIMultiDict(headers) for item in carrier: headers.add(item.key, item.val) res = await _request(self, method, str_or_url, **kwargs) span.tag(Tag(key=tags.HttpStatus, val=res.status, overridable=True)) if res.status >= 400: span.error_occurred = True return res
def _wrap_run_wsgi(): context = get_context() carrier = Carrier() for item in carrier: item.val = handler.headers[item.key.capitalize()] path = handler.path or '/' with context.new_entry_span(op=path.split("?")[0], carrier=carrier) as span: url = 'http://' + handler.headers[ "Host"] + path if 'Host' in handler.headers else path span.layer = Layer.Http span.component = Component.General span.peer = '%s:%s' % handler.client_address span.tag(Tag(key=tags.HttpMethod, val=handler.command)) span.tag(Tag(key=tags.HttpUrl, val=url)) try: return _run_wsgi() finally: status_code = int(getattr(handler, '_status_code', -1)) if status_code > -1: span.tag( Tag(key=tags.HttpStatus, val=status_code, overridable=True)) if status_code >= 400: span.error_occurred = True
async def _sw_handle_request(self, request, start_time: float): context = get_context() carrier = Carrier() for item in carrier: val = request.headers.get(item.key) if val is not None: item.val = val with context.new_entry_span(op=request.path, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.AioHttp span.peer = '%s:%d' % request._transport_peername if isinstance(request._transport_peername, (list, tuple))\ else request._transport_peername span.tag(Tag(key=tags.HttpMethod, val=request.method)) # pyre-ignore span.tag(Tag(key=tags.HttpUrl, val=str(request.url))) # pyre-ignore resp, reset = await _handle_request(self, request, start_time) span.tag(Tag(key=tags.HttpStatus, val=resp.status, overridable=True)) if resp.status >= 400: span.error_occurred = True return resp, reset
def _sw_invoke_request(self, request, *args, **kwargs): context = get_context() carrier = Carrier() for item in carrier: val = request.headers.get(item.key) if val is not None: item.val = val with context.new_entry_span(op=request.path, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.Pyramid span.peer = request.remote_host or request.remote_addr span.tag(Tag(key=tags.HttpMethod, val=request.method)) span.tag(Tag(key=tags.HttpUrl, val=str(request.url))) resp = _invoke_request(self, request, *args, **kwargs) span.tag(Tag(key=tags.HttpStatus, val=resp.status_code, overridable=True)) if resp.status_code >= 400: span.error_occurred = True return resp
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] != "http": await self._app(scope, receive, send) return # Create Request request = Request(scope, receive=receive) # After Request span = await self._create_span(request=request) scope.setdefault("trace_ctx", span) # Default status code used when the application does not return a valid response # or an unhandled exception occurs. status_code = 500 async def wrapped_send(message: Message) -> None: if message['type'] == 'http.response.start': nonlocal status_code status_code = message['status'] await send(message) try: await self._app(scope, receive, wrapped_send) except Exception as err: span.log(ex=err) span.raised() finally: if scope["type"] == "http": span.tag(Tag(key=tags.HttpUrl, val=str(request.url), overridable=False)) span.tag(Tag(key=tags.HttpStatus, val=status_code, overridable=False)) span.stop()
def _sw_execute(this: _Bulk, *args, **kwargs): address = this.collection.database.client.address peer = "%s:%s" % address context = get_context() sw_op = "MixedBulkWriteOperation" with context.new_exit_span(op="MongoDB/" + sw_op, peer=peer, component=Component.MongoDB) as span: span.layer = Layer.Database bulk_result = _execute(this, *args, **kwargs) span.tag(Tag(key=tags.DbType, val="MongoDB")) span.tag( Tag(key=tags.DbInstance, val=this.collection.database.name)) if config.pymongo_trace_parameters: filters = "" bulk_ops = this.ops for bulk_op in bulk_ops: opname = bulk_op_map.get(bulk_op[0]) _filter = opname + " " + str(bulk_op[1]) filters = filters + _filter + " " max_len = config.pymongo_parameters_max_length filters = filters[0:max_len] + "..." if len( filters) > max_len else filters span.tag(Tag(key=tags.DbStatement, val=filters)) return bulk_result
def _sw_send_message(this: Cursor, operation): address = this.collection.database.client.address peer = "%s:%s" % address context = get_context() op = "FindOperation" with context.new_exit_span(op="MongoDB/" + op, peer=peer, component=Component.MongoDB) as span: span.layer = Layer.Database # __send_message return nothing __send_message(this, operation) span.tag(Tag(key=tags.DbType, val="MongoDB")) span.tag( Tag(key=tags.DbInstance, val=this.collection.database.name)) if config.pymongo_trace_parameters: filters = "find " + str(operation.spec) max_len = config.pymongo_parameters_max_length filters = filters[0:max_len] + "..." if len( filters) > max_len else filters span.tag(Tag(key=tags.DbStatement, val=filters)) return
def _sw_request(this: Session, method, url, params=None, data=None, headers=None, cookies=None, files=None, auth=None, timeout=None, allow_redirects=True, proxies=None, hooks=None, stream=None, verify=None, cert=None, json=None): from urllib.parse import urlparse url_param = urlparse(url) # ignore trace skywalking self request if config.protocol == 'http' and config.collector_address.rstrip( '/').endswith(url_param.netloc): return _request(this, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json) context = get_context() carrier = Carrier() with context.new_exit_span(op=url_param.path or "/", peer=url_param.netloc, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.General if headers is None: headers = {} for item in carrier: headers[item.key] = item.val else: for item in carrier: headers[item.key] = item.val try: res = _request(this, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json) span.tag(Tag(key=tags.HttpMethod, val=method.upper())) span.tag(Tag(key=tags.HttpUrl, val=url)) span.tag(Tag(key=tags.HttpStatus, val=res.status_code)) if res.status_code >= 400: span.error_occurred = True except BaseException as e: span.raised() raise e return res
def _sw_send_command(this: Connection, *args, **kwargs): peer = "%s:%s" % (this.host, this.port) op = args[0] context = get_context() with context.new_exit_span(op="Redis/" + op or "/", peer=peer) as span: span.layer = Layer.Cache span.component = Component.Redis res = _send_command(this, *args, **kwargs) span.tag(Tag(key=tags.DbType, val="Redis")) span.tag(Tag(key=tags.DbInstance, val=this.db)) span.tag(Tag(key=tags.DbStatement, val=op)) return res
def _sw_send(this, topic, value=None, key=None, headers=None, partition=None, timestamp_ms=None): # ignore trace skywalking self request if config.protocol == 'kafka' and config.kafka_topic_segment == topic or config.kafka_topic_management == topic: return _send(this, topic, value=value, key=key, headers=headers, partition=partition, timestamp_ms=timestamp_ms) peer = ";".join(this.config["bootstrap_servers"]) context = get_context() carrier = Carrier() with context.new_exit_span(op="Kafka/" + topic + "/Producer" or "/", peer=peer, carrier=carrier) as span: span.layer = Layer.MQ span.component = Component.KafkaProducer if headers is None: headers = [] for item in carrier: headers.append((item.key, item.val.encode("utf-8"))) else: for item in carrier: headers.append((item.key, item.val.encode("utf-8"))) try: res = _send(this, topic, value=value, key=key, headers=headers, partition=partition, timestamp_ms=timestamp_ms) span.tag(Tag(key=tags.MqBroker, val=peer)) span.tag(Tag(key=tags.MqTopic, val=topic)) except BaseException as e: span.raised() raise e return res
def _sw_open(this: OpenerDirector, fullurl, data, timeout): context = get_context() with context.new_exit_span(op=fullurl.selector, peer=fullurl.host) as span: span.layer = Layer.Http span.component = Component.Http try: res = _open(this, fullurl, data, timeout) span.tag(Tag(key=tags.HttpMethod, val=fullurl.get_method())) span.tag(Tag(key=tags.HttpUrl, val=fullurl.full_url)) span.tag(Tag(key=tags.HttpStatus, val=res.code)) if res.code >= 400: span.error_occurred = True except HTTPError as e: span.raised() raise e return res
def _sw_do_method(): context = get_context() with context.new_entry_span(op=this.path) as span: span.layer = Layer.Http span.component = Component.Http span.peer = '%s:%s' % this.client_address span.tag(Tag(key=tags.HttpMethod, val=method)) _do_method()
def callproc(self, procname, parameters=None): dsn = self.connection.get_dsn_parameters() peer = dsn['host'] + ':' + dsn['port'] with get_context().new_exit_span( op="PostgreSLQ/Psycopg/callproc", peer=peer, component=Component.Psycopg) as span: span.layer = Layer.Database args = '(' + ('' if not parameters else ','.join(parameters)) + ')' span.tag(Tag(key=tags.DbType, val="PostgreSQL")) span.tag(Tag(key=tags.DbInstance, val=dsn['dbname'])) span.tag(Tag(key=tags.DbStatement, val=procname + args)) return self._self_cur.callproc(procname, parameters)
def _sw_format_http1_reponse(status: int, headers, body=b""): if status is not None: entry_span = get_context().active_span() if entry_span is not None and type(entry_span) is not NoopSpan: if status >= 400: entry_span.error_occurred = True entry_span.tag(Tag(key=tags.HttpStatus, val=status)) return _format_http1_response(status, headers, body)
async def _create_span(request: Request) -> Span: context = get_context() span = context.new_entry_span(op=request.url.path, carrier=Carrier()) span.start() span.layer = Layer.Http span.component = Component.Requests span.peer = f"{request.client.host}:{request.client.port}" span.tag(tag=Tag(key=tags.HttpMethod, val=request.method, overridable=False)) return span
def _sw_basic_publish(this, exchange, routing_key, body, properties=None, mandatory=False): peer = '%s:%s' % (this.connection.params.host, this.connection.params.port) context = get_context() carrier = Carrier() import pika with context.new_exit_span(op="RabbitMQ/Topic/" + exchange + "/Queue/" + routing_key + "/Producer" or "/", peer=peer, carrier=carrier) as span: span.layer = Layer.MQ span.component = Component.RabbitmqProducer properties = pika.BasicProperties( ) if properties is None else properties if properties.headers is None: headers = {} for item in carrier: headers[item.key] = item.val properties.headers = headers else: for item in carrier: properties.headers[item.key] = item.val try: res = _basic_publish(this, exchange, routing_key, body, properties=properties, mandatory=mandatory) span.tag(Tag(key=tags.MqBroker, val=peer)) span.tag(Tag(key=tags.MqTopic, val=exchange)) span.tag(Tag(key=tags.MqQueue, val=routing_key)) except BaseException as e: span.raised() raise e return res
def _sw_request(this: RequestMethods, method, url, fields=None, headers=None, **urlopen_kw): from urllib.parse import urlparse url_param = urlparse(url) carrier = Carrier() context = get_context() with context.new_exit_span(op=url_param.path or "/", peer=url_param.netloc, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.Urllib3 if headers is None: headers = {} for item in carrier: headers[item.key] = item.val else: for item in carrier: headers[item.key] = item.val try: res = _request(this, method, url, fields=fields, headers=headers, **urlopen_kw) span.tag(Tag(key=tags.HttpMethod, val=method.upper())) span.tag(Tag(key=tags.HttpUrl, val=url)) span.tag(Tag(key=tags.HttpStatus, val=res.status)) if res.status >= 400: span.error_occurred = True except BaseException as e: span.raised() raise e return res
def _wrap_run_wsgi(): context = get_context() carrier = Carrier() for item in carrier: item.val = handler.headers[item.key.capitalize()] with context.new_entry_span(op=handler.path, carrier=carrier) as span: span.layer = Layer.Http span.component = Component.General span.peer = '%s:%s' % handler.client_address span.tag(Tag(key=tags.HttpMethod, val=handler.command)) return _run_wsgi()