Skip to content

Commit

Permalink
Merge pull request #9 from Lightricks/feature/change_influx_reporter_…
Browse files Browse the repository at this point in the history
…to_milisecond_precision
  • Loading branch information
Asaf Marashe authored Dec 17, 2020
2 parents 96d5548 + 4dc0fc2 commit 0b7507d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 7 deletions.
2 changes: 1 addition & 1 deletion pyformance/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.0.7"
__version__ = "2.0.0"
2 changes: 1 addition & 1 deletion pyformance/meters/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

@dataclass
class EventPoint:
time: int
time: float
values: Dict[str, Any]


Expand Down
54 changes: 50 additions & 4 deletions pyformance/reporters/influx.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import base64
import logging
import re
from enum import Enum

from six import iteritems

Expand All @@ -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):
"""
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand All @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py27,py34,py35,py36
envlist = py37

[testenv]
commands=
Expand Down

0 comments on commit 0b7507d

Please sign in to comment.