kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 1 | import logging |
kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 2 | from typing import Tuple, Iterator |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 3 | |
| 4 | import numpy |
| 5 | |
kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 6 | from cephlib.numeric_types import DataSource, TimeSeries |
| 7 | from cephlib.storage_selectors import c_interpolate_ts_on_seconds_border |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 8 | |
kdanylov aka koder | 026e5f2 | 2017-05-15 01:04:39 +0300 | [diff] [blame^] | 9 | from .result_classes import IWallyStorage |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 10 | from .suits.io.fio_hist import expected_lat_bins |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 11 | |
| 12 | |
| 13 | logger = logging.getLogger("wally") |
| 14 | |
| 15 | # Separately for each test heatmaps & agg acroos whole time histos: |
| 16 | # * fio latency heatmap for all instances |
| 17 | # * data dev iops across all osd |
| 18 | # * data dev bw across all osd |
| 19 | # * date dev qd across all osd |
| 20 | # * journal dev iops across all osd |
| 21 | # * journal dev bw across all osd |
| 22 | # * journal dev qd across all osd |
| 23 | # * net dev pps across all hosts |
| 24 | # * net dev bps across all hosts |
| 25 | |
| 26 | # Main API's |
| 27 | # get sensors by pattern |
| 28 | # allign values to seconds |
| 29 | # cut ranges for particular test |
| 30 | # transform into 2d histos (either make histos or rebin them) and clip outliers same time |
| 31 | |
| 32 | |
| 33 | AGG_TAG = 'ALL' |
| 34 | |
| 35 | |
kdanylov aka koder | 026e5f2 | 2017-05-15 01:04:39 +0300 | [diff] [blame^] | 36 | def find_all_series(rstorage: IWallyStorage, suite_id: str, job_id: str, metric: str) -> Iterator[TimeSeries]: |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 37 | "Iterated over selected metric for all nodes for given Suite/job" |
kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 38 | return (rstorage.get_ts(ds) for ds in rstorage.iter_ts(suite_id=suite_id, job_id=job_id, metric=metric)) |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 39 | |
| 40 | |
kdanylov aka koder | 026e5f2 | 2017-05-15 01:04:39 +0300 | [diff] [blame^] | 41 | def get_aggregated(rstorage: IWallyStorage, suite_id: str, job_id: str, metric: str, |
kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 42 | trange: Tuple[int, int]) -> TimeSeries: |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 43 | "Sum selected metric for all nodes for given Suite/job" |
| 44 | |
kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 45 | tss = list(find_all_series(rstorage, suite_id, job_id, metric)) |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 46 | |
| 47 | if len(tss) == 0: |
kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 48 | raise NameError("Can't found any TS for {},{},{}".format(suite_id, job_id, metric)) |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 49 | |
kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 50 | ds = DataSource(suite_id=suite_id, job_id=job_id, node_id=AGG_TAG, sensor='fio', |
| 51 | dev=AGG_TAG, metric=metric, tag='csv') |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 52 | |
kdanylov aka koder | 3a9e5db | 2017-05-09 20:00:44 +0300 | [diff] [blame] | 53 | tss_inp = [c_interpolate_ts_on_seconds_border(ts, tp='fio', allow_broken_step=(metric == 'lat')) for ts in tss] |
| 54 | res = None |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 55 | |
kdanylov aka koder | 3a9e5db | 2017-05-09 20:00:44 +0300 | [diff] [blame] | 56 | for ts in tss_inp: |
| 57 | if ts.time_units != 's': |
| 58 | msg = "time_units must be 's' for fio sensor" |
| 59 | logger.error(msg) |
| 60 | raise ValueError(msg) |
| 61 | |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 62 | if metric == 'lat' and (len(ts.data.shape) != 2 or ts.data.shape[1] != expected_lat_bins): |
kdanylov aka koder | 026e5f2 | 2017-05-15 01:04:39 +0300 | [diff] [blame^] | 63 | msg = "Sensor {}.{} on node {} has shape={}. Can only process sensors with shape=[X, {}].".format( |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 64 | ts.source.dev, ts.source.sensor, ts.source.node_id, ts.data.shape, expected_lat_bins) |
| 65 | logger.error(msg) |
| 66 | raise ValueError(msg) |
| 67 | |
| 68 | if metric != 'lat' and len(ts.data.shape) != 1: |
| 69 | msg = "Sensor {}.{} on node {} has shape={}. Can only process 1D sensors.".format( |
| 70 | ts.source.dev, ts.source.sensor, ts.source.node_id, ts.data.shape) |
| 71 | logger.error(msg) |
| 72 | raise ValueError(msg) |
| 73 | |
kdanylov aka koder | 3a9e5db | 2017-05-09 20:00:44 +0300 | [diff] [blame] | 74 | assert trange[0] >= ts.times[0] and trange[1] <= ts.times[-1], \ |
| 75 | "[{}, {}] not in [{}, {}]".format(ts.times[0], ts.times[-1], trange[0], trange[-1]) |
kdanylov aka koder | 736e5c1 | 2017-05-07 17:27:14 +0300 | [diff] [blame] | 76 | |
kdanylov aka koder | 3a9e5db | 2017-05-09 20:00:44 +0300 | [diff] [blame] | 77 | idx1, idx2 = numpy.searchsorted(ts.times, trange) |
| 78 | idx2 += 1 |
| 79 | |
| 80 | assert (idx2 - idx1) == (trange[1] - trange[0] + 1), \ |
| 81 | "Broken time array at {} for {}".format(trange, ts.source) |
| 82 | |
| 83 | dt = ts.data[idx1: idx2] |
| 84 | if res is None: |
| 85 | res = dt |
| 86 | else: |
| 87 | assert res.shape == dt.shape, "res.shape(={}) != dt.shape(={})".format(res.shape, dt.shape) |
| 88 | res += dt |
| 89 | |
kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 90 | agg_ts = TimeSeries(res, source=ds, |
kdanylov aka koder | 3a9e5db | 2017-05-09 20:00:44 +0300 | [diff] [blame] | 91 | times=tss_inp[0].times.copy(), |
| 92 | units=tss_inp[0].units, |
| 93 | histo_bins=tss_inp[0].histo_bins, |
| 94 | time_units=tss_inp[0].time_units) |
kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 95 | |
| 96 | return agg_ts |
| 97 | |