3 Concepts

This chapter defines the terms used throughout the manual. Each concept comes with an example of how it appears in the .conf and .xml files. The examples are fragments: the following chapters describe every parameter and attribute.

3.1 Host, item and key#

These are Zabbix concepts:

Host.

A monitored entity in Zabbix. Each Databbix monitor sends the data of a single host, identified by General.Name.

Item.

A piece of data that Zabbix periodically collects from a host (number of sessions, free space in a tablespace…). The items served by Databbix are of type Zabbix agent (active).

Key.

The item identifier, of the form name[parameter1,parameter2,...]. The name says which item of which query must be computed, and the parameters say for which object (which tablespace, which database…).

Example. The Zabbix host ORAPROD has an active item with the key:

tez.ora.tspace.pctfree[USERS]

The monitor whose .conf has Name = ORAPROD looks in its XML files for the <item> named tez.ora.tspace.pctfree and computes it for the USERS tablespace.

3.2 Monitor#

A monitor is the unit of work of Databbix: it links one data source with one Zabbix host. It is defined in a .conf file and runs in its own thread. For example, if a machine watches three databases, there are three .conf files, three monitors and three hosts in Zabbix.

A monitor is made of:

  • an engine and a connection to the data source;

  • a query collection;

  • a connection to the Zabbix server and the list of the host’s active items;

  • a scheduler that decides when to run each query.

Example. File /etc/databbix/dbs/oraprod.conf with the minimum for an Oracle monitor:

[General]
Name = ORAPROD                 # host in Zabbix

[Zabbix]
Server = zabbix.example.com    # where data is sent
Port = 10051

[Data]
Module = DB                    # query modules used

[Database]                     # where data comes from
DBDriver = Oracle
ConnectionString = oraprod
UserName = zabbix
Password = secret

3.3 Query engine#

The engine is the component that knows how to talk to one kind of data source. Each monitor uses a single engine, chosen with General.Engine. The engine determines:

  • which connection section the monitor file has ([Database], [Webservice] or [MQTT]);

  • which elements and attributes the XML files accept (for example, <sql> in Database and <url> in Webservice);

  • which query types exist and how values are obtained.

Engine Data source What a query is
Database SQL databases through a driver: Oracle, PGsql or ODBC. An SQL statement.
Webservice REST (JSON) or SOAP web services. An HTTP call to a URL; values are extracted from the response.
MQTT An MQTT broker. Reading the last value published on a topic.

All the XML files of a monitor must belong to the monitor’s engine: the engine is declared in the engine attribute of <Queries>.

Example. A REST service monitor declares the engine in its .conf:

[General]
Name = JDEPROD
Engine = Webservice
QueryFile = /etc/databbix/query-jde.xml

[Webservice]
BaseURL = https://jde.example.com:9888/restservice

and the XML file it uses declares the same engine:

<Queries engine="Webservice">
    ...
</Queries>

3.4 Query collection#

The set of queries resulting from loading the XML files of a monitor (QueryFile). Within a collection, query names and item names are unique: this is how Databbix knows which query to run for each key Zabbix asks for.

If several monitors use the same engine, the same files and the same environment variables, they share a single in-memory copy of the collection.

Example. A collection made of the distribution’s query file plus a local one:

[General]
QueryFile = /etc/databbix/query.xml
QueryFile = /etc/databbix/query-local.xml

3.5 Query#

A query (<query>) defines an operation on the data source (an SQL statement, a service call…) and the Zabbix items obtained from its result. A query can produce many items, and Databbix runs it only once for all of them.

Depending on how the result relates to the items, there are several types: basic, filter, bind, discovery and constant. They are described in chapter 7.

Example. A basic query that produces two items from a single statement:

<query name="PGWriter" module="PG">
    <sql><![CDATA[
        select checkpoints_timed, checkpoints_req
        from pg_stat_bgwriter
        ]]>
    </sql>
    <item name="tez.pg.checkpointtimed" column="checkpoints_timed"/>
    <item name="tez.pg.checkpointreq"   column="checkpoints_req"/>
</query>

3.6 Query item#

Within a query, each <item> says where the value of a Zabbix item comes from: which column of the SQL result, which path of the JSON response, an internal figure (execution time)… Its name attribute is the key name in Zabbix.

Besides the items defined in the XML files, Databbix answers a few internal items, such as agent.ping or agent.version.

Example. Three ways of getting the value:

