Extensions

Metric-Farmer can be easily extended by developers with own solutions for source and target types.

The reasons for this are the measurement from not yet supported sources (e.g. a department specific Excel list) or the storage of measurement results on not yet supported targets (e.g. a specific company metric system like Prometheus)

Concept

Metric-Farmer can be extend by using the entry-point mechanism of setuptools.

So a Metric-Farmer extension must be a valid Python package, which contains a setup.py file.

import os
from setuptools import setup

setup(
    name='Your extension',
      # ... More, but not for us important configurations
    entry_points={
        'metricfarmer': ['unimportant_name=your_package.your_modul:ExtensionClass']
    }
)

During installation of this package, the entry_point content gets registered on the used Python environment.

For Metric-Farmer the entry-point entry must be a class, which inherits from metricfarmer.extensions.MetricFarmerExtension and must have common variables, which define sources and target types.

Metric-Farmer creates an instance of this class during startup. From this point all defined sources and targets types of the extension are available.

A single Python package can register as many Metric-Farmer extensions as it likes.

Step by step introductions

  1. Create a new folder my_project
  2. Create a setup.py file and a my_mf_extension.py inside the above folder.
  3. For mf_my_extension.py use the following content.
from metricfarmer.extensions import MetricFarmerExtension

def my_source_a(**kwargs):
   return 100

def my_target_a(metrics, **kwargs):
   for metric in metrics.keys():
      print metric

class MyExtension(MetricFarmerExtension):
    def __init__(self, app):
        self.app = app

        self.name = "My Extension"
        self.namespace = 'me'
        self.author = 'Awesome guy'
        self.description = 'Metric-Farmer extension...'

        self.source_classes = {
            'my_source': my_source_a
        }

        self.target_classes = {
            'my_target': my_target_a
        }
  1. Then register this class inside your setup.py file:
import os
from setuptools import setup, find_packages

setup(
    name='My extension project',
    version='0.0.1',
    license='MIT',
    author='Me',
    author_email='me@me.com',
    description='Collects and stores metrics for my project.',
    platforms='any',
    packages=find_packages(),
    install_requires=['metricfarmer'],
    entry_points={
        'metricfarmer': ['my_extension=my_project.mf_my_extension:MyExtension']
    }
)
  1. After that you need to install your package, so that Python is aware of the new entry_point entry:
pip install -e .

6. Finally you should be able to address your source class with me.my_source and the target class with me.my_target in the related class parameters of source/target type definitions.

Example

Take a look into the source code of Metric Farmer, as it is using the entry-point mechanism to register all available sources and targets.

Visit https://github.com/useblocks/metricfarmer/tree/master/metricfarmer/extensions to get an overview about all folders and files.

The most important stuff is happening in file mf_extension.py. There the needed class gets defined.

This class is then used in the setup.py file as value for the metricfarmer entry-point.