sydost-tracekit 0.0.1__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.
Files changed (58) hide show
  1. sydost_tracekit-0.0.1/CHANGELOG.md +30 -0
  2. sydost_tracekit-0.0.1/CITATION.cff +36 -0
  3. sydost_tracekit-0.0.1/LICENSE +21 -0
  4. sydost_tracekit-0.0.1/PKG-INFO +141 -0
  5. sydost_tracekit-0.0.1/README.md +106 -0
  6. sydost_tracekit-0.0.1/README.ru.md +105 -0
  7. sydost_tracekit-0.0.1/docs/en/api.md +21 -0
  8. sydost_tracekit-0.0.1/docs/en/bounds.md +100 -0
  9. sydost_tracekit-0.0.1/docs/en/cli.md +44 -0
  10. sydost_tracekit-0.0.1/docs/en/quickstart.md +29 -0
  11. sydost_tracekit-0.0.1/docs/en/recorder-deployment.md +50 -0
  12. sydost_tracekit-0.0.1/docs/en/trace-format.md +54 -0
  13. sydost_tracekit-0.0.1/docs/ru/api.md +21 -0
  14. sydost_tracekit-0.0.1/docs/ru/bounds.md +98 -0
  15. sydost_tracekit-0.0.1/docs/ru/cli.md +44 -0
  16. sydost_tracekit-0.0.1/docs/ru/quickstart.md +29 -0
  17. sydost_tracekit-0.0.1/docs/ru/recorder-deployment.md +50 -0
  18. sydost_tracekit-0.0.1/docs/ru/trace-format.md +53 -0
  19. sydost_tracekit-0.0.1/examples/01_quickstart.py +9 -0
  20. sydost_tracekit-0.0.1/examples/02_bounds.py +12 -0
  21. sydost_tracekit-0.0.1/examples/03_refined_bound.py +9 -0
  22. sydost_tracekit-0.0.1/examples/04_exact_integral.py +10 -0
  23. sydost_tracekit-0.0.1/examples/05_clock_alignment.py +10 -0
  24. sydost_tracekit-0.0.1/examples/06_recorder_local.py +10 -0
  25. sydost_tracekit-0.0.1/examples/07_tune.py +10 -0
  26. sydost_tracekit-0.0.1/experiments/recorder_overhead.py +45 -0
  27. sydost_tracekit-0.0.1/experiments/sampling_accuracy.py +51 -0
  28. sydost_tracekit-0.0.1/pyproject.toml +266 -0
  29. sydost_tracekit-0.0.1/pyproject.toml.orig +175 -0
  30. sydost_tracekit-0.0.1/scripts/check_commit_msg.py +82 -0
  31. sydost_tracekit-0.0.1/scripts/git-hooks/commit-msg +6 -0
  32. sydost_tracekit-0.0.1/src/sydost_tracekit/__init__.py +96 -0
  33. sydost_tracekit-0.0.1/src/sydost_tracekit/bounds.py +202 -0
  34. sydost_tracekit-0.0.1/src/sydost_tracekit/cli.py +131 -0
  35. sydost_tracekit-0.0.1/src/sydost_tracekit/clock.py +74 -0
  36. sydost_tracekit-0.0.1/src/sydost_tracekit/collector.py +131 -0
  37. sydost_tracekit-0.0.1/src/sydost_tracekit/integral.py +154 -0
  38. sydost_tracekit-0.0.1/src/sydost_tracekit/load.py +106 -0
  39. sydost_tracekit-0.0.1/src/sydost_tracekit/reconstruct.py +49 -0
  40. sydost_tracekit-0.0.1/src/sydost_tracekit/recorder.py +259 -0
  41. sydost_tracekit-0.0.1/src/sydost_tracekit/replay.py +100 -0
  42. sydost_tracekit-0.0.1/src/sydost_tracekit/synthetic.py +197 -0
  43. sydost_tracekit-0.0.1/src/sydost_tracekit/trace.py +154 -0
  44. sydost_tracekit-0.0.1/src/sydost_tracekit/tune.py +91 -0
  45. sydost_tracekit-0.0.1/tests/conftest.py +37 -0
  46. sydost_tracekit-0.0.1/tests/data/synthetic_ref.npz +0 -0
  47. sydost_tracekit-0.0.1/tests/test_bounds.py +128 -0
  48. sydost_tracekit-0.0.1/tests/test_collector_cli.py +175 -0
  49. sydost_tracekit-0.0.1/tests/test_docs.py +70 -0
  50. sydost_tracekit-0.0.1/tests/test_examples.py +15 -0
  51. sydost_tracekit-0.0.1/tests/test_integral.py +99 -0
  52. sydost_tracekit-0.0.1/tests/test_load_clock.py +122 -0
  53. sydost_tracekit-0.0.1/tests/test_package.py +24 -0
  54. sydost_tracekit-0.0.1/tests/test_recorder.py +211 -0
  55. sydost_tracekit-0.0.1/tests/test_synthetic_reference.py +34 -0
  56. sydost_tracekit-0.0.1/tests/test_trace.py +72 -0
  57. sydost_tracekit-0.0.1/tests/test_tune_replay.py +73 -0
  58. sydost_tracekit-0.0.1/tests/test_validation.py +81 -0
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+
3
+ All notable changes of sydost-tracekit are documented here. The project follows
4
+ [Semantic Versioning](https://semver.org).
5
+
6
+ ## [0.0.1] — 2026-11-11
7
+
8
+ First release: reference memory traces of virtual machines and the accuracy of the
9
+ accumulated-deficit estimate from samples (A. Ferubko, O. Kazakov, BGITU).
10
+
11
+ * Recorder: the tick after a sample is the first one not behind by a whole period; an overdue
12
+ tick is run once, a tick is never sampled twice.
13
+ * `synthetic`: scenarios A, B, C reproduce the prototype arrays bit for bit; held-out scenario D.
14
+
15
+ * `recorder`: the guest recorder, Python standard library only, one file; drift-free
16
+ schedule, late and skipped tick accounting, CPU share of the recorder.
17
+ * `collector`: host collector of libvirt memory statistics with the snapshot age
18
+ (optional extra `kvm`, imported lazily).
19
+ * `Trace`, `load_trace`, `save_trace`, `TraceFormatError`: the trace format with validation;
20
+ `recordings_to_trace` and `demand` (balloon-aware) for recordings.
21
+ * `clock`: host and guest clock alignment (Cristian's algorithm) and drift in ppm.
22
+ * `integral`: deficit, its estimate from samples, `positive_part_integral` (exact, crossing
23
+ points), `sampling_study`.
24
+ * `bounds`: statement 4.1 (`hold_error_bound`), the refined hold bound
25
+ (`hold_error_bounds_refined`), statement 4.2 (`linear_error_bound`), `estimate_constants`,
26
+ `plan_sampling` (the sampling rate for a target error).
27
+ * `replay`, `tune`: controller replay with fixed polling, Pareto front and selection under
28
+ `P(θ) ≤ α` and `D ≤ D_max`.
29
+ * Command line `sydost-tracekit record | integrate | bound | tune`.
30
+ * Documentation in English and Russian, seven examples, tests with coverage.
@@ -0,0 +1,36 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use this software, please cite it as below."
3
+ type: software
4
+ title: "sydost-tracekit: reference memory traces of virtual machines and accuracy of accumulated-deficit estimates from samples"
5
+ abstract: >-
6
+ A Python library for recording reference memory traces of virtual machines (a
7
+ stdlib-only guest recorder and a libvirt host collector), for estimating the
8
+ accumulated memory deficit from samples with explicit error bounds (hold and
9
+ linear reconstruction, refined hold bound, exact integral of the positive part),
10
+ for choosing a sampling rate for a target error, and for tuning the monitoring
11
+ configuration by a Pareto front.
12
+ version: 0.0.1
13
+ date-released: 2026-11-11
14
+ license: MIT
15
+ repository-code: "https://github.com/89605502155/sydost-tracekit"
16
+ url: "https://github.com/89605502155/sydost-tracekit"
17
+ keywords:
18
+ - memory trace
19
+ - virtualization
20
+ - KVM
21
+ - libvirt
22
+ - sampling
23
+ - accumulated deficit
24
+ - error bound
25
+ - monitoring
26
+ authors:
27
+ - family-names: Ferubko
28
+ given-names: Andrey
29
+ email: ferubko1999@yandex.ru
30
+ orcid: "https://orcid.org/0009-0006-5625-137X"
31
+ affiliation: "Bryansk State Engineering-Technological University (BGITU)"
32
+ - family-names: Kazakov
33
+ given-names: Oleg
34
+ email: kazakov@bgitu.ru
35
+ orcid: "https://orcid.org/0000-0001-9665-8138"
36
+ affiliation: "Bryansk State Engineering-Technological University (BGITU)"
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrey Ferubko, Oleg Kazakov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: sydost-tracekit
3
+ Version: 0.0.1
4
+ Summary: Reference memory traces of virtual machines and accuracy of accumulated-deficit estimates from samples: stdlib guest recorder, libvirt collector, error bounds, tuning by Pareto front
5
+ Keywords: memory-trace,virtualization,kvm,libvirt,sampling,integral,deficit,error-bound,monitoring,tuning
6
+ Author: Andrey Ferubko, Oleg Kazakov
7
+ Author-email: Andrey Ferubko <ferubko1999@yandex.ru>, Oleg Kazakov <kazakov@bgitu.ru>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
23
+ Classifier: Topic :: System :: Monitoring
24
+ Classifier: Typing :: Typed
25
+ Requires-Dist: numpy>=1.26
26
+ Requires-Dist: libvirt-python>=8.0 ; extra == 'kvm'
27
+ Requires-Python: >=3.11
28
+ Project-URL: Homepage, https://github.com/89605502155/sydost-tracekit
29
+ Project-URL: Documentation, https://github.com/89605502155/sydost-tracekit/tree/main/docs
30
+ Project-URL: Repository, https://github.com/89605502155/sydost-tracekit
31
+ Project-URL: Issues, https://github.com/89605502155/sydost-tracekit/issues
32
+ Project-URL: Changelog, https://github.com/89605502155/sydost-tracekit/blob/main/CHANGELOG.md
33
+ Provides-Extra: kvm
34
+ Description-Content-Type: text/markdown
35
+
36
+ # sydost-tracekit
37
+
38
+ [Русская версия](README.ru.md) · [Documentation](docs/en/quickstart.md) · [Changelog](CHANGELOG.md)
39
+
40
+ `sydost-tracekit` records reference memory traces of virtual machines, estimates the
41
+ accumulated memory deficit from samples taken at a coarser step, bounds the error of
42
+ that estimate, and tunes the monitoring configuration on the traces.
43
+
44
+ The accumulated deficit `D = ∫ (d − a)⁺ dt` is an integral. Samples of the demand held
45
+ for a step ℓ define a simple function, so the estimate converges to `D` as ℓ → 0.
46
+ The library gives explicit error bounds: `ℓ·V(d)` for holding the samples (first order)
47
+ and `ℓ²·(T·M/12 + K·L/3)` for linear interpolation (second order).
48
+
49
+ Developed at Bryansk State Engineering-Technological University (BGITU) by Andrey Ferubko
50
+ ([ORCID](https://orcid.org/0009-0006-5625-137X)) and Oleg Kazakov
51
+ ([ORCID](https://orcid.org/0000-0001-9665-8138)).
52
+
53
+ ## Install
54
+
55
+ ```sh
56
+ pip install sydost-tracekit # analysis, bounds, tuning, CLI
57
+ pip install "sydost-tracekit[kvm]" # adds libvirt-python for the host collector
58
+ uv add sydost-tracekit
59
+ ```
60
+
61
+ The guest recorder needs only the Python standard library: copy the single file
62
+ `src/sydost_tracekit/recorder.py` into the guest (see the deployment guide).
63
+
64
+ ## Quickstart
65
+
66
+ ```python
67
+ from sydost_tracekit import deficit_integral, estimate_from_samples, simulate, synthetic_trace
68
+
69
+ tr = synthetic_trace("A", T=600.0, dt=0.1, seed=7) # reference trace, step 0.1 s
70
+ run = simulate(tr, interval_s=4.0) # allocation of a controller polled every 4 s
71
+ D = deficit_integral(tr.d, run.alloc, tr.dt)
72
+ est = estimate_from_samples(tr.t[::20], tr.d[:, ::20], run.alloc, tr.dt, "linear")
73
+ print(f"D = {D:.1f} MiB*s, linear estimate from 2 s samples = {est:.1f} MiB*s")
74
+ ```
75
+
76
+ ## Command line
77
+
78
+ ```sh
79
+ sydost-tracekit record --hz 10 --duration 600 --out trace_vm1.csv # run the recorder here
80
+ sydost-tracekit integrate ref.csv --alloc alloc.csv --steps 0.5,1,2 # estimate D from samples
81
+ sydost-tracekit bound ref.csv --steps 1 --target 1e4 # bounds and sampling rate
82
+ sydost-tracekit tune train.csv --intervals 1,2,4,8 --alpha 0.5 --dmax 10
83
+ ```
84
+
85
+ ## Features
86
+
87
+ - **Sampling rate for a target error.** `plan_sampling` gives the method and the step
88
+ (rate) for which the a-priori bound does not exceed the target, from the constants of
89
+ a reference trace.
90
+ - **Refined hold bound.** `hold_error_bounds_refined` counts only the variation that
91
+ matters for the deficit (the rises above the allocation and the falls of the held
92
+ value above it). It is valid and tighter than `ℓ·V(d)`; the examples show it.
93
+ - **Exact integral of the positive part** of a piecewise linear signal via the crossing
94
+ points (`positive_part_integral`); a step allocation is a repeated knot.
95
+ - **Guest recorder** in the standard library only: drift-free schedule, late and skipped
96
+ tick accounting, CPU share of the recorder itself.
97
+ - **Host–guest clock alignment**: offset from request–response exchanges (Cristian's
98
+ algorithm, the error is at most half of the round trip) and linear drift in ppm.
99
+ - **Trace format** with validation (uniform grid, finite values, unique names).
100
+ - **Tuner**: sweep of configurations, Pareto front, selection under `P(θ) ≤ α` and
101
+ `D ≤ D_max`.
102
+
103
+ ## How it differs from generic tools
104
+
105
+ | Need | Generic tools | sydost-tracekit |
106
+ |---|---|---|
107
+ | Integral of a sampled series | `scipy.integrate.trapezoid`, `pandas` resampling | the integral of the **deficit** `(d − a)⁺` with a known allocation, and the exact crossing-point formula |
108
+ | Error of the integral | none: no bound for a sampled deficit | explicit bounds `ℓ·V(d)`, `ℓ²(T·M/12 + K·L/3)` and the refined hold bound |
109
+ | "What sampling rate do I need?" | rule of thumb | the step for a target absolute error, from the trace |
110
+ | Collection | Prometheus, node_exporter, collectd: sample every 15–60 s by default | a stdlib guest recorder at 10 Hz with overhead accounting, and a libvirt host collector |
111
+ | Tuning | manual thresholds | Pareto front over monitoring cost, selection under constraints |
112
+
113
+ ## Documentation
114
+
115
+ - English: [quickstart](docs/en/quickstart.md), [trace format](docs/en/trace-format.md),
116
+ [bounds and theory](docs/en/bounds.md), [recorder deployment](docs/en/recorder-deployment.md),
117
+ [API](docs/en/api.md), [CLI](docs/en/cli.md).
118
+ - Русский: [README.ru.md](README.ru.md), [docs/ru](docs/ru).
119
+
120
+ Runnable scripts are in [examples](examples/); they finish in a few seconds.
121
+
122
+ ## Development
123
+
124
+ ```sh
125
+ uv sync
126
+ uv run ruff check . && uv run ruff format --check .
127
+ uv run mypy
128
+ uv run pytest
129
+ ```
130
+
131
+ Enable the commit-message rule once per clone: `git config core.hooksPath scripts/git-hooks`.
132
+ Heavy experiments (minutes of recording at 100 Hz) are in [experiments](experiments/), not run by the tests.
133
+
134
+ ## Citation
135
+
136
+ See [CITATION.cff](CITATION.cff). Authors: Andrey Ferubko (ferubko1999@yandex.ru) and
137
+ Oleg Kazakov (kazakov@bgitu.ru), Bryansk State Engineering-Technological University (BGITU).
138
+
139
+ ## License
140
+
141
+ MIT, see [LICENSE](LICENSE). Copyright (c) 2026 Andrey Ferubko, Oleg Kazakov.
@@ -0,0 +1,106 @@
1
+ # sydost-tracekit
2
+
3
+ [Русская версия](README.ru.md) · [Documentation](docs/en/quickstart.md) · [Changelog](CHANGELOG.md)
4
+
5
+ `sydost-tracekit` records reference memory traces of virtual machines, estimates the
6
+ accumulated memory deficit from samples taken at a coarser step, bounds the error of
7
+ that estimate, and tunes the monitoring configuration on the traces.
8
+
9
+ The accumulated deficit `D = ∫ (d − a)⁺ dt` is an integral. Samples of the demand held
10
+ for a step ℓ define a simple function, so the estimate converges to `D` as ℓ → 0.
11
+ The library gives explicit error bounds: `ℓ·V(d)` for holding the samples (first order)
12
+ and `ℓ²·(T·M/12 + K·L/3)` for linear interpolation (second order).
13
+
14
+ Developed at Bryansk State Engineering-Technological University (BGITU) by Andrey Ferubko
15
+ ([ORCID](https://orcid.org/0009-0006-5625-137X)) and Oleg Kazakov
16
+ ([ORCID](https://orcid.org/0000-0001-9665-8138)).
17
+
18
+ ## Install
19
+
20
+ ```sh
21
+ pip install sydost-tracekit # analysis, bounds, tuning, CLI
22
+ pip install "sydost-tracekit[kvm]" # adds libvirt-python for the host collector
23
+ uv add sydost-tracekit
24
+ ```
25
+
26
+ The guest recorder needs only the Python standard library: copy the single file
27
+ `src/sydost_tracekit/recorder.py` into the guest (see the deployment guide).
28
+
29
+ ## Quickstart
30
+
31
+ ```python
32
+ from sydost_tracekit import deficit_integral, estimate_from_samples, simulate, synthetic_trace
33
+
34
+ tr = synthetic_trace("A", T=600.0, dt=0.1, seed=7) # reference trace, step 0.1 s
35
+ run = simulate(tr, interval_s=4.0) # allocation of a controller polled every 4 s
36
+ D = deficit_integral(tr.d, run.alloc, tr.dt)
37
+ est = estimate_from_samples(tr.t[::20], tr.d[:, ::20], run.alloc, tr.dt, "linear")
38
+ print(f"D = {D:.1f} MiB*s, linear estimate from 2 s samples = {est:.1f} MiB*s")
39
+ ```
40
+
41
+ ## Command line
42
+
43
+ ```sh
44
+ sydost-tracekit record --hz 10 --duration 600 --out trace_vm1.csv # run the recorder here
45
+ sydost-tracekit integrate ref.csv --alloc alloc.csv --steps 0.5,1,2 # estimate D from samples
46
+ sydost-tracekit bound ref.csv --steps 1 --target 1e4 # bounds and sampling rate
47
+ sydost-tracekit tune train.csv --intervals 1,2,4,8 --alpha 0.5 --dmax 10
48
+ ```
49
+
50
+ ## Features
51
+
52
+ - **Sampling rate for a target error.** `plan_sampling` gives the method and the step
53
+ (rate) for which the a-priori bound does not exceed the target, from the constants of
54
+ a reference trace.
55
+ - **Refined hold bound.** `hold_error_bounds_refined` counts only the variation that
56
+ matters for the deficit (the rises above the allocation and the falls of the held
57
+ value above it). It is valid and tighter than `ℓ·V(d)`; the examples show it.
58
+ - **Exact integral of the positive part** of a piecewise linear signal via the crossing
59
+ points (`positive_part_integral`); a step allocation is a repeated knot.
60
+ - **Guest recorder** in the standard library only: drift-free schedule, late and skipped
61
+ tick accounting, CPU share of the recorder itself.
62
+ - **Host–guest clock alignment**: offset from request–response exchanges (Cristian's
63
+ algorithm, the error is at most half of the round trip) and linear drift in ppm.
64
+ - **Trace format** with validation (uniform grid, finite values, unique names).
65
+ - **Tuner**: sweep of configurations, Pareto front, selection under `P(θ) ≤ α` and
66
+ `D ≤ D_max`.
67
+
68
+ ## How it differs from generic tools
69
+
70
+ | Need | Generic tools | sydost-tracekit |
71
+ |---|---|---|
72
+ | Integral of a sampled series | `scipy.integrate.trapezoid`, `pandas` resampling | the integral of the **deficit** `(d − a)⁺` with a known allocation, and the exact crossing-point formula |
73
+ | Error of the integral | none: no bound for a sampled deficit | explicit bounds `ℓ·V(d)`, `ℓ²(T·M/12 + K·L/3)` and the refined hold bound |
74
+ | "What sampling rate do I need?" | rule of thumb | the step for a target absolute error, from the trace |
75
+ | Collection | Prometheus, node_exporter, collectd: sample every 15–60 s by default | a stdlib guest recorder at 10 Hz with overhead accounting, and a libvirt host collector |
76
+ | Tuning | manual thresholds | Pareto front over monitoring cost, selection under constraints |
77
+
78
+ ## Documentation
79
+
80
+ - English: [quickstart](docs/en/quickstart.md), [trace format](docs/en/trace-format.md),
81
+ [bounds and theory](docs/en/bounds.md), [recorder deployment](docs/en/recorder-deployment.md),
82
+ [API](docs/en/api.md), [CLI](docs/en/cli.md).
83
+ - Русский: [README.ru.md](README.ru.md), [docs/ru](docs/ru).
84
+
85
+ Runnable scripts are in [examples](examples/); they finish in a few seconds.
86
+
87
+ ## Development
88
+
89
+ ```sh
90
+ uv sync
91
+ uv run ruff check . && uv run ruff format --check .
92
+ uv run mypy
93
+ uv run pytest
94
+ ```
95
+
96
+ Enable the commit-message rule once per clone: `git config core.hooksPath scripts/git-hooks`.
97
+ Heavy experiments (minutes of recording at 100 Hz) are in [experiments](experiments/), not run by the tests.
98
+
99
+ ## Citation
100
+
101
+ See [CITATION.cff](CITATION.cff). Authors: Andrey Ferubko (ferubko1999@yandex.ru) and
102
+ Oleg Kazakov (kazakov@bgitu.ru), Bryansk State Engineering-Technological University (BGITU).
103
+
104
+ ## License
105
+
106
+ MIT, see [LICENSE](LICENSE). Copyright (c) 2026 Andrey Ferubko, Oleg Kazakov.
@@ -0,0 +1,105 @@
1
+ # sydost-tracekit
2
+
3
+ [English version](README.md) · [Документация](docs/ru/quickstart.md) · [История версий](CHANGELOG.md)
4
+
5
+ `sydost-tracekit` записывает эталонные трассы памяти виртуальных машин, оценивает накопленный
6
+ дефицит памяти по отсчётам с более грубым шагом, даёт границы погрешности этой оценки и
7
+ настраивает конфигурацию мониторинга по трассам.
8
+
9
+ Накопленный дефицит `D = ∫ (d − a)⁺ dt` — интеграл. Отсчёты потребности, удержанные на шаге ℓ,
10
+ задают простую функцию, поэтому оценка сходится к `D` при ℓ → 0. Библиотека даёт явные границы
11
+ погрешности: `ℓ·V(d)` для удержания (первый порядок) и `ℓ²·(T·M/12 + K·L/3)` для линейной
12
+ интерполяции (второй порядок).
13
+
14
+ Разработано в Брянском государственном инженерно-технологическом университете (БГИТУ)
15
+ Андреем Ферубко ([ORCID](https://orcid.org/0009-0006-5625-137X)) и Олегом Казаковым
16
+ ([ORCID](https://orcid.org/0000-0001-9665-8138)).
17
+
18
+ ## Установка
19
+
20
+ ```sh
21
+ pip install sydost-tracekit # анализ, границы, настройка, командная строка
22
+ pip install "sydost-tracekit[kvm]" # добавляет libvirt-python для сборщика на хосте
23
+ uv add sydost-tracekit
24
+ ```
25
+
26
+ Гостевой регистратор требует только стандартной библиотеки Python: скопируйте один файл
27
+ `src/sydost_tracekit/recorder.py` в гостевую ВМ (см. руководство по развёртыванию).
28
+
29
+ ## Быстрый старт
30
+
31
+ ```python
32
+ from sydost_tracekit import deficit_integral, estimate_from_samples, simulate, synthetic_trace
33
+
34
+ tr = synthetic_trace("A", T=600.0, dt=0.1, seed=7) # эталонная трасса, шаг 0,1 с
35
+ run = simulate(tr, interval_s=4.0) # выделение контроллера, опрашиваемого раз в 4 с
36
+ D = deficit_integral(tr.d, run.alloc, tr.dt)
37
+ est = estimate_from_samples(tr.t[::20], tr.d[:, ::20], run.alloc, tr.dt, "linear")
38
+ print(f"D = {D:.1f} MiB*s, линейная оценка по отсчётам раз в 2 с = {est:.1f} MiB*s")
39
+ ```
40
+
41
+ ## Командная строка
42
+
43
+ ```sh
44
+ sydost-tracekit record --hz 10 --duration 600 --out trace_vm1.csv # запустить регистратор здесь
45
+ sydost-tracekit integrate ref.csv --alloc alloc.csv --steps 0.5,1,2 # оценить D по отсчётам
46
+ sydost-tracekit bound ref.csv --steps 1 --target 1e4 # границы и частота опроса
47
+ sydost-tracekit tune train.csv --intervals 1,2,4,8 --alpha 0.5 --dmax 10
48
+ ```
49
+
50
+ ## Возможности
51
+
52
+ - **Частота опроса для заданной погрешности.** `plan_sampling` даёт метод и шаг (частоту),
53
+ при которых априорная граница не превышает цель, по константам эталонной трассы.
54
+ - **Уточнённая граница для удержания.** `hold_error_bounds_refined` учитывает только вариацию,
55
+ существенную для дефицита (подъёмы потребности над выделением и спады удерживаемого значения
56
+ над ним). Она верна и уже, чем `ℓ·V(d)`; примеры это показывают.
57
+ - **Точный интеграл положительной части** кусочно-линейного сигнала по точкам пересечения
58
+ (`positive_part_integral`); ступенчатое выделение — повторённый узел.
59
+ - **Гостевой регистратор** только на стандартной библиотеке: расписание без дрейфа, учёт
60
+ опозданий и пропущенных тиков, доля CPU самого регистратора.
61
+ - **Совмещение часов хоста и гостя**: смещение по обменам «запрос–ответ» (алгоритм Кристиана,
62
+ погрешность не больше половины времени обмена) и линейный дрейф в ppm.
63
+ - **Формат трасс** с проверкой (равномерная сетка, конечные значения, уникальные имена).
64
+ - **Настройка**: перебор конфигураций, фронт Парето, выбор при ограничениях `P(θ) ≤ α` и
65
+ `D ≤ D_max`.
66
+
67
+ ## Чем отличается от общих инструментов
68
+
69
+ | Задача | Общие инструменты | sydost-tracekit |
70
+ |---|---|---|
71
+ | Интеграл по отсчётам | `scipy.integrate.trapezoid`, пересэмплирование в `pandas` | интеграл **дефицита** `(d − a)⁺` при известном выделении и точная формула по точкам пересечения |
72
+ | Погрешность интеграла | нет: границы для дискретного дефицита не дают | явные границы `ℓ·V(d)`, `ℓ²(T·M/12 + K·L/3)` и уточнённая граница для удержания |
73
+ | «Какая частота опроса нужна?» | эмпирическое правило | шаг для заданной абсолютной погрешности по трассе |
74
+ | Сбор | Prometheus, node_exporter, collectd: по умолчанию опрос раз в 15–60 с | регистратор в госте на 10 Гц с учётом накладных расходов и сборщик libvirt на хосте |
75
+ | Настройка | ручные пороги | фронт Парето по стоимости мониторинга, выбор при ограничениях |
76
+
77
+ ## Документация
78
+
79
+ - Русский: [быстрый старт](docs/ru/quickstart.md), [формат трасс](docs/ru/trace-format.md),
80
+ [границы и теория](docs/ru/bounds.md), [развёртывание регистратора](docs/ru/recorder-deployment.md),
81
+ [API](docs/ru/api.md), [командная строка](docs/ru/cli.md).
82
+ - English: [README.md](README.md), [docs/en](docs/en).
83
+
84
+ Готовые скрипты лежат в [examples](examples/); каждый выполняется за несколько секунд.
85
+
86
+ ## Разработка
87
+
88
+ ```sh
89
+ uv sync
90
+ uv run ruff check . && uv run ruff format --check .
91
+ uv run mypy
92
+ uv run pytest
93
+ ```
94
+
95
+ Правило сообщений коммитов включается один раз на клон: `git config core.hooksPath scripts/git-hooks`.
96
+ Тяжёлые эксперименты (записи минутами на 100 Гц) лежат в [experiments](experiments/) и тестами не запускаются.
97
+
98
+ ## Цитирование
99
+
100
+ См. [CITATION.cff](CITATION.cff). Авторы: Андрей Ферубко (ferubko1999@yandex.ru) и
101
+ Олег Казаков (kazakov@bgitu.ru), Брянский государственный инженерно-технологический университет (БГИТУ).
102
+
103
+ ## Лицензия
104
+
105
+ MIT, см. [LICENSE](LICENSE). Copyright (c) 2026 Andrey Ferubko, Oleg Kazakov.
@@ -0,0 +1,21 @@
1
+ # API
2
+
3
+ The public names are exported from `sydost_tracekit`. Each function has a numpy-style
4
+ docstring with runnable examples.
5
+
6
+ | Group | Names | Purpose |
7
+ |---|---|---|
8
+ | Traces | `Trace`, `load_trace`, `save_trace`, `TraceFormatError` | trace on a uniform grid, CSV format |
9
+ | Recordings | `read_recorder_csv`, `demand`, `recordings_to_trace` | recorder output to traces |
10
+ | Clocks | `ClockSample`, `estimate_offset`, `guest_to_host`, `fit_drift` | host–guest alignment |
11
+ | Reconstruction | `hold`, `linear` | samples to a function of time |
12
+ | Integral | `deficit`, `deficit_integral`, `total_variation`, `positive_part_integral`, `estimate_from_samples`, `sampling_study` | deficit and its estimate |
13
+ | Bounds | `hold_error_bound`, `hold_error_bounds_refined`, `linear_error_bound`, `estimate_constants`, `Constants`, `required_step`, `plan_sampling`, `Plan` | a-priori and refined bounds, sampling plan |
14
+ | Replay | `ReserveController`, `simulate`, `RunResult` | controller replay with fixed polling |
15
+ | Tuning | `sweep`, `pareto_front`, `select` | cost–quality front and selection |
16
+ | Synthetic | `synthetic_trace`, `VmProfile`, `SCENARIOS` | scenarios A, B, C (identical to the prototype for the same seed); D held out |
17
+ | Guest | `sydost_tracekit.recorder.record`, `main` | stdlib recorder (also the file copied to guests) |
18
+ | Host | `sydost_tracekit.collector.collect`, `connect` | libvirt collector (extra `kvm`) |
19
+
20
+ Units: time in seconds, memory in MiB, the accumulated deficit in MiB·s (the CLI prints GiB·s
21
+ where the name says so).
@@ -0,0 +1,100 @@
1
+ # Bounds and theory
2
+
3
+ ## The estimate from samples
4
+
5
+ Let `a` be the allocation (known exactly from the host journal), and `d` the demand.
6
+ The deficit is `f = (d − a)⁺` and `D = ∫ f dt`. Samples of `d` at step `ℓ`, held
7
+ until the next sample, define a simple function `d_ℓ`. The estimate is
8
+
9
+ D_ℓ = ∫ (d_ℓ − a)⁺ dt.
10
+
11
+ As `ℓ → 0`, `d_ℓ → d` almost everywhere, and by the Lebesgue dominated convergence theorem
12
+ `D_ℓ → D` (the integrands are bounded by the maximum memory plus the reserve).
13
+
14
+ ## Statement 4.1: hold
15
+
16
+ |D_ℓ − D| ≤ ℓ · V(d),
17
+
18
+ where `V(d)` is the total variation of the demand. It follows from `|x⁺ − y⁺| ≤ |x − y|`.
19
+ The bound is valid and of first order in `ℓ`, but it counts variation at all times.
20
+
21
+ ```python
22
+ import numpy as np
23
+ from sydost_tracekit import hold_error_bound
24
+
25
+ print(hold_error_bound(np.array([[0.0, 2.0, 1.0]]), 0.5))
26
+ ```
27
+
28
+ ## Refined hold bound
29
+
30
+ Let `x_k` be the held value at the fine point `k`. The error of a point is nonzero only if
31
+ the demand or the held value is above the allocation. Pointwise,
32
+
33
+ −(d_k − max(x_k, a_k))⁺ ≤ (estimate − exact at k) ≤ (x_k − max(d_k, a_k))⁺,
34
+
35
+ and summing over the fine grid with step `dt` gives
36
+
37
+ −dt Σ (d_k − max(x_k, a_k))⁺ ≤ D_ℓ − D ≤ dt Σ (x_k − max(d_k, a_k))⁺.
38
+
39
+ The lower bound counts only the rises of the demand above the allocation, the upper bound
40
+ only the falls of the held value above it. It is never looser than `ℓ·V(d)`, and it is much
41
+ tighter when the demand stays below the allocation.
42
+
43
+ ```python
44
+ from sydost_tracekit import hold_error_bounds_refined, simulate, synthetic_trace
45
+
46
+ tr = synthetic_trace("A", T=600.0, dt=0.1, seed=7)
47
+ alloc = simulate(tr, interval_s=4.0).alloc
48
+ lo, hi = hold_error_bounds_refined(tr.d, alloc, tr.dt, ell=4.0)
49
+ print(f"refined: [{lo:.1f}, {hi:.1f}] MiB*s")
50
+ ```
51
+
52
+ ## Statement 4.2: linear interpolation
53
+
54
+ If `d` is `L`-Lipschitz with `K` kinks and `|d''| ≤ M` away from the kinks, then
55
+
56
+ |D_lin − D| ≤ ℓ² · (T·M/12 + K·L/3).
57
+
58
+ On a smooth step the interpolation error is at most `M·u·(ℓ − u)/2` (u is the time from the
59
+ start of the step), and its integral is `M·ℓ³/12`. On a step with a kink the error is at most
60
+ `2L·u·(ℓ − u)/ℓ`, and its integral `L·ℓ²/3`. Summing over the steps gives the statement.
61
+ The standard error estimate of linear interpolation is the reference for the derivation.
62
+ The constants are estimated from a reference trace by `estimate_constants`; for a noisy trace
63
+ `M` and `K` are large and the bound is loose.
64
+
65
+ ## Exact integral of the positive part
66
+
67
+ On each segment of a piecewise linear signal, `g = x − a` is linear. The integral of its
68
+ positive part follows from the crossing point with zero, so the integral of `(x − a)⁺` is
69
+ exact:
70
+
71
+ ```python
72
+ import numpy as np
73
+ from sydost_tracekit import positive_part_integral
74
+
75
+ t = np.array([0.0, 1.0, 2.0])
76
+ x = np.array([0.0, 4.0, 0.0])
77
+ a = np.array([2.0, 2.0, 2.0])
78
+ print(positive_part_integral(t, x, a))
79
+ ```
80
+
81
+ ## What sampling rate is needed?
82
+
83
+ For an admissible absolute error `E` (MiB·s), the admissible step is the largest `ℓ` for which
84
+ the bound of the method does not exceed `E`: `ℓ = E / V` for hold, `ℓ = sqrt(E / C)` for
85
+ linear, with `C = Σ (T·M/12 + K·L/3)` over the machines. `plan_sampling` picks the method with
86
+ the larger step, that is, the lower rate.
87
+
88
+ ```python
89
+ from sydost_tracekit import estimate_constants, plan_sampling, synthetic_trace
90
+
91
+ tr = synthetic_trace("B", T=600.0, dt=0.1, seed=7)
92
+ plan = plan_sampling(1e4, estimate_constants(tr.d, tr.dt))
93
+ print(plan.method, round(plan.step_s, 3), round(plan.rate_hz, 3))
94
+ ```
95
+
96
+ ## Scope
97
+
98
+ The bounds are for the reconstruction of the demand. They assume that the allocation is
99
+ known exactly, and that the balloon is instant. Synthetic traces are for debugging; the
100
+ conclusions of a study must rest on traces of a real system.
@@ -0,0 +1,44 @@
1
+ # Command line
2
+
3
+ `sydost-tracekit` has four commands. Each has `--help`.
4
+
5
+ ## record
6
+
7
+ Runs the guest recorder on this machine. It writes the CSV and the JSON summary.
8
+
9
+ ```sh
10
+ sydost-tracekit record --hz 10 --duration 600 --out trace_vm1.csv
11
+ ```
12
+
13
+ ## integrate
14
+
15
+ Estimates the deficit from samples of a reference trace for several steps and methods.
16
+ The allocation file has the same format and grid as the reference.
17
+
18
+ ```sh
19
+ sydost-tracekit integrate ref.csv --alloc alloc.csv --steps 0.5,1,2 --methods hold,linear
20
+ ```
21
+
22
+ The output gives the exact `D` and the relative error in percent for each step and method.
23
+
24
+ ## bound
25
+
26
+ Prints the constants of the reference trace (`V`, `L`, `M`, `K`), the linear bound and the
27
+ hold bound `ℓ·V` for the steps given, and, with `--target`, the method, step and rate that
28
+ meet an absolute error in MiB·s.
29
+
30
+ ```sh
31
+ sydost-tracekit bound ref.csv --steps 1,2 --target 10000
32
+ ```
33
+
34
+ ## tune
35
+
36
+ Replays fixed polling intervals on the trace, prints the cost (samples per machine-hour),
37
+ `P(θ)`, `D`, the Pareto flag, and the selected interval under `P ≤ α` and `D ≤ D_max`.
38
+
39
+ ```sh
40
+ sydost-tracekit tune train.csv --intervals 1,2,4,8 --theta 64 --alpha 0.5 --dmax 10
41
+ ```
42
+
43
+ `--theta` is the deficit threshold in MiB. `--dmax` is in GiB·s. Without `--dmax` there is no
44
+ limit on `D`. If no interval satisfies the constraints, the command says so.
@@ -0,0 +1,29 @@
1
+ # Quickstart
2
+
3
+ Install the package, then estimate the accumulated deficit of a trace from samples.
4
+
5
+ ```sh
6
+ pip install sydost-tracekit
7
+ ```
8
+
9
+ The first example takes a synthetic trace (scenario A, four machines), replays a
10
+ controller polled every 4 seconds, and estimates the deficit from samples every 2 seconds:
11
+
12
+ ```python
13
+ from sydost_tracekit import deficit_integral, estimate_from_samples, simulate, synthetic_trace
14
+
15
+ tr = synthetic_trace("A", T=600.0, dt=0.1, seed=7) # reference trace, step 0.1 s
16
+ run = simulate(tr, interval_s=4.0) # allocation of a controller polled every 4 s
17
+ D = deficit_integral(tr.d, run.alloc, tr.dt)
18
+ est = estimate_from_samples(tr.t[::20], tr.d[:, ::20], run.alloc, tr.dt, "linear")
19
+ print(f"D = {D:.1f} MiB*s, linear estimate from 2 s samples = {est:.1f} MiB*s")
20
+ ```
21
+
22
+ Next steps:
23
+
24
+ - [Trace format](trace-format.md): how the demand of a machine is stored.
25
+ - [Bounds](bounds.md): how large the error of the estimate can be, and which sampling rate is needed.
26
+ - [Recorder deployment](recorder-deployment.md): how to run the guest recorder.
27
+ - [CLI](cli.md) and [API](api.md).
28
+
29
+ The examples in [examples](../../examples/) show each function on a short script.