コード例 #1
0
ファイル: amqp.py プロジェクト: metricq/metricq-grafana
async def get_counter_data(app, metric, start, stop, width):
    time_begin = timer()
    target = Target(metric, order_time_value=True)
    start_time = Timestamp(start * 10**6)
    end_time = Timestamp(stop * 10**6)
    interval = (end_time - start_time) / width
    results, metadata = await asyncio.gather(
        target.get_response(app, start_time, end_time, interval),
        target.get_metadata(app),
    )
    result = results[0] if len(results) > 0 else {"datapoints": []}

    datapoints = [
        datapoint for datapoint in result["datapoints"]
        if start <= datapoint[0] <= stop
    ]

    rv = {
        "description": metadata.get("description", ""),
        "unit": metadata.get("unit", ""),
        "data": datapoints,
    }
    time_diff = timer() - time_begin
    logger.log(
        logging.DEBUG if time_diff < 1 else logging.INFO,
        "get_counter_data for {} returned {} values and took {} s",
        metric,
        len(rv["data"]),
        time_diff,
    )
    return rv
コード例 #2
0
def test_history_set_epoch(empty_history):
    # An empty StateTransitionHistory should not have an epoch set
    assert empty_history.epoch is None

    # The first transition to be inserted is discarded, only its timestamp is
    # kept as the epoch value for this history.
    empty_history.insert(Timestamp(0), State.OK)
    assert empty_history.epoch == Timestamp(0)
    assert not empty_history.transitions
コード例 #3
0
 async def _run(self):
     logger.info("{!r}: started", self)
     try:
         while True:
             if self._last_timestamp is None or self._throttle:
                 # We either never got bumped or we just missed a deadline
                 # and ran the timeout callback.  Wait for the entire
                 # timeout duration in either case, so that we don't spam
                 # the timeout callback.
                 timeout = self._timeout + self._grace_period
                 await self._run_timeout_callback_after(timeout)
             else:
                 # Calculate a deadline by which we expect the next bump,
                 # based on the last time at which we got bumped.
                 # We assume our local clock and the clock source for the
                 # last timestamp to be synchronized within the grace period.
                 # If the deadline is in the past, immediately run the
                 # timeout callback.
                 now = Timestamp.now()
                 deadline = self._last_timestamp + self._timeout + self._grace_period
                 if deadline <= now:
                     logger.debug("{!r}: deadline in the past!", self)
                     self._run_timeout_callback()
                     self._throttle = True
                 else:
                     wait_duration = deadline - now
                     await self._run_timeout_callback_after(wait_duration)
     except CancelledError:
         logger.info("{!r}: stopped", self)
         raise
     except Exception as e:  # pylint: disable=broad-except
         logger.exception(
             "{!r}: unexpected error inside TimeoutCheck callback: {}",
             self, e)
コード例 #4
0
async def test_timeout_check_bump_once(timeout_check: TimeoutCheck):
    now = Timestamp.now()
    timeout_check.bump(now)

    await step()

    callback = cast(Callback, timeout_check._timeout_callback)
    assert not callback.called
    assert timeout_check._last_timestamp == now
コード例 #5
0
    def _metric():
        timestamp = Timestamp(0)
        delta = Timedelta.from_s(1)
        value = 0.0

        while True:
            yield (timestamp, value)
            timestamp += delta
            value += 1.0
コード例 #6
0
async def test_source_send_error_value_is_none(source_metric: SourceMetric):
    async def send(metric, chunk: DataChunk):
        assert len(chunk.value) == 1 and isnan(chunk.value[0])

    # Replace the send call by a mock and inspect it there.  We cannot inspect
    # the chunk from mock_calls after the call to error since the chunk will
    # have been reset already, so it would always be empty.
    source_metric.source.attach_mock(AsyncMock(side_effect=send), "_send")

    await source_metric.error(Timestamp(0))
コード例 #7
0
ファイル: amqp.py プロジェクト: metricq/metricq-grafana
async def get_history_data(app, request):
    time_begin = timer()
    targets = []
    for target_dict in request["targets"]:
        metrics = [target_dict["metric"]]
        # guess if this is a pattern (regex) to expand by sending it to the manager
        if "(" in target_dict["metric"] and ")" in target_dict["metric"]:
            metrics = await app["history_client"].get_metrics(
                metadata=False, historic=True, selector=target_dict["metric"])
        for metric in metrics:
            targets.append(
                Target(
                    metric=metric,
                    name=target_dict.get("name", None),
                    functions=list(parse_functions(target_dict)),
                    scaling_factor=float(target_dict.get(
                        "scaling_factor", "1")),
                ))

    start_time = Timestamp.from_iso8601(request["range"]["from"])
    end_time = Timestamp.from_iso8601(request["range"]["to"])
    # Grafana gives inconsistent information here:
    #    intervalMs is very coarse grained
    #    maxDataPoints is not really the number of pixels, usually less
    # interval = Timedelta.from_ms(request["intervalMs"])
    interval = ((end_time - start_time) / request["maxDataPoints"]) * 2
    results = await asyncio.gather(*[
        target.get_response(app, start_time, end_time, interval)
        for target in targets
    ])
    rv = functools.reduce(operator.iconcat, results, [])
    time_diff = timer() - time_begin
    logger.log(
        logging.DEBUG if time_diff < 1 else logging.INFO,
        "get_history_data for {} targets took {} s",
        len(targets),
        time_diff,
    )

    return rv
