Testing & Debugging
TutorialTesting & Debugging Python Extensions
Python extensions run inside the EEC/ActiveGate process. When they break, you need to know where to look and what the error patterns mean.
Log Locations
# Extension datasource logs (your extension's output)
/var/lib/dynatrace/remotepluginmodule/log/extensions/datasources/{extension-name}/
# EEC general logs
/var/lib/dynatrace/remotepluginmodule/log/extensions/
# ActiveGate logs
/var/log/dynatrace/gateway/
# Fastcheck logs (startup validation)
/var/lib/dynatrace/remotepluginmodule/log/extensions/datasources/
Common Error Patterns
1. Missing __main__.py
ERROR: No module named 'your_extension.__main__'
Fix: Add __main__.py with main() entry point. The EEC runs python -m your_package.
2. Import Errors
ModuleNotFoundError: No module named 'some_library'
Fix: Bundle dependencies in the wheel. Use pip wheel to include all deps, or add them to setup.py / pyproject.toml.
3. Authentication Failures
ERROR: 401 Unauthorized - API call to https://device/api/status failed
Fix: Check monitoring configuration credentials. Verify the token/password is correct and hasn't expired.
4. Timeout During Collection
ERROR: Connection timed out after 30s - https://device/api/data
Fix: Increase timeout, check network connectivity from ActiveGate to target device. Consider if the API is slow and needs pagination.
5. Extension Crash Loop
Extension process exited with code 1, restarting...
Extension process exited with code 1, restarting...
Fix: Unhandled exception in initialize() or collect_data(). Wrap everything in try/except. Check the datasource log for the actual traceback.
Debugging Workflow
- Check extension status in Dynatrace UI: Settings → Extensions → your extension → Monitoring configurations → Status
- Read the datasource log:
tail -100 /var/lib/dynatrace/remotepluginmodule/log/extensions/datasources/{name}/*.log - Check fastcheck: If the extension never starts collecting, fastcheck failed. Look for
fastcheckin the log. - Verify metrics arrive: Query
GET /api/v2/metrics?text={prefix}— if no metrics appear, the extension isn't reporting successfully. - Check entity creation:
GET /api/v2/entities?entitySelector=type({your_type})
Local Testing (Before Deployment)
You can test your Python code locally before packaging:
# Install the SDK
pip install dynatrace-extension
# Run with a mock config
python -m your_extension --local-config config.json
Create a config.json with your monitoring configuration values:
{
"url": "https://test-device.local",
"api_token": "test-token-123",
"endpoints": [
{"url": "https://device1.local", "name": "Device 1"}
]
}
Packaging for Deployment
# 1. Build the wheel
cd your_extension/
python -m build --wheel
# 2. Place wheel in extension package
mkdir -p ext/lib
cp dist/your_extension-0.0.1-py3-none-any.whl ext/lib/
# 3. Create extension.yaml in ext/
# 4. Assemble and sign (same as SNMP)
dt ext assemble --source ext --output extension.zip
dt ext sign --src extension.zip --key developer.pem --output bundle.zip
Real Debug Story: Waze Police v0.0.1
The extension uploaded fine but never reported metrics. The datasource log showed:
ERROR: No module named 'waze_police.__main__'
Root cause: the wheel was built without __main__.py. The __init__.py had the Extension class, but the EEC needs __main__.py as the entry point because it runs python -m waze_police.
Fix: Added __main__.py with:
from .extension import WazePoliceExtension
def main():
WazePoliceExtension().run()
if __name__ == "__main__":
main()
Real Debug Story: Nexus SNMPv2c Bug
The Nexus extension (Python + SNMP hybrid) had 50 missing SNMP metrics. The code at line 106-115 only handled SNMPv1 and SNMPv3 — SNMPv2c fell through to the SNMPv3 handler, causing authentication failures on every SNMP poll. The NX-API metrics worked fine because they used REST, not SNMP.
# Bug (v0.0.1):
if version == "v1":
self.auth = CommunityData(community, mpModel=0)
# v2 case missing! Falls through to:
else: # v3
self.auth = UsmUserData(...)
# Fix:
if version == "v1":
self.auth = CommunityData(community, mpModel=0)
elif version == "v2":
self.auth = CommunityData(community, mpModel=1)
else: # v3
self.auth = UsmUserData(...)
🛠 Hands-On Exercise
Edit the YAML in the editor, then click "Check My Work" to validate.
Debug This Extension
This extension YAML has 4 bugs that would cause problems in production. Find and fix them all:
- A scalar OID missing
.0(would fail SNMP GET) - A count metric with wrong key naming
- A metric used in snmp: but missing from metrics: metadata
- A table subgroup with a scalar OID ending in
.0
This is the kind of pre-deployment validation you'd do on every extension before shipping.