drewkerrigan/nagios-http-json

Please add an option to send an individual guid with every call and add - if set -add it to the output

Closed this issue · 9 comments

Hello,

I have another request:
Could you please add the option to send an individual guid with every request?

Usecase:
In a huge microservice environment where this check is used to monitor health-endpoints, sending an individual guid is very helpful for the developers to precisely track down issues.

Hi, would it be possible to use the HTTP headers for this use case?

  -A HEADERS, --headers HEADERS
                        The http headers in JSON format.

So search service could have a X-REQUEST-ID header, maybe this could work in combination with a random number

Some shells provide a RANDOM env for example:

~/ echo $RANDOM
6358
~/ echo $RANDOM
15365

That is a good idea! I will try this.

Unfortunately I cant get it to work :~

echo $RANDOM works in the shell (rhel8).

I try to access it with:

template Service "generic_cf_health_check" {
  import "generic-service"
  vars.rand = {{ getenv("RANDOM") }}
  vars.http_json_headers = {{ return "{\"Accept\": \"application/json\", \"X-REQUEST-ID\": \"" + macro("$service.vars.rand$")  + "\"}" }}
...

But unfortunately Icinga executes it with an empty value.

API-Output of the check execution:

                    "command": [
                        "/usr/lib64/nagios/plugins/check_http_json.py",
                        "-A",
                        "{\"Accept\": \"application/json\", \"X-REQUEST-ID\": \"\"}",
...

Do you see any flaw in my snipplet?

In my mind an addition to the check whould be something like this:

import uuid
...
if args.guid:
            guid = str(uuid.uuid4())
...
if args.headers:
            headers=json.loads(args.headers)
            if args.guid:
                req.add_header('X-REQUEST-ID', guid)
...
parser.add_argument('-g', '--guid', action='store_true', help='Add GUID to headers.')

Hi, the $RANDOM might only be available in the Bash

Since you might be using Icinga, you could try this:

https://icinga.com/docs/icinga-2/latest/doc/18-library-reference/#random

I tried it with RANDOM() and it works. Unfortunately I got feedback from our developers, with thebresult, that an uuid is explicit needed. An integer is not sufficient. Could you please implement it?

I'm not 100% sure yet if and how to implement this. My current thoughts:

Headers are definitely the way to go and we already have a flag to set them. This provide the highest degree of flexibility, since users are free to decide if and how to set them. An opinionated uuid flag could lead to a situation in which another user might want a different (not uuid4) format.

And we already got a lot of CLI flags. Once something is in the plugin we need to support and keep it (unless we deprecate it and break backward compatibility).

Let me think about it.

@K0nne just for fun I threw together an Icinga DSL function that generates (non RFC 4122 conform) UUID4:

object CheckCommand "random uuid" {
  command = [ "/bin/echo" ]

  arguments = {
    "--uuid" = "$uuid$"
  }

  vars.uuid = {{
    characters = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]

    min = 0
    max = len(characters)-1
    interval = min-max

    uuid = ""
    for (var i in range(1, 37, 1)) {
      if (i in [9, 14, 19, 24]) {
        uuid += "-"
        continue
      }
      uuid += characters[Math.round(Math.abs(min + (Math.random() * interval)))]
    }

    return uuid
  }}
}

You are right. uuid4 is too strict. Your approach looks fine to me. I think I can get away with this.
Thank you!