Nagios: SAP CCMS Monitoring

In a previous blog-entry I described how to change check_sap_cons (sap-ccms nagios package) to report performance data.

After some time this was not enough anymore. Configuring CCMS with its warning/critical values is a mess and also a global configuration. So there was the need to modify the script once again, so nagios gives the warning/critical values and then with these values the check itself decides if the i.e response time is good enough or not.

Here is the modified check_sap_cons (within my system check_sap_cons_perf).

#include
#include
#include "sap_moni.h"
#include "sap_moni_ccm.h"

#define ERROR 2

/*=======================================================================
(C) Copyright SAP AG, 2002

Author : Dostert/SAP

modified 2009: Silvan Hunkirchen
Project : Get data from R/3 using XMB
Using : RFCSDK
========================================================================*/

//void usage(char *progname) {
void usage() {
#define BL printf(

BL”Agent\n\n”);
BL”Syntax:

\n\n”);

BL” defined in %s \n”, AGENT_INI_FILE );
BL” defined in %s\n”, AGENT_LOGIN_FILE );
BL”
\n” );
BL” \n” );
BL” \n” );
}

int main(int argc, char **argv) {

RFC_HANDLE rfc_handle;
AlMoniHandle_T *MoniHandle;
int NrOfMoniTempl;

AlMoniNode_T *nodes;
unsigned int NrOfNodes;

char templ_name[AL_MONI_MAX_TEMPL_NAME_LENGTH];
int highest_alert = 0;

// Modification from original CVS
int i,j; // counter for perfdata-creation
// char perfdata_name[20]; // variable for perfdata name
char perfdata_unit[20]; // variable for perfdata unit
char perfdata[255]; // variable for perfdata value
unsigned int warn; // warn value from nagios
unsigned int crit; // crit value from nagios
unsigned int ret_ok=0; // return code for nagios
unsigned int ret_warn=1; // return code for nagios
unsigned int ret_crit=2; // return code for nagios
unsigned int perfvalue; // perfvalue comparision
char *perfdata_temp;
// end modification

if (argc != 6) {
usage();
return ERROR;
}

strcpy(templ_name, argv[1]);

// modification
// strcpy (perfdata_name, argv[3]);
strcpy (perfdata_unit, argv[3]);
warn=atoi(argv[4]);
crit=atoi(argv[5]);
// end modification //

//printf (“%s”,perfdata_unit);
//printf (“%d %d”,warn, crit);

if ( sapmon_init(&MoniHandle, &NrOfMoniTempl) >= AG_FIRST_ERROR) {
printf(“Could not initialize INI-File\n”);
return ERROR;
}

if( sapmon_connect(argv[2], &rfc_handle) >= AG_FIRST_ERROR) {
printf(“Could not log on\n”);
return ERROR;
}

for (i = 0; i < NrOfMoniTempl; i++) {
if ( strcmp(sapmon_get_template_name(MoniHandle[i]), templ_name) != 0)
continue;

sapmon_request(&rfc_handle, &(MoniHandle[i]), 1 );
sapmon_request_tree(MoniHandle[i], &nodes, &NrOfNodes);

for (j = 0; j < NrOfNodes; j++) {

//modification
// Copy first MAX_STR_LENGTH characters into perfdata
strncpy(perfdata, nodes[j].currentValue, 255);
perfdata_temp = strtok (perfdata, ” “);
//explicitly set the last byte of the buffer to 0 after calling strncpy
perfdata[255 – 1] = 0;
unsigned int a = 0;
unsigned int b = 0;

for(a = 0; a < 255; ++a){
if (perfdata[a] != ‘ ‘){ // Look for a ‘
perfdata[b]=perfdata[a];
++b;
}
}

// old comparision of alert status. Takes Actualval from RZ20 and checks if the current returncode is higher than highest_alert that was previously saved
// if (nodes[j].Actualval > highest_alert)
// highest_alert = nodes[j].Actualval;
perfvalue=atoi(perfdata_temp);
if (perfvalue > warn)
{
if (perfvalue > crit)
highest_alert=ret_crit;
// printf (“crit”);
else
highest_alert=ret_warn;
// printf (“warn”);
}
else
highest_alert=ret_ok;
// printf (“ok”);
if (strcmp(nodes[j].Objectname, nodes[j].Mtnameshrt) != 0)
//printf(“%s %s %s %s %s %d|%s=%s%s;%d;%d;;\n”,nodes[j].Mtsysid, nodes[j].Mtmcname, nodes[j].Objectname, nodes[j].Mtnameshrt, nodes[j].currentValue, nodes[j].Actualval,nodes[j].Mtnameshrt, perfvalue,perfdata_unit,warn,crit);
printf(“%s %s %s %s %s|%s=%d%s;%d;%d;;\n”,nodes[j].Mtsysid, nodes[j].Mtmcname, nodes[j].Objectname, nodes[j].Mtnameshrt, nodes[j].currentValue,nodes[j].Mtnameshrt, perfvalue,perfdata_unit,warn,crit);
else
printf(“%s %s %s\n”,nodes[j].Mtsysid, nodes[j].Mtmcname, nodes[j].Objectname);
}
}

//Nothing found
if (NrOfNodes == 0) {
highest_alert = 3;
printf(“No information gathered! System up?\n”);
}

//Log off
sapmon_disconnect(&rfc_handle);

//return highest_alert -1;
return highest_alert;
}

The sourcecode differs in several options from the original one.
First you have to call the program with UNIT WARNING CRITICAL values.
Unit is used for performancedata process as it is set for the UOM value of pnp. WARNING and CRITICAL are selfexplaining.

As the SAP environment here has several application servers I used a new check (check_multi) to create one check, which checks all app-server that are being used.

I will explain the configuration for check_multi and the complete configuration of nagios within the next blog-entries.

Advertisements
This entry was posted in Nagios, SAP, SuSE and tagged , , , , , . Bookmark the permalink.

4 Responses to Nagios: SAP CCMS Monitoring

  1. JaneRadriges says:

    I really like your post. Does it copyright protected?

  2. tinnitis says:

    Thank you for the advice. I’ve found your first point to be most effective.

  3. Team Roster says:

    You you could change the page subject Nagios: SAP CCMS Monitoring | Unix Experiences to something more catching for your subject you write. I liked the blog post withal.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s