How to use external Python packages

Extensions 1.0 end of life

OneAgent and ActiveGate version 1.299 are the last versions supporting OneAgent and ActiveGate Extensions 1.0 framework. You can continue using Extensions 1.0 if you stay at OneAgent or ActiveGate version 1.299. Note that this means you'll be using an unsupported Python version 3.8. We strongly recommend migrating your extensions to the latest Extensions 2.0 framework.

For more information, see General guidance and how to migrate.

Using external Python package

Extension are standard Python scripts running in an embedded Python engine. Every standard Python package can be used in an extension. For example, you can use url.request for a simple import like this:

import urllib.request
from ruxit.api.base_plugin import RemoteBasePlugin
class MyPlugin (RemoteBasePlugin):
def query(self, **kwargs):
response = urllib.request.urlopen('https://www.google.com/')
response_data = response.read()

Sometimes you may find it necessary to use an external package, for example Python driver for Apache Cassandra.
The installation of such a package requires two steps:

  1. Development - prepare the environment for testing an extension in extension simulator.
  2. Deployment - prepare the extension package for an upload to Dynatrace Server, OneAgent-monitored host (OneAgent extensions) and the ActiveGate (ActiveGate extensions).

Development environment with external package

Let's create an extension using driver for Apache Cassandra:

from cassandra.cluster import Cluster
from ruxit.api.base_plugin import RemoteBasePlugin
class MyCassandraPlugin(RemoteBasePlugin):
def query(self, **kwargs):
cluster = Cluster(self.config['cluster'].split(','))
session = cluster.connect(self.config['space'])

In the deployment stage, the extension should be tested with extension simulator. Add the plugin.json definition for Python script:

{
"name": "custom.remote.python.MyCassandraPlugin",
"version": "1.0",
"type": "python",
"entity": "CUSTOM_DEVICE",
"processTypeNames": ["PYTHON"],
"technologies": ["CASSANDRA"],
"source": {
"package": "my_cassandra_plugin",
"className": "MyCassandraPlugin",
"activation": "Remote"
},
"configUI": {
"displayName": "My Cassandra Active Plugin",
"properties": [
{
"key": "cluster",
"displayName": "Cluster IPs",
"displayHint": "list of IP addresses"
},
{
"key": "space",
"displayName": "Cassandra space"
}
]
},
"properties": [
{
"key": "cluster",
"type": "String"
},
{
"key": "space",
"type": "String"
}
]
}

Install the Cassandra driver in your development environment.

Every package should contain its documentation with instructions on installation process. For example, to install the Python driver for Apache Cassandra, execute the following command:

pip3 install cassandra-driver

This is sufficient for extension simulator to run an extension using an external package.

Plugin deployment with external package

In the deployment stage, you upload the developed extension to Dynatrace Server, hosts with OneAgent-monoitored hosts (OneAgent extensions) and production Environment ActiveGate (ActiveGate extensions).

For the deployment to work, the plugin.json has to refer to the Cassandra driver. Update the plugin.json definition with install_requires field in the source object. You may add version condition if necessary e.g. cassadra_driver>=1.0.0:

{
"name": "custom.remote.python.MyCassandraPlugin",
"version": "1.0",
"type": "python",
"entity": "CUSTOM_DEVICE",
"processTypeNames": ["PYTHON"],
"technologies": ["CASSANDRA"],
"source": {
"package": "my_cassandra_plugin",
"className": "MyCassandraPlugin",
"activation": "Remote",
"install_requires": ["cassandra-driver>=1.0.0"]
},
"configUI": {
"displayName": "My Cassandra Active Plugin",
"properties": [
{
"key": "cluster",
"displayName": "Cluster IPs",
"displayHint": "list of IP addresses"
},
{
"key": "space",
"displayName": "Cassandra space"
}
]
},
"properties": [
{
"key": "cluster",
"type": "String"
},
{
"key": "space",
"type": "String"
}
]
}

The command plugin_sdk build_plugin builds the extension zip archive and uploads it to Dynatrace Server. The zip file is located in /opt/dynatrace/remotepluginmodule/plugin_deployment/custom.remote.python.MyCassandraPlugin.zip on Linux
or c:\Program Files\dynatrace\remotepluginmodule\plugin_deployment\custom.remote.python.MyCassandraPlugin.zip on Windows

The command plugin_sdk build_plugin uses pip package manager to download and prepare any package needed by an extension.

Building extensions with external packages

The command plugin_sdk build_plugin automatically prepares an extension with the external libraries that are defined in the install_requires field of plugin.json. You don't need to place an external package in the source extension directory.

The extension zip file is located in /opt/dynatrace/remotepluginmodule/plugin_deployment on Linux
or
c:\Program Files\dynatrace\remotepluginmodule\plugin_deployment on Windows

Built-in packages

There are a few external packages already used by the plugin module. These aren't included in plugin.json:

You can find these libraries in the THIRDPARTYLICENSEREADME.txt file located in /opt/dynatrace/remotepluginmodule/agent on Linux
or
c:\Program Files\dynatrace\remotepluginmodule\agent on Windows

Native (C-compiled) components of Python packages

If the python package that you want to use contains any native dependencies these are resolved by pip automatically so there are are additional steps required during extension deployment phase.

Note the you must build a extension on the same system (Linux or Windows) and hardware platform (ActiveGate supports only 64-bit systems) as the destination production host. Native components of the Python package are not compatible between different systems and hardware platforms.

If you encounter any obstacles in installing a package using pip, copy the package folder together with the native libraries, but without the dist-info directory, to the extension directory.

Loading external libraries

Keep in mind the order in which the libraries are loaded:

  1. Engine libraries (Docker client, request, urllib3, etc.)
  2. Built-in extension libraries (in alphabetical order of directories)
  3. Custom extension libraries (in alphabetical order of directories)

Custom and built-in external packages may be of a different version. Loading of the newest version isn't guaranteed.