beamlit 0.0.34rc53__py3-none-any.whl → 0.0.34rc55__py3-none-any.whl

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.
@@ -1,7 +1,12 @@
1
+ import logging
1
2
  from typing import Any
2
3
 
3
4
  from fastapi import FastAPI
4
- from opentelemetry import metrics, trace
5
+ from opentelemetry import _logs, metrics, trace
6
+ from opentelemetry._logs import set_logger_provider
7
+ from opentelemetry.exporter.otlp.proto.grpc._log_exporter import (
8
+ OTLPLogExporter,
9
+ )
5
10
  from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import (
6
11
  OTLPMetricExporter,
7
12
  )
@@ -10,8 +15,9 @@ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
10
15
  )
11
16
  from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
12
17
  from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
13
- from opentelemetry.instrumentation.logging import LoggingInstrumentor
14
18
  from opentelemetry.metrics import NoOpMeterProvider
19
+ from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
20
+ from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
15
21
  from opentelemetry.sdk.metrics import MeterProvider
16
22
  from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
17
23
  from opentelemetry.sdk.resources import Resource
@@ -24,6 +30,7 @@ from .settings import get_settings
24
30
 
25
31
  tracer: trace.Tracer | None = None
26
32
  meter: metrics.Meter | None = None
33
+ logger: LoggerProvider | None = None
27
34
 
28
35
 
29
36
  def get_tracer() -> trace.Tracer:
@@ -38,6 +45,12 @@ def get_meter() -> metrics.Meter:
38
45
  return meter
39
46
 
40
47
 
48
+ def get_logger() -> LoggerProvider:
49
+ if logger is None:
50
+ raise Exception("Logger is not initialized")
51
+ return logger
52
+
53
+
41
54
  def get_resource_attributes() -> Dict[str, Any]:
42
55
  resources = Resource.create()
43
56
  resources_dict: Dict[str, Any] = {}
@@ -68,12 +81,17 @@ def get_span_exporter() -> OTLPSpanExporter | None:
68
81
  return OTLPSpanExporter()
69
82
 
70
83
 
84
+ def get_log_exporter() -> OTLPLogExporter | None:
85
+ settings = get_settings()
86
+ if not settings.enable_opentelemetry:
87
+ return None
88
+ return OTLPLogExporter()
89
+
90
+
71
91
  def instrument_app(app: FastAPI):
72
92
  global tracer
73
93
  global meter
74
94
  settings = get_settings()
75
- if settings is None:
76
- raise Exception("Settings are not initialized")
77
95
 
78
96
  if not settings.enable_opentelemetry:
79
97
  # Use NoOp implementations to stub tracing and metrics
@@ -113,11 +131,30 @@ def instrument_app(app: FastAPI):
113
131
  else:
114
132
  meter = metrics.get_meter(__name__)
115
133
 
134
+ if not isinstance(_logs.get_logger_provider(), LoggerProvider):
135
+ logger_provider = LoggerProvider()
136
+ set_logger_provider(logger_provider)
137
+ logger_provider.add_log_record_processor(
138
+ BatchLogRecordProcessor(get_log_exporter())
139
+ )
140
+ handler = LoggingHandler(
141
+ level=logging.NOTSET, logger_provider=logger_provider
142
+ )
143
+ logging.getLogger().addHandler(handler)
144
+ else:
145
+ logger_provider = _logs.get_logger_provider()
146
+
116
147
  # Only instrument the app when OpenTelemetry is enabled
117
- FastAPIInstrumentor.instrument_app(
118
- app=app, tracer_provider=trace.get_tracer_provider(), meter_provider=metrics.get_meter_provider()
119
- )
120
- HTTPXClientInstrumentor().instrument(meter_provider=metrics.get_meter_provider())
121
- LoggingInstrumentor(tracer_provider=trace.get_tracer_provider()).instrument(
122
- set_logging_format=True
123
- )
148
+ FastAPIInstrumentor.instrument_app(app)
149
+ HTTPXClientInstrumentor().instrument()
150
+
151
+
152
+ def shutdown_instrumentation():
153
+ if tracer is not None:
154
+ trace_provider = trace.get_tracer_provider()
155
+ if isinstance(trace_provider, TracerProvider):
156
+ trace_provider.shutdown()
157
+ if meter is not None:
158
+ meter_provider = metrics.get_meter_provider()
159
+ if isinstance(meter_provider, MeterProvider):
160
+ meter_provider.shutdown()
beamlit/serve/app.py CHANGED
@@ -3,6 +3,7 @@ import importlib
3
3
  import os
4
4
  import sys
5
5
  import traceback
6
+ from contextlib import asynccontextmanager
6
7
  from logging import getLogger
7
8
  from uuid import uuid4
8
9
 
@@ -13,9 +14,9 @@ from traceloop.sdk import Traceloop
13
14
 
14
15
  from beamlit.common import HTTPError, get_settings, init
15
16
  from beamlit.common.instrumentation import (
16
- get_metrics_exporter,
17
17
  get_resource_attributes,
18
18
  get_span_exporter,
19
+ shutdown_instrumentation,
19
20
  instrument_app,
20
21
  )
21
22
 
@@ -41,16 +42,14 @@ logger.info(
41
42
  f" on {settings.server.host}:{settings.server.port}"
42
43
  )
43
44
 
44
- if settings.enable_opentelemetry:
45
- Traceloop.init(
46
- app_name=settings.name,
47
- exporter=get_span_exporter(),
48
- metrics_exporter=get_metrics_exporter(),
49
- resource_attributes=get_resource_attributes(),
50
- should_enrich_metrics=os.getenv("ENRICHED_METRICS", "false") == "true",
51
- )
52
45
 
53
- app = FastAPI(docs_url=None, redoc_url=None)
46
+ @asynccontextmanager
47
+ async def lifespan(app: FastAPI):
48
+ yield
49
+ shutdown_instrumentation()
50
+
51
+
52
+ app = FastAPI(docs_url=None, redoc_url=None, lifespan=lifespan)
54
53
  app.add_middleware(
55
54
  CorrelationIdMiddleware,
56
55
  header_name="x-beamlit-request-id",
@@ -59,6 +58,13 @@ app.add_middleware(
59
58
  app.add_middleware(AddProcessTimeHeader)
60
59
  app.add_middleware(AccessLogMiddleware)
61
60
  instrument_app(app)
61
+ if settings.enable_opentelemetry:
62
+ Traceloop.init(
63
+ app_name=settings.name,
64
+ exporter=get_span_exporter(),
65
+ resource_attributes=get_resource_attributes(),
66
+ should_enrich_metrics=os.getenv("ENRICHED_METRICS", "false") == "true",
67
+ )
62
68
 
63
69
 
64
70
  @app.get("/health")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beamlit
3
- Version: 0.0.34rc53
3
+ Version: 0.0.34rc55
4
4
  Summary: Add your description here
5
5
  Author-email: cploujoux <ch.ploujoux@gmail.com>
6
6
  Requires-Python: >=3.12
@@ -17,7 +17,6 @@ Requires-Dist: opentelemetry-api>=1.28.2
17
17
  Requires-Dist: opentelemetry-exporter-otlp>=1.28.2
18
18
  Requires-Dist: opentelemetry-instrumentation-fastapi>=0.49b2
19
19
  Requires-Dist: opentelemetry-instrumentation-httpx>=0.49b2
20
- Requires-Dist: opentelemetry-instrumentation-logging>=0.49b2
21
20
  Requires-Dist: opentelemetry-sdk>=1.28.2
22
21
  Requires-Dist: pydantic-settings<2.7.0,>=2.6.1
23
22
  Requires-Dist: pydantic<2.11.0,>=2.10.3
@@ -130,7 +130,7 @@ beamlit/authentication/credentials.py,sha256=p_1xenabCbQuRz7BiFk7oTK4uCxAt_zoyku
130
130
  beamlit/authentication/device_mode.py,sha256=tmr22gllKOZwBRub_QjF5pYa425x-nE8tQNpZ_EGR6g,3644
131
131
  beamlit/common/__init__.py,sha256=saX5X3hRCJ9erSlXuSkZ2VGgquvpgdcofAU_9sM4bCE,354
132
132
  beamlit/common/error.py,sha256=f9oJDFxhoHK-vpjxBgEp0NwWIk0N_THPemUI7uQxVzU,270
133
- beamlit/common/instrumentation.py,sha256=GVYeat7qCcqzDoKSYig3s8ZCC172R9JiQIr3Evv3kik,4293
133
+ beamlit/common/instrumentation.py,sha256=bW3UN0Ca24zPFZSYjqWkrFfBVDp_yL10T3jVD403KvI,5386
134
134
  beamlit/common/logger.py,sha256=nN_dSOl4bs13QU3Rod-w3e3jYOnlSrHx3_bs-ACY6Aw,1115
135
135
  beamlit/common/secrets.py,sha256=sid81bOe3LflkMKDHwBsBs9nIju8bp5-v9qU9gkyNMc,212
136
136
  beamlit/common/settings.py,sha256=b2rvby-ufG3M0AB1ReoWFM-1EzF1LaE-gbokO9HvQDI,3810
@@ -252,10 +252,10 @@ beamlit/models/websocket_channel.py,sha256=jg3vN7yS_oOIwGtndtIUr1LsyEA58RXLXahqS
252
252
  beamlit/models/workspace.py,sha256=l__bIpbA4oJvxXo7UbEoCcqkvu9MiNt5aXXpZ3bgwHg,4309
253
253
  beamlit/models/workspace_labels.py,sha256=WbnUY6eCTkUNdY7hhhSF-KQCl8fWFfkCf7hzCTiNp4A,1246
254
254
  beamlit/models/workspace_user.py,sha256=70CcifQWYbeWG7TDui4pblTzUe5sVK0AS19vNCzKE8g,3423
255
- beamlit/serve/app.py,sha256=DXWxQoMeuA5FYvBMyLrP94OEWQbwLf4GZk3I9fkwSPA,3523
255
+ beamlit/serve/app.py,sha256=gYQvUK_S7g0Em-idND8HrVDqgg5LlIemheSGlX2Jj8U,3638
256
256
  beamlit/serve/middlewares/__init__.py,sha256=1dVmnOmhAQWvWktqHkKSIX-YoF6fmMU8xkUQuhg_rJU,148
257
257
  beamlit/serve/middlewares/accesslog.py,sha256=Mu4T4_9OvHybjA0ApzZFpgi2C8f3X1NbUk-76v634XM,631
258
258
  beamlit/serve/middlewares/processtime.py,sha256=lDAaIasZ4bwvN-HKHvZpaD9r-yrkVNZYx4abvbjbrCg,411
259
- beamlit-0.0.34rc53.dist-info/METADATA,sha256=mYmSQ4b1y6e0X4Ead4ZQOE4Bk0akR7ot4Q-7NOCzC9I,2405
260
- beamlit-0.0.34rc53.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
261
- beamlit-0.0.34rc53.dist-info/RECORD,,
259
+ beamlit-0.0.34rc55.dist-info/METADATA,sha256=4yvNNr_yX2lRYsd14PFw8dB6ykRdp1BIBe0lKOeckM4,2344
260
+ beamlit-0.0.34rc55.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
261
+ beamlit-0.0.34rc55.dist-info/RECORD,,