🐍 Python Extensions — Module 12

Testing & Debugging

Tutorial

Testing & 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

  1. Check extension status in Dynatrace UI: Settings → Extensions → your extension → Monitoring configurations → Status
  2. Read the datasource log: tail -100 /var/lib/dynatrace/remotepluginmodule/log/extensions/datasources/{name}/*.log
  3. Check fastcheck: If the extension never starts collecting, fastcheck failed. Look for fastcheck in the log.
  4. Verify metrics arrive: Query GET /api/v2/metrics?text={prefix} — if no metrics appear, the extension isn't reporting successfully.
  5. 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.

extension.yamlYAML
Loading...