promtext-cli 0.1.2.dev98__tar.gz → 0.1.2.dev100__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.dev98 → promtext_cli-0.1.2.dev100}/.copier-answers.yml +1 -1
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/.pre-commit-config.yaml +1 -1
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/PKG-INFO +1 -1
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/promtext_cli/main.py +2 -2
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/promtext_cli/promtext.py +15 -13
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/pyproject.toml +22 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/tests/test_blackbox.py +6 -13
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/tests/test_functional.py +38 -40
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/.commitlintrc.yaml +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/.forgejo/workflows/commitlint.yaml +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/.forgejo/workflows/lint.yaml +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/.forgejo/workflows/publish.yaml +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/.forgejo/workflows/test.yaml +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/.gitignore +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/README.md +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/cliff.toml +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/promtext_cli/__init__.py +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/renovate.json +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/tests/.gitkeep +0 -0
- {promtext_cli-0.1.2.dev98 → promtext_cli-0.1.2.dev100}/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.dev100
|
|
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
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""module providing the core functionality"""
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
|
-
from pathlib import Path
|
|
5
4
|
import logging
|
|
6
5
|
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
7
|
|
|
8
|
-
from prometheus_client.parser import text_string_to_metric_families
|
|
9
8
|
from prometheus_client import CollectorRegistry, Gauge, write_to_textfile
|
|
9
|
+
from prometheus_client.parser import text_string_to_metric_families
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class Promtext:
|
|
@@ -21,7 +21,7 @@ class Promtext:
|
|
|
21
21
|
self.metrics = {}
|
|
22
22
|
|
|
23
23
|
def _arguments(self):
|
|
24
|
-
"""
|
|
24
|
+
"""Load every input item from arguments & define cli"""
|
|
25
25
|
# required file first
|
|
26
26
|
parser = argparse.ArgumentParser(description="Prometheus textfile helper")
|
|
27
27
|
parser.add_argument(
|
|
@@ -70,13 +70,11 @@ class Promtext:
|
|
|
70
70
|
# check if self.args.filename exists with pathlib
|
|
71
71
|
if self.textfile.is_file():
|
|
72
72
|
for f in text_string_to_metric_families(
|
|
73
|
-
self.textfile.read_text(encoding="utf-8")
|
|
73
|
+
self.textfile.read_text(encoding="utf-8"),
|
|
74
74
|
):
|
|
75
75
|
# per metric: iterate over samples, create metric in registry
|
|
76
76
|
m = False
|
|
77
|
-
samples =
|
|
78
|
-
for s in f.samples:
|
|
79
|
-
samples.append(s)
|
|
77
|
+
samples = list(f.samples)
|
|
80
78
|
if len(samples) > 0:
|
|
81
79
|
# if we have samples, use the labelnames from them
|
|
82
80
|
labelnames = list(samples[0].labels.keys())
|
|
@@ -92,7 +90,8 @@ class Promtext:
|
|
|
92
90
|
else:
|
|
93
91
|
# we don't support other types yet, continue in these cases
|
|
94
92
|
self.logger.warning(
|
|
95
|
-
"unsupported metric type %s, dropping",
|
|
93
|
+
"unsupported metric type %s, dropping",
|
|
94
|
+
f.type,
|
|
96
95
|
)
|
|
97
96
|
continue
|
|
98
97
|
for s in samples:
|
|
@@ -109,7 +108,8 @@ class Promtext:
|
|
|
109
108
|
)
|
|
110
109
|
else:
|
|
111
110
|
self.logger.warning(
|
|
112
|
-
"got empty metric %s from old file, dropping",
|
|
111
|
+
"got empty metric %s from old file, dropping",
|
|
112
|
+
f.name,
|
|
113
113
|
)
|
|
114
114
|
|
|
115
115
|
def _build_metrics(self):
|
|
@@ -139,19 +139,21 @@ class Promtext:
|
|
|
139
139
|
|
|
140
140
|
# There is no way to access existing labelnames directly
|
|
141
141
|
# pylint: disable=W0212
|
|
142
|
-
old_labelnames = list(m._labelnames)
|
|
142
|
+
old_labelnames = list(m._labelnames) # noqa: SLF001
|
|
143
143
|
for la in old_labelnames:
|
|
144
144
|
self.logger.info("processing label %s", la)
|
|
145
145
|
if la in labels: # labelvalues are needed in order!
|
|
146
146
|
labelvalues.append(labels[la])
|
|
147
147
|
else:
|
|
148
148
|
self.logger.error(
|
|
149
|
-
"previously known label '%s' missing, cannot update!",
|
|
149
|
+
"previously known label '%s' missing, cannot update!",
|
|
150
|
+
la,
|
|
150
151
|
)
|
|
151
152
|
sys.exit(1)
|
|
152
153
|
if len(old_labelnames) != len(labels.keys()):
|
|
153
154
|
self.logger.error(
|
|
154
|
-
"labelnames for metric %s not the same, cannot update!
|
|
155
|
+
"""labelnames for metric %s not the same, cannot update!
|
|
156
|
+
Old: %s, New: %s""",
|
|
155
157
|
self.args.metric,
|
|
156
158
|
old_labelnames,
|
|
157
159
|
list(labels.keys()),
|
|
@@ -45,4 +45,26 @@ cache-keys = [{ file = "pyproject.toml" }, { git = { commit = true, tags = true
|
|
|
45
45
|
[tool.coverage.run]
|
|
46
46
|
source = ["promtext_cli", "tests"]
|
|
47
47
|
|
|
48
|
+
[tool.ruff.lint]
|
|
49
|
+
select = ["ALL"]
|
|
50
|
+
ignore = [
|
|
51
|
+
"D104",
|
|
52
|
+
"D107",
|
|
53
|
+
"D200",
|
|
54
|
+
"D203",
|
|
55
|
+
"D205",
|
|
56
|
+
"D213",
|
|
57
|
+
"D400",
|
|
58
|
+
"D401",
|
|
59
|
+
"D415", # TODO: Remove later
|
|
60
|
+
"FIX002", # TODO: Remove later
|
|
61
|
+
"TD002", # TODO: Remove later
|
|
62
|
+
"TD003", # TODO: Remove later
|
|
63
|
+
"ANN", # TODO: Remove later
|
|
64
|
+
"COM812",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint.per-file-ignores]
|
|
68
|
+
"tests/**.py" = ["S101", "INP001", "PLR2004"]
|
|
69
|
+
|
|
48
70
|
# TODO: Dev/CI scripts for lint & co.
|
|
@@ -1,39 +1,32 @@
|
|
|
1
1
|
# pylint: disable=R0801
|
|
2
|
-
"""
|
|
2
|
+
"""Blackbox-like testing of the promtext cli tool"""
|
|
3
3
|
|
|
4
4
|
import shutil
|
|
5
|
+
|
|
5
6
|
from cli_test_helpers import shell
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
def test_entrypoint():
|
|
9
|
-
"""
|
|
10
|
-
Is entrypoint script installed? (pyproject.toml)
|
|
11
|
-
"""
|
|
10
|
+
"""Is entrypoint script installed? (pyproject.toml)"""
|
|
12
11
|
assert shutil.which("promtext")
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
def test_help():
|
|
16
|
-
"""
|
|
17
|
-
Does the help command work?
|
|
18
|
-
"""
|
|
15
|
+
"""Does the help command work?"""
|
|
19
16
|
result = shell("promtext --help")
|
|
20
17
|
assert result.exit_code == 0
|
|
21
18
|
assert "usage:" in result.stdout
|
|
22
19
|
|
|
23
20
|
|
|
24
21
|
def test_empty():
|
|
25
|
-
"""
|
|
26
|
-
Does the command fails with no arguments?
|
|
27
|
-
"""
|
|
22
|
+
"""Does the command fails with no arguments?"""
|
|
28
23
|
result = shell("promtext")
|
|
29
24
|
assert result.exit_code == 2
|
|
30
25
|
assert "usage:" in result.stderr
|
|
31
26
|
|
|
32
27
|
|
|
33
28
|
def test_new_file(tmp_path):
|
|
34
|
-
"""
|
|
35
|
-
Does the command create a new file with metrics content?
|
|
36
|
-
"""
|
|
29
|
+
"""Does the command create a new file with metrics content?"""
|
|
37
30
|
promfile = tmp_path / "new_file.prom"
|
|
38
31
|
result = shell(f"promtext {promfile} test_metric 0")
|
|
39
32
|
assert result.exit_code == 0
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# pylint: disable=R0801,W0511
|
|
2
|
-
"""
|
|
2
|
+
"""Functional testing by calling the methods directly"""
|
|
3
3
|
|
|
4
|
-
from cli_test_helpers import ArgvContext
|
|
5
4
|
import pytest
|
|
5
|
+
from cli_test_helpers import ArgvContext
|
|
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):
|
|
11
|
-
"""
|
|
12
|
-
Does the command create a new file with metrics content?
|
|
13
|
-
"""
|
|
11
|
+
"""Does the command create a new file with metrics content?"""
|
|
14
12
|
promfile = tmp_path / "new_file.prom"
|
|
15
13
|
with ArgvContext("promtext", str(promfile), "test_metric", "0"):
|
|
16
14
|
promtext_main()
|
|
@@ -26,12 +24,15 @@ def test_new_file(tmp_path):
|
|
|
26
24
|
|
|
27
25
|
|
|
28
26
|
def test_labels(tmp_path):
|
|
29
|
-
"""
|
|
30
|
-
Does the command create a new file with metrics content?
|
|
31
|
-
"""
|
|
27
|
+
"""Does the command create a new file with metrics content?"""
|
|
32
28
|
promfile = tmp_path / "label_file.prom"
|
|
33
29
|
with ArgvContext(
|
|
34
|
-
"promtext",
|
|
30
|
+
"promtext",
|
|
31
|
+
"--label",
|
|
32
|
+
"testlabel=testvalue",
|
|
33
|
+
str(promfile),
|
|
34
|
+
"test_metric",
|
|
35
|
+
0,
|
|
35
36
|
):
|
|
36
37
|
promtext_main()
|
|
37
38
|
assert promfile.exists()
|
|
@@ -46,8 +47,7 @@ def test_labels(tmp_path):
|
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
def test_existing_metric_append_metric(tmp_path):
|
|
49
|
-
"""
|
|
50
|
-
Does the command append a new metric to an existing file
|
|
50
|
+
"""Does the command append a new metric to an existing file
|
|
51
51
|
with metrics content and preserve existing metrics?
|
|
52
52
|
"""
|
|
53
53
|
promfile = tmp_path / "existing_file.prom"
|
|
@@ -57,10 +57,15 @@ def test_existing_metric_append_metric(tmp_path):
|
|
|
57
57
|
"# TYPE existing_metric gauge"
|
|
58
58
|
"\n"
|
|
59
59
|
'existing_metric{testlabel="testvalue"} 0.0'
|
|
60
|
-
"\n"
|
|
60
|
+
"\n",
|
|
61
61
|
)
|
|
62
62
|
with ArgvContext(
|
|
63
|
-
"promtext",
|
|
63
|
+
"promtext",
|
|
64
|
+
"--label",
|
|
65
|
+
"testlabel=testvalue",
|
|
66
|
+
str(promfile),
|
|
67
|
+
"new_metric",
|
|
68
|
+
0,
|
|
64
69
|
):
|
|
65
70
|
promtext_main()
|
|
66
71
|
assert promfile.exists()
|
|
@@ -81,8 +86,7 @@ def test_existing_metric_append_metric(tmp_path):
|
|
|
81
86
|
|
|
82
87
|
|
|
83
88
|
def test_existing_metric_append_labelvalue(tmp_path):
|
|
84
|
-
"""
|
|
85
|
-
Does the command append a new metric to an existing file
|
|
89
|
+
"""Does the command append a new metric to an existing file
|
|
86
90
|
with metrics content and preserve existing metrics?
|
|
87
91
|
"""
|
|
88
92
|
promfile = tmp_path / "existing_file.prom"
|
|
@@ -92,10 +96,15 @@ def test_existing_metric_append_labelvalue(tmp_path):
|
|
|
92
96
|
"# TYPE existing_metric gauge"
|
|
93
97
|
"\n"
|
|
94
98
|
'existing_metric{testlabel="existing"} 0.0'
|
|
95
|
-
"\n"
|
|
99
|
+
"\n",
|
|
96
100
|
)
|
|
97
101
|
with ArgvContext(
|
|
98
|
-
"promtext",
|
|
102
|
+
"promtext",
|
|
103
|
+
"--label",
|
|
104
|
+
"testlabel=new",
|
|
105
|
+
str(promfile),
|
|
106
|
+
"existing_metric",
|
|
107
|
+
0,
|
|
99
108
|
):
|
|
100
109
|
promtext_main()
|
|
101
110
|
assert promfile.exists()
|
|
@@ -112,8 +121,7 @@ def test_existing_metric_append_labelvalue(tmp_path):
|
|
|
112
121
|
|
|
113
122
|
|
|
114
123
|
def test_existing_metric_multilabel(tmp_path):
|
|
115
|
-
"""
|
|
116
|
-
Does the command append a new metric to an existing file
|
|
124
|
+
"""Does the command append a new metric to an existing file
|
|
117
125
|
with metrics content and preserve existing metrics?
|
|
118
126
|
"""
|
|
119
127
|
promfile = tmp_path / "existing_file.prom"
|
|
@@ -123,7 +131,7 @@ def test_existing_metric_multilabel(tmp_path):
|
|
|
123
131
|
"# TYPE existing_metric gauge"
|
|
124
132
|
"\n"
|
|
125
133
|
'existing_metric{first="existing", second="existing"} 0.0'
|
|
126
|
-
"\n"
|
|
134
|
+
"\n",
|
|
127
135
|
)
|
|
128
136
|
with ArgvContext(
|
|
129
137
|
"promtext",
|
|
@@ -150,9 +158,7 @@ def test_existing_metric_multilabel(tmp_path):
|
|
|
150
158
|
|
|
151
159
|
|
|
152
160
|
def test_existing_metric_overwrite(tmp_path):
|
|
153
|
-
"""
|
|
154
|
-
Does the command overwrite a metric/labelset
|
|
155
|
-
"""
|
|
161
|
+
"""Does the command overwrite a metric/labelset"""
|
|
156
162
|
promfile = tmp_path / "existing_file.prom"
|
|
157
163
|
promfile.write_text(
|
|
158
164
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -160,7 +166,7 @@ def test_existing_metric_overwrite(tmp_path):
|
|
|
160
166
|
"# TYPE existing_metric gauge"
|
|
161
167
|
"\n"
|
|
162
168
|
'existing_metric{testlabel="existing"} 0.0'
|
|
163
|
-
"\n"
|
|
169
|
+
"\n",
|
|
164
170
|
)
|
|
165
171
|
with ArgvContext(
|
|
166
172
|
"promtext",
|
|
@@ -183,9 +189,7 @@ def test_existing_metric_overwrite(tmp_path):
|
|
|
183
189
|
|
|
184
190
|
|
|
185
191
|
def test_existing_metric_plain(tmp_path):
|
|
186
|
-
"""
|
|
187
|
-
Does the command overwrite a metric without a label?
|
|
188
|
-
"""
|
|
192
|
+
"""Does the command overwrite a metric without a label?"""
|
|
189
193
|
promfile = tmp_path / "existing_file.prom"
|
|
190
194
|
promfile.write_text(
|
|
191
195
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -193,7 +197,7 @@ def test_existing_metric_plain(tmp_path):
|
|
|
193
197
|
"# TYPE existing_metric gauge"
|
|
194
198
|
"\n"
|
|
195
199
|
"existing_metric 0.0"
|
|
196
|
-
"\n"
|
|
200
|
+
"\n",
|
|
197
201
|
)
|
|
198
202
|
with ArgvContext("promtext", str(promfile), "existing_metric", "42"):
|
|
199
203
|
promtext_main()
|
|
@@ -209,9 +213,7 @@ def test_existing_metric_plain(tmp_path):
|
|
|
209
213
|
|
|
210
214
|
|
|
211
215
|
def test_existing_metric_labeldrop(tmp_path, capsys):
|
|
212
|
-
"""
|
|
213
|
-
missing labels are not possible, promtext should fail
|
|
214
|
-
"""
|
|
216
|
+
"""Missing labels are not possible, promtext should fail"""
|
|
215
217
|
promfile = tmp_path / "existing_file.prom"
|
|
216
218
|
promfile.write_text(
|
|
217
219
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -219,7 +221,7 @@ def test_existing_metric_labeldrop(tmp_path, capsys):
|
|
|
219
221
|
"# TYPE existing_metric gauge"
|
|
220
222
|
"\n"
|
|
221
223
|
'existing_metric{testlabel="existing"} 0.0'
|
|
222
|
-
"\n"
|
|
224
|
+
"\n",
|
|
223
225
|
)
|
|
224
226
|
|
|
225
227
|
with (
|
|
@@ -244,9 +246,7 @@ def test_existing_metric_labeldrop(tmp_path, capsys):
|
|
|
244
246
|
|
|
245
247
|
|
|
246
248
|
def test_existing_metric_labelchange(tmp_path, capsys):
|
|
247
|
-
"""
|
|
248
|
-
changing labels are not possible, promtext should fail
|
|
249
|
-
"""
|
|
249
|
+
"""Changing labels are not possible, promtext should fail"""
|
|
250
250
|
promfile = tmp_path / "existing_file.prom"
|
|
251
251
|
promfile.write_text(
|
|
252
252
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -254,7 +254,7 @@ def test_existing_metric_labelchange(tmp_path, capsys):
|
|
|
254
254
|
"# TYPE existing_metric gauge"
|
|
255
255
|
"\n"
|
|
256
256
|
'existing_metric{existinglabel="existing"} 0.0'
|
|
257
|
-
"\n"
|
|
257
|
+
"\n",
|
|
258
258
|
)
|
|
259
259
|
|
|
260
260
|
with (
|
|
@@ -288,9 +288,7 @@ def test_existing_metric_labelchange(tmp_path, capsys):
|
|
|
288
288
|
|
|
289
289
|
|
|
290
290
|
def test_existing_metric_labeladd(tmp_path, capsys):
|
|
291
|
-
"""
|
|
292
|
-
adding new labels are not possible, promtext should fail
|
|
293
|
-
"""
|
|
291
|
+
"""Adding new labels are not possible, promtext should fail"""
|
|
294
292
|
promfile = tmp_path / "existing_file.prom"
|
|
295
293
|
promfile.write_text(
|
|
296
294
|
"# HELP existing_metric metric appended by promtext-cli"
|
|
@@ -298,7 +296,7 @@ def test_existing_metric_labeladd(tmp_path, capsys):
|
|
|
298
296
|
"# TYPE existing_metric gauge"
|
|
299
297
|
"\n"
|
|
300
298
|
'existing_metric{existinglabel="existing"} 0.0'
|
|
301
|
-
"\n"
|
|
299
|
+
"\n",
|
|
302
300
|
)
|
|
303
301
|
|
|
304
302
|
with (
|
|
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
|