Extensions
Reference documentation
- What is a Sensu extension?
- Installing Sensu extensions
- Installing Sensu legacy extensions
- Configuring Sensu extensions
- The Sensu Extension gem
- The Sensu Extensions gem template
What is a Sensu extension?
Unlike Sensu plugins, which spawn a new child process at every execution, Sensu extensions execute directly inside the EventMachine reactor thread of a Sensu client or server process. Because they avoid the overhead of spawning a new process at every invocation, Sensu extensions can fulfill the same functions as plugins, acting as checks, filters, mutators or handlers, but with much greater efficiency.
WARNING: While their performance characteristics are quite desirable, Sensu extensions come with major caveats: extensions have full access to Sensu’s internals, and any extension which blocks the EventMachine reactor for any period of time (e.g. blocking on disk IO or network request) will have a very significant negative impact on Sensu’s performance and functionality. The details of evented programming as implemented by EventMachine are outside the scope of this document, but Javier Acero has helpfully written on the implications of blocking the reactor.
Installing Sensu extensions
As of version 0.26, Sensu supports loading extensions from properly packaged gems. This approach takes advantage of the existing RubyGems infrastructure and tools to make publishing and installing Sensu extensions easy.
Use sensu-install
to install Sensu Extensions
The Sensu Core package provides a tool called sensu-install
(a simple wrapper
around the Ruby gem
utility). The Sensu Install tool (sensu-install
)
simplifies installation of Ruby-based extensions. The sensu-install
tool can be
run with one or more arguments that determine the action(s) to take.
$ sensu-install -h
Usage: sensu-install [options]
-h, --help Display this message
-v, --verbose Enable verbose logging
-p, --plugin PLUGIN Install a Sensu PLUGIN
-P, --plugins PLUGIN[,PLUGIN] PLUGIN or comma-delimited list of Sensu plugins to install
-e, --extension EXTENSION Install a Sensu EXTENSION
-E, --extensions EXTENSION[,EXT] EXTENSION or comma-delimited list of Sensu extensions to install
-s, --source SOURCE Install Sensu plugins and extensions from a custom SOURCE
-c, --clean Clean up (remove) other installed versions of the plugin(s) and/or extension(s)
-x, --proxy PROXY Install Sensu plugins and extensions via a PROXY URL
NOTE: sensu-install
is only available in Sensu Core >= 0.21.0
.
Sensu extensions can be installed using the sensu-install
executable:
EXAMPLE
sensu-install -e sensu-extensions-system-profile
Or sensu-install
can prepend sensu-extensions-
automatically:
sensu-install -e system-profile
Configuring Sensu to load extensions
Once an extension is installed via gem, Sensu must be explicitly configured to
load the extension. This is accomplished by providing
configuration under the top level extensions
attribute:
EXAMPLE
{
"extensions": {
"system-profile": {
"gem": "sensu-extensions-system-profile"
}
}
}
EXAMPLE
Configuration may optionally include a version specification:
{
"extensions": {
"system_profile": {
"gem": "sensu-extensions-system-profile",
"version": "1.0.0"
}
}
}
Once extensions have been explicitly enabled in Sensu’s configuration, they will be loaded the next time Sensu processes are restarted. Informational messages are printed to the log when extensions are loaded:
EXAMPLE
{"timestamp":"2016-08-08T16:37:25.711275+0000","level":"warn","message":"loading
extension gem","gem":"sensu-extensions-system-profile","version":"1.0.0"}
{"timestamp":"2016-08-08T16:37:25.711419+0000","level":"warn","message":"requiring
extension gem","require":"sensu/extensions/system-profile"}
{"timestamp":"2016-08-08T16:37:25.711579+0000","level":"warn","message":"loaded
extension","type":"check","name":"system_profile","description":"collects system
metrics, using the graphite plain-text format"}
NOTE: Explicit extension loading does not apply to legacy extensions, which are loaded by virtue of being placed in the extension directory.
Installing Sensu legacy extensions
Sensu extensions which are not properly packaged as gems are considered “legacy”, meaning they predate the new specification for loading Sensu Extensions from gems.
These legacy extensions are loaded from the directory specified by the
--extension_dir
flag provided when Sensu processes are started. On most
systems this defaults to /etc/sensu/extensions
, as specified by the command
flags passed to the sensu-client or sensu-server process via the service
supervision scheme in use (e.g. init, runit, upstart, systemd, etc).
Extensions should be installed directly into the extensions directory.
When an legacy extension has dependencies on third-party Ruby gems or other external applications, those dependencies must be installed into the Sensu embedded Ruby environment as well.
Configuring Sensu Extensions
The configurability of Sensu extensions is entirely a function of the extension code.
For example, filters and mutators cannot be applied to an extension via a standard
handler definition. Instead, these aspects of the extension’s configuration must be
defined in code by overriding the Sensu::Extension::Base definition
method:
EXAMPLE
def definition
{
:type => "extension",
:name => name,
:filters => ["occurrences"],
:mutator => "only_check_output"
}
end
The above code would configure the associated extension to apply the
occurrences
filter, and then the only_check_output
mutator, prior to
executing the extension’s custom run
method.
By virtue of being loaded into the Sensu client or server process, Sensu extensions have access to the running Sensu configuration. As such an extension can make use of any available configuration scopes, but the prevailing convention is for extensions to use unique top-level configuration scopes.
The system_profile
extension installed in a previous example looks to the
top-level system_profile
configuration scope. The following configuration
added to /etc/sensu/conf.d
would change the system_profile
extension’s
Graphite path prefix from a default value of “system” to “profile”:
EXAMPLE
{
"system_profile": {
"path_prefix": "profile"
}
}
The sensu-extension gem
Unlike Sensu plugins, which may be written in any programming language, Sensu
extensions must be written in Ruby. The sensu-extension gem provides
Sensu::Extension::Base
and other classes which Sensu extensions should
subclass.
The sensu-extensions gem template
The sensu-extensions gem template provides a starting point for those who wish
to author their own Sensu extension as a Ruby gem. It is recommended that your
gem follow the naming pattern “sensu-extension-$NAME” in order to ensure it can
be easily installed with sensu-install
.
NOTE: if you choose not to use this template for your extension, note the
directory structure it demonstrates (e.g. placing extension code under
lib/sensu/extensions/
) are required to ensure the extension is properly loaded.
Example extensions
For simple examples of Sensu extensions, consider the only_check_output
mutator or the debug
handler), both of which ship with Sensu.
You can find other Sensu extensions, some of which are packaged in the Sensu Core distribution, by searching RubyGems.