Problem with "," in Service if long output is used

Hello,

I am developing some checks for 1.6 and wondering how to get rid of this comma in service name if a long output is used.

My code looks like this:

 # Send long output
    yield 0, "\n%s" % ''.join(data.get('long_output'))

The service looks like that:

I also tried to add the “\n” at the first line of long output, but no way to get rid of this ugly “,”

Anyone an idea?

Thanks

Michael

you can try to add the output of the long_output to the last output of infotext.

yield 0, "Method 1 Archive Status Success\n%s" % ''.join(data.get('long_output'))

Hello,

Does this mean I have to add “’\n’.join(data.get(‘long_output’)” to each “yield” in my code? Sounds not so efficient :frowning:

 # Test Method 1 Archive Status
    if archive_status_1.lower() == "success":
        yield 0, u'Method 1 Archive Status Success ', [("failedlogs_1", failedlogs_1, None, None, None, "count")]
    elif archive_status_1.lower() == "n/a":
        pass
    else:
        yield 2, u'Method 1 Archive Status %s ' % archive_status_1, [("failedlogs_1", failedlogs_1, None, None, None, "count")]
    # Method 2 Archive Status
    if archive_status_2.lower() == "success":
        yield 0, u'Method 2 Archive Status Success ' [("failedlogs_2", failedlogs_2, None, None, None, "count")]
    elif archive_status_2.lower() == "n/a":
        pass
    else:
        yield 2, u'Method 2 Archive Status %s ' % archive_status_2, [("failedlogs_2", failedlogs_2, None, None, None, "count")]
    #Output metrics in case failarchpath is set
    if failarchpath != 'n/a':
        yield 0,'',[("logs",fail_arch_logs, fail_arch_logs_warn, fail_arch_logs_crit, None, "count")]
    # Test count of log files in FAILARCHPATH
    if fail_arch_logs >= fail_arch_logs_crit:
        yield 2, u'Found %s log files in %s ' % (fail_arch_logs, failarchpath)
    elif fail_arch_logs >= fail_arch_logs_warn:
        yield 1, u'Found %s log files in %s ' % (fail_arch_logs, failarchpath)
    # Send long output
    yield 0, "\n%s" % '\n'.join(data.get('long_output'))

Thanks

Michael

No only with the last yield, I think yield will always write something to the Infotext, so if there already text it will first add a , and the append the new text. In your case this is empty.

Exactly this always adds this stupid “,”

from your code example, I gess you need a nice summary message that you can add to the infotext as last message followed by the long_output.

Yeah, maybe I am not creative enough :sweat_smile:

I am wondering why this suppress all my subsequent info texts yields:

def check_db2_archive_tsm(item, params, data):
    fail_arch_logs = data.get('fail_arch_logs',0)
    failarchpath =  data.get('failarchpath')
    failedlogs_1 = data.get('next_log_1') - data.get('first_failure_1') +1
    failedlogs_2 = data.get('next_log_2') - data.get('first_failure_2') +1
    archive_status_1 = data.get('archive_status_1','UNKNOWN')
    archive_status_2 = data.get('archive_status_2','UNKNOWN')
    fail_arch_logs_warn,fail_arch_logs_crit = params["fail_arch_logs"]
    long_output = '\n'.join(data.get('long_output'))
    # Send long output
    yield 0, u' \n%s' % long_output
    # Test Method 1 Archive Status
    if archive_status_1.lower() == "success":
        yield 0, u'Method 1 Archive Status Success', [("failedlogs_1", failedlogs_1, None, None, None, "count")]
    elif archive_status_1.lower() == "n/a":
        pass
    else:
        yield 2, u'Method 1 Archive Status %s ' % archive_status_1, [("failedlogs_1", failedlogs_1, None, None, None, "count")]
    # Method 2 Archive Status
    if archive_status_2.lower() == "success":
        yield 0, u'Method 2 Archive Status Success', [("failedlogs_2", failedlogs_2, None, None, None, "count")]
    elif archive_status_2.lower() == "n/a":
        pass
    else:
        yield 2, u'Method 2 Archive Status %s ' % archive_status_2, [("failedlogs_2", failedlogs_2, None, None, None, "count")]
    #Output metrics in case failarchpath is set
    if failarchpath != 'n/a':
        yield 0,'',[("logs",fail_arch_logs, fail_arch_logs_warn, fail_arch_logs_crit, None, "count")]
    # Test count of log files in FAILARCHPATH
    if fail_arch_logs >= fail_arch_logs_crit:
        yield 2, u'Found %s log files in %s ' % (fail_arch_logs, failarchpath)
    elif fail_arch_logs >= fail_arch_logs_warn:
        yield 1, u'Found %s log files in %s ' % (fail_arch_logs, failarchpath)

as far as I now, as soon as you have one \n in your output everything that follows is long_output.
So you need to move your yield 0, u' \n%s' % long_output to the end of your check.

btw. have you a sample data section?

So you need to move your yield 0, u' \n%s' % long_output to the end of your check.

That’s exactly what I am doing and this produces the “,”.

btw. have you a sample data section?

Could you please explain a bit more in detail what that means?

Thank you for your help

Michael

a sample of your input data for the check.

I know, but if you doing it at the beginning all outher output is gone…

Here is the data:

{'archive_status_1': u'Success',
 'archive_status_2': u'n/a',
 'fail_arch_logs': 0,
 'failarchpath': 'n/a',
 'first_failure_1': 0,
 'first_failure_2': 0,
 'logarchmeth1': u'vendor:/usr/tivoli/tsm/tdp_r3/db264/libtdpdb264.a',
 'logarchmeth2': u'off',
 'long_output': [u'HADR database role                                      = PRIMARY',
                 u'First log archive method                 (LOGARCHMETH1) = VENDOR:/usr/tivoli/tsm/tdp_r3/db264/libtdpdb264.a',
                 u'Second log archive method                (LOGARCHMETH2) = OFF',
                 u'Failover log archive path                (FAILARCHPATH) =',
                 u'FAILARCHPATH not set.',
                 u'Method 1 Archive Status       Success',
                 u'Method 1 Next Log to Archive  33',
                 u'Method 1 First Failure        n/a',
                 u'Method 2 Archive Status       n/a',
                 u'Method 2 Next Log to Archive  n/a',
                 u'Method 2 First Failure        n/a'],
 'next_log_1': 33,
 'next_log_2': 0}
DB2 Archiv TSM db2rc4:MC5 OK - Method 1 Archive Status Success,
{'archive_status_1': u'Success',
 'archive_status_2': u'n/a',
 'fail_arch_logs': 0,
 'failarchpath': u'/db2/rc4/fap_dir/',
 'first_failure_1': 0,
 'first_failure_2': 0,
 'logarchmeth1': u'vendor:/usr/tivoli/tsm/tdp_r3/db264/libtdpdb264.a',
 'logarchmeth2': u'off',
 'long_output': [u'HADR database role                                      = PRIMARY',
                 u'First log archive method                 (LOGARCHMETH1) = VENDOR:/usr/tivoli/tsm/tdp_r3/db264/libtdpdb264.a',
                 u'Second log archive method                (LOGARCHMETH2) = OFF',
                 u'Failover log archive path                (FAILARCHPATH) = /db2/RC4/fap_dir/',
                 u'0 archive log(s) in FAILARCHPATH: /db2/RC4/fap_dir/.',
                 u'Method 1 Archive Status       Success',
                 u'Method 1 Next Log to Archive  1731',
                 u'Method 1 First Failure        n/a',
                 u'Method 2 Archive Status       n/a',
                 u'Method 2 Next Log to Archive  n/a',
                 u'Method 2 First Failure        n/a'],
 'next_log_1': 1731,
 'next_log_2': 0}

looks like there is no good summary text, but anyway. I have done a little rework of your code.
It will first collect all the info_text and perf_data and at the end yield the info_text entrys one by one and with the last info_text entry it will yield the text+longoutput and all the perf_data. In this way you sould get rid of the ugly ,

def check_db2_archive_tsm(item, params, data):
    fail_arch_logs = data.get('fail_arch_logs', 0)
    failarchpath = data.get('failarchpath')
    failedlogs_1 = data.get('next_log_1') - data.get('first_failure_1') + 1
    failedlogs_2 = data.get('next_log_2') - data.get('first_failure_2') + 1
    archive_status_1 = data.get('archive_status_1', 'UNKNOWN')
    archive_status_2 = data.get('archive_status_2', 'UNKNOWN')
    fail_arch_logs_warn, fail_arch_logs_crit = params["fail_arch_logs"]
    long_output = '\n'.join(data.get('long_output'))

    info_text = []
    perf_data = []

    # Send long output
    # yield 0, u' \n%s' % long_output
    # Test Method 1 Archive Status
    if archive_status_1.lower() == "success":
        info_text.append((0, u'Method 1 Archive Status Success'))
        perf_data.append(("failedlogs_1", failedlogs_1, None, None, None, "count"))
    elif archive_status_1.lower() == "n/a":
        pass
    else:
        info_text.append((2, u'Method 1 Archive Status %s ' % archive_status_1,))
        perf_data.append(("failedlogs_1", failedlogs_1, None, None, None, "count"))
    # Method 2 Archive Status
    if archive_status_2.lower() == "success":
        info_text.append((0, u'Method 2 Archive Status Success'))
        perf_data.append(("failedlogs_2", failedlogs_2, None, None, None, "count"))
    elif archive_status_2.lower() == "n/a":
        pass
    else:
        info_text.append((2, u'Method 2 Archive Status %s ' % archive_status_2))
        perf_data.append(("failedlogs_2", failedlogs_2, None, None, None, "count"))
    # Output metrics in case failarchpath is set
    if failarchpath != 'n/a':
        perf_data.append(("logs", fail_arch_logs, fail_arch_logs_warn, fail_arch_logs_crit, None, "count"))
    # Test count of log files in FAILARCHPATH
    if fail_arch_logs >= fail_arch_logs_crit:
        info_text.append((2, u'Found %s log files in %s ' % (fail_arch_logs, failarchpath)))
    elif fail_arch_logs >= fail_arch_logs_warn:
        info_text.append((1, u'Found %s log files in %s ' % (fail_arch_logs, failarchpath)))

    i = len(info_text)
    for state, text in info_text:
        if i != 1:
            yield state, text
            i -= 1
        else:
            yield state, text+long_output, perf_data

@thl-cmk Thank you very much for this code, I see what you mean. I thought there is a more elegant way, it renders the yield more or less useless. Function could even return a complete list.

Yes and no. With the above code you don’t have to deal with the status code a lot, you get your warn/crit directly at the point where the belong and you have not only a summary status.
And it is closer to cmk2.0 check API :wink:

Hello @thl-cmk ,

Today I found the time to test your code. Unfortunately it shows parts of the long output in the info text section:

I allowed myself to do some modification to your code:

@get_parsed_item_data
def check_db2_archive_tsm(item, params, data):
    fail_arch_logs = data.get('fail_arch_logs', 0)
    failarchpath = data.get('failarchpath')
    failedlogs_1 = data.get('next_log_1') - data.get('first_failure_1') + 1
    failedlogs_2 = data.get('next_log_2') - data.get('first_failure_2') + 1
    archive_status_1 = data.get('archive_status_1', 'UNKNOWN')
    archive_status_2 = data.get('archive_status_2', 'UNKNOWN')
    fail_arch_logs_warn, fail_arch_logs_crit = params["fail_arch_logs"]
    long_output = '\n'.join(data.get('long_output'))

    info_text = []
    perf_data = []

    # Send long output
    # yield 0, u' \n%s' % long_output
    # Test Method 1 Archive Status
    if archive_status_1.lower() == "success":
        info_text.append([0, u'Method 1 Archive Status Success'])
        perf_data.append(["failedlogs_1", failedlogs_1, None, None, None, "count"])
    elif archive_status_1.lower() == "n/a":
        pass
    else:
        info_text.append([2, u'Method 1 Archive Status %s ' % archive_status_1,])
        perf_data.append(["failedlogs_1", failedlogs_1, None, None, None, "count"])
    # Method 2 Archive Status
    if archive_status_2.lower() == "success":
        info_text.append([0, u'Method 2 Archive Status Success'])
        perf_data.append(["failedlogs_2", failedlogs_2, None, None, None, "count"])
    elif archive_status_2.lower() == "n/a":
        pass
    else:
        info_text.append([2, u'Method 2 Archive Status %s ' % archive_status_2])
        perf_data.append(["failedlogs_2", failedlogs_2, None, None, None, "count"])
    # Output metrics in case failarchpath is set
    if failarchpath != 'n/a':
        perf_data.append(["logs", fail_arch_logs, fail_arch_logs_warn, fail_arch_logs_crit, None, "count"])
    # Test count of log files in FAILARCHPATH
    if fail_arch_logs >= fail_arch_logs_crit:
        info_text.append([2, u'Found %s log files in %s ' % (fail_arch_logs, failarchpath)])
    elif fail_arch_logs >= fail_arch_logs_warn:
        info_text.append([1, u'Found %s log files in %s ' % (fail_arch_logs, failarchpath)])

    info_text[-1][-1] += "\n%s" % long_output
    info_text[-1].append(perf_data)
    for item in info_text:
        yield item

This way I get the correct results including long output:

Thank you for this lesson

Michael

I see, I did miss the leading newline for the long_output. And nice optimization for the yield. I wasn’t aware that you can submit all pieces of info text at once.

/Thomas

1 Like