promtext-cli 0.1.2.dev97__tar.gz → 0.1.2.dev98__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/.copier-answers.yml +1 -1
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/PKG-INFO +1 -1
- promtext_cli-0.1.2.dev98/promtext_cli/main.py +12 -0
- promtext_cli-0.1.2.dev98/promtext_cli/promtext.py +182 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/pyproject.toml +2 -2
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/tests/test_functional.py +14 -18
- promtext_cli-0.1.2.dev97/promtext_cli/main.py +0 -152
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/.commitlintrc.yaml +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/.forgejo/workflows/commitlint.yaml +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/.forgejo/workflows/lint.yaml +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/.forgejo/workflows/publish.yaml +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/.forgejo/workflows/test.yaml +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/.gitignore +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/.pre-commit-config.yaml +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/README.md +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/cliff.toml +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/promtext_cli/__init__.py +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/renovate.json +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/tests/.gitkeep +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/tests/test_blackbox.py +0 -0
- {promtext_cli-0.1.2.dev97 → promtext_cli-0.1.2.dev98}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: promtext-cli
|
|
3
|
-
Version: 0.1.2.
|
|
3
|
+
Version: 0.1.2.dev98
|
|
4
4
|
Summary: Prometheus Textfile Tooling
|
|
5
5
|
Project-URL: Documentation, https://codeberg.org/margau/promtext-cli/src/branch/main#readme
|
|
6
6
|
Project-URL: Issues, https://codeberg.org/margau/promtext-cli/issues
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"""this is the module providing the core functionality"""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import logging
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from prometheus_client.parser import text_string_to_metric_families
|
|
9
|
+
from prometheus_client import CollectorRegistry, Gauge, write_to_textfile
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Promtext:
|
|
13
|
+
"""Class for the core functionality"""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
self.textfile = None
|
|
17
|
+
self.logger = None
|
|
18
|
+
self.args = None
|
|
19
|
+
self.registry = CollectorRegistry()
|
|
20
|
+
|
|
21
|
+
self.metrics = {}
|
|
22
|
+
|
|
23
|
+
def _arguments(self):
|
|
24
|
+
"""load every input item from arguments & define cli"""
|
|
25
|
+
# required file first
|
|
26
|
+
parser = argparse.ArgumentParser(description="Prometheus textfile helper")
|
|
27
|
+
parser.add_argument(
|
|
28
|
+
"filename",
|
|
29
|
+
type=str,
|
|
30
|
+
help="Path to existing or new prometheus textfile, will be updated",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# metric name, required
|
|
34
|
+
parser.add_argument("metric", type=str, help="metric name (new or updated)")
|
|
35
|
+
|
|
36
|
+
# metric value as int/float, required
|
|
37
|
+
parser.add_argument("value", type=float, help="metric value")
|
|
38
|
+
|
|
39
|
+
# metric documentation as optional argument
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"--docs",
|
|
42
|
+
type=str,
|
|
43
|
+
help="metric documentation",
|
|
44
|
+
default="metric appended by promtext-cli",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# labels, key-value, minimum 0, repeatable
|
|
48
|
+
parser.add_argument(
|
|
49
|
+
"--label",
|
|
50
|
+
metavar="KEY=VALUE",
|
|
51
|
+
help="label key=value pairs",
|
|
52
|
+
action="append",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# log level from argparse
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"-v",
|
|
58
|
+
"--verbose",
|
|
59
|
+
action="store_const",
|
|
60
|
+
dest="loglevel",
|
|
61
|
+
const=logging.INFO,
|
|
62
|
+
)
|
|
63
|
+
self.args = parser.parse_args()
|
|
64
|
+
|
|
65
|
+
# processing: check if file is available, if yes, parse
|
|
66
|
+
self.textfile = Path(self.args.filename)
|
|
67
|
+
|
|
68
|
+
def parse_file(self):
|
|
69
|
+
"""If possible, convert the input textfile to metrics in the registry"""
|
|
70
|
+
# check if self.args.filename exists with pathlib
|
|
71
|
+
if self.textfile.is_file():
|
|
72
|
+
for f in text_string_to_metric_families(
|
|
73
|
+
self.textfile.read_text(encoding="utf-8")
|
|
74
|
+
):
|
|
75
|
+
# per metric: iterate over samples, create metric in registry
|
|
76
|
+
m = False
|
|
77
|
+
samples = []
|
|
78
|
+
for s in f.samples:
|
|
79
|
+
samples.append(s)
|
|
80
|
+
if len(samples) > 0:
|
|
81
|
+
# if we have samples, use the labelnames from them
|
|
82
|
+
labelnames = list(samples[0].labels.keys())
|
|
83
|
+
# metric-type specific init
|
|
84
|
+
if f.type == "gauge":
|
|
85
|
+
m = Gauge(
|
|
86
|
+
f.name,
|
|
87
|
+
f.documentation,
|
|
88
|
+
unit=f.unit,
|
|
89
|
+
labelnames=labelnames,
|
|
90
|
+
registry=self.registry,
|
|
91
|
+
)
|
|
92
|
+
else:
|
|
93
|
+
# we don't support other types yet, continue in these cases
|
|
94
|
+
self.logger.warning(
|
|
95
|
+
"unsupported metric type %s, dropping", f.type
|
|
96
|
+
)
|
|
97
|
+
continue
|
|
98
|
+
for s in samples:
|
|
99
|
+
if len(labelnames) > 0:
|
|
100
|
+
labelvalues = list(s.labels.values())
|
|
101
|
+
m.labels(*labelvalues).set(s.value)
|
|
102
|
+
else:
|
|
103
|
+
m.set(s.value)
|
|
104
|
+
self.metrics[f.name] = m
|
|
105
|
+
self.logger.info(
|
|
106
|
+
"copy gauge metric %s with labels %s from old file",
|
|
107
|
+
f.name,
|
|
108
|
+
", ".join(labelnames),
|
|
109
|
+
)
|
|
110
|
+
else:
|
|
111
|
+
self.logger.warning(
|
|
112
|
+
"got empty metric %s from old file, dropping", f.name
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
def _build_metrics(self):
|
|
116
|
+
# add new metric from commandline
|
|
117
|
+
m = False
|
|
118
|
+
|
|
119
|
+
# figure out labelkey- and values
|
|
120
|
+
labels = {}
|
|
121
|
+
if self.args.label:
|
|
122
|
+
for lpair in self.args.label:
|
|
123
|
+
k, v = lpair.split("=")
|
|
124
|
+
labels[k] = v
|
|
125
|
+
|
|
126
|
+
labelvalues = []
|
|
127
|
+
# here, we use a new metric
|
|
128
|
+
if self.args.metric not in self.metrics:
|
|
129
|
+
self.logger.info("adding new metric %s", self.args.metric)
|
|
130
|
+
m = Gauge(
|
|
131
|
+
self.args.metric,
|
|
132
|
+
self.args.docs,
|
|
133
|
+
registry=self.registry,
|
|
134
|
+
labelnames=labels.keys(),
|
|
135
|
+
)
|
|
136
|
+
labelvalues = labels.values()
|
|
137
|
+
else:
|
|
138
|
+
m = self.metrics[self.args.metric]
|
|
139
|
+
|
|
140
|
+
# There is no way to access existing labelnames directly
|
|
141
|
+
# pylint: disable=W0212
|
|
142
|
+
old_labelnames = list(m._labelnames)
|
|
143
|
+
for la in old_labelnames:
|
|
144
|
+
self.logger.info("processing label %s", la)
|
|
145
|
+
if la in labels: # labelvalues are needed in order!
|
|
146
|
+
labelvalues.append(labels[la])
|
|
147
|
+
else:
|
|
148
|
+
self.logger.error(
|
|
149
|
+
"previously known label '%s' missing, cannot update!", la
|
|
150
|
+
)
|
|
151
|
+
sys.exit(1)
|
|
152
|
+
if len(old_labelnames) != len(labels.keys()):
|
|
153
|
+
self.logger.error(
|
|
154
|
+
"labelnames for metric %s not the same, cannot update! Old: %s, New: %s",
|
|
155
|
+
self.args.metric,
|
|
156
|
+
old_labelnames,
|
|
157
|
+
list(labels.keys()),
|
|
158
|
+
)
|
|
159
|
+
sys.exit(1)
|
|
160
|
+
self.logger.info("updating metric %s", self.args.metric)
|
|
161
|
+
|
|
162
|
+
# actually set the value
|
|
163
|
+
if len(labelvalues) > 0:
|
|
164
|
+
m.labels(*labelvalues).set(self.args.value)
|
|
165
|
+
else:
|
|
166
|
+
m.set(self.args.value)
|
|
167
|
+
|
|
168
|
+
def output_file(self):
|
|
169
|
+
"""Output to a textfile"""
|
|
170
|
+
write_to_textfile(self.textfile, self.registry)
|
|
171
|
+
self.logger.info("wrote to %s", self.textfile)
|
|
172
|
+
|
|
173
|
+
def cli_entrypoint(self):
|
|
174
|
+
"""Main method called from the CLI"""
|
|
175
|
+
self._arguments()
|
|
176
|
+
|
|
177
|
+
logging.basicConfig(level=self.args.loglevel)
|
|
178
|
+
self.logger = logging.getLogger(__name__)
|
|
179
|
+
|
|
180
|
+
self.parse_file()
|
|
181
|
+
self._build_metrics()
|
|
182
|
+
self.output_file()
|
|
@@ -28,7 +28,7 @@ Source = "https://codeberg.org/margau/promtext-cli.git"
|
|
|
28
28
|
|
|
29
29
|
# Scripts
|
|
30
30
|
[project.scripts]
|
|
31
|
-
promtext = "promtext_cli.main
|
|
31
|
+
promtext = "promtext_cli:main.main"
|
|
32
32
|
|
|
33
33
|
[dependency-groups]
|
|
34
34
|
dev = [
|
|
@@ -43,6 +43,6 @@ dev = [
|
|
|
43
43
|
cache-keys = [{ file = "pyproject.toml" }, { git = { commit = true, tags = true } }]
|
|
44
44
|
|
|
45
45
|
[tool.coverage.run]
|
|
46
|
-
source = ["
|
|
46
|
+
source = ["promtext_cli", "tests"]
|
|
47
47
|
|
|
48
48
|
# TODO: Dev/CI scripts for lint & co.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
from cli_test_helpers import ArgvContext
|
|
5
5
|
import pytest
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
from promtext_cli.main import main as promtext_main
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def test_new_file(tmp_path):
|
|
@@ -13,7 +13,7 @@ def test_new_file(tmp_path):
|
|
|
13
13
|
"""
|
|
14
14
|
promfile = tmp_path / "new_file.prom"
|
|
15
15
|
with ArgvContext("promtext", str(promfile), "test_metric", "0"):
|
|
16
|
-
|
|
16
|
+
promtext_main()
|
|
17
17
|
assert promfile.exists()
|
|
18
18
|
assert promfile.read_text() == (
|
|
19
19
|
"# HELP test_metric metric appended by promtext-cli"
|
|
@@ -33,7 +33,7 @@ def test_labels(tmp_path):
|
|
|
33
33
|
with ArgvContext(
|
|
34
34
|
"promtext", "--label", "testlabel=testvalue", str(promfile), "test_metric", 0
|
|
35
35
|
):
|
|
36
|
-
|
|
36
|
+
promtext_main()
|
|
37
37
|
assert promfile.exists()
|
|
38
38
|
assert promfile.read_text() == (
|
|
39
39
|
"# HELP test_metric metric appended by promtext-cli"
|
|
@@ -62,7 +62,7 @@ def test_existing_metric_append_metric(tmp_path):
|
|
|
62
62
|
with ArgvContext(
|
|
63
63
|
"promtext", "--label", "testlabel=testvalue", str(promfile), "new_metric", 0
|
|
64
64
|
):
|
|
65
|
-
|
|
65
|
+
promtext_main()
|
|
66
66
|
assert promfile.exists()
|
|
67
67
|
assert promfile.read_text() == (
|
|
68
68
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -97,7 +97,7 @@ def test_existing_metric_append_labelvalue(tmp_path):
|
|
|
97
97
|
with ArgvContext(
|
|
98
98
|
"promtext", "--label", "testlabel=new", str(promfile), "existing_metric", 0
|
|
99
99
|
):
|
|
100
|
-
|
|
100
|
+
promtext_main()
|
|
101
101
|
assert promfile.exists()
|
|
102
102
|
assert promfile.read_text() == (
|
|
103
103
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -135,7 +135,7 @@ def test_existing_metric_multilabel(tmp_path):
|
|
|
135
135
|
"existing_metric",
|
|
136
136
|
"42",
|
|
137
137
|
):
|
|
138
|
-
|
|
138
|
+
promtext_main()
|
|
139
139
|
assert promfile.exists()
|
|
140
140
|
assert promfile.read_text() == (
|
|
141
141
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -170,7 +170,7 @@ def test_existing_metric_overwrite(tmp_path):
|
|
|
170
170
|
"existing_metric",
|
|
171
171
|
"42",
|
|
172
172
|
):
|
|
173
|
-
|
|
173
|
+
promtext_main()
|
|
174
174
|
assert promfile.exists()
|
|
175
175
|
assert promfile.read_text() == (
|
|
176
176
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -196,7 +196,7 @@ def test_existing_metric_plain(tmp_path):
|
|
|
196
196
|
"\n"
|
|
197
197
|
)
|
|
198
198
|
with ArgvContext("promtext", str(promfile), "existing_metric", "42"):
|
|
199
|
-
|
|
199
|
+
promtext_main()
|
|
200
200
|
assert promfile.exists()
|
|
201
201
|
assert promfile.read_text() == (
|
|
202
202
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -226,7 +226,7 @@ def test_existing_metric_labeldrop(tmp_path, capsys):
|
|
|
226
226
|
ArgvContext("promtext", str(promfile), "existing_metric", "42"),
|
|
227
227
|
pytest.raises(SystemExit) as pytest_wrapped_e,
|
|
228
228
|
):
|
|
229
|
-
|
|
229
|
+
promtext_main()
|
|
230
230
|
assert promfile.exists()
|
|
231
231
|
assert promfile.read_text() == (
|
|
232
232
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -240,10 +240,7 @@ def test_existing_metric_labeldrop(tmp_path, capsys):
|
|
|
240
240
|
assert pytest_wrapped_e.type is SystemExit
|
|
241
241
|
assert pytest_wrapped_e.value.code == 1
|
|
242
242
|
captured = capsys.readouterr()
|
|
243
|
-
assert
|
|
244
|
-
"ERROR:promtext_cli.main:previously known label 'testlabel' missing, cannot update!"
|
|
245
|
-
in captured.err
|
|
246
|
-
)
|
|
243
|
+
assert "previously known label 'testlabel' missing, cannot update!" in captured.err
|
|
247
244
|
|
|
248
245
|
|
|
249
246
|
def test_existing_metric_labelchange(tmp_path, capsys):
|
|
@@ -271,7 +268,7 @@ def test_existing_metric_labelchange(tmp_path, capsys):
|
|
|
271
268
|
),
|
|
272
269
|
pytest.raises(SystemExit) as pytest_wrapped_e,
|
|
273
270
|
):
|
|
274
|
-
|
|
271
|
+
promtext_main()
|
|
275
272
|
assert promfile.exists()
|
|
276
273
|
assert promfile.read_text() == (
|
|
277
274
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -286,8 +283,7 @@ def test_existing_metric_labelchange(tmp_path, capsys):
|
|
|
286
283
|
assert pytest_wrapped_e.value.code == 1
|
|
287
284
|
captured = capsys.readouterr()
|
|
288
285
|
assert (
|
|
289
|
-
"
|
|
290
|
-
in captured.err
|
|
286
|
+
"previously known label 'existinglabel' missing, cannot update!" in captured.err
|
|
291
287
|
)
|
|
292
288
|
|
|
293
289
|
|
|
@@ -318,7 +314,7 @@ def test_existing_metric_labeladd(tmp_path, capsys):
|
|
|
318
314
|
),
|
|
319
315
|
pytest.raises(SystemExit) as pytest_wrapped_e,
|
|
320
316
|
):
|
|
321
|
-
|
|
317
|
+
promtext_main()
|
|
322
318
|
assert promfile.exists()
|
|
323
319
|
assert promfile.read_text() == (
|
|
324
320
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -333,7 +329,7 @@ def test_existing_metric_labeladd(tmp_path, capsys):
|
|
|
333
329
|
assert pytest_wrapped_e.value.code == 1
|
|
334
330
|
captured = capsys.readouterr()
|
|
335
331
|
assert (
|
|
336
|
-
"
|
|
332
|
+
"labelnames for metric existing_metric not the same, cannot update"
|
|
337
333
|
in captured.err
|
|
338
334
|
)
|
|
339
335
|
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"""promtext_cli is providing a CLI to cleanly update prometheus textfiles from scripts"""
|
|
2
|
-
|
|
3
|
-
# pylint: disable=C0116,R0914,R0912,R0915
|
|
4
|
-
# this rules will be fixed by a object-oriented refactoring
|
|
5
|
-
|
|
6
|
-
import argparse
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
import logging
|
|
9
|
-
import sys
|
|
10
|
-
|
|
11
|
-
from prometheus_client.parser import text_string_to_metric_families
|
|
12
|
-
from prometheus_client import CollectorRegistry, Gauge, write_to_textfile
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def promtext():
|
|
16
|
-
# setup argpars
|
|
17
|
-
# required file first
|
|
18
|
-
parser = argparse.ArgumentParser(description="Prometheus textfile helper")
|
|
19
|
-
parser.add_argument(
|
|
20
|
-
"filename",
|
|
21
|
-
type=str,
|
|
22
|
-
help="Path to existing or new prometheus textfile, will be updated",
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
# metric name, required
|
|
26
|
-
parser.add_argument("metric", type=str, help="metric name (new or updated)")
|
|
27
|
-
|
|
28
|
-
# metric value as int/float, required
|
|
29
|
-
parser.add_argument("value", type=float, help="metric value")
|
|
30
|
-
|
|
31
|
-
# metric documentation as optional argument
|
|
32
|
-
parser.add_argument(
|
|
33
|
-
"--docs",
|
|
34
|
-
type=str,
|
|
35
|
-
help="metric documentation",
|
|
36
|
-
default="metric appended by promtext-cli",
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
# labels, key-value, minimum 0, repeatable
|
|
40
|
-
parser.add_argument(
|
|
41
|
-
"--label", metavar="KEY=VALUE", help="label key=value pairs", action="append"
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
# log level from argparse
|
|
45
|
-
parser.add_argument(
|
|
46
|
-
"-v",
|
|
47
|
-
"--verbose",
|
|
48
|
-
action="store_const",
|
|
49
|
-
dest="loglevel",
|
|
50
|
-
const=logging.INFO,
|
|
51
|
-
)
|
|
52
|
-
args = parser.parse_args()
|
|
53
|
-
logging.basicConfig(level=args.loglevel)
|
|
54
|
-
logger = logging.getLogger(__name__)
|
|
55
|
-
|
|
56
|
-
# processing: check if file is available, if yes, parse
|
|
57
|
-
textfile = Path(args.filename)
|
|
58
|
-
|
|
59
|
-
registry = CollectorRegistry()
|
|
60
|
-
metrics = {}
|
|
61
|
-
|
|
62
|
-
# check if args.filename exists with pathlib
|
|
63
|
-
if textfile.is_file():
|
|
64
|
-
for f in text_string_to_metric_families(textfile.read_text(encoding="utf-8")):
|
|
65
|
-
# per metric: iterate over samples, create metric in registry
|
|
66
|
-
m = False
|
|
67
|
-
samples = []
|
|
68
|
-
for s in f.samples:
|
|
69
|
-
samples.append(s)
|
|
70
|
-
if len(samples) > 0:
|
|
71
|
-
# if we have samples, use the labelnames from them
|
|
72
|
-
labelnames = list(samples[0].labels.keys())
|
|
73
|
-
# metric-type specific init
|
|
74
|
-
if f.type == "gauge":
|
|
75
|
-
m = Gauge(
|
|
76
|
-
f.name,
|
|
77
|
-
f.documentation,
|
|
78
|
-
unit=f.unit,
|
|
79
|
-
labelnames=labelnames,
|
|
80
|
-
registry=registry,
|
|
81
|
-
)
|
|
82
|
-
else:
|
|
83
|
-
# we don't support other types yet, continue in these cases
|
|
84
|
-
logger.warning("unsupported metric type %s, dropping", f.type)
|
|
85
|
-
continue
|
|
86
|
-
for s in samples:
|
|
87
|
-
if len(labelnames) > 0:
|
|
88
|
-
labelvalues = list(s.labels.values())
|
|
89
|
-
m.labels(*labelvalues).set(s.value)
|
|
90
|
-
else:
|
|
91
|
-
m.set(s.value)
|
|
92
|
-
metrics[f.name] = m
|
|
93
|
-
logger.info(
|
|
94
|
-
"copy gauge metric %s with labels %s from old file",
|
|
95
|
-
f.name,
|
|
96
|
-
", ".join(labelnames),
|
|
97
|
-
)
|
|
98
|
-
else:
|
|
99
|
-
logger.warning("got empty metric %s from old file, dropping", f.name)
|
|
100
|
-
|
|
101
|
-
# add new metric from commandline
|
|
102
|
-
m = False
|
|
103
|
-
|
|
104
|
-
# figure out labelkey- and values
|
|
105
|
-
labels = {}
|
|
106
|
-
if args.label:
|
|
107
|
-
for lpair in args.label:
|
|
108
|
-
k, v = lpair.split("=")
|
|
109
|
-
labels[k] = v
|
|
110
|
-
|
|
111
|
-
labelvalues = []
|
|
112
|
-
# here, we use a new metric
|
|
113
|
-
if args.metric not in metrics:
|
|
114
|
-
logger.info("adding new metric %s", args.metric)
|
|
115
|
-
m = Gauge(args.metric, args.docs, registry=registry, labelnames=labels.keys())
|
|
116
|
-
labelvalues = labels.values()
|
|
117
|
-
else:
|
|
118
|
-
m = metrics[args.metric]
|
|
119
|
-
|
|
120
|
-
# There is no way to access existing labelnames directly
|
|
121
|
-
# pylint: disable=W0212
|
|
122
|
-
old_labelnames = list(m._labelnames)
|
|
123
|
-
for la in old_labelnames:
|
|
124
|
-
logger.info("processing label %s", la)
|
|
125
|
-
if la in labels: # labelvalues are needed in order!
|
|
126
|
-
labelvalues.append(labels[la])
|
|
127
|
-
else:
|
|
128
|
-
logger.error("previously known label '%s' missing, cannot update!", la)
|
|
129
|
-
sys.exit(1)
|
|
130
|
-
if len(old_labelnames) != len(labels.keys()):
|
|
131
|
-
logger.error(
|
|
132
|
-
"labelnames for metric %s not the same, cannot update! Old: %s, New: %s",
|
|
133
|
-
args.metric,
|
|
134
|
-
old_labelnames,
|
|
135
|
-
list(labels.keys()),
|
|
136
|
-
)
|
|
137
|
-
sys.exit(1)
|
|
138
|
-
logger.info("updating metric %s", args.metric)
|
|
139
|
-
|
|
140
|
-
# actually set the value
|
|
141
|
-
if len(labelvalues) > 0:
|
|
142
|
-
m.labels(*labelvalues).set(args.value)
|
|
143
|
-
else:
|
|
144
|
-
m.set(args.value)
|
|
145
|
-
|
|
146
|
-
# write to file
|
|
147
|
-
write_to_textfile(args.filename, registry)
|
|
148
|
-
logger.info("wrote to %s", args.filename)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if __name__ == "__main__":
|
|
152
|
-
promtext()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|