How can I read sensu event data in a Pipe handler SensuGO

Hello Team - I did read through the blogs and also found this https://github.com/sensu/sensu-go/issues/2528 . Are there easy ways to read and consume event data in a pipe handler using which I can trigger the next course of action. Is this possible ?

My use-case is , I would like to consume the event.output value for processing.

Thanks
Muthu

Hello

If what you’re trying to achieve is for example to create a handler which will read the event, extract the “event.output” to send it somewhere else. It’s quite easy.

You basically just have to do something which will read the stdin for the json representation of the event and then access the check->output field. And then do what ever you want with the value you retrieved. I did some perl script to do so and lately I did some handler in go too.

If you have some knowledge in go, you can use the sensu-plugin-tool which can create a go project for a hanlder (using the following template). I found it quite easy to develop with this template

Edited my question - Its a Pipe Handler to be specifc

Thank you Luc for a fast response. Could you share a sample code if you have it handy ?

Pipe handler should work :slight_smile:

{
    "type": "Handler",
    "api_version": "core/v2",
    "metadata": {
        "name": "test-handler",
        "namespace": "default"
    },
    "spec": {
        "command": "/usr/local/bin/my-handler.pl",
        "type": "pipe"
    }
}
#!/usr/bin/perl
use strict;
use warnings;
use JSON::MaybeXS;
use Data::Dumper;
use IO::Socket::INET;

# Minimum version to use the given/when structure
use 5.010;

no if ( $] >= 5.018 ), 'warnings' => 'experimental';

while(my $line = <> ) {
    chomp( $line );

    my $event = decode_json($line);

    my $check_name = $event->{'check'}->{'metadata'}->{'name'};
    my $entity_name = $event->{'entity'}->{'metadata'}->{'name'};
    my $check_result = $event->{'check'}->{'status'};
    my $message = $event->{'check'}->{'output'}
    
    # Do something
    print "Output: " . $message . "\n";
}

Just copy paste a part of a script I used. it could probably help you to get started

1 Like

How can I read the event data in this handler ? Good that you are a Perl pro :slight_smile: . Are you saying the stdin to the perl script is event data implicitly ? If yes, how can I explicitly read the event data inside the script ?

Sorry just trying to connect the dots.

Perfectly done. Thank you Luc, will try this out :slight_smile:

Hey!

First off Sensu Go handlers retrieve events in json format. But there’s no event.output. What you probably want is event.check.output

When developing a handler I usually is take a look at the event json representation I want to process so I can understand its structure. Here’s how you can do that with sensuctl

sensuctl event info <entityname> <checkname> --format json

Here’s a truncated example from my system… I like using jq to pretty print the json into something more human readable.

sensuctl event info carbon-f31 keepalive --format json |jq
{
  "check": {
    "handlers": [
      "keepalive"
    ],
    "high_flap_threshold": 0,
    "interval": 20,
    "low_flap_threshold": 0,
    "publish": false,
    "runtime_assets": null,
    "subscriptions": [],
    "proxy_entity_name": "",
    "check_hooks": null,
    "stdin": false,
    "subdue": null,
    "ttl": 0,
    "timeout": 120,
    "round_robin": false,
    "executed": 1589398958,
    "history": [
...

The ‘output’ is actually from the check object inside the event structure.

 sensuctl event info carbon-f31 keepalive --format json |jq .check.output
"No keepalive sent from carbon-f31 for 669495 seconds (>= 120)"

When developing or testing handlers, prior to putting them in production, what I like doing is saving a specific event json into a text file on disk and running the handler manually piping in the json event.

sensuctl event info carbon-f31 keepalive --format json  > failing_keepalive_event.json
cat failing_keepalive_event.json | my_custom_handler

Once you have the event captured in a json file like that, you can even make that part of your CI/CD tests if your developing a plugin.

Hope this helps.

1 Like

Thank you @jspaleta . I did verify the stdin to my handler works perfectly.

sensuctl event info | test.py

However, when the handler is getting called during the workflow, the handler doesn’t do anything as expected :frowning:

       data = json.load(sys.stdin)
       provided_input = data["entity"]['metadata']['name']
       entity = "entity:"+provided_input
       check_output = data["check"]["output"]
       ns = data["check"]["metadata"]["namespace"] 

A simple jq handler says jq not found, I do have it in the path.

type: Handler
api_version: core/v2
metadata:
name: inc-handler
namespace: default
spec:
command: jq
filters:

  • not_silenced
    timeout: 120
    type: pipe

Am I missing anything here ?

Hi, jq might be in your user path, but maybe not the sensu one. Maybe you should use the full path to JQ.

For your handler, can you try for instance to print “data” (or the stdin content) to a text file (/tmp/debug_handler.log or something similar) just to be sure of what you get in input?

1 Like

@kmuthuku,

This is one of the things that can trip people up on systemd systems a lot. The default environment including the executable path is usually pretty cut down.

I use the file /etc/sysconfig/sensu-backend to explicitly set the PATH envvar to be explicitly what I want. The provided systemd service file comes preconfigured to try to read envvars from this file before starting the sensu-backend process.

1 Like

Thanks Luc and @jspaleta for your help here. Finally I could make this work. The problem was the SensuGO container didnt had the needed binary to run the asset :frowning: . Basically, I was using
#!/usr/bin/python and ub-16 image that I built the container from didn’t had this path, but /usr/bin/python3 . I rebuilt the image with the needed binaries to be able to run my asset. Lazy way would be /usr/bin/env python, but I am good for now.

Thanks again. This is one of the blogs that I always get instant replies.

You/your team and SensuGO rocks :slight_smile:

2 Likes