Skip to content

Latest commit

 

History

History
131 lines (80 loc) · 5.43 KB

count_unique_strings_items.md

File metadata and controls

131 lines (80 loc) · 5.43 KB
↩️ Back

COUNT UNIQUE STRINGS FROM MULTIPLE ITEMS

Some hosts may have several items that return values that can be aggregated for a general calculation or just for overall observation.

For example, if a Windows host has a system with multiple monitored services that are discovered by the "Windows services discovery" rule, a status item is created for each service. Then, an aggregated item could count how many services are in the "running" or "stopped" state.

Let's say a Linux system has multiple items that retrieve log errors from a system. Each item retrieves a specific error code for alerting purposes. It may be possible to sum the total number of errors from all log items in a given time.

These examples are not number items per se, but could also be needed for aggregations. Despite the obvious possibilities, Zabbix does not support string aggregation. According to the documentation, "only unsigned integer and float values (type of information) are supported for aggregate calculation items."

In order for a Zabbix system to generate aggreations from strings, a few steps or transformations are required.


Possible benefits

  • Observe system or environmental behavior using an aggregated metric;
  • Calculate an indicator for a service level objective.

Scenario

Consider a few items that retrieve string values of either "Ended OK" or "Ended Not OK". They represent the status of a "Job" from a scheduling system.


1. Consider the sample below

Note

For the purposes of this example, the actual collected values are generated by some JavaScript items that randomly generate the two strings values above.

Items:

  • Random String Ended Ok
  • Random String Ended Ok 2
  • Random String Ended Not Ok
  • Random String Ended Not Ok 2

Random strings


The following Javascript function is used for the items.

const randomNum = Math.floor(Math.random() * 2);
if (randomNum === 1) {
  return "Ended OK";
} else {
  return "Ended Not OK";
}

2. Just sum the items

A new calculated item could be created to sum up all the items of interest. The most basic syntax is to sum the last value of all items in the calculation using the last() function. Something like this:

sum(last(//javascript.random.string[ok]),last(//javascript.random.string[ok2]),last(//javascript.random.string[notok]),last(//javascript.random.string[notok2]))

In terms of numbers, and for only 4 items, this is a workable expression. However, these are text items and they are not supported for aggregation. Also, when there are several items, the expression becomes impractical. A Low Level Discovery (LLD) could easily create dozens or hundreds of items. This would make adding the item keys to an expression very labor intensive, not to mention that the LLD could dynamically create and remove items.

Note

You can actually create a calculated item that sums text items, but Zabbix will display an "Unsupported item" error. In my opinion, and in this context, this is the only case where a comprehensive error message is displayed.

For example:
Cannot evaluate expression: function argument "Ended Not OK" is not a numeric value at "sum(last(//javascript.random.string[ok]),last(//javascript.random.string[ok2]),last(//javascript.random.string[notok]),last(//javascript.random.string[notok2]))"


3. Creating an aggregated item

For the aggregation to work, the collected values must be converted to a number. Considering that there are 2 possible string values, "Ended OK" or "Ended Not OK", they can be converted to binary numbers 1 and 0 by using the replace preprocessing step and setting the item's "Type of information" to Numeric (unsigned).

Tip

A value mapping can help to interpret the returned values.

Replace preprocessing step


After converting the items to numbers, we can create a new calculated item that aggregates these numbers. Instead of using a large expression, we can consolidate it to something smaller.

sum(last_foreach(//javascript.random.string[*]))

Ended OK aggreation

The last_foreach function creates an array with the last value of the selected items and, then, the sum function adds those values. Only "Ended OK" values are added in the function, as they have been converted to the number 1.


If it is necessary to count the number of "Ended Not OK" values, another calculated item must be created.

sum(exists_foreach(//javascript.random.string[*])) - sum(last_foreach(//javascript.random.string[*]))

Ended Not OK aggreation

This time, the item simply subtracts the total number of status items from the "Ended OK" items. The exists_foreach function returns 1 for each enabled item found, and again the sum function adds these values together.


3. The resulting aggreation

Finally, the resulting values are aggregated and ready for observation.

Ended OK aggreation


What if there are more than 2 possible values to be aggregated?
to be continued...


⬆️ Top