コード例 #8
0
def run_source(ssource):
    ssource.declare_metrics(
        {"dummy.time": {
            "unit": "s",
            "location": "localhost"
        }})
    try:
        while True:
            ssource.send("dummy.time", Timestamp.now(), time.time())
            time.sleep(0.1)
    except KeyboardInterrupt:
        logger.info("stopping SynchronousSource")
    ssource.stop()
コード例 #9
0
    def run(self):
        assert self.import_begin is None
        if not click.confirm(f'Please make sure the MetricQ db with the token '
                             f'{self.token}" is not running! Continue?'):
            return

        self.update_config()
        self.create_bindings()
        self.import_begin = Timestamp.now()
        self.run_import()

        if self.failed_imports:
            print('The following metrics have failed to import:')
            for metric in self.failed_imports:
                print(f' - {metric.metricq_name}')
コード例 #10
0
ファイル: utils.py プロジェクト: metricq/metricq-tools
 def convert(self, value: str, param: Optional[Parameter],
             ctx: Optional[Context]) -> Any:
     if value is None:
         return None
     elif isinstance(value, str):
         try:
             return Timestamp.from_iso8601(value)
         except ValueError:
             self.fail(
                 "expected an ISO-8601 timestamp (e.g. 2012-12-21T00:00:00Z)",
                 param=param,
                 ctx=ctx,
             )
     else:
         return value
コード例 #11
0
    def real_run(self):
        assert self._import_begin is None
        self._confirm(f"Please make sure the MetricQ db with the token "
                      f'"{self._metricq_token}" is not running! Continue?')

        self._update_config()
        if not self._resume:
            self._create_bindings()
        self._import_begin = Timestamp.now()
        self._run_import()

        if self._failed_imports:
            print("The following metrics have failed to import:")
            for metric in self._failed_imports:
                print(f" - {metric.metricq_name}")
コード例 #12
0
ファイル: conftest.py プロジェクト: metricq/metricq-sink-nsca
class Ticker:
    DEFAULT_DELTA = Timedelta.from_s(1)
    DEFAULT_START = Timestamp(0)

    def __init__(self, delta=DEFAULT_DELTA, start=DEFAULT_START):
        self.delta = delta
        self.start = start
        self.now = self.start

    def __next__(self):
        now = self.now
        self.now += self.delta
        return now

    def __iter__(self):
        return self
コード例 #13
0
def synchronous_source(server, token):
    ssource = SynchronousSource(token=token, management_url=server)
    ssource.declare_metrics({
        "test.example.random": {
            "unit": "s",
            "description":
            "a test metric that just contains random numbers in the range [0.0, 1.0)",
            "rate": 10.0,
            "location": "localhost",
        }
    })
    try:
        while True:
            ssource.send("test.example.random", Timestamp.now(),
                         random.random())
            time.sleep(0.1)
    except KeyboardInterrupt:
        logger.info("stopping SynchronousSource")
    ssource.stop()
コード例 #14
0
ファイル: test_types.py プロジェクト: metricq/metricq-python
    assert isclose(agg.mean_integral, VALUE)
    assert isclose(agg.mean_sum, VALUE)


def test_timeaggregate_from_value_pair_non_monotonic(
        timestamp: Timestamp, time_delta_10s: Timedelta):
    later = timestamp + time_delta_10s

    with pytest.raises(NonMonotonicTimestamps):
        TimeAggregate.from_value_pair(timestamp_before=later,
                                      timestamp=timestamp,
                                      value=42.0)


@pytest.mark.parametrize(
    ("date_string", "expected"),
    [
        # Sanity check
        ("1970-01-01T00:00:00Z", Timestamp(0)),
        # Parser supports sub-second digits
        ("1970-01-01T00:00:00.0Z", Timestamp(0)),
        # Parser drops sub-microsecond digits
        ("1970-01-01T00:00:00.000001337Z", Timestamp(1000)),
        # Timezones other that UTC are supported
        ("1970-01-01T00:00:00-01:00", Timestamp(
            Timedelta.from_string("1h").ns)),
    ],
)
def test_timestamp_from_iso8601(date_string: str, expected: Timestamp):
    assert Timestamp.from_iso8601(date_string) == expected
コード例 #15
0
ファイル: test_types.py プロジェクト: metricq/metricq-python
def test_timestamp_from_iso8601(date_string: str, expected: Timestamp):
    assert Timestamp.from_iso8601(date_string) == expected
コード例 #16
0
def test_timestamp_param():
    value = "2021-05-02T00:00:00Z"
    assert TIMESTAMP.convert(value, param=None,
                             ctx=None) == Timestamp.from_iso8601(value)
コード例 #17
0
ファイル: test_types.py プロジェクト: metricq/metricq-python
def timestamp():
    return Timestamp.from_iso8601("2021-03-03T18:00:00Z")
コード例 #18
0
def history_with_epoch_set():
    history = StateTransitionHistory(None)
    history.insert(Timestamp(0), State.OK)
    return history