From c3e5747b772f7b9430d8ae952a1c0916c4383041 Mon Sep 17 00:00:00 2001 From: Asaf Marashe Date: Sun, 13 Dec 2020 15:06:43 +0200 Subject: [PATCH 1/4] tox: package only against python 3.7. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index e6a7bd9..4f9fc6b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27,py34,py35,py36 +envlist = py37 [testenv] commands= From 0baf1dacad72fa13157b00c54e736a68b3224fdb Mon Sep 17 00:00:00 2001 From: Asaf Marashe Date: Sun, 13 Dec 2020 16:22:00 +0200 Subject: [PATCH 2/4] meters/event: fix time type hint. --- pyformance/meters/event.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyformance/meters/event.py b/pyformance/meters/event.py index d8e76bb..fde67bb 100644 --- a/pyformance/meters/event.py +++ b/pyformance/meters/event.py @@ -8,7 +8,7 @@ @dataclass class EventPoint: - time: int + time: float values: Dict[str, Any] From 3d1544e35d574da08c13171153a3824651340d6d Mon Sep 17 00:00:00 2001 From: Asaf Marashe Date: Sun, 13 Dec 2020 16:36:22 +0200 Subject: [PATCH 3/4] influx reporter: make reporting precision configurable. --- pyformance/reporters/influx.py | 54 +++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/pyformance/reporters/influx.py b/pyformance/reporters/influx.py index ada4244..d9b78e9 100644 --- a/pyformance/reporters/influx.py +++ b/pyformance/reporters/influx.py @@ -3,6 +3,7 @@ import base64 import logging import re +from enum import Enum from six import iteritems @@ -26,6 +27,14 @@ DEFAULT_INFLUX_PASSWORD = None DEFAULT_INFLUX_PROTOCOL = "http" +class ReportingPrecision(Enum): + HOURS = "h" + MINUTES = "m" + SECONDS = "s" + MILLISECONDS = "ms" + MICROSECONDS = "u" + NANOSECONDS = "ns" + class InfluxReporter(Reporter): """ @@ -47,7 +56,13 @@ def __init__( autocreate_database=False, clock=None, global_tags=None, + reporting_precision = ReportingPrecision.SECONDS ): + """ + :param reporting_precision: The precision in which the reporter reports to influx. + The default is seconds. This is a tradeoff between precision and performance. More + coarse precision may result in significant improvements in compression and vice versa. + """ super(InfluxReporter, self).__init__(registry, reporting_interval, clock) self.prefix = prefix self.database = database @@ -64,6 +79,8 @@ def __init__( else: self.global_tags = global_tags + self.reporting_precision = reporting_precision + def _create_database(self): url = "%s://%s:%s/query" % (self.protocol, self.server, self.port) q = quote("CREATE DATABASE %s" % self.database) @@ -87,10 +104,14 @@ def _create_database(self): def report_now(self, registry=None, timestamp=None): if self.autocreate_database and not self._did_create_database: self._create_database() - timestamp = timestamp or int(round(self.clock.time())) + timestamp = timestamp or self.clock.time() + timestamp_in_reporting_precision = _to_timestamp_in_precision( + timestamp=timestamp, + precision=self.reporting_precision + ) metrics = (registry or self.registry).dump_metrics(key_is_metric=True) - influx_lines = self._get_influx_protocol_lines(metrics, timestamp) + influx_lines = self._get_influx_protocol_lines(metrics, timestamp_in_reporting_precision) # If you don't have anything nice to say than don't say nothing if influx_lines: post_data = "\n".join(influx_lines) @@ -120,11 +141,15 @@ def _get_influx_protocol_lines(self, metrics, timestamp): for event in metric_values.get("events", []): values = InfluxReporter._stringify_values(event.values) + event_timestamp = _to_timestamp_in_precision( + timestamp=event.time, + precision=self.reporting_precision + ) line = "%s%s %s %s" % ( table, tags, values, - int(round(event.time)) + event_timestamp ) lines.append(line) @@ -160,7 +185,7 @@ def _stringify_tags(self, metric): return "" def _get_url(self): - path = "/write?db=%s&precision=s" % self.database + path = "/write?db=%s&precision=%s" % (self.database, self.reporting_precision.value) return "%s://%s:%s%s" % (self.protocol, self.server, self.port, path) def _add_auth_data(self, request): @@ -186,6 +211,27 @@ def _try_send(self, url, data): response ) +def _to_timestamp_in_precision(timestamp: float, precision: ReportingPrecision) -> int: + if precision == ReportingPrecision.HOURS: + return int(timestamp / 60 / 60) + + if precision == ReportingPrecision.MINUTES: + return int(timestamp / 60) + + if precision == ReportingPrecision.SECONDS: + return int(timestamp) + + if precision == ReportingPrecision.MILLISECONDS: + return int(timestamp * 1e3) + + if precision == ReportingPrecision.MICROSECONDS: + return int(timestamp * 1e6) + + if precision == ReportingPrecision.NANOSECONDS: + return int(timestamp * 1e9) + + raise Exception("Unsupported ReportingPrecision") + def _format_field_value(value): if isinstance(value, MarkInt): From 4dc0fc20566d3f30898dd6c873f3d837f0ba7dfb Mon Sep 17 00:00:00 2001 From: Asaf Marashe Date: Thu, 17 Dec 2020 10:12:22 +0200 Subject: [PATCH 4/4] version: change from 1.0.7 to 2.0.0. Breaking changes in this version: supporting only python 3.7. --- pyformance/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyformance/__version__.py b/pyformance/__version__.py index 9e604c0..8c0d5d5 100644 --- a/pyformance/__version__.py +++ b/pyformance/__version__.py @@ -1 +1 @@ -__version__ = "1.0.7" +__version__ = "2.0.0"