aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/gunicorn/instrument
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/gunicorn/instrument
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are hereHEADmaster
Diffstat (limited to '.venv/lib/python3.12/site-packages/gunicorn/instrument')
-rw-r--r--.venv/lib/python3.12/site-packages/gunicorn/instrument/__init__.py0
-rw-r--r--.venv/lib/python3.12/site-packages/gunicorn/instrument/statsd.py133
2 files changed, 133 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/gunicorn/instrument/__init__.py b/.venv/lib/python3.12/site-packages/gunicorn/instrument/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/gunicorn/instrument/__init__.py
diff --git a/.venv/lib/python3.12/site-packages/gunicorn/instrument/statsd.py b/.venv/lib/python3.12/site-packages/gunicorn/instrument/statsd.py
new file mode 100644
index 00000000..2c54b2e7
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/gunicorn/instrument/statsd.py
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -
+#
+# This file is part of gunicorn released under the MIT license.
+# See the NOTICE for more information.
+
+"Bare-bones implementation of statsD's protocol, client-side"
+
+import logging
+import socket
+from re import sub
+
+from gunicorn.glogging import Logger
+
+# Instrumentation constants
+METRIC_VAR = "metric"
+VALUE_VAR = "value"
+MTYPE_VAR = "mtype"
+GAUGE_TYPE = "gauge"
+COUNTER_TYPE = "counter"
+HISTOGRAM_TYPE = "histogram"
+
+
+class Statsd(Logger):
+ """statsD-based instrumentation, that passes as a logger
+ """
+ def __init__(self, cfg):
+ Logger.__init__(self, cfg)
+ self.prefix = sub(r"^(.+[^.]+)\.*$", "\\g<1>.", cfg.statsd_prefix)
+
+ if isinstance(cfg.statsd_host, str):
+ address_family = socket.AF_UNIX
+ else:
+ address_family = socket.AF_INET
+
+ try:
+ self.sock = socket.socket(address_family, socket.SOCK_DGRAM)
+ self.sock.connect(cfg.statsd_host)
+ except Exception:
+ self.sock = None
+
+ self.dogstatsd_tags = cfg.dogstatsd_tags
+
+ # Log errors and warnings
+ def critical(self, msg, *args, **kwargs):
+ Logger.critical(self, msg, *args, **kwargs)
+ self.increment("gunicorn.log.critical", 1)
+
+ def error(self, msg, *args, **kwargs):
+ Logger.error(self, msg, *args, **kwargs)
+ self.increment("gunicorn.log.error", 1)
+
+ def warning(self, msg, *args, **kwargs):
+ Logger.warning(self, msg, *args, **kwargs)
+ self.increment("gunicorn.log.warning", 1)
+
+ def exception(self, msg, *args, **kwargs):
+ Logger.exception(self, msg, *args, **kwargs)
+ self.increment("gunicorn.log.exception", 1)
+
+ # Special treatment for info, the most common log level
+ def info(self, msg, *args, **kwargs):
+ self.log(logging.INFO, msg, *args, **kwargs)
+
+ # skip the run-of-the-mill logs
+ def debug(self, msg, *args, **kwargs):
+ self.log(logging.DEBUG, msg, *args, **kwargs)
+
+ def log(self, lvl, msg, *args, **kwargs):
+ """Log a given statistic if metric, value and type are present
+ """
+ try:
+ extra = kwargs.get("extra", None)
+ if extra is not None:
+ metric = extra.get(METRIC_VAR, None)
+ value = extra.get(VALUE_VAR, None)
+ typ = extra.get(MTYPE_VAR, None)
+ if metric and value and typ:
+ if typ == GAUGE_TYPE:
+ self.gauge(metric, value)
+ elif typ == COUNTER_TYPE:
+ self.increment(metric, value)
+ elif typ == HISTOGRAM_TYPE:
+ self.histogram(metric, value)
+ else:
+ pass
+
+ # Log to parent logger only if there is something to say
+ if msg:
+ Logger.log(self, lvl, msg, *args, **kwargs)
+ except Exception:
+ Logger.warning(self, "Failed to log to statsd", exc_info=True)
+
+ # access logging
+ def access(self, resp, req, environ, request_time):
+ """Measure request duration
+ request_time is a datetime.timedelta
+ """
+ Logger.access(self, resp, req, environ, request_time)
+ duration_in_ms = request_time.seconds * 1000 + float(request_time.microseconds) / 10 ** 3
+ status = resp.status
+ if isinstance(status, str):
+ status = int(status.split(None, 1)[0])
+ self.histogram("gunicorn.request.duration", duration_in_ms)
+ self.increment("gunicorn.requests", 1)
+ self.increment("gunicorn.request.status.%d" % status, 1)
+
+ # statsD methods
+ # you can use those directly if you want
+ def gauge(self, name, value):
+ self._sock_send("{0}{1}:{2}|g".format(self.prefix, name, value))
+
+ def increment(self, name, value, sampling_rate=1.0):
+ self._sock_send("{0}{1}:{2}|c|@{3}".format(self.prefix, name, value, sampling_rate))
+
+ def decrement(self, name, value, sampling_rate=1.0):
+ self._sock_send("{0}{1}:-{2}|c|@{3}".format(self.prefix, name, value, sampling_rate))
+
+ def histogram(self, name, value):
+ self._sock_send("{0}{1}:{2}|ms".format(self.prefix, name, value))
+
+ def _sock_send(self, msg):
+ try:
+ if isinstance(msg, str):
+ msg = msg.encode("ascii")
+
+ # http://docs.datadoghq.com/guides/dogstatsd/#datagram-format
+ if self.dogstatsd_tags:
+ msg = msg + b"|#" + self.dogstatsd_tags.encode('ascii')
+
+ if self.sock:
+ self.sock.send(msg)
+ except Exception:
+ Logger.warning(self, "Error sending message to statsd", exc_info=True)