def test_telemetry_processor_apply_not_accepted(self): base = self._base def callback_function(envelope): return envelope.data.base_type == "type2" base.add_telemetry_processor(callback_function) envelope = TelemetryItem(name="", time="", data=MonitorBase(base_type="type1")) envelope2 = TelemetryItem(name="", time="", data=MonitorBase(base_type="type2")) envelopes = base._apply_telemetry_processors([envelope, envelope2]) self.assertEqual(len(envelopes), 1) self.assertEqual(envelopes[0].data.base_type, "type2")
def test_telemetry_processor_apply(self): base = self._base def callback_function(envelope): envelope.data.base_type += "_world" base.add_telemetry_processor(callback_function) envelope = TelemetryItem(name="", time="", data=MonitorBase(base_type="type1")) base._apply_telemetry_processors([envelope]) self.assertEqual(envelope.data.base_type, "type1_world")
def convert_span_to_envelope(span: Span) -> TelemetryItem: envelope = TelemetryItem( name="", instrumentation_key="", tags=dict(_utils.azure_monitor_context), time=ns_to_iso_str(span.start_time), ) envelope.tags["ai.operation.id"] = "{:032x}".format(span.context.trace_id) parent = span.parent if parent: envelope.tags["ai.operation.parentId"] = "{:016x}".format( parent.span_id) if span.kind in (SpanKind.CONSUMER, SpanKind.SERVER): envelope.name = "Microsoft.ApplicationInsights.Request" data = RequestData( name=span.name, id="{:016x}".format(span.context.span_id), duration=_utils.ns_to_duration(span.end_time - span.start_time), response_code=str(span.status.status_code.value), success=span.status.is_ok, properties={}, ) envelope.data = MonitorBase(base_data=data, base_type="RequestData") if "http.method" in span.attributes: # HTTP if "http.route" in span.attributes: envelope.tags["ai.operation.name"] = span.attributes[ "http.route"] elif "http.path" in span.attributes: envelope.tags["ai.operation.name"] = span.attributes[ "http.path"] else: envelope.tags["ai.operation.name"] = span.name if "http.url" in span.attributes: data.url = span.attributes["http.url"] data.properties["request.url"] = span.attributes["http.url"] if "http.status_code" in span.attributes: status_code = span.attributes["http.status_code"] data.response_code = str(status_code) elif "messaging.system" in span.attributes: # Messaging envelope.tags["ai.operation.name"] = span.name if "messaging.destination" in span.attributes: if "net.peer.name" in span.attributes: data.properties["source"] = "{}/{}".format( span.attributes["net.peer.name"], span.attributes["messaging.destination"], ) elif "net.peer.ip" in span.attributes: data.properties["source"] = "{}/{}".format( span.attributes["net.peer.ip"], span.attributes["messaging.destination"], ) else: data.properties["source"] = span.attributes[ "messaging.destination"] else: envelope.name = "Microsoft.ApplicationInsights.RemoteDependency" data = RemoteDependencyData( name=span.name, id="{:016x}".format(span.context.span_id), result_code=str(span.status.status_code.value), duration=_utils.ns_to_duration(span.end_time - span.start_time), success=span.status.is_ok, properties={}, ) envelope.data = MonitorBase(base_data=data, base_type="RemoteDependencyData") if span.kind in (SpanKind.CLIENT, SpanKind.PRODUCER): if "http.method" in span.attributes: # HTTP data.type = "HTTP" if "net.peer.port" in span.attributes: name = "" if "net.peer.name" in span.attributes: name = span.attributes["net.peer.name"] elif "net.peer.ip" in span.attributes: name = str(span.attributes["net.peer.ip"]) data.target = "{}:{}".format( name, str(span.attributes["net.peer.port"]), ) elif "http.url" in span.attributes: url = span.attributes["http.url"] # data is the url data.data = url parse_url = urlparse(url) # target matches authority (host:port) data.target = parse_url.netloc if "http.status_code" in span.attributes: status_code = span.attributes["http.status_code"] data.result_code = str(status_code) elif "db.system" in span.attributes: # Database data.type = span.attributes["db.system"] # data is the full statement if "db.statement" in span.attributes: data.data = span.attributes["db.statement"] if "db.name" in span.attributes: data.target = span.attributes["db.name"] else: data.target = span.attributes["db.system"] elif "rpc.system" in span.attributes: # Rpc data.type = "rpc.system" if "rpc.service" in span.attributes: data.target = span.attributes["rpc.service"] else: data.target = span.attributes["rpc.system"] elif "messaging.system" in span.attributes: # Messaging data.type = "Queue Message | {}" \ .format(span.attributes["messaging.system"]) if "net.peer.ip" in span.attributes and \ "messaging.destination" in span.attributes: data.target = "{}/{}".format( span.attributes["net.peer.ip"], span.attributes["messaging.destination"]) else: data.target = span.attributes["messaging.system"] else: # TODO: Azure specific types data.type = "N/A" else: # SpanKind.INTERNAL data.type = "InProc" data.success = True for key in span.attributes: # Remove Opentelemetry related span attributes from custom dimensions if key.startswith("http.") or \ key.startswith("db.") or \ key.startswith("rpc.") or \ key.startswith("net.") or \ key.startswith("messaging."): continue data.properties[key] = span.attributes[key] if span.links: links = [] for link in span.links: operation_id = "{:032x}".format(link.context.trace_id) span_id = "{:016x}".format(link.context.span_id) links.append({"operation_Id": operation_id, "id": span_id}) data.properties["_MS.links"] = json.dumps(links) # TODO: tracestate, tags return envelope
def convert_span_to_envelope(span: Span) -> TelemetryItem: envelope = TelemetryItem( name="", instrumentation_key="", tags=dict(utils.azure_monitor_context), time=ns_to_iso_str(span.start_time), ) envelope.tags["ai.operation.id"] = "{:032x}".format(span.context.trace_id) parent = span.parent if parent: envelope.tags["ai.operation.parentId"] = "{:016x}".format( parent.span_id) if span.kind in (SpanKind.CONSUMER, SpanKind.SERVER): envelope.name = "Microsoft.ApplicationInsights.Request" data = RequestData( id="{:016x}".format(span.context.span_id), duration=utils.ns_to_duration(span.end_time - span.start_time), response_code=str(span.status.status_code.value), success=span.status.status_code == StatusCode.OK, # Modify based off attributes or Status properties={}, ) envelope.data = MonitorBase(base_data=data, base_type="RequestData") if "http.method" in span.attributes: data.name = span.attributes["http.method"] if "http.route" in span.attributes: data.name = data.name + " " + span.attributes["http.route"] envelope.tags["ai.operation.name"] = data.name data.properties["request.name"] = data.name elif "http.path" in span.attributes: data.properties["request.name"] = ( data.name + " " + span.attributes["http.path"]) if "http.url" in span.attributes: data.url = span.attributes["http.url"] data.properties["request.url"] = span.attributes["http.url"] if "http.status_code" in span.attributes: status_code = span.attributes["http.status_code"] data.response_code = str(status_code) data.success = 200 <= status_code < 400 else: envelope.name = "Microsoft.ApplicationInsights.RemoteDependency" data = RemoteDependencyData( name=span.name, id="{:016x}".format(span.context.span_id), result_code=str(span.status.status_code.value), duration=utils.ns_to_duration(span.end_time - span.start_time), success=span.status.status_code == StatusCode.OK, # Modify based off attributes or Status properties={}, ) envelope.data = MonitorBase(base_data=data, base_type="RemoteDependencyData") if span.kind in (SpanKind.CLIENT, SpanKind.PRODUCER): if ("component" in span.attributes and span.attributes["component"] == "http"): # TODO: check other component types (e.g. db) data.type = "HTTP" if "http.url" in span.attributes: url = span.attributes["http.url"] # data is the url data.data = url parse_url = urlparse(url) # TODO: error handling, probably put scheme as well # target matches authority (host:port) data.target = parse_url.netloc if "http.method" in span.attributes: # name is METHOD/path data.name = (span.attributes["http.method"] + "/" + parse_url.path) if "http.status_code" in span.attributes: status_code = span.attributes["http.status_code"] data.result_code = str(status_code) data.success = 200 <= status_code < 400 else: # SpanKind.INTERNAL data.type = "InProc" data.success = True for key in span.attributes: # This removes redundant data from ApplicationInsights if key.startswith("http."): continue data.properties[key] = span.attributes[key] if span.links: links = [] for link in span.links: operation_id = "{:032x}".format(link.context.trace_id) span_id = "{:016x}".format(link.context.span_id) links.append({"operation_Id": operation_id, "id": span_id}) data.properties["_MS.links"] = json.dumps(links) # TODO: tracestate, tags return envelope