From fc01b08e6feadeed440ff70053d7ecc85ed8038e Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Tue, 28 Nov 2017 10:43:10 -0500 Subject: [PATCH 1/2] use _DOT_ to replace literal . in tagged series filenames --- webapp/graphite/tags/utils.py | 2 +- webapp/tests/test_tags.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/graphite/tags/utils.py b/webapp/graphite/tags/utils.py index d8a70801c..d58515183 100644 --- a/webapp/graphite/tags/utils.py +++ b/webapp/graphite/tags/utils.py @@ -95,7 +95,7 @@ def encode(metric, sep='.'): """ if ';' in metric: metric_hash = sha256(metric.encode('utf8')).hexdigest() - return sep.join(['_tagged', metric_hash[0:3], metric_hash[3:6], metric.replace('.', '-')]) + return sep.join(['_tagged', metric_hash[0:3], metric_hash[3:6], metric.replace('.', '_DOT_')]) # metric isn't tagged, just replace dots with the separator and trim any leading separator return metric.replace('.', sep).lstrip(sep) diff --git a/webapp/tests/test_tags.py b/webapp/tests/test_tags.py index 8b261972a..4fcbc97db 100644 --- a/webapp/tests/test_tags.py +++ b/webapp/tests/test_tags.py @@ -28,7 +28,7 @@ def test_taggedseries(self): self.assertEqual(parsed.path, 'test.a;blah=blah;hello=tiger') # test encoding - self.assertEqual(TaggedSeries.encode(parsed.path), '_tagged.2b0.2af.test-a;blah=blah;hello=tiger') + self.assertEqual(TaggedSeries.encode(parsed.path), '_tagged.2b0.2af.test_DOT_a;blah=blah;hello=tiger') # test path without tags parsed = TaggedSeries.parse('test.a') From 0209a3d5ccedff54de90db936355a861d055e5e3 Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Tue, 28 Nov 2017 10:55:54 -0500 Subject: [PATCH 2/2] add tagged series decode method --- webapp/graphite/tags/utils.py | 11 +++++++++++ webapp/tests/test_tags.py | 8 +++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/webapp/graphite/tags/utils.py b/webapp/graphite/tags/utils.py index d58515183..218087724 100644 --- a/webapp/graphite/tags/utils.py +++ b/webapp/graphite/tags/utils.py @@ -100,6 +100,17 @@ def encode(metric, sep='.'): # metric isn't tagged, just replace dots with the separator and trim any leading separator return metric.replace('.', sep).lstrip(sep) + @staticmethod + def decode(path, sep='.'): + """ + Helper function to decode tagged series from storage in whisper etc + """ + if path.startswith('_tagged'): + return path.split(sep, 3)[-1].replace('_DOT_', '.') + + # metric isn't tagged, just replace the separator with dots + return path.replace(sep, '.') + def __init__(self, metric, tags, series_id=None): self.metric = metric self.tags = tags diff --git a/webapp/tests/test_tags.py b/webapp/tests/test_tags.py index 4fcbc97db..6da3bdf5e 100644 --- a/webapp/tests/test_tags.py +++ b/webapp/tests/test_tags.py @@ -30,6 +30,9 @@ def test_taggedseries(self): # test encoding self.assertEqual(TaggedSeries.encode(parsed.path), '_tagged.2b0.2af.test_DOT_a;blah=blah;hello=tiger') + # test decoding + self.assertEqual(TaggedSeries.decode('_tagged.2b0.2af.test_DOT_a;blah=blah;hello=tiger'), parsed.path) + # test path without tags parsed = TaggedSeries.parse('test.a') self.assertIsInstance(parsed, TaggedSeries) @@ -40,7 +43,10 @@ def test_taggedseries(self): self.assertEqual(parsed.path, 'test.a') # test encoding - self.assertEqual(TaggedSeries.encode(parsed.path), 'test.a') + self.assertEqual(TaggedSeries.encode('test.a', sep='/'), 'test/a') + + # test encoding + self.assertEqual(TaggedSeries.decode('test/a', sep='/'), 'test.a') # test parsing openmetrics parsed = TaggedSeries.parse(r'test.a{hello="tiger",blah="bla\"h"}')