Migrate CheckMK Plugin from 1.x to 2.x, whats equal to parse_json

Hello,

we are migrating CheckMK 1 plugins to 2 with the new API.

For some CheckMK Agent outputs we use JSON that was parsed with the “parse_json” parse_function in CheckMK 1. In CheckMK 2 i dont see any equal function, when using the register.agent_section() you can define a parse_function but you already get data that was already parsed by internal checkMK.

Is there a chance you can get the raw agent output or at least define that the agent output is JSON and so the checkmk check plugin gets the parsed JSON?

Thanks in advance
Rene

Hi René!

I wasn’t even aware that we had a parse_json function in cmk 1.x and wrote my own. However, that’s very easy:

First, your agent should use a different separator (default is whitespace, which we don’t want here). So:

<<<my_section:sep(0)>>>
{ "field1": "value1", "field2": 42, "field3": "value with spaces" }

This separator 0 means: “don’t separate anything whithin the lines; do not split at whitespace”.

On the server side this will appear as a list of lists (as usual) but each “inner list” has just one element (the complete line). It appears as:

section = [
    [ '{ "field1": "value1", "field2": 42, "field3": "value with spaces" }' ]
]

Your parse function can then be as easy as this:

import json

def parse_json(string_table):

    # json input all in one line:
    json_string = ''.join(word for line in string_table for word in line)  
    
    parsed = json.loads(json_string)
    return parsed

This will first join all the agent output of this section into one long line and then convert it to a Python structure like so:

{
    "field1": "value1", 
    "field2": 42, 
    "field3": "value with spaces"
}
1 Like

Thanks a lot, the “:sep(0)” was the magic key : )

If your agent output valid JSON then no such function is needed.
All my special agents use pure JSON output and a “json.loads(section[0][0])” is enough.

A simple parse function for JSON section could look like this.

def parse_redfish(string_table: StringTable) -> RedfishAPIData:
    """parse one line of data to dictionary"""
    try:
        return json.loads(string_table[0][0])
    except (IndexError, json.decoder.JSONDecodeError):
        return {}

The RedfishAPIData can be ignored.
For multiline JSON every line need to be a valid JSON structure and the parse function need to respect this.

1 Like

Sure, the parse function can be simplified or dropped completely depending on how the agent output is formatted. For example, the approach with string_table[0][0] won’t work if the agent output looks like this (which is also valid JSON):

<<<my_section:sep(0)>>>
{
    "field1": "value1",
    "field2": 42,
    "field3": "value with spaces"
}

In this case you first need to join the lines into one big string.

That is not valid JSON as agent output.
That is text looking like JSON :smiley:

Of course it is. See RFC4627:

Insignificant whitespace is allowed before or after any of the six structural characters.

So newlines and indentation is explicitely allowed and does not invalidate the JSON.