<!-- from an SQL column -->
<item name="tez.ora.sessions" column="n"/>
<!-- from a path inside a service's JSON response -->
<item name="ts.jde.instance.state" path="instanceState" type="INT"/>
<!-- from an internal figure: seconds the query took -->
<item name="tez.ora.tspace.exectime" built_in="exec_time"/>

3.7 Parameter#

A parameter (<parameter>) links a parameter of the Zabbix key to the query. Depending on the query type, the parameter value is used to:

  • choose a row of the result (filter);

  • pass it to the SQL statement or the URL (bind);

  • choose the context in which the query runs.

Example. With the key tez.pg.sessions[sales], the first parameter (sales) selects the row whose datname column is sales:

<parameter column="datname" order="1" type="STRING"/>

With the key tez.pg.param[max_connections], the first parameter is passed to the SQL statement in the :name variable:

<parameter bind=":name" order="1" type="STRING"/>

3.8 Module#

A module is a name that groups related queries (DB, Instance, PG, MSSQL…). Each query and each context declares its module with the module attribute, and each monitor declares the modules it uses with Data.Module.

Example.

<query name="Sessions" module="Instance"> ... </query>
[Data]
Module = DB
Module = Instance

3.9 Discovery#

Low-level discovery (LLD) is the Zabbix mechanism to create items automatically for the objects that exist (one item per tablespace, per database…). In Databbix, a discovery query returns the list of objects in the JSON format Zabbix expects. It is usually paired with a filter query that computes the values of each discovered object.

Example. Discovery of the databases of a PostgreSQL server:

<query name="PGDiscoverDB" module="PG" discovery="yes">
    <sql><![CDATA[
        select datname from pg_database where datname not like 'template%'
        ]]>
    </sql>
    <item name="tez.pg.db.discovery"/>
    <field name="DBNAME" column="datname"/>
</query>

The item tez.pg.db.discovery returns to Zabbix:

{"data":[{"{#DBNAME}":"postgres"},{"{#DBNAME}":"sales"}]}

