summary refs log tree commit diff
path: root/synapse/metrics
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2018-05-02 16:52:42 +0100
committerErik Johnston <erik@matrix.org>2018-05-02 16:52:42 +0100
commit32015e1109bc955697353d8f8088e3f6b538d12c (patch)
treef3f8b7265608eb52d8c44b6dc2fd8efd863443ee /synapse/metrics
parentMerge pull request #3168 from matrix-org/rav/fix_logformatter (diff)
downloadsynapse-32015e1109bc955697353d8f8088e3f6b538d12c.tar.xz
Escape label values in prometheus metrics
Diffstat (limited to 'synapse/metrics')
-rw-r--r--synapse/metrics/metric.py22
1 files changed, 20 insertions, 2 deletions
diff --git a/synapse/metrics/metric.py b/synapse/metrics/metric.py
index 89bd47c3f7..1a09e417c9 100644
--- a/synapse/metrics/metric.py
+++ b/synapse/metrics/metric.py
@@ -16,6 +16,7 @@
 
 from itertools import chain
 import logging
+import re
 
 logger = logging.getLogger(__name__)
 
@@ -56,8 +57,7 @@ class BaseMetric(object):
         return not len(self.labels)
 
     def _render_labelvalue(self, value):
-        # TODO: escape backslashes, quotes and newlines
-        return '"%s"' % (value)
+        return '"%s"' % (_escape_label_value(value),)
 
     def _render_key(self, values):
         if self.is_scalar():
@@ -299,3 +299,21 @@ class MemoryUsageMetric(object):
             "process_psutil_rss:total %d" % sum_rss,
             "process_psutil_rss:count %d" % len_rss,
         ]
+
+
+def _escape_character(c):
+    """Replaces a single character with its escape sequence.
+    """
+    if c == "\\":
+        return "\\\\"
+    elif c == "\"":
+        return "\\\""
+    elif c == "\n":
+        return "\\n"
+    return c
+
+
+def _escape_label_value(value):
+    """Takes a label value and escapes quotes, newlines and backslashes
+    """
+    return re.sub(r"([\n\"\\])", lambda m: _escape_character(m.group(1)), value)