def trace_and_record_stats(self, method_name, fn, *args, **kwargs): __TRACER = execution_context.get_opencensus_tracer() or noop_tracer.NoopTracer() __STATS_RECORDER = stats.Stats().stats_recorder start_time = time.time() tags = tag_map_module.TagMap() tags.insert(key_method, tag_value_module.TagValue(method_name)) mm = __STATS_RECORDER.new_measurement_map() with __TRACER.span(name=method_name) as span: try: return fn(*args, **kwargs) except Exception as e: # an error to record span.status = Status.from_exception(e) # TODO: (@odeke-em) perhaps shorten the exception when added as a tag here? tags.insert(key_error, e.__str__()) # Then finally after recording the exception, re-raise it. raise e else: # Success tags.insert(key_status, "ok") finally: latency_ms = (time.time() - start_time) * 1000 mm.measure_float_put(m_latency_ms, latency_ms) mm.measure_int_put(m_calls, 1) mm.record(tags)
def exception(self, exception: Exception): """ Sends the exception to App Insights :param exception: Actual exception to be sent :return: """ self.logger.exception(exception, extra=self.custom_dimensions) # Mark current span/operation with internal error if self.current_span() is not None: self.current_span().status = Status(2, exception) self.current_span().attributes['http.status_code'] = 500
def find_food(): tracer = get_opencensus_tracer() with tracer.span(name="finding_food") as finding_food_span: start = time.time() mmap = stats_recorder.new_measurement_map() target_food = request.args['target_food'] finding_food_span.add_annotation( "Looking for food {}".format(target_food)) food_options = [] with tracer.span(name="querying_supplier") as _: vendors_with_target = _query_supplier(target_food) no_vendor_fails = True for vendor in vendors_with_target: with tracer.span( name="querying_vendor_{}".format(vendor)) as vendor_span: vendor_request = vendor + "/get_food?target_food={}".format( target_food) try: option = json.loads(requests.get(vendor_request).content) food_options.append( FoodOption(vendor, option['stock'], option['price'])) except Exception as e: vendor_span.status = Status( 500, 'Vendor request {} failed with error {}'.format( vendor_request, e)) no_vendor_fails = False finding_food_span.add_annotation( "{} vendor responses".format(len(food_options)), no_vendor_found=(len(food_options) == 0)) if len(food_options) == 0: return_string = 'No options found :(' else: return_string = 'You have {} options<br/>'.format( len(food_options)) for food_option in food_options: return_string += '{} has {} left at {} price<br/>' \ .format(food_option.vendor_url, food_option.stock, food_option.price) tmap = tag_map_module.TagMap() tmap.insert(key_method, tag_value_module.TagValue("find_food")) if no_vendor_fails: tmap.insert(key_status, tag_value_module.TagValue("OK")) else: tmap.insert(key_status, tag_value_module.TagValue("Vendor request failed")) end_ms = (time.time() - start) * 1000.0 # Seconds to milliseconds mmap.measure_float_put(m_latency_ms, end_ms) mmap.measure_int_put(m_num_requests, 1) mmap.record(tmap) return return_string
def home(): locations = [] # Setup custom tracer # Get the Tracer object tracer = execution_context.get_opencensus_tracer() # Name should be descriptive with tracer.span(name="datastore.query()") as span: kind = "Hive" locations = [] for latlng in datastore_client.query(kind=kind).fetch(): locations.append({ 'loc': { "lat": latlng["LatLng"]['latitude'], "lon": latlng["LatLng"]['longitude'], }, "description": gettext("Authored by %(Firstname)s %(Familyname)s", Firstname=latlng['Firstname'], Familyname=latlng['Familyname']) }) location_count = len(locations) logger.debug("Found %d HiveLocation entries for map." % location_count) # Add info into our trace # Annotation: https://opencensus.io/tracing/span/time_events/annotation/ # Status: https://opencensus.io/tracing/span/status/ # For annotation first param is description, additional are freeform attributes span.add_annotation("Query all hive locations from datastore", kind=kind, count=location_count) if location_count > 0: span.status = Status(0, "Found %d hive locations." % location_count) else: # Not found span.status = Status(5, "Zero locations found.") return render_template("mymap.html", hive_locations=locations)
def doWork(): # 5. Start another span. Because this is within the scope of the "main" span, # this will automatically be a child span. with tracer.span(name="doWork") as span: msg = "doing busy work" print(msg) # - warning should show as a trace in app insights logger.warning(msg) try: time.sleep(0.1) except: # 6. Set status upon error span.status = Status(5, "Error occurred") # 7. Annotate our span to capture metadata about our operation span.add_annotation("invoking doWork")
def doExtraWork(counter): with tracer.span(name="doExtraWork") as span: msg = "doing other busy work" print(msg) # - info won't show in app insights logger.info(msg) try: time.sleep(0.1) print(1 / 0) except: # 6. Set status upon error print("Error!") logger.error("error should be a trace in app insights") logger.exception('Captured an exception') span.status = Status(5, "Error occurred") # 7. Annotate our span to capture metadata about our operation span.add_annotation(f"invoking doWork for:{counter}")
def trace_and_record_stats_with_key_and_value(method_name, fn, key, value, *args, **kwargs): __TRACER = execution_context.get_opencensus_tracer( ) or noop_tracer.NoopTracer() __STATS_RECORDER = stats.stats.stats_recorder start_time = time.time() tags = tag_map.TagMap() tags.insert(key_method, tag_value.TagValue(method_name)) mm = __STATS_RECORDER.new_measurement_map() with __TRACER.span(name=method_name) as span: try: return fn(*args, **kwargs) except Exception as e: span.status = Status.from_exception(e) tags.insert(key_status, "ERROR") tags.insert(key_error, e.__str__()) # Re-raise that exception after we've extracted the error. raise e else: tags.insert(key_status, "OK") finally: latency_ms = (time.time() - start_time) * 1e3 mm.measure_float_put(m_latency_ms, latency_ms) key_lengths = heuristical_lengths(key) value_lengths = heuristical_lengths(value) for key_length in key_lengths: mm.measure_int_put(m_key_length, key_length) for value_length in value_lengths: mm.measure_int_put(m_value_length, value_length) mm.record(tags)