Extension Structure

The basic bare-bone structure of an extension is as follows:

my_extension
├── README.md
├── activation.json
├── extension
│   ├── activationSchema.json
│   └── extension.yaml
├── my_extension
│   ├── __init__.py
│   └── __main__.py
└── setup.py

This structure can be generated by running the Create command dt-sdk create my_extension.

Extension Definition

extension.yaml

This is the main configuration file of the extension. It contains information about the extension name, version, and so on.

Here is what a sample extension definition looks like:

name: custom:my-extension
version: 0.0.1
minDynatraceVersion: "1.285"
author:
  name: "Dynatrace"

python:
  runtime:
    module: my_extension
    version:
      min: "3.10"

  activation:
    remote:
      path: activationSchema.json
    local:
      path: activationSchema.json

Extension Name

name:

All extensions must have a unique name. The name must be in the custom: namespace, when it is a custom extension.

Official extensions

Only Dynatrace can create extensions in the com.dynatrace.extension namespace. These extensions are signed by Dynatrace and are considered official.

Extension Version

version:

The version field must be bumped every time the extension is uploaded to the environment. Otherwise an error will be thrown. The environment does not accept the same version twice. Each uploaded version must always be unique for the audit tracking purposes.

Minimal Dynatrace Version

minDynatraceVersion:

The minDynatraceVersion field specifies the minimal Dynatrace version that is required to run the extension. If the ActiveGate or OneAgent version is lower than the specified one, then the extension will not be activated on that agent.

This is useful when the extension uses some of the new features that are not yet available in the older versions of Dynatrace environment or extension execution controller.

Python

python:

This is a specification of datasource that Extension Framework understands. There are different datasources that can be used to collect data from the multitude of sources.

Datasources

Other datasources include snmp, jmx, prometheus, sql, wmi.

They can’t be used within the same extension, but all EF2.0 extensions follow the same format, where there is the extension.yaml file, which contains the required definition of the datasource.

Python Runtime

runtime:

Here we can specify which minimal version of Python is required to run the extension. This does not play a big role, since the version of Python is determined by what is received from ActiveGate or OneAgent. This field is mandatory.

Don’t bring your own Python

Custom Python runtime is not supported. ActiveGate and OneAgent supply the Python interpreter for the extension to be able to run. It is impossible to specify a custom Python interpreter or use one that is installed on the system.

The module field specifies the name of the main Python module that contains the extension logic. This module must be importable by the Python interpreter, thus it must always contain the __init__.py file to be considered a valid Python module.

Datasource Activation

activation:

This is a specification of the datasource activation. It might contain local: and remote: sections or only one of them.

  • local: means the extension can run on OneAgent. When you deploy the extension, the environment will automatically read this value and will understand that an active OneAgent is required to run this extension.

  • remote: means the extension can run on ActiveGate. When you deploy the extension, the environment will automatically read this value and will understand that an active ActiveGate is required to run this extension.

The path: within the activation section contains a path to the configuration that specifies a full definition of the monitoring configuration. What fields must be there? Of what type? Does it contain lists? What are the possible values? All of these can be describied in the activationSchema.json file.

Activation Schema

activationSchema.json

This is a schema file that describes the structure of the monitoring configuration.

For the purposes of giving an example, here is a very simple schema with a single field that will run on ActiveGate. The schema generated by the Create command is much larger and contains more fields, passwords, list items, and so on.

{
    "types": {
        "pythonRemote": {
            "type": "object",
            "properties": {
                "host": {
                "displayName": "Host",
                "type": "text",
                "nullable": false,
                "default": ""
                }
            }
        }
    },
    "dynatrace": "1",
    "description": "Extension configuration",
    "schemaId": "python-extension.activation",
    "displayName": "Extension configuration",
    "ownerProductManagement": "Albus Dumbledore",
    "ownerDevelopment": "Peter Parker",
    "maturity": "GENERAL_AVAILABILITY",
    "allowedScopes": ["environment"],
    "multiObject": false,
    "properties": {
        "pythonRemote": {
        "displayName": "Python Remote Extension",
            "type": {
                "$ref": "#/types/pythonRemote"
            }
        }
    }
}

Activation Config

activation.json

This is a config file that can be used for local testing, when extension instance is launched using the Run command. It must contain all of the mandatory fields as defined in the Activation Schema.

When extension is deployed to the Dynatrace environment and monitoring configuration is created, then the environment provides an individual activation config for each instance of the extension.

Here is what a sample activation config looks like:

{
    "enabled": true,
    "description": "my_extension activation",
    "version": "0.0.1",
    "activationContext": "REMOTE",
    "pythonRemote": {
        "endpoints": [
            {
                "url": "http://127.0.0.1:15672",
                "user": "guest",
                "password": "guest"
            }
        ]
    }
}

Setup.py

setup.py

This is a standard Python setup file that is used to package the extension and is used by the extension execution controller to install the extension on the ActiveGate or OneAgent along with the required dependencies.

from setuptools import setup, find_packages

setup(
    name="my_extension",
    version="0.0.1",
    description="My_extension python EF2 extension",
    author="Dynatrace",
    packages=find_packages(),
    python_requires=">=3.10",
    include_package_data=True,
    install_requires=["dt-extensions-sdk"],
    extras_require={"dev": ["dt-extensions-sdk[cli]"]},
)

Dependencies

The setup.py file is the place where any dependencies must be specified in the install_requires section.

The dt-extensions-sdk package must always be specified as a dependency. However, theoretically, it is possible to write a Python code that will be capable of communication with the extension execution controller without using the SDK.

We do not recommend doing that, since the SDK provides everything that is needed and getting rid of it is an equivalent of reinventing the wheel.

Bumping version

When bumping the version of the extension in the extension.yaml, the setup.py file must be updated as well. The two versions must match.

Extension size

Be careful when adding dependencies to the extension. The size of the extension must not exceed 15MB. If it does, then the extension will not be accepted by the environment.

When building the extension using the Build command, the dependencies can be downloaded for all target platforms (Linux, Windows) and the size of the dependencies for some of them might be quite large.