Deutsch Lieber auf Deutsch? Hier lang.

Today I learned a cool new trick, made possible by the Item Preprocessing that is available since Zabbix 3.4. This is not a Zabbix blog, but I consider this so useful and so not-intuitive that I just have to write it down.

For the occasional visitor: Zabbix is an open source enterprise class monitoring solution. I use it not only at work, but also at home — not only to monitor the meat on my BBQ. :-)

In my opinion, Zabbix is really great when it comes to anything that can be expressed in numerics. It can also handle string data, but having had minor problems with that I try to avoid strings whenever it is possible. States can be expressed numerically and stored in integer values, using value mapping it is possible to show the states in a meaningful way.

Today I came across a problem that I wasn’t able to implement at first. A web service told me the state of an application, which could be either RUNNING, STOPPING or STOPPED. It’s easy to create a string-item to handle this, and to implement a trigger that notifies if the service is STOPPED. However, in this case I had to create a trigger that tells if the service is in the state STOPPING for more than a certain time, indicating that it might have a problem shutting down. I couldn’t find a solution to this, since the trigger function str("STOPPING",15m) would trigger if at least one of the values during the last 15 minutes was “STOPPING”.

Item Preprocessing to the rescue!

Three steps

Three steps

Zabbix 3.4 brought a feature called Item Preprocessing. A value can be fetched, and before it gets stored it can be dissected or converted in several ways. One of these is, to apply regular expressions to the fetched value, in a “find and replace” kind of way.

It turned out that I needed a fairly complex expression, but in the end I was able to convert the states from the webservice to simple integers. Searching the web, i found something about “conditional replacement”, and using this great online regex tester I was able to come up with this beauty:

Using this, I can convert the string that is extracted from the web service’s output using a JSON path in two further steps:

  • First, attach a “dictionary” to the value: replace the full value (.*) with with itself, followed by the replacement values: \1:STOPPED=0:STOPPING=1:RUNNING=2.
  • Then, replace the regex (STOPPED|STOPPING|RUNNING)(?=.*:\1=(\d)) by the value of the second capturing group \2.

In this way the item can be configured as an unsigned integer, since there are only the numbers 0, 1 or 2 that have to be stored. And I can apply the usual trigger-function-magic to notify if the value is 1 for a certain length of time. Added benefit: I can use the graph view of this item to see if there were any deviations from the wanted “RUNNING” state, when they occured and how long they lasted.

Better ideas?

I’m pretty enthusiastic about this way of processing the values. But I’m also very interested in opinions: is there a better way to deal with this problem? Something obvious that I haven’t seen?

Deutsch Lieber auf Deutsch? Hier lang.

BBQ temperatures in Zabbix

BBQ temperatures in Zabbix

Unfortunately, this project is still work in progress. But I want to tell of the first test run anyways. The electronics didn’t do exactly as it was supposed, but you see where this is going.

About two years ago, I built a prototype of a BBQ thermometer, which I showed here (german only, sorry). It really was just a quick hack, not really intended for repeated usage. I have learned a lot since then, and now I want to build something like that, but this time as a ‘real project’.

Being able to measure core temperatures of multiple pieces of meat, I didn’t have to think about the project’s name for long: Multimeater! :-D

The Hardware

The Hardware

Like some of my last projects, this is based on an ESP8266-module, with software developed in the Arduino IDE. So it already runs WiFi. My firmware is — as in some of my other recent projects — based on the Homie-framework. It sends collected values via MQTT to my broker, from there they are delivered to Zabbix. Values are measured with two high temperature sensors each connected to a MAX6675, and four common meat thermometers on a MCP3208.

Six temperatures? Yes. The plan is, to acquire the inner temperature of the pit on two positions. Under certain circumstances, these temperatures can be too high for the meat sensors. So I take two separate sensors for this, one on each end of the pit (which is a bit lengthy on a smoker, so there really is a relevant bit of a temperature drop in between). And with four meat thermometers I can monitor core temperatures of — you guessed it — up to four pieces of meat.

Zabbix is usually used as a monitoring software for server systems. But it doesn’t just work in enterprise environments, I am collecting some… let’s say unusual values at home. ;-)

In this case, I just used it to see graphs of the temperatures. But if I’m really starting to smoke me a pulled pork over night, I can tell Zabbix to wake me up if temperatures are out of a predefined range.

As mentioned, today’s run was just a test. And of course, several things didn’t work out as they were planned. I had a problem with the high temperature measurements in the pit. Those values turned out to be completely useless. But since I just bought three pieces of meat for today, I was able to use the fourth meat sensor for the pit temperature. Then I misplaced the sensor in my piece of ham, so the graph looks a bit strange. And to top all this off, heavy rain poured down during the test. Currently, there is no roof over the smoker, so that didn’t make it easier, either.

All in all, everything looked quite promising. I keep bringing this forward, and as soon as I really get it to work I’m going to publish it here, of course with circuit and firmware.

Oh, and since I’m sure that I’ll get that question: technical problems aside, I had some awesome pieces of meat from this test. Everybody really enjoyed it. :-D