blob: 26771e954a951c5d3f7abb67a839904b11f7c357 [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Utility functions for recording CL's action metrics."""
from __future__ import print_function
from infra_libs import ts_mon
from chromite.lib import clactions
from chromite.lib import constants
from chromite.lib import cros_logging as logging
from chromite.lib import metrics
def RecordSubmissionMetrics(action_history, submitted_change_strategies):
"""Record submission metrics in monarch.
action_history: A CLActionHistory instance for all cl actions for all
changes in submitted_change_strategies.
submitted_change_strategies: A dictionary from GerritPatchTuples to
submission strategy strings. These changes will have their handling
times recorded in monarch.
# TODO(phobbs) move to top level after
handling_time_metric = metrics.CumulativeSecondsDistribution(
wall_clock_time_metric = metrics.CumulativeSecondsDistribution(
precq_time_metric = metrics.CumulativeSecondsDistribution(
wait_time_metric = metrics.CumulativeSecondsDistribution(
cq_run_time_metric = metrics.CumulativeSecondsDistribution(
cq_tries_metric = metrics.CumulativeSmallIntegerDistribution(
# These 3 false rejection metrics are different in subtle but important ways.
# false_rejections: distribution of the number of times a CL was rejected,
# broken down by what it was rejected by (cq vs. pre-cq). Every CL will emit
# two data points to this distribution.
false_rejection_metric = metrics.CumulativeSmallIntegerDistribution(
# false_rejections_total: distribution of the total number of times a CL
# was rejected (not broken down by phase). Note that there is no way to
# independently calculate this from |false_rejections| distribution above,
# since one cannot reconstruct after the fact which pre-cq and cq data points
# (for the same underlying CL) belong together.
false_rejection_total_metric = metrics.CumulativeSmallIntegerDistribution(
# false_rejection_count: counter of the total number of false rejections that
# have occurred (broken down by phase)
false_rejection_count_metric = metrics.Counter(
# This metric excludes rejections which were forgiven by the CL-exonerator
# service.
false_rejections_minus_exonerations_metric = \
description='The number of rejections - exonerations per CL.',
precq_false_rejections = action_history.GetFalseRejections(
cq_false_rejections = action_history.GetFalseRejections(
exonerations = action_history.GetExonerations()
for change, strategy in submitted_change_strategies.iteritems():
strategy = strategy or ''
handling_time = clactions.GetCLHandlingTime(change, action_history)
wall_clock_time = clactions.GetCLWallClockTime(change, action_history)
precq_time = clactions.GetPreCQTime(change, action_history)
wait_time = clactions.GetCQWaitTime(change, action_history)
run_time = clactions.GetCQRunTime(change, action_history)
pickups = clactions.GetCQAttemptsCount(change, action_history)
fields = {'submission_strategy': strategy}
handling_time_metric.add(handling_time, fields=fields)
wall_clock_time_metric.add(wall_clock_time, fields=fields)
precq_time_metric.add(precq_time, fields=fields)
wait_time_metric.add(wait_time, fields=fields)
cq_run_time_metric.add(run_time, fields=fields)
cq_tries_metric.add(pickups, fields=fields)
rejection_types = (
(constants.PRE_CQ, precq_false_rejections),
(constants.CQ, cq_false_rejections),
total_rejections = 0
for by, rej in rejection_types:
c = len(rej.get(change, []))
f = dict(fields, rejected_by=by)
false_rejection_metric.add(c, fields=f)
false_rejection_count_metric.increment_by(c, fields=f)
total_rejections += c
false_rejection_total_metric.add(total_rejections, fields=fields)
n_exonerations = len(exonerations.get(change, []))
# TODO( max(0, ...) is required because of an accounting
# bug where sometimes this quantity is negative.
net_rejections = total_rejections - n_exonerations
if net_rejections < 0:
'Exonerations is larger than total rejections for CL %s.'
' See', change)
max(0, net_rejections),