boundary-analyzer 0.2.0__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 (65) hide show
  1. boundary_analyzer-0.2.0/CHANGELOG.md +34 -0
  2. boundary_analyzer-0.2.0/PKG-INFO +50 -0
  3. boundary_analyzer-0.2.0/README.md +269 -0
  4. boundary_analyzer-0.2.0/pyproject.toml +29 -0
  5. boundary_analyzer-0.2.0/setup.cfg +4 -0
  6. boundary_analyzer-0.2.0/src/boundary_analyzer/__init__.py +0 -0
  7. boundary_analyzer-0.2.0/src/boundary_analyzer/__main__.py +7 -0
  8. boundary_analyzer-0.2.0/src/boundary_analyzer/auto_setup/__init__.py +4 -0
  9. boundary_analyzer-0.2.0/src/boundary_analyzer/auto_setup/django_wrapper.py +48 -0
  10. boundary_analyzer-0.2.0/src/boundary_analyzer/auto_setup/djangorest_wrapper.py +44 -0
  11. boundary_analyzer-0.2.0/src/boundary_analyzer/auto_setup/fastapi_wrapper.py +59 -0
  12. boundary_analyzer-0.2.0/src/boundary_analyzer/auto_setup/flask_wrapper.py +53 -0
  13. boundary_analyzer-0.2.0/src/boundary_analyzer/auto_setup/setup_instrumentation.py +805 -0
  14. boundary_analyzer-0.2.0/src/boundary_analyzer/auto_setup/starlette_wrapper.py +43 -0
  15. boundary_analyzer-0.2.0/src/boundary_analyzer/auto_setup/tornado_wrapper.py +38 -0
  16. boundary_analyzer-0.2.0/src/boundary_analyzer/cli.py +390 -0
  17. boundary_analyzer-0.2.0/src/boundary_analyzer/dashboard/__init__.py +0 -0
  18. boundary_analyzer-0.2.0/src/boundary_analyzer/dashboard/app.py +1778 -0
  19. boundary_analyzer-0.2.0/src/boundary_analyzer/dashboard/charts.py +910 -0
  20. boundary_analyzer-0.2.0/src/boundary_analyzer/detection/db_table_extractor.py +241 -0
  21. boundary_analyzer-0.2.0/src/boundary_analyzer/detection/endpoint_extractor.py +150 -0
  22. boundary_analyzer-0.2.0/src/boundary_analyzer/detection/endpoint_normalizer.py +142 -0
  23. boundary_analyzer-0.2.0/src/boundary_analyzer/detection/mapping_builder.py +137 -0
  24. boundary_analyzer-0.2.0/src/boundary_analyzer/llm/__init__.py +11 -0
  25. boundary_analyzer-0.2.0/src/boundary_analyzer/llm/analysis.py +323 -0
  26. boundary_analyzer-0.2.0/src/boundary_analyzer/llm/client.py +100 -0
  27. boundary_analyzer-0.2.0/src/boundary_analyzer/llm/context.py +229 -0
  28. boundary_analyzer-0.2.0/src/boundary_analyzer/llm/instrumentation.py +52 -0
  29. boundary_analyzer-0.2.0/src/boundary_analyzer/llm/prompts.py +152 -0
  30. boundary_analyzer-0.2.0/src/boundary_analyzer/metrics/cohesion_rules.py +20 -0
  31. boundary_analyzer-0.2.0/src/boundary_analyzer/metrics/scom.py +207 -0
  32. boundary_analyzer-0.2.0/src/boundary_analyzer/metrics/threshold_ultimate.py +121 -0
  33. boundary_analyzer-0.2.0/src/boundary_analyzer/parsing/trace_reader.py +114 -0
  34. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/__init__.py +0 -0
  35. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/run_pipeline.py +189 -0
  36. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/step_01_collect_traces.py +88 -0
  37. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/step_02_read_traces.py +29 -0
  38. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/step_03_find_endpoints.py +38 -0
  39. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/step_04_find_db_tables.py +43 -0
  40. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/step_05_build_mapping.py +55 -0
  41. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/step_06_compute_scom.py +74 -0
  42. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/step_07_rank_and_flag.py +99 -0
  43. boundary_analyzer-0.2.0/src/boundary_analyzer/pipeline/step_08_make_report.py +80 -0
  44. boundary_analyzer-0.2.0/src/boundary_analyzer/reporting/__init__.py +0 -0
  45. boundary_analyzer-0.2.0/src/boundary_analyzer/reporting/report_builder.py +122 -0
  46. boundary_analyzer-0.2.0/src/boundary_analyzer/settings_loader.py +166 -0
  47. boundary_analyzer-0.2.0/src/boundary_analyzer/test_data/__init__.py +0 -0
  48. boundary_analyzer-0.2.0/src/boundary_analyzer/test_data/generate_test_traces.py +306 -0
  49. boundary_analyzer-0.2.0/src/boundary_analyzer/validation/__init__.py +0 -0
  50. boundary_analyzer-0.2.0/src/boundary_analyzer/validation/compare_metrics.py +250 -0
  51. boundary_analyzer-0.2.0/src/boundary_analyzer.egg-info/PKG-INFO +50 -0
  52. boundary_analyzer-0.2.0/src/boundary_analyzer.egg-info/SOURCES.txt +63 -0
  53. boundary_analyzer-0.2.0/src/boundary_analyzer.egg-info/dependency_links.txt +1 -0
  54. boundary_analyzer-0.2.0/src/boundary_analyzer.egg-info/entry_points.txt +3 -0
  55. boundary_analyzer-0.2.0/src/boundary_analyzer.egg-info/requires.txt +5 -0
  56. boundary_analyzer-0.2.0/src/boundary_analyzer.egg-info/top_level.txt +1 -0
  57. boundary_analyzer-0.2.0/tests/test_dashboard_smoke.py +21 -0
  58. boundary_analyzer-0.2.0/tests/test_llm_analysis.py +103 -0
  59. boundary_analyzer-0.2.0/tests/test_llm_client.py +137 -0
  60. boundary_analyzer-0.2.0/tests/test_llm_context.py +179 -0
  61. boundary_analyzer-0.2.0/tests/test_llm_instrumentation.py +57 -0
  62. boundary_analyzer-0.2.0/tests/test_llm_prompts.py +37 -0
  63. boundary_analyzer-0.2.0/tests/test_pipeline_integration.py +149 -0
  64. boundary_analyzer-0.2.0/tests/test_setup_instructions.py +19 -0
  65. boundary_analyzer-0.2.0/tests/test_teastore_pipeline.py +172 -0
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ ## v1.0.0 (2026-06-11)
4
+
5
+ ### Features
6
+ - **SCOM pipeline** : computes Service-COhesion Metric from Jaeger traces (health filtering, endpoint extraction, DB table detection, endpoint-table mapping, threshold analysis, report generation)
7
+ - **CLI tool** : `mba` / `boundary-analyzer` commands (`run`, `setup`, `dashboard`, `teastore`)
8
+ - **Auto-instrumentation** : auto-detects Python microservices (FastAPI, Flask, Django), injects OpenTelemetry, collects traces via Jaeger, runs SCOM analysis
9
+ - **TeaStore support** : Docker Compose deployment with OTel Java agent, traffic generator, trace exporter, full SCOM pipeline
10
+ - **Dashboard** : interactive Dash web UI for SCOM results
11
+ - **LLM analysis** (optional) : AI-powered narrative report via OpenRouter (Qwen), disabled by default
12
+
13
+ ### Improvements
14
+ - Segment-based health matching (`HEALTH_KEYWORDS`) instead of fragile `endswith` — `/health/all`, `/auth/health`, `/ready/isready`, `/metrics` (via `http.target`) correctly filtered
15
+ - `--skip-no-db-services` flag to exclude stateless services (proxy, orchestrator, etc.) from SCOM ranking
16
+ - `run_teastore()` function extracted for programmatic access
17
+
18
+ ### Bug fixes
19
+ - MissingGreenlet in classroom-repository (added `selectinload`)
20
+ - datetime timezone-aware comparison in enrollment-service
21
+ - `academic_year` int→str conversion in enrollment-service
22
+ - Scope bug in `cleaned_parts` variable in CLI cleanup logic
23
+ - SQLAlchemy duplicate instrumentation (event listeners only, no `SQLAlchemyInstrumentor`/`AsyncPGInstrumentor`)
24
+ - `[project.scripts]` whitespace in pyproject.toml
25
+
26
+ ### Tests
27
+ - 74 tests total (58 existing + 16 TeaStore)
28
+ - TeaStore synthetic fixtures (persistence-service with 5 tables, auth-service without DB)
29
+ - 3 test classes : TeaStorePipelineTest, TeaStoreSkipNoDbTest, TeaStoreNoFilterTest
30
+
31
+ ### Infrastructure
32
+ - CI via GitHub Actions (`.github/workflows/ci.yml`) — Python 3.11 × 3.12
33
+ - `mba` CLI alias alongside `boundary-analyzer`
34
+ - Version bump to 0.2.0
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.4
2
+ Name: boundary-analyzer
3
+ Version: 0.2.0
4
+ Summary: SCOM-based microservice boundary analysis from Jaeger traces
5
+ Author-email: Ray Ague <rayague03@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/rayague/measure-automation
8
+ Project-URL: Repository, https://github.com/rayague/measure-automation
9
+ Requires-Python: >=3.11
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: requests>=2.31.0
12
+ Requires-Dist: pandas>=2.2.0
13
+ Requires-Dist: PyYAML>=6.0.1
14
+ Requires-Dist: dash>=2.14.0
15
+ Requires-Dist: plotly>=5.18.0
16
+
17
+ # Changelog
18
+
19
+ ## v1.0.0 (2026-06-11)
20
+
21
+ ### Features
22
+ - **SCOM pipeline** : computes Service-COhesion Metric from Jaeger traces (health filtering, endpoint extraction, DB table detection, endpoint-table mapping, threshold analysis, report generation)
23
+ - **CLI tool** : `mba` / `boundary-analyzer` commands (`run`, `setup`, `dashboard`, `teastore`)
24
+ - **Auto-instrumentation** : auto-detects Python microservices (FastAPI, Flask, Django), injects OpenTelemetry, collects traces via Jaeger, runs SCOM analysis
25
+ - **TeaStore support** : Docker Compose deployment with OTel Java agent, traffic generator, trace exporter, full SCOM pipeline
26
+ - **Dashboard** : interactive Dash web UI for SCOM results
27
+ - **LLM analysis** (optional) : AI-powered narrative report via OpenRouter (Qwen), disabled by default
28
+
29
+ ### Improvements
30
+ - Segment-based health matching (`HEALTH_KEYWORDS`) instead of fragile `endswith` — `/health/all`, `/auth/health`, `/ready/isready`, `/metrics` (via `http.target`) correctly filtered
31
+ - `--skip-no-db-services` flag to exclude stateless services (proxy, orchestrator, etc.) from SCOM ranking
32
+ - `run_teastore()` function extracted for programmatic access
33
+
34
+ ### Bug fixes
35
+ - MissingGreenlet in classroom-repository (added `selectinload`)
36
+ - datetime timezone-aware comparison in enrollment-service
37
+ - `academic_year` int→str conversion in enrollment-service
38
+ - Scope bug in `cleaned_parts` variable in CLI cleanup logic
39
+ - SQLAlchemy duplicate instrumentation (event listeners only, no `SQLAlchemyInstrumentor`/`AsyncPGInstrumentor`)
40
+ - `[project.scripts]` whitespace in pyproject.toml
41
+
42
+ ### Tests
43
+ - 74 tests total (58 existing + 16 TeaStore)
44
+ - TeaStore synthetic fixtures (persistence-service with 5 tables, auth-service without DB)
45
+ - 3 test classes : TeaStorePipelineTest, TeaStoreSkipNoDbTest, TeaStoreNoFilterTest
46
+
47
+ ### Infrastructure
48
+ - CI via GitHub Actions (`.github/workflows/ci.yml`) — Python 3.11 × 3.12
49
+ - `mba` CLI alias alongside `boundary-analyzer`
50
+ - Version bump to 0.2.0
@@ -0,0 +1,269 @@
1
+ # measure-automation
2
+
3
+ A tool for analyzing microservice boundaries using runtime traces from OpenTelemetry/Jaeger. It computes Service Cohesion Measure (SCOM) to detect services with low cohesion that may have wrong boundaries.
4
+
5
+ ## Prerequisites
6
+
7
+ - Python 3.11+
8
+ - Jaeger instance running (http://localhost:16686 by default)
9
+ - Your services instrumented with OpenTelemetry
10
+
11
+ ## Installation
12
+
13
+ ```powershell
14
+ python -m pip install -e .
15
+ ```
16
+
17
+ Or install dependencies manually:
18
+
19
+ ```powershell
20
+ python -m pip install requests pandas pyyaml dash plotly
21
+ ```
22
+
23
+ ## Configuration
24
+
25
+ Edit `config/settings.yaml`:
26
+
27
+ ```yaml
28
+ jaeger_base_url: "http://localhost:16686"
29
+ service_name: "YOUR_SERVICE_NAME" # Set to a real service from Jaeger
30
+ lookback_minutes: 10
31
+ limit_traces: 20
32
+ output_dir: "data/raw/traces"
33
+
34
+ # SCOM calculation method
35
+ # - "paper": CI/CImax normalization from the paper (endpoints < 2 => 0)
36
+ # - "weighted": weighted Jaccard (legacy)
37
+ # - "simple": unweighted Jaccard (legacy)
38
+ scom_method: "weighted" # Options: "paper", "weighted" or "simple"
39
+ table_weighting: true
40
+ endpoint_weighting: true
41
+
42
+ # Threshold method for suspicious services
43
+ threshold_method: "percentile" # Options: "percentile", "zscore", or "fixed"
44
+ threshold_percentile: 25.0
45
+ threshold_zscore: -1.5
46
+ scom_threshold: 0.5
47
+ ```
48
+
49
+ ## Pipeline Steps
50
+
51
+ Run the pipeline in order:
52
+
53
+ ## One-command (Professional) Usage
54
+
55
+ After installation, you can run the full pipeline with a single command.
56
+
57
+ ```powershell
58
+ boundary-analyzer run
59
+ ```
60
+
61
+ Equivalent:
62
+
63
+ ```powershell
64
+ python -m boundary_analyzer run
65
+ ```
66
+
67
+ ### Options
68
+
69
+ - **`--skip-collect`**
70
+ Skips Step 01 (Jaeger trace collection) and reuses the existing traces in the folder configured by `output_dir` in `config/settings.yaml`.
71
+
72
+ - **`--dashboard`**
73
+ Launches the dashboard after the pipeline completes.
74
+
75
+ - **`--data-dir <path>`**
76
+ Base directory containing `interim/` and `processed/` for the dashboard (default: `data`).
77
+
78
+ - **`--dash-host <host>`**
79
+ Dashboard bind host (default: `127.0.0.1`). Use `0.0.0.0` to expose on LAN.
80
+
81
+ - **`--dash-port <port>`**
82
+ Dashboard port (default: `8050`).
83
+
84
+ - **`--settings <path>`**
85
+ Path to `settings.yaml`. This applies to all pipeline steps.
86
+
87
+ Note: for MongoDB spans, the tool counts collections as "tables" (for backward compatibility in CSV/report columns).
88
+
89
+ ### Examples
90
+
91
+ Run everything (collect traces + compute results + report):
92
+
93
+ ```powershell
94
+ boundary-analyzer run
95
+ ```
96
+
97
+ Reuse traces already collected and open the dashboard:
98
+
99
+ ```powershell
100
+ boundary-analyzer run --skip-collect --dashboard
101
+ ```
102
+
103
+ Launch only the dashboard:
104
+
105
+ ```powershell
106
+ boundary-analyzer dashboard
107
+ ```
108
+
109
+ The dashboard is available by default at:
110
+
111
+ `http://127.0.0.1:8050`
112
+
113
+ Launch the dashboard for a different results folder:
114
+
115
+ ```powershell
116
+ boundary-analyzer dashboard --data-dir .\demo-service\scom_report
117
+ ```
118
+
119
+ ## Setup mode (when your project has no Jaeger / OpenTelemetry)
120
+
121
+ If your target project is not instrumented yet (no OpenTelemetry, no Jaeger), you can use the auto-setup command.
122
+ It will:
123
+ - detect the framework
124
+ - install OpenTelemetry packages (unless you pass `--no-install`)
125
+ - generate an instrumentation file for your app
126
+ - start Jaeger (unless you pass `--no-jaeger`)
127
+ - ask you to restart your app and send some traffic
128
+ - collect traces and run the analysis
129
+
130
+ ```powershell
131
+ boundary-analyzer setup --project-path .\path\to\your-service
132
+ ```
133
+
134
+ Common options:
135
+
136
+ - **`--framework <name>`**: force a framework instead of auto-detect
137
+ - **`--service-name <name>`**: set the Jaeger service name
138
+ - **`--no-jaeger`**: skip starting Jaeger (use if already running)
139
+ - **`--no-install`**: skip installing OpenTelemetry packages
140
+ - **`--jaeger-host <host>`**: Jaeger host (default: `localhost`)
141
+
142
+ Example:
143
+
144
+ ```powershell
145
+ boundary-analyzer setup --project-path .\demo-service --service-name demo-service
146
+ ```
147
+
148
+ Run setup and open the dashboard on the generated results:
149
+
150
+ ```powershell
151
+ boundary-analyzer setup --project-path .\demo-service --service-name demo-service --dashboard
152
+ ```
153
+
154
+ ### Step 01: Collect traces from Jaeger
155
+
156
+ Collects trace data from Jaeger API for a specific service.
157
+
158
+ ```powershell
159
+ python .\src\boundary_analyzer\pipeline\step_01_collect_traces.py
160
+ ```
161
+
162
+ **Output:** `data/raw/traces/jaeger_traces_{service}_{timestamp}.json`
163
+
164
+ ### Step 02: Read and flatten traces
165
+
166
+ Reads all trace files and flattens spans into a CSV format.
167
+
168
+ ```powershell
169
+ python .\src\boundary_analyzer\pipeline\step_02_read_traces.py
170
+ ```
171
+
172
+ **Output:** `data/interim/spans.csv`
173
+
174
+ ### Step 03: Find endpoints
175
+
176
+ Extracts HTTP endpoints from spans (method + route normalization).
177
+
178
+ ```powershell
179
+ python .\src\boundary_analyzer\pipeline\step_03_find_endpoints.py
180
+ ```
181
+
182
+ **Output:** `data/interim/endpoints.csv`
183
+
184
+ ### Step 04: Find database tables
185
+
186
+ Extracts database table names from SQL operations in spans.
187
+
188
+ ```powershell
189
+ python .\src\boundary_analyzer\pipeline\step_04_find_db_tables.py
190
+ ```
191
+
192
+ **Output:** `data/interim/db_operations.csv`
193
+
194
+ ### Step 05: Build endpoint-table mapping
195
+
196
+ Links endpoints to database tables by walking the span parent chain.
197
+
198
+ ```powershell
199
+ python .\src\boundary_analyzer\pipeline\step_05_build_mapping.py
200
+ ```
201
+
202
+ **Output:** `data/interim/endpoint_table_map.csv`
203
+
204
+ ### Step 06: Compute SCOM scores
205
+
206
+ Calculates Service Cohesion Measure for each service using weighted Jaccard similarity.
207
+
208
+ ```powershell
209
+ python .\src\boundary_analyzer\pipeline\step_06_compute_scom.py
210
+ ```
211
+
212
+ **Output:** `data/processed/service_scom.csv`
213
+
214
+ ### Step 07: Rank and flag suspicious services
215
+
216
+ Applies statistical threshold (percentile, Z-score, or fixed) to flag services with low cohesion.
217
+
218
+ ```powershell
219
+ python .\src\boundary_analyzer\pipeline\step_07_rank_and_flag.py
220
+ ```
221
+
222
+ **Output:**
223
+ - `data/processed/service_rank.csv`
224
+ - `data/processed/suspicious_services.csv`
225
+
226
+ ### Step 08: Generate report
227
+
228
+ Creates a Markdown report with analysis results.
229
+
230
+ ```powershell
231
+ python .\src\boundary_analyzer\pipeline\step_08_make_report.py
232
+ ```
233
+
234
+ **Output:** `reports/latest/report.md`
235
+
236
+ ## Dashboard
237
+
238
+ Launch the interactive dashboard to visualize results:
239
+
240
+ ```powershell
241
+ python .\src\boundary_analyzer\dashboard\app.py
242
+ ```
243
+
244
+ The dashboard will be available at `http://localhost:8050`
245
+
246
+ ## Quick Start
247
+
248
+ Run all steps in sequence:
249
+
250
+ ```powershell
251
+ python .\src\boundary_analyzer\pipeline\step_01_collect_traces.py
252
+ python .\src\boundary_analyzer\pipeline\step_02_read_traces.py
253
+ python .\src\boundary_analyzer\pipeline\step_03_find_endpoints.py
254
+ python .\src\boundary_analyzer\pipeline\step_04_find_db_tables.py
255
+ python .\src\boundary_analyzer\pipeline\step_05_build_mapping.py
256
+ python .\src\boundary_analyzer\pipeline\step_06_compute_scom.py
257
+ python .\src\boundary_analyzer\pipeline\step_07_rank_and_flag.py
258
+ python .\src\boundary_analyzer\pipeline\step_08_make_report.py
259
+ python .\src\boundary_analyzer\dashboard\app.py
260
+ ```
261
+
262
+ ## Documentation
263
+
264
+ See `docs/research_method.md` for detailed information about:
265
+ - Core concepts (coupling, cohesion, wrong cuts)
266
+ - Analysis method and limitations
267
+ - SCOM calculation formula
268
+ - Threshold selection methods
269
+ - Future improvements
@@ -0,0 +1,29 @@
1
+ [project]
2
+ name = "boundary-analyzer"
3
+ version = "0.2.0"
4
+ description = "SCOM-based microservice boundary analysis from Jaeger traces"
5
+ readme = "CHANGELOG.md"
6
+ license = "MIT"
7
+ authors = [{ name = "Ray Ague", email = "rayague03@gmail.com" }]
8
+ requires-python = ">=3.11"
9
+ dependencies = [
10
+ "requests>=2.31.0",
11
+ "pandas>=2.2.0",
12
+ "PyYAML>=6.0.1",
13
+ "dash>=2.14.0",
14
+ "plotly>=5.18.0",
15
+ ]
16
+
17
+ [project.urls]
18
+ Homepage = "https://github.com/rayague/measure-automation"
19
+ Repository = "https://github.com/rayague/measure-automation"
20
+
21
+ [project.scripts]
22
+ boundary-analyzer = "boundary_analyzer.cli:main"
23
+ mba = "boundary_analyzer.cli:main"
24
+
25
+ [tool.setuptools]
26
+ package-dir = {"" = "src"}
27
+
28
+ [tool.setuptools.packages.find]
29
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ from boundary_analyzer.cli import main
4
+
5
+
6
+ if __name__ == "__main__":
7
+ raise SystemExit(main())
@@ -0,0 +1,4 @@
1
+ # auto_setup/__init__.py
2
+ # This file makes auto_setup a proper Python package.
3
+ # You can import from it like:
4
+ # from auto_setup.setup_instrumentation import detect_framework
@@ -0,0 +1,48 @@
1
+ """
2
+ otel_instrumentation.py – Django / Django REST Framework
3
+ ==========================================================
4
+ This file sets up OpenTelemetry tracing for your Django application.
5
+
6
+ HOW IT WORKS:
7
+ - Every HTTP request Django handles becomes a span.
8
+ - Every ORM database query also becomes a span.
9
+ - All spans are sent to Jaeger.
10
+
11
+ YOU DO NOT NEED TO EDIT THIS FILE.
12
+ Add these 2 lines BEFORE django.setup() in your manage.py or wsgi.py:
13
+
14
+ from otel_instrumentation import init_tracing
15
+ init_tracing()
16
+ """
17
+
18
+ from opentelemetry import trace
19
+ from opentelemetry.sdk.trace import TracerProvider
20
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
21
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
22
+ from opentelemetry.sdk.resources import Resource
23
+ from opentelemetry.instrumentation.django import DjangoInstrumentor
24
+ from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
25
+
26
+
27
+ def init_tracing():
28
+ """
29
+ Call this function ONCE, before django.setup() is called.
30
+ """
31
+
32
+ resource = Resource.create({"service.name": "{{SERVICE_NAME}}"})
33
+
34
+ exporter = OTLPSpanExporter(
35
+ endpoint="http://{{JAEGER_HOST}}:{{JAEGER_GRPC_PORT}}"
36
+ )
37
+
38
+ provider = TracerProvider(resource=resource)
39
+ provider.add_span_processor(BatchSpanProcessor(exporter))
40
+ trace.set_tracer_provider(provider)
41
+
42
+ # Automatically trace every Django view / URL
43
+ DjangoInstrumentor().instrument()
44
+
45
+ # Automatically trace every ORM query
46
+ SQLAlchemyInstrumentor().instrument()
47
+
48
+ print(f"[OTel] Tracing enabled → Jaeger at {{JAEGER_HOST}}:{{JAEGER_GRPC_PORT}}")
@@ -0,0 +1,44 @@
1
+ """
2
+ otel_instrumentation.py – Django REST Framework
3
+ =================================================
4
+ Same setup as Django — DRF sits on top of Django,
5
+ so we instrument at the Django level.
6
+
7
+ Add these 2 lines BEFORE django.setup():
8
+
9
+ from otel_instrumentation import init_tracing
10
+ init_tracing()
11
+ """
12
+
13
+ # Django REST Framework uses the same Django instrumentation
14
+ from opentelemetry import trace
15
+ from opentelemetry.sdk.trace import TracerProvider
16
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
17
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
18
+ from opentelemetry.sdk.resources import Resource
19
+ from opentelemetry.instrumentation.django import DjangoInstrumentor
20
+ from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
21
+
22
+
23
+ def init_tracing():
24
+ """
25
+ Initialize tracing for Django REST Framework.
26
+ DRF is built on top of Django, so we instrument Django directly.
27
+ """
28
+ resource = Resource.create({"service.name": "{{SERVICE_NAME}}"})
29
+
30
+ exporter = OTLPSpanExporter(
31
+ endpoint="http://{{JAEGER_HOST}}:{{JAEGER_GRPC_PORT}}"
32
+ )
33
+
34
+ provider = TracerProvider(resource=resource)
35
+ provider.add_span_processor(BatchSpanProcessor(exporter))
36
+ trace.set_tracer_provider(provider)
37
+
38
+ # Instrument every DRF/Django view automatically
39
+ DjangoInstrumentor().instrument()
40
+
41
+ # Instrument every database query automatically
42
+ SQLAlchemyInstrumentor().instrument()
43
+
44
+ print(f"[OTel] Tracing enabled → Jaeger at {{JAEGER_HOST}}:{{JAEGER_GRPC_PORT}}")
@@ -0,0 +1,59 @@
1
+ """
2
+ otel_instrumentation.py – FastAPI
3
+ ===================================
4
+ This file sets up OpenTelemetry tracing for your FastAPI application.
5
+
6
+ HOW IT WORKS:
7
+ - Every HTTP request becomes a span (recorded event).
8
+ - Every database query (via SQLAlchemy) also becomes a span.
9
+ - All spans are sent to Jaeger so we can see and analyze them.
10
+
11
+ YOU DO NOT NEED TO EDIT THIS FILE.
12
+ Just call init_tracing() at the top of your main.py (before app = FastAPI()).
13
+ """
14
+
15
+ from opentelemetry import trace
16
+ from opentelemetry.sdk.trace import TracerProvider
17
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
18
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
19
+ from opentelemetry.sdk.resources import Resource
20
+ from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
21
+ from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
22
+
23
+
24
+ def init_tracing(app=None):
25
+ """
26
+ Call this function ONCE at the start of your app.
27
+
28
+ If you pass your FastAPI app object, HTTP routes will be traced automatically.
29
+ Example:
30
+ app = FastAPI()
31
+ init_tracing(app)
32
+
33
+ If you do not pass the app, call FastAPIInstrumentor().instrument_app(app)
34
+ after creating it.
35
+ """
36
+
37
+ # Tell Jaeger the name of this service
38
+ resource = Resource.create({"service.name": "{{SERVICE_NAME}}"})
39
+
40
+ # Send traces to Jaeger via gRPC
41
+ exporter = OTLPSpanExporter(
42
+ endpoint="http://{{JAEGER_HOST}}:{{JAEGER_GRPC_PORT}}"
43
+ )
44
+
45
+ provider = TracerProvider(resource=resource)
46
+ provider.add_span_processor(BatchSpanProcessor(exporter))
47
+ trace.set_tracer_provider(provider)
48
+
49
+ # Instrument database queries automatically
50
+ SQLAlchemyInstrumentor().instrument()
51
+
52
+ # Instrument the FastAPI app if provided
53
+ if app is not None:
54
+ FastAPIInstrumentor.instrument_app(app)
55
+ else:
56
+ # Will instrument the first FastAPI app created after this call
57
+ FastAPIInstrumentor().instrument()
58
+
59
+ print(f"[OTel] Tracing enabled → Jaeger at {{JAEGER_HOST}}:{{JAEGER_GRPC_PORT}}")
@@ -0,0 +1,53 @@
1
+ """
2
+ otel_instrumentation.py – Flask
3
+ ================================
4
+ This file sets up OpenTelemetry tracing for your Flask application.
5
+
6
+ HOW IT WORKS:
7
+ - Every HTTP request your app receives becomes a "span" (a recorded event).
8
+ - Every database query also becomes a span.
9
+ - All spans are sent to Jaeger so we can see them.
10
+
11
+ YOU DO NOT NEED TO EDIT THIS FILE.
12
+ Just call init_tracing() at the top of your main app file.
13
+ """
14
+
15
+ from opentelemetry import trace
16
+ from opentelemetry.sdk.trace import TracerProvider
17
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
18
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
19
+ from opentelemetry.sdk.resources import Resource
20
+ from opentelemetry.instrumentation.flask import FlaskInstrumentor
21
+ from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
22
+
23
+
24
+ def init_tracing():
25
+ """
26
+ Call this function ONCE at the start of your app.
27
+ It configures OpenTelemetry to send traces to Jaeger.
28
+ """
29
+
30
+ # 'resource' tells Jaeger which service these traces belong to
31
+ resource = Resource.create({"service.name": "{{SERVICE_NAME}}"})
32
+
33
+ # 'exporter' sends the traces to Jaeger over gRPC
34
+ exporter = OTLPSpanExporter(
35
+ endpoint="http://{{JAEGER_HOST}}:{{JAEGER_GRPC_PORT}}"
36
+ )
37
+
38
+ # 'provider' is the main tracing engine
39
+ provider = TracerProvider(resource=resource)
40
+
41
+ # 'processor' batches spans and sends them to the exporter
42
+ provider.add_span_processor(BatchSpanProcessor(exporter))
43
+
44
+ # Register the provider globally
45
+ trace.set_tracer_provider(provider)
46
+
47
+ # Automatically trace every Flask HTTP request
48
+ FlaskInstrumentor().instrument()
49
+
50
+ # Automatically trace every SQLAlchemy database query
51
+ SQLAlchemyInstrumentor().instrument()
52
+
53
+ print(f"[OTel] Tracing enabled → Jaeger at {{JAEGER_HOST}}:{{JAEGER_GRPC_PORT}}")