caabea3a91
The class moved since we merged the agents. Change-Id: I5c81218167907e518c50e7b3a9f8d9bd6cb87a16
169 lines
7.4 KiB
ReStructuredText
169 lines
7.4 KiB
ReStructuredText
..
|
|
Copyright 2012 Nicolas Barcet for Canonical
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
not use this file except in compliance with the License. You may obtain
|
|
a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
License for the specific language governing permissions and limitations
|
|
under the License.
|
|
|
|
.. _plugins-and-containers:
|
|
|
|
=======================
|
|
Writing Agent Plugins
|
|
=======================
|
|
|
|
This documentation gives you some clues on how to write a new agent or
|
|
plugin for Ceilometer if you wish to instrument a measurement which
|
|
has not yet been covered by an existing plugin.
|
|
|
|
Agents
|
|
======
|
|
|
|
Polling agent might be run either on central cloud management nodes or on the
|
|
compute nodes (where direct hypervisor polling is quite logical).
|
|
|
|
The agent running on each compute node polls for compute resources
|
|
usage. Each metric collected is tagged with the resource ID (such as
|
|
an instance) and the owner, including tenant and user IDs. The metrics
|
|
are then reported to the collector via the message bus. More detailed
|
|
information follows.
|
|
|
|
The agent running on the cloud central management node polls other types of
|
|
resources from a management server (usually using OpenStack services API to
|
|
collect this data).
|
|
|
|
The polling agent is implemented in ``ceilometer/agent/manager.py``. As
|
|
you will see in the manager, the agent loads all plugins defined in
|
|
the namespace ``ceilometer.poll.agent``, then periodically calls their
|
|
:func:`get_samples` method.
|
|
|
|
Plugins
|
|
=======
|
|
|
|
A polling agent can support multiple plugins to retrieve different
|
|
information and send them to the collector. As stated above, an agent
|
|
will automatically activate all possible plugins if no additional information
|
|
about what to poll was passed. Previously we had separated compute and
|
|
central agents with different namespaces with plugins (pollsters) defined
|
|
within. Currently we keep separated namespaces - ``ceilometer.poll.compute``
|
|
and ``ceilometer.poll.central`` for quick separation of what to poll depending
|
|
on where is polling agent running. This will load, among others, the
|
|
:class:`ceilometer.compute.pollsters.cpu.CPUPollster`, which is defined in
|
|
the folder ``ceilometer/compute/pollsters``.
|
|
|
|
Notifications mechanism uses plugins as well, for instance
|
|
:class:`ceilometer.compute.notifications.instance.InstanceNotifications` plugin
|
|
which is defined in the ``ceilometer/compute/notifications`` folder.
|
|
|
|
We are using these two existing plugins as examples as the first one provides
|
|
an example of how to interact when you need to retrieve information from an
|
|
external system (pollster) and the second one is an example of how to forward
|
|
an existing event notification on the standard OpenStack queue to ceilometer.
|
|
|
|
Pollster
|
|
--------
|
|
|
|
Compute plugins are defined as subclasses of the
|
|
:class:`ceilometer.compute.BaseComputePollster` class as defined in
|
|
the ``ceilometer/compute/__init__.py`` file. Pollsters must implement one
|
|
method: ``get_samples(self, manager, context)``, which returns a
|
|
sequence of ``Sample`` objects as defined in the
|
|
``ceilometer/sample.py`` file.
|
|
|
|
In the ``CPUPollster`` plugin, the ``get_samples`` method is implemented as a
|
|
loop which, for each instances running on the local host, retrieves the
|
|
cpu_time from the hypervisor and sends back two ``Sample`` objects. The first
|
|
one, named "cpu", is of type "cumulative", meaning that between two polls, its
|
|
value is not reset while the instance remains active, or in other words that
|
|
the CPU value is always provided as a duration that continuously increases
|
|
since the creation of the instance. The second one, named "cpu_util", is of
|
|
type "gauge", meaning that its value is the percentage of cpu utilization.
|
|
|
|
Note that the ``LOG`` method is only used as a debugging tool and does not
|
|
participate in the actual metering activity.
|
|
|
|
There is the way to specify either namespace(s) with pollsters or just
|
|
list of concrete pollsters to use, or even both of these parameters on the
|
|
polling agent start via CLI parameter:
|
|
|
|
ceilometer-polling --polling-namespaces central compute
|
|
|
|
This command will basically make polling agent to load all plugins from the
|
|
central and compute namespaces and poll everything it can. If you need to load
|
|
only some of the pollsters, you can use ``pollster-list`` option:
|
|
|
|
ceilometer-polling --pollster-list image image.size storage.*
|
|
|
|
If both of these options are passed, the polling agent will load only those
|
|
pollsters specified in the pollster list, that can be loaded from the selected
|
|
namespaces.
|
|
|
|
.. note::
|
|
|
|
Agents coordination cannot be used in case of pollster-list option usage.
|
|
This allows to avoid both samples duplication and their lost.
|
|
|
|
Notifications
|
|
-------------
|
|
|
|
Notifications are defined as subclass of the
|
|
:class:`ceilometer.agent.plugin_base.NotificationBase` meta class.
|
|
Notifications must implement:
|
|
|
|
``event_types`` which should be a sequence of strings defining the event types to be given to the plugin and
|
|
|
|
``process_notification(self, message)`` which receives an event message from the list provided to event_types and returns a sequence of Sample objects as defined in the ``ceilometer/sample.py`` file.
|
|
|
|
In the ``InstanceNotifications`` plugin, it listens to three events:
|
|
|
|
* compute.instance.create.end
|
|
|
|
* compute.instance.exists
|
|
|
|
* compute.instance.delete.start
|
|
|
|
using the ``get_event_type`` method and subsequently the method
|
|
``process_notification`` will be invoked each time such events are happening which
|
|
generates the appropriate sample objects to be sent to the collector.
|
|
|
|
Adding new plugins
|
|
------------------
|
|
|
|
Although we have described a list of the metrics Ceilometer should
|
|
collect, we cannot predict all of the ways deployers will want to
|
|
measure the resources their customers use. This means that Ceilometer
|
|
needs to be easy to extend and configure so it can be tuned for each
|
|
installation. A plugin system based on `setuptools entry points`_
|
|
makes it easy to add new monitors in the agents. In particular,
|
|
Ceilometer now uses Stevedore_, and you should put your entry point
|
|
definitions in the ``entry_points.txt`` file of your Ceilometer egg.
|
|
|
|
.. _setuptools entry points: http://pythonhosted.org/setuptools/setuptools.html#dynamic-discovery-of-services-and-plugins
|
|
|
|
.. _Stevedore: http://stevedore.readthedocs.org
|
|
|
|
Installing a plugin automatically activates it the next time the
|
|
ceilometer daemon starts. Rather than running and reporting errors or
|
|
simply consuming cycles for no-ops, plugins may disable themselves at
|
|
runtime based on configuration settings defined by other components (for example, the
|
|
plugin for polling libvirt does not run if it sees that the system is
|
|
configured using some other virtualization tool). Additionally, if no
|
|
valid resources can be discovered the plugin will be disabled.
|
|
|
|
|
|
Tests
|
|
=====
|
|
Any new plugin or agent contribution will only be accepted into the project if
|
|
provided together with unit tests. Those are defined for the compute agent
|
|
plugins in the directory ``tests/compute`` and for the agent itself in ``test/agent``.
|
|
Unit tests are run in a continuous integration process for each commit made to
|
|
the project, thus ensuring as best as possible that a given patch has no side
|
|
effect to the rest of the project.
|