blob: fdb1635a50c02ce9b5300f2f43dae31948cb53bf [file] [log] [blame]
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import socket
from recipe_engine import recipe_api
# Path to the send_ts_mon_values package in infra-python.
SEND_TS_MON_VALUES = 'infra.tools.send_ts_mon_values'
class TSMonApi(recipe_api.RecipeApi):
def __init__(self, **kwargs):
super(TSMonApi, self).__init__(**kwargs)
self._infra_python_path = None
def _ensure_infra_python(self):
if self._infra_python_path:
return
# TODO(tmrts): Create a smaller CIPD package that just contains the package
# send_ts_mon_values and its dependencies and fetch it here instead.
self._infra_python_path = self.m.path['cache'].join('infra-python')
self.m.cipd.ensure(
self._infra_python_path,
self.m.cipd.EnsureFile().add_package(
'infra/infra_python/${platform}', 'latest'))
def send_counter_value(self, name, value, fields=None, service_name='luci',
job_name='recipe', step_name='upload ts_mon metrics'):
"""Sends a value to the ts_mon monitoring service.
Based on the ts_mon monitoring pipeline and script for sending data to it:
https://cs.chromium.org/chromium/infra/infra/tools/send_ts_mon_values/.
Internal users can read more about ts_mon at go/brown-bag-timeseries-basics.
Note that the candinality of all possible combinations of different values
passed to fields should be less than 5000, i.e. do not use unique
identifiers or timestamps and instead use values from a known small set.
Additionally, the reported values for each unique combination of field
values get downsampled by ts_mon according to the following rules:
- no downsampling for 12 hrs
- keep at most 1 data point for each min for the next 1 week
- keep at most 1 data point for 5 mins interval for the next 12 weeks
- Keep at most 1 data point for 30 mins interval for the next 52 weeks
Therefore, please keep in mind that for metrics reported with high frequency
(which can also be caused by having them reported at low frequency, but from
large number of bots), the graphs may change as a result of downsampling and
thus users may see different values in the past than what was reported
originally and what was used to generate alerts.
Arguments:
name: Name of the metric, which is automatically prefixed with
/chrome/infra, i.e. /foo/bar will become /chrome/infra/foo/bar.
value: The value to be reported.
fields: Dictionary with fields to be associated with the value.
service_name: Name of the service being monitored.
job_name: Name of this job instance of the task.
step_name: Name of the step sending information to ts_mon.
"""
self._ensure_infra_python()
counter_config = {'name': name, 'value': value}
counter_config.update(fields or {})
result = self.m.python(step_name, self._infra_python_path.join('run.py'), [
SEND_TS_MON_VALUES,
'--ts-mon-target-type', 'task',
'--ts-mon-task-service-name', service_name,
'--ts-mon-task-job-name', job_name,
'--counter-file', self.m.json.input(counter_config),
])
result.presentation.logs['counter_config'] = self.m.json.dumps(
counter_config, indent=2, separators=(',', ': ')).splitlines()