@@ -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
170251def _configure_logger ():
0 commit comments