def test_transmission_206_500(self): test_envelope = TelemetryItem(name="testEnvelope", time=datetime.now()) custom_envelopes_to_export = [TelemetryItem(name="Test", time=datetime.now( )), TelemetryItem(name="Test", time=datetime.now()), test_envelope] with mock.patch("requests.Session.request") as post: post.return_value = MockResponse( 206, json.dumps( { "itemsReceived": 5, "itemsAccepted": 3, "errors": [ {"index": 0, "statusCode": 400, "message": ""}, { "index": 2, "statusCode": 500, "message": "Internal Server Error", }, ], } ), ) result = self._base._transmit(custom_envelopes_to_export) self.assertEqual(result, ExportResult.FAILED_RETRYABLE) self._base.storage.get() self.assertEqual( self._base.storage.get().get()[0]["name"], "testEnvelope" )
def setUpClass(cls): os.environ[ "APPINSIGHTS_INSTRUMENTATIONKEY"] = "1234abcd-5678-4efa-8abc-1234567890ab" cls._base = BaseExporter() cls._envelopes_to_export = [ TelemetryItem(name="Test", time=datetime.now()) ]
def _transmit_from_storage(self) -> None: for blob in self.storage.gets(): # give a few more seconds for blob lease operation # to reduce the chance of race (for perf consideration) if blob.lease(self._timeout + 5): envelopes = [TelemetryItem(**x) for x in blob.get()] result = self._transmit(list(envelopes)) if result == ExportResult.FAILED_RETRYABLE: blob.lease(1) else: blob.delete()
def test_transmission_206_bogus(self): envelopes_to_export = map(lambda x: x.as_dict(), tuple( [TelemetryItem(name="testEnvelope", time=datetime.now())])) self._base.storage.put(envelopes_to_export) with mock.patch("requests.Session.request") as post: post.return_value = MockResponse( 206, json.dumps( { "itemsReceived": 5, "itemsAccepted": 3, "errors": [{"foo": 0, "bar": 1}], } ), ) result = self._base._transmit(self._envelopes_to_export) self.assertEqual(result, ExportResult.FAILED_NOT_RETRYABLE)
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), ) if span.resource and span.resource.attributes: # TODO: Get Resource attributes from OpenTelemetry SDK when available service_name = span.resource.attributes.get("service.name") service_namespace = span.resource.attributes.get("service.namespace") service_instance_id = span.resource.attributes.get( "service.instance.id") if service_name: if service_namespace: envelope.tags["ai.cloud.role"] = service_namespace + \ "." + service_name else: envelope.tags["ai.cloud.role"] = service_name if service_instance_id: envelope.tags["ai.cloud.roleInstance"] = service_instance_id 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