and in Zabbix the prototype tez.pg.sessions[{#DBNAME}] is defined, which produces tez.pg.sessions[postgres] and tez.pg.sessions[sales].

3.10 Context#

A context is a connection state that can be changed between queries without reconnecting. Typical examples are the current database in SQL Server or PostgreSQL and the container (PDB) in Oracle multitenant. Thanks to contexts, a single monitor with a single connection can query every database on a server.

Contexts only exist in the Database engine. They are declared in the XML file with a default value. Each query runs in the default context, in a fixed one or in the one given by the item key. Databbix groups queries by context so as to switch as few times as possible.

Example. The context Database is declared, with default value master, along with a query that runs in the database given by the first key parameter:

<context name="Database" module="MSSQL" default="master"/>

<query name="MSFGSpace" module="MSSQL" select="FILTER">
    <sql> ... </sql>
    <parameter context="Database" order="1"/>
    <parameter column="filegroup_name" order="2" type="STRING"/>
    <item name="tez.mssql.fgspace.used" column="used"/>
</query>

The key tez.mssql.fgspace.used[sales,PRIMARY] runs the query in the sales database and returns the value for the PRIMARY filegroup.

3.11 Environment variable#

An environment variable is a named value substituted in the XML files with the syntax ${Name}. It is used to write generic XML files and adapt them to each installation from the configuration: a schema name, the administration database, etc.

They are unrelated to operating system environment variables. They are defined with <environment> in the XML file (default value) and with Environment = Name=Value in databbix.conf or in the monitor file, which take precedence.

Example. The XML file declares the variable and uses it in the SQL:

<environment name="SvmSchema" default="svm920"/>

<query name="JdeSpecJobs" module="JDEDB">
    <sql><![CDATA[
        select count(*) as n from ${SvmSchema}.f986110
        ]]>
    </sql>
    <item name="ts.jdedb.specjobs" column="n"/>
</query>

A monitor that says nothing queries svm920.f986110. Another monitor with this line queries svm910.f986110:

[General]
Environment = SvmSchema=svm910

3.12 Runtime data#

Values that are only known once the connection is established, such as the database product the driver is connected to. They are used in the Database engine (section 9.2.4). They are read with the runtime(’NAME’) function in <when> conditions, to pick the right SQL for each database.

Example.

<sql>
  <multiple>
    <when condition="runtime('DB.DATABASE') = 'Oracle'"><![CDATA[
        select sysdate as now_ts from dual ]]></when>
    <when><![CDATA[
        select current_timestamp as now_ts ]]></when>
  </multiple>
</sql>

3.13 Scripts and transformations#

XML files can include functions written in JavaScript or Python (<script>). These functions are used to:

  • transform a value before sending it to Zabbix (for example, turn a date into elapsed seconds);

  • process a web service response before extracting the values;

  • generate credentials and validate responses in web service authentication.

Each monitor has an interpreter for its query collection. Scripts declared at <Queries> level are shared by all queries; those declared inside a <query> are only visible in that query. All scripts in a collection must be in the same language. Chapter 12 explains how to write them.

Example. A global function and an item that uses it:

<script language="Javascript"><![CDATA[
    function toUnix(date) {
        return Math.round(Date.parse(date) / 1000);
    }
    ]]>
</script>

<query name="LastBackup" module="DB">
    <sql><![CDATA[
        select max(completion_time) as end_time from v$backup_set ]]>
    </sql>
    <item name="local.ora.lastbackup" column="end_time" transform="Javascript:toUnix"/>
</query>

3.14 Caching and scheduling#

Zabbix decides how often it wants each item (the item’s update interval). Databbix groups items by query and, when several items of the same query are due, runs the query only once.

The result of a query is cached for a maximum time (the monitor’s General.MaxCache or the query’s maxCache attribute, whichever is smaller). While the result is valid, the items of that query are served from the cache, without running it again.

Example. The monitor allows results to be reused for 60 seconds, but one particular query only for 30:

[General]
MaxCache = 60
<query name="TSSpace" module="DB" select="FILTER" maxCache="30"> ... </query>

3.15 Web service authentication#

Most web services require authentication before answering. Three pieces are involved in Databbix:

Authentication engine.

An authentication mechanism written in C++ inside Databbix: HTTPAuth, RESTToken, JDE and Oasis (table 3.1). Not to be confused with the monitor’s query engine (Webservice).

Authentication method.

A customisation of an authentication engine for a particular service, defined in a query file with the <authentication> element. It has a name (name attribute), states the engine it uses (type attribute) and provides JavaScript or Python functions that decide, for example, which login request is sent, where the token is in the response or when to authenticate again. Only HTTPAuth and RESTToken can be customised.

Credentials.

User, password and other data (environment, role…) defined in the monitor file with UserName, Password and Credentials = key=value. This way, XML files contain no secrets.

The monitor’s Webservice.Authenticator parameter gives a name, which Databbix resolves in this order:

  1. It looks in the monitor’s query files for an authentication method (<authentication>) with that name. If found, it uses its engine with the method’s functions.

  2. Otherwise, it looks for an authentication engine with that name and uses it directly, without customisation.

  3. If neither exists, the monitor cannot connect and logs the error.

Table 3.1. Authentication engines

Engine Mechanism
HTTPAuth Standard HTTP authentication. The method is given by the method credential: BASIC, DIGEST, NTLM (with username and password) or HEADER (a fixed header, with header and value). Optionally, a script can generate the credentials.
RESTToken Token authentication. A login request is made and the token obtained is sent in every call as a header or cookie. It is configured entirely in the XML file, with scripts that build the login request, validate the response and detect when to authenticate again.
JDE Token for the JD Edwards REST services (Server Manager).
Oasis WS-Security UsernameToken header for SOAP services.

The authentication session (for example, the current token) is kept while the monitor runs and renewed when the service rejects it. If Webservice.AuthPersistFile is set, it is also saved to disk to be reused after a restart.

Example 1. The HTTPAuth engine without customisation: since there is no method called HTTPAuth in the XML files, the engine is used directly, and the credentials go in the .conf.

[Webservice]
BaseURL = https://api.example.com/
Authenticator = HTTPAuth
UserName = monitor
Password = secret
Credentials = method=BASIC

Example 2. The AISAuth authentication method, which customises the RESTToken engine, defined in the XML file and used from the .conf:

<authentication type="RESTToken" name="AISAuth">
    <script language="Javascript"> ... </script>
    <login type="JsonPost">
        <url>v2/tokenrequest</url>
        <request-function language="Javascript" function="authGenerate"/>
        <accept-function  language="Javascript" function="authAccept"/>
    </login>
    <token type="Header" name="jde-AIS-Auth"/>
    <verify-call language="Javascript" function="verifyCall"/>
</authentication>
[Webservice]
BaseURL = https://ais.example.com/jderest/
Authenticator = AISAuth
UserName = monitor
Password = secret
Credentials = environment=JPD920
Credentials = role=*ALL
AuthPersistFile = /var/lib/databbix/ais-token.json

Chapter 12 explains how to write the functions of an authentication method.