(metric: str, timing_buckets: Iterable[int], tags: Dict[str, str] = None,
                            bucket_tag: str = 'duration', callback: Callable = None)
return timer
Create a context manager that times and reports to the metric providers as a histogram

    Example Usage:

    ::

        timer = metrics_histogram_timer('commcare.some.special.metric', tags={
            'type': type,
        ], timing_buckets=(.001, .01, .1, 1, 10, 100))
        with timer:
            some_special_thing()

    This will result it a call to `metrics_histogram` with the timer value.

    Note: Histograms are implemented differently by each provider. See documentation for details.

    :param metric: Name of the metric (must start with 'commcare.')
    :param tags: metric tags to include
    :param timing_buckets: sequence of numbers representing time thresholds, in seconds
    :param bucket_tag: The name of the bucket tag to use (if used by the underlying provider)
    :param callback: a callable which will be called when exiting the context manager with a single argument
                     of the timer duratio
    :return: A context manager that will perform the specified timing
             and send the specified metric
Create a context manager that times and reports to the metric providers as a histogram
Create a context manager that times and reports to the metric providers as a histogram
def metrics_histogram_timer(metric: str, timing_buckets: Iterable[int], tags: Dict[str, str] = None,
                            bucket_tag: str = 'duration', callback: Callable = None):
    """
    Create a context manager that times and reports to the metric providers as a histogram

    Example Usage:

    ::

        timer = metrics_histogram_timer('commcare.some.special.metric', tags={
            'type': type,
        ], timing_buckets=(.001, .01, .1, 1, 10, 100))
        with timer:
            some_special_thing()

    This will result it a call to `metrics_histogram` with the timer value.

    Note: Histograms are implemented differently by each provider. See documentation for details.

    :param metric: Name of the metric (must start with 'commcare.')
    :param tags: metric tags to include
    :param timing_buckets: sequence of numbers representing time thresholds, in seconds
    :param bucket_tag: The name of the bucket tag to use (if used by the underlying provider)
    :param callback: a callable which will be called when exiting the context manager with a single argument
                     of the timer duratio
    :return: A context manager that will perform the specified timing
             and send the specified metric

    """
    timer = TimingContext()
    original_stop = timer.stop

    def new_stop(name=None):
        original_stop(name)
        if callback:
            callback(timer.duration)
        metrics_histogram(
            metric, timer.duration,
            bucket_tag=bucket_tag, buckets=timing_buckets, bucket_unit='s',
            tags=tags
        )
        timer_name = metric
        if metric.startswith('commcare.'):
            timer_name = ".".join(metric.split('.')[1:])  # remove the 'commcare.' prefix
        add_breadcrumb(
            category="timing",
            message=f"{timer_name}: {timer.duration:0.3f}",
            level="info",
        )

    timer.stop = new_stop
    return timer
def metrics_histogram_timer ( metric : str , timing_buckets : Iterable [ int ] , tags : Dict [ str , str ] = None , bucket_tag : str = 'duration' , callback : Callable = None ) : timer = TimingContext ( ) original_stop = timer . stop def new_stop ( name = None ) : original_stop ( name ) if callback : callback ( timer . duration ) metrics_histogram ( metric , timer . duration , bucket_tag = bucket_tag , buckets = timing_buckets , bucket_unit = 's' , tags = tags ) timer_name = metric if metric . startswith ( 'commcare.' ) : timer_name = "." . join ( metric . split ( '.' ) [ 1 : ] ) # remove the 'commcare.' prefix add_breadcrumb ( category = "timing" , message = f"{timer_name}: {timer.duration:0.3f}" , level = "info" , ) timer . stop = new_stop return timer