async def _push_to_dynatrace(context: Context, lines_batch: List[IngestLine]): ingest_input = "\n".join([line.to_string() for line in lines_batch]) if context.print_metric_ingest_input: context.log("Ingest input is: ") context.log(ingest_input) ingest_response = await context.session.post( url=f"{context.dynatrace_url.rstrip('/')}/api/v2/metrics/ingest", headers={ "Authorization": f"Api-Token {context.dynatrace_api_key}", "Content-Type": "text/plain; charset=utf-8" }, data=ingest_input, verify_ssl=context.require_valid_certificate) if ingest_response.status == 401: context.dynatrace_connectivity = DynatraceConnectivity.ExpiredToken raise Exception("Expired token") elif ingest_response.status == 403: context.dynatrace_connectivity = DynatraceConnectivity.WrongToken raise Exception( "Wrong token - missing 'Ingest metrics using API V2' permission") elif ingest_response.status == 404 or ingest_response.status == 405: context.dynatrace_connectivity = DynatraceConnectivity.WrongURL raise Exception("Wrong URL") ingest_response_json = await ingest_response.json() context.dynatrace_request_count[ ingest_response.status] = context.dynatrace_request_count.get( ingest_response.status, 0) + 1 context.dynatrace_ingest_lines_ok_count += ingest_response_json.get( "linesOk", 0) context.dynatrace_ingest_lines_invalid_count += ingest_response_json.get( "linesInvalid", 0) context.log(f"Ingest response: {ingest_response_json}") await log_invalid_lines(context, ingest_response_json, lines_batch)
async def push_ingest_lines(context: Context, fetch_metric_results: List[IngestLine]): lines_sent = 0 maximum_lines_threshold = context.maximum_metric_data_points_per_minute start_time = time.time() try: lines_batch = [] for result in fetch_metric_results: lines_batch.append(result) lines_sent += 1 if len(lines_batch) >= context.metric_ingest_batch_size: await _push_to_dynatrace(context, lines_batch) lines_batch = [] if lines_sent >= maximum_lines_threshold: await _push_to_dynatrace(context, lines_batch) lines_dropped_count = len( fetch_metric_results) - maximum_lines_threshold context.dynatrace_ingest_lines_dropped_count = lines_dropped_count context.log( f"Number of metric lines exceeded maximum {maximum_lines_threshold}, dropped {lines_dropped_count} lines" ) return if lines_batch: await _push_to_dynatrace(context, lines_batch) except Exception as e: if isinstance(e, InvalidURL): context.dynatrace_connectivity = DynatraceConnectivity.WrongURL context.log( f"Failed to push ingest lines to Dynatrace due to {type(e).__name__} {e}" ) finally: context.push_to_dynatrace_execution_time = time.time() - start_time context.log( f"Finished uploading metric ingest lines to Dynatrace in {context.push_to_dynatrace_execution_time} s" )