Overrides is an often overlooked feature of Low-level discovery that makes the discovery of different entities in your environment so much more flexible. In this blog post, we will take a look at how overrides work and how we can use them to extend our Low-level discovery rules with additional logic.
When it comes to Zabbix, Low-level discovery (also known as LLD) is a vital part of the Zabbix feature set. Automated creation of items, triggers, graphs, and hosts, based on existing entities is invaluable in larger environments, where creating these entities by hand is simply not feasible.
But what about use cases where some of your entities need to be created in a somewhat unique fashion compared to the rest of the discovered entities? Say, one of the items needs to have a unique update interval because it’s more critical than the rest. Or what if some of my network interfaces need to have lower trigger severities since they are not mission-critical?
Before Zabbix 5.0 this used to be a common question – how can I work around use cases like that? The only solution used to be creating separate discovery rules and utilizing LLD filters, for example:
LLD rule A discovers one set of entities with their own properties, and filters out everything else, while LLD rule B discovers the few unique entities that require different configuration parameters while filtering out the entities already discovered by the LLD rule A.
Not very elegant, is it? You can also imagine the LLD rule bloat that would occur in large infrastructures with many unique entities. Thankfully, overrides introduced in Zabbix 5.0 address the question in a very efficient manner.
Low-level discovery overrides
Let’s recall how LLD works. Under the hood LLD is a JSON array with LLD macro and macro value pairs:
[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},{"{#IFNAME}":"eth2"},{"{#IFNAME}":"eth1"}]
In this small example of an LLD JSON, we can see each of our interfaces next to the LLD macro – these are our discovered entities. With overrides, we can define modify objects related to each of these discovered entities.
Overrides are available for each of your LLD rules. Once you open the particular LLD rule, navigate to the “Overrides” tab and add a new override. There are three parts to Overrides:
- Filters define which of the discovered entities we are going to modify with this override. This is done by matching against the contents of a specific LLD macro or simply checking if a specific LLD macro exists for a discovered entity.
- Operation conditions define which of the objects (items, triggers, graphs, hosts) we are going to override for the discovered entity.
- Lastly, we have to define which of the object attributes we are going to change (item update intervals, trigger severity, item history storage period, etc.)
Multiple overrides in a single Low-level discovery rule
In use cases where we have defined multiple overrides in a single LLD rule, there are few things that we need to consider. First off, the override order does matter! The overrides are displayed in a reorderable drag-and-drop list, so we can change the ordering of the overrides by dragging them around.
Secondly, when defining configuring an LLD override we can select from two behaviors if the override matches the discovered entity:
- Continue overrides – subsequent overrides for the current entity will be processed.
- Stop processing – subsequent overrides for the current entity will be ignored.
For this reason, the order of our overrides can have a significant impact, especially if we have selected to Stop processing subsequent overrides if one of our overrides matches a discovered entity.
Network interface discovery override
Let’s take a look at an example of how we can use overrides and define unique settings for some of the discovered network interfaces.
Without any overrides, we can see that we are discovering interfaces eth0, eth1, eth2, and lo. All of them have the same update interval and history/trend retention settings. When we open up the trigger section, we can also see that the triggers for all of the interfaces have the same severity settings, all are enabled and discovered.
Discovered triggers without using any overrides
Now let’s implement a few overrides.
- Change severity to high for the eth1 interface down trigger
- Change the history/trend storage period for the items created for the lo interface
Let’s define our first override. We are going to be overriding a trigger prototype on {#IFNAME} matches eth1.
Override only interfaces that match eth1 in the {#IFNAME} macro value
For this entity, we will be changing the severity of the Trigger prototype containing the string “Link down” in the trigger prototype name. Change trigger severity only for triggers that contain Link down in their name
For our second override let’s change the history and trend storage period on items for the entity where {#IFNAME} matches lo, since storing history data for the loopback interface isn’t critical for us.
Override only interfaces that match lo in the {#IFNAME} macro value
To apply this override on the items created from any item prototype in this discovery rule, my operation condition is going to contain an empty matches pattern.
Change item History/Trend storage period for any item created for the lo interface
Once we re-run the discovery rule, we will see that the changes have been applied to our items and triggers created from the corresponding prototypes.
Note the lo interface History/Trend storage periods – they have been changed as per our override
Note the eth1 trigger severity – it’s now High, as per our override
This way we can finally create any discovered object with a set of unique properties, despite our object prototypes having static settings. The example above is just a general use case of how we can utilize overrides – there can be many complex scenarios for utilizing overrides, especially if we take the execution order and stop/continue processing settings into account. If you are interested in the full list of changes that we can perform on different objects by using overrides, feel free to take a look at the Overrides section in our documentation.
Hopefully, the blog post gave you a glimpse of the flexibility that the override feature is capable of delivering. If you have an interesting use case for overrides or any questions/comments – you are very much welcome to share those in the comments section below the post!
Hello,
is it possible to just create item/trigger for interface errors if #IFALIAS is empty? If yes, how?
If by empty you mean that there’s no value for the {#IFALIAS} macro, then yes.
You could use filter rule {#LLD_MACRO} exists or {#LLD_MACRO} does not exist.
And then accordingly define the override operations in which you can state when an object should/should not be discovered. Similarly, you could also do this on the LLD rule filter level.
Unfortunately, this will not work on versions <5.4, since the exists/does not exist filters were introduces in 5.4
Thank you very much for this infomation, so the following should also be possibel with zabbix, great.. https://fosdem.org/2021/schedule/event/nemolargescalemon/
i would like to use override rules to disable history for selected items only. i cannot use macros in this case because setting a history value of “0” is not allowed in zabbix,
however, all items generated by the LLD have some sort of dynamic name like “Interface 1, 2, 3, ….” and so it is not poaaisble to use a pattern to match them.
is it possbile to use LLD Macros inside override filters ? if not, what would be a workaround to use macros with dynamic item names ?