phlo-otel 0.1.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.
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: phlo-otel
3
+ Version: 0.1.0
4
+ Summary: OpenTelemetry traces and metrics for Phlo
5
+ Author-email: Phlo Team <team@phlo.dev>
6
+ License: MIT
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/plain
9
+ Requires-Dist: phlo>=0.1.0
10
+ Requires-Dist: opentelemetry-api>=1.27.0
11
+ Requires-Dist: opentelemetry-sdk>=1.27.0
12
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.27.0
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest>=7.0; extra == "dev"
15
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
16
+
17
+ OpenTelemetry instrumentation for Phlo hook events.
@@ -0,0 +1,166 @@
1
+ # phlo-otel
2
+
3
+ OpenTelemetry instrumentation for Phlo. Translates hook events into OTel traces and metrics.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ uv pip install -e packages/phlo-otel
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ Uses standard OTel environment variables, with Phlo settings as defaults when
14
+ the OTel variables are unset:
15
+
16
+ | Variable | Default | Description |
17
+ |---|---|---|
18
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4317` | OTLP gRPC endpoint |
19
+ | `OTEL_SERVICE_NAME` | `PHLO_LOG_SERVICE_NAME` or `phlo` | Service name in traces/metrics |
20
+ | `OTEL_SERVICE_NAMESPACE` | `PHLO_SERVICE_NAMESPACE` or `phlo` | Service namespace |
21
+ | `OTEL_SERVICE_VERSION` | `PHLO_SERVICE_VERSION` or `0.1.0` | Service version attached to resources |
22
+ | `OTEL_SERVICE_INSTANCE_ID` | `PHLO_SERVICE_INSTANCE_ID` or hostname | Service instance identifier |
23
+ | `OTEL_TRACES_EXPORTER` | unset | Set to `otlp` or configure an OTLP endpoint to enable trace export |
24
+ | `OTEL_METRICS_EXPORTER` | unset | Set to `otlp` or configure an OTLP endpoint to enable metrics export |
25
+ | `OTEL_LOGS_EXPORTER` | `none` | Set to `otlp` to enable OTLP log export |
26
+ | `PHLO_PROJECT` | `PHLO_PROJECT` setting or service name | Project identifier attached to resources |
27
+
28
+ Additional resource metadata comes from Phlo settings and `OTEL_RESOURCE_ATTRIBUTES`,
29
+ including `deployment.environment`, `phlo.package`, `phlo.runtime`, and
30
+ `phlo.project`.
31
+
32
+ Phlo settings supported for resource defaults:
33
+
34
+ - `PHLO_LOG_SERVICE_NAME`
35
+ - `PHLO_SERVICE_NAMESPACE`
36
+ - `PHLO_SERVICE_VERSION`
37
+ - `PHLO_SERVICE_INSTANCE_ID`
38
+ - `PHLO_PROJECT`
39
+ - `PHLO_ENVIRONMENT`
40
+
41
+ ## What gets instrumented
42
+
43
+ | Hook Event | Trace Span | Metric |
44
+ |---|---|---|
45
+ | `IngestionEvent` | `ingestion.<table>` | `phlo.ingestion.runs`, `phlo.ingestion.rows`, `phlo.ingestion.duration` |
46
+ | `TransformEvent` | `transform.<tool>.<target>` | `phlo.transform.runs`, `phlo.transform.duration` |
47
+ | `QualityResultEvent` | `quality.<check>` | `phlo.quality.checks` |
48
+ | `LineageEvent` | `lineage.edges` | `phlo.lineage.events`, `phlo.lineage.edges` |
49
+ | `PublishEvent` | `publish.<target_system>` | `phlo.publish.runs`, `phlo.publish.tables`, `phlo.publish.duration` |
50
+ | `ServiceLifecycleEvent` | `service.<service>.<phase>` | `phlo.service.lifecycle.events` |
51
+ | `SchemaMigrationEvent` | `schema_migration.<table>` | `phlo.schema_migration.runs`, `phlo.schema_migration.changes` |
52
+ | `DataMigrationEvent` | `data_migration.<migration>` | `phlo.data_migration.runs`, `phlo.data_migration.rows_read`, `phlo.data_migration.rows_written`, `phlo.data_migration.duration` |
53
+ | `TelemetryEvent` | — | `phlo.telemetry.<name>` fallback (`gauge` by default; `counter`, `histogram`, and `up_down_counter` supported via payload) |
54
+ | `LogEvent` | — | OTLP log records with Phlo correlation attributes |
55
+
56
+ Trace and metric export activate when you configure an OTLP endpoint or set the
57
+ standard exporter env vars. OTLP log export is supported but stays opt-in.
58
+ Failure statuses across workflow events also increment `phlo.errors`.
59
+ Spans and OTLP log records carry shared correlation fields when hook producers
60
+ provide them, including `run_id`, `asset_key`, `partition_key`, `job_name`,
61
+ and trace/span identifiers.
62
+
63
+ ### Backend routing
64
+
65
+ `phlo-otel` stays backend-neutral. Recommended routing patterns:
66
+
67
+ - `phlo-otel -> Alloy -> Grafana-native backends`
68
+ - `phlo-otel -> OpenTelemetry Collector -> multiple downstream backends`
69
+ - `phlo-otel -> Collector -> ClickStack`
70
+
71
+ Collector configuration should own backend fan-out and backend-specific exporters.
72
+ Do not add a dedicated ClickStack exporter path inside `phlo-otel`.
73
+
74
+ ### Stable semantic attributes
75
+
76
+ Representative spans and OTLP log records include a stable semantic envelope:
77
+
78
+ - `phlo.event_type`
79
+ - `phlo.stage`
80
+ - `phlo.system`
81
+ - `phlo.operation` when a bounded operation is available
82
+ - `phlo.status` when the source event carries status
83
+
84
+ Examples:
85
+
86
+ - ingestion spans: `phlo.stage=ingestion`
87
+ - transform spans: `phlo.stage=transform`, `phlo.system=dbt`
88
+ - publish spans: `phlo.stage=publish`, `phlo.system=<target_system>`, `phlo.operation=publish`
89
+ - service lifecycle spans: `phlo.stage=service`, `phlo.operation=<phase>`
90
+ - migration spans: `phlo.stage=migration`
91
+
92
+ Example:
93
+
94
+ ```bash
95
+ export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
96
+ export OTEL_TRACES_EXPORTER=otlp
97
+ export OTEL_METRICS_EXPORTER=otlp
98
+ export OTEL_LOGS_EXPORTER=otlp
99
+ ```
100
+
101
+ ### Telemetry metric kinds
102
+
103
+ `TelemetryEvent(event_type="telemetry.metric")` defaults to a gauge. Override the
104
+ instrument type with `payload["metric_kind"]` or `payload["otel_metric_kind"]`.
105
+
106
+ Supported values:
107
+
108
+ - `gauge`
109
+ - `counter`
110
+ - `histogram`
111
+ - `up_down_counter`
112
+
113
+ Example:
114
+
115
+ ```python
116
+ telemetry.emit_metric(
117
+ name="rows_written",
118
+ value=250,
119
+ unit="rows",
120
+ payload={"metric_kind": "counter", "source": "nightscout"},
121
+ )
122
+ ```
123
+
124
+ ### Metric label policy
125
+
126
+ Telemetry metric payloads are filtered to low-cardinality labels before export.
127
+ Allowed label keys currently include:
128
+
129
+ - `backend`
130
+ - `classification`
131
+ - `environment`
132
+ - `namespace`
133
+ - `operation`
134
+ - `phase`
135
+ - `result`
136
+ - `service`
137
+ - `source`
138
+ - `source_type`
139
+ - `status`
140
+ - `target`
141
+ - `target_system`
142
+ - `tool`
143
+
144
+ Identifiers such as `run_id`, `partition_key`, and `asset_key` stay in traces
145
+ and logs rather than metric labels.
146
+
147
+ ### Maintenance metric promotion
148
+
149
+ Known Iceberg maintenance telemetry is promoted into bounded workflow metrics:
150
+
151
+ - `iceberg.maintenance.run` -> `phlo.maintenance.runs`
152
+ - `iceberg.maintenance.duration_seconds` -> `phlo.maintenance.duration`
153
+ - `iceberg.maintenance.tables_processed` -> `phlo.maintenance.tables_processed`
154
+ - `iceberg.maintenance.errors` -> `phlo.maintenance.errors`
155
+ - `iceberg.maintenance.snapshots_deleted` -> `phlo.maintenance.snapshots_deleted`
156
+ - `iceberg.maintenance.orphan_files` -> `phlo.maintenance.orphan_files`
157
+ - `iceberg.maintenance.total_records` -> `phlo.maintenance.records_processed`
158
+ - `iceberg.maintenance.total_size_mb` -> `phlo.maintenance.size_mb`
159
+
160
+ Unknown telemetry names still fall back to `phlo.telemetry.<name>`.
161
+
162
+ ## Architecture
163
+
164
+ Hooks into the existing `HookBus` as a `HookPlugin`, alongside core telemetry hook handling.
165
+ Point the OTLP exporters at Alloy or OpenTelemetry Collector, then route onward
166
+ to your trace, metric, and log backends there.
@@ -0,0 +1,39 @@
1
+ [build-system]
2
+ requires = ["setuptools>=45", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "phlo-otel"
7
+ version = "0.1.0"
8
+ description = "OpenTelemetry traces and metrics for Phlo"
9
+ readme = {text = "OpenTelemetry instrumentation for Phlo hook events.", content-type = "text/plain"}
10
+ requires-python = ">=3.11"
11
+ authors = [
12
+ {name = "Phlo Team", email = "team@phlo.dev"},
13
+ ]
14
+ license = {text = "MIT"}
15
+ dependencies = [
16
+ "phlo>=0.1.0",
17
+ "opentelemetry-api>=1.27.0",
18
+ "opentelemetry-sdk>=1.27.0",
19
+ "opentelemetry-exporter-otlp-proto-grpc>=1.27.0",
20
+ ]
21
+
22
+ [project.optional-dependencies]
23
+ dev = [
24
+ "pytest>=7.0",
25
+ "ruff>=0.1.0",
26
+ ]
27
+
28
+ [project.entry-points."phlo.plugins.hooks"]
29
+ otel = "phlo_otel.hooks_plugin:OtelHookPlugin"
30
+
31
+ [tool.setuptools]
32
+ package-dir = {"" = "src"}
33
+
34
+ [tool.setuptools.packages.find]
35
+ where = ["src"]
36
+
37
+ [tool.ruff]
38
+ line-length = 100
39
+ target-version = "py311"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,10 @@
1
+ """OpenTelemetry instrumentation for Phlo hook events."""
2
+
3
+ from phlo_otel.provider import get_log_emitter, get_meter, get_tracer, shutdown_otel
4
+
5
+ __all__ = [
6
+ "get_log_emitter",
7
+ "get_tracer",
8
+ "get_meter",
9
+ "shutdown_otel",
10
+ ]