Skip to content

Commit 513e647

Browse files
committed
chore: fmt
1 parent 09be39f commit 513e647

1 file changed

Lines changed: 117 additions & 36 deletions

File tree

python/src/otel/otel_sdk/otel_wrapper.py

Lines changed: 117 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -110,61 +110,142 @@ def _load_instrumentations():
110110
- OTEL_PYTHON_DISABLED_INSTRUMENTATIONS: Disable specific instrumentations (comma-separated)
111111
112112
Available optional instrumentations:
113-
- requests: Popular HTTP client library
114-
- urllib: Standard library HTTP client
115-
- urllib3: Low-level HTTP client library
116-
- Database libraries: psycopg2, pymongo, pymysql, etc.
117-
118-
Example: OTEL_PYTHON_ENABLED_INSTRUMENTATIONS=requests,psycopg2
113+
- HTTP clients: requests, aiohttp-client, urllib, urllib3
114+
- Web frameworks: django, flask, fastapi, starlette, falcon, pyramid, tornado
115+
- Databases: psycopg2, pymongo, pymysql, mysql, asyncpg, sqlite3, sqlalchemy
116+
- AWS services: boto, boto3sqs
117+
- Messaging: celery, redis
118+
- Other: grpc, jinja2, pymemcache, elasticsearch, wsgi, asgi, dbapi
119+
120+
Example: OTEL_PYTHON_ENABLED_INSTRUMENTATIONS=requests,psycopg2,redis
119121
"""
120122
active_instrumentations = _get_active_instrumentations()
121123

124+
# Instrumentation registry - maps names to import paths and instrumentor classes
125+
# Format: "name": ("module.path", "InstrumentorClass")
126+
INSTRUMENTATIONS = {
127+
# botocore is always loaded (see below), included here for completeness
128+
"botocore": (
129+
"opentelemetry.instrumentation.botocore",
130+
"BotocoreInstrumentor",
131+
),
132+
# HTTP Clients
133+
"requests": (
134+
"opentelemetry.instrumentation.requests",
135+
"RequestsInstrumentor",
136+
),
137+
"aiohttp-client": (
138+
"opentelemetry.instrumentation.aiohttp_client",
139+
"AioHttpClientInstrumentor",
140+
),
141+
"urllib": ("opentelemetry.instrumentation.urllib", "URLLibInstrumentor"),
142+
"urllib3": ("opentelemetry.instrumentation.urllib3", "URLLib3Instrumentor"),
143+
# Web Frameworks
144+
"django": ("opentelemetry.instrumentation.django", "DjangoInstrumentor"),
145+
"flask": ("opentelemetry.instrumentation.flask", "FlaskInstrumentor"),
146+
"fastapi": ("opentelemetry.instrumentation.fastapi", "FastAPIInstrumentor"),
147+
"starlette": (
148+
"opentelemetry.instrumentation.starlette",
149+
"StarletteInstrumentor",
150+
),
151+
"falcon": ("opentelemetry.instrumentation.falcon", "FalconInstrumentor"),
152+
"pyramid": ("opentelemetry.instrumentation.pyramid", "PyramidInstrumentor"),
153+
"tornado": ("opentelemetry.instrumentation.tornado", "TornadoInstrumentor"),
154+
# Databases
155+
"psycopg2": (
156+
"opentelemetry.instrumentation.psycopg2",
157+
"Psycopg2Instrumentor",
158+
),
159+
"pymongo": ("opentelemetry.instrumentation.pymongo", "PymongoInstrumentor"),
160+
"pymysql": ("opentelemetry.instrumentation.pymysql", "PyMySQLInstrumentor"),
161+
"mysql": (
162+
"opentelemetry.instrumentation.mysql",
163+
"MySQLInstrumentor",
164+
),
165+
"asyncpg": ("opentelemetry.instrumentation.asyncpg", "AsyncPGInstrumentor"),
166+
"sqlite3": ("opentelemetry.instrumentation.sqlite3", "SQLite3Instrumentor"),
167+
"sqlalchemy": (
168+
"opentelemetry.instrumentation.sqlalchemy",
169+
"SQLAlchemyInstrumentor",
170+
),
171+
# AWS Services
172+
"boto": ("opentelemetry.instrumentation.boto", "BotoInstrumentor"),
173+
"boto3sqs": ("opentelemetry.instrumentation.boto3sqs", "Boto3SQSInstrumentor"),
174+
# Messaging & Caching
175+
"celery": ("opentelemetry.instrumentation.celery", "CeleryInstrumentor"),
176+
"redis": ("opentelemetry.instrumentation.redis", "RedisInstrumentor"),
177+
"pymemcache": (
178+
"opentelemetry.instrumentation.pymemcache",
179+
"PymemcacheInstrumentor",
180+
),
181+
# Search
182+
"elasticsearch": (
183+
"opentelemetry.instrumentation.elasticsearch",
184+
"ElasticsearchInstrumentor",
185+
),
186+
# RPC
187+
"grpc": ("opentelemetry.instrumentation.grpc", "GrpcInstrumentorClient"),
188+
# Templating
189+
"jinja2": ("opentelemetry.instrumentation.jinja2", "Jinja2Instrumentor"),
190+
# WSGI/ASGI
191+
"wsgi": ("opentelemetry.instrumentation.wsgi", "OpenTelemetryMiddleware"),
192+
"asgi": ("opentelemetry.instrumentation.asgi", "OpenTelemetryMiddleware"),
193+
# Database API
194+
"dbapi": ("opentelemetry.instrumentation.dbapi", "trace_integration"),
195+
}
196+
122197
# botocore (AWS SDK) - ALWAYS loaded for Lambda (like Node.js AwsInstrumentation)
123198
try:
124199
from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
125200

126201
BotocoreInstrumentor().instrument()
127-
logger.debug("Loaded botocore instrumentation")
202+
logger.debug("Loaded botocore instrumentation (always enabled)")
128203
except ImportError:
129204
logger.warning("botocore instrumentation not available")
130205
except Exception as e:
131206
logger.warning(f"Failed to load botocore instrumentation: {e}")
132207

133-
# requests (HTTP library) - commonly used in Lambda for external API calls
134-
if "requests" in active_instrumentations:
135-
try:
136-
from opentelemetry.instrumentation.requests import RequestsInstrumentor
137-
138-
RequestsInstrumentor().instrument()
139-
logger.debug("Loaded requests instrumentation")
140-
except ImportError:
141-
logger.debug("requests instrumentation not available")
142-
except Exception as e:
143-
logger.warning(f"Failed to load requests instrumentation: {e}")
144-
145-
# urllib (standard library HTTP) - rarely used in Lambda but available
146-
if "urllib" in active_instrumentations:
147-
try:
148-
from opentelemetry.instrumentation.urllib import URLLibInstrumentor
208+
# Load optional instrumentations based on active_instrumentations
209+
for name, (module_path, class_name) in INSTRUMENTATIONS.items():
210+
# Skip botocore since it's always loaded above
211+
if name == "botocore":
212+
continue
149213

150-
URLLibInstrumentor().instrument()
151-
logger.debug("Loaded urllib instrumentation")
152-
except ImportError:
153-
logger.debug("urllib instrumentation not available")
154-
except Exception as e:
155-
logger.warning(f"Failed to load urllib instrumentation: {e}")
214+
# Check if this instrumentation should be loaded
215+
if name not in active_instrumentations:
216+
continue
156217

157-
# urllib3 (HTTP library) - rarely used directly in Lambda but available
158-
if "urllib3" in active_instrumentations:
159218
try:
160-
from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor
219+
# Dynamically import the instrumentation module
220+
module = importlib.import_module(module_path)
221+
instrumentor_class = getattr(module, class_name)
222+
223+
# Special handling for certain instrumentations
224+
if name in ("wsgi", "asgi"):
225+
# WSGI/ASGI are middleware, not instrumentors - skip auto-loading
226+
logger.debug(
227+
f"Skipping {name} instrumentation (middleware, not auto-instrumentable)"
228+
)
229+
continue
230+
elif name == "dbapi":
231+
# dbapi is a function, not a class - skip auto-loading
232+
logger.debug(
233+
f"Skipping {name} instrumentation (requires manual integration)"
234+
)
235+
continue
236+
237+
# Instrument the library
238+
instrumentor_class().instrument()
239+
logger.debug(f"Loaded {name} instrumentation")
161240

162-
URLLib3Instrumentor().instrument()
163-
logger.debug("Loaded urllib3 instrumentation")
164241
except ImportError:
165-
logger.debug("urllib3 instrumentation not available")
242+
logger.debug(
243+
f"{name} instrumentation not available (package not installed)"
244+
)
245+
except AttributeError as e:
246+
logger.warning(f"Failed to find {class_name} in {module_path}: {e}")
166247
except Exception as e:
167-
logger.warning(f"Failed to load urllib3 instrumentation: {e}")
248+
logger.warning(f"Failed to load {name} instrumentation: {e}")
168249

169250

170251
def _configure_logger():

0 commit comments

Comments
 (0)