Ad Widget

Collapse

Agent Module retain variable during calls

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • zhjim
    Junior Member
    • Jan 2012
    • 8

    #1

    Agent Module retain variable during calls

    Hi there,

    playing around with the module extension of version 2.2 I came upon a strange behaviour I have no idea how to explain. I want to retain the value of a variable through out calls to item retrival. Just incrementing the value in the function and returning that new value. Sometime its all good and the correct value gets returned. Just most of the time the value seems to jump back to an older value and then gets incremented further. Or stays as it for some 2 - 3 calls and then increment.

    Is it even possible to retain a value over succesive get item value calls? Do I miss something obvious?
    Also the README file in the modules directory of the source put that line to compile the dummy-module.c as
    PHP Code:
    gcc -shared -o dummy.so dummy.-I../../../include 
    I had to use
    PHP Code:
    gcc -fPIC -shared ./simple.-I../../zabbix-2.2.0/include 
    to get the module compiled.

    Here goes the code and some explanation what I like to have:
    At first I wanted to get the status variables of an apache server. Started out writing a simple socket application that gets and parses the values from the server. I save the variable inside a struct which I refer to over a pointer in the main function. As I did not like to get all the stat vars from the server on every call to the item functions I created a bit mask and only get new values if the same variable is accesed a second time. I then incorperated this into the dummy module and got me two get item value functions. But this did not work out due to the value jumping around (also the pointer to the struct remained constant). I now shrinked the module down to very basic functions. But still the value jumps
    PHP Code:
    #include <stdbool.h>

    // defines various includes. Depending on --configure options
    // also has include for libcurl
    #include "sysinc.h"

    // holds the structs for request and response
    // as well as result defines
    #include "module.h"

    // modules.c loads the modules and
    // has some infos what is needed for a working module

    // variable declaration
    static int item_timeout 0;
    static 
    unsigned int req_tot 0;
    static 
    unsigned int uptime 100;
    bool old;

    // return value
    void debug(charmsg);
    int getrtot(charserver);
    int getUp(charserver);

    // prototypes for key functions
    int zbx_module_apache_stats_rtot(AGENT_REQUEST *requestAGENT_RESULT *result);
    int zbx_module_apache_stats_up(AGENT_REQUEST *requestAGENT_RESULT *result);

    // array with keys of the module
    static ZBX_METRIC keys[] =
    /* Keyname, flags, function to call, test parameters */
    {
            {
    "apache.status.requests.total"0zbx_module_apache_stats_rtot0},
            {
    "apache.status.uptime"0zbx_module_apache_stats_up0},
            {
    NULL}
    };

    // function mandatory (src/libs/zbxmodules/modules.c)
    // init function of module
    // load config and alike
    int zbx_module_init(){
    bool okay false;
    char msg[255];
    debug("module_init: called\n");

            
    // Init variables
            
    req_tot 0;
            
    uptime 100;
            
    old true;

            
    // All good so module can finish loading
            
    okay true;

            if ( 
    okay ) {
                    return 
    ZBX_MODULE_OK;           // see include/module.h for possible values
            
    } else {
                    return 
    ZBX_MODULE_FAIL;
            }
    }
    // function mandatory (src/libs/zbxmodules/modules.c
    // cleaner
    int zbx_module_uninit(){

            return 
    ZBX_MODULE_OK;
    }

    // function mandatory (src/libs/zbxmodules/modules.c
    // return api version of module
    int zbx_module_api_version(){
            return 
    ZBX_MODULE_API_VERSION_ONE;
    }

    // function non-mandatory
    // sets timeout of items
    void zbx_module_item_timeout(int timeout){
            
    item_timeout timeout;
    }

    // function mandatory (src/libs/zbxmodules/modules.c
    // returns list to keys of module
    ZBX_METRIC *zbx_module_item_list(){
            return 
    keys;
    }

    // Structure can be found in include/module.h
    // As well as the different return types
    // key function

    int zbx_module_apache_stats_rtot(AGENT_REQUEST *requestAGENT_RESULT *result){
    bool okay false;
    int value;
    char *server;
    debug("stats_rtot: called\n");

            if ( (
    value getrtot(server)) != -){
                    
    debug("stats_rtot: value okay\n");
                    
    okay true;
                    
    SET_UI64_RESULT(resultvalue);
            }

            if ( 
    okay ) {
                    
    debug("stats_rtot: return ok\n");
                    return 
    SYSINFO_RET_OK;
            } else {
                    
    debug("stats_rtot: return false\n");
                    
    SET_MSG_RESULT(resultstrdup("Unkown error"));
                    return 
    SYSINFO_RET_FAIL;
            }
    }
    int zbx_module_apache_stats_up(AGENT_REQUEST *requestAGENT_RESULT *result){
    bool okay false;
    int value;
    char *server;
    debug("stats_up: called\n");

            if ( (
    value getUp(server)) != -){
                    
    debug("stats_up: value okay\n");
                    
    okay true;
                    
    SET_UI64_RESULT(resultvalue);
            }

            if ( 
    okay ) {
                    
    debug("stats_up: return ok\n");
                    return 
    SYSINFO_RET_OK;
            } else {
                    
    debug("stats_up: return false\n");
                    
    SET_MSG_RESULT(resultstrdup("Unkown error"));
                    return 
    SYSINFO_RET_FAIL;
            }
    }


    void debug(charmsg){
    FILE *debug fopen"/tmp/apache.so.log""a");

            
    fprintf(debug"%s"msg);
            
    fclose(debug);

    }

    // Parses lines of status page and puts in struct apstat
    //
    // returns 0 on success
    // returns 1 on parse error
    int getrtot(charserver){
    char msg[255];
    sprintf(msg"rtot: start: old =  %d, req_tot = %d\n"oldreq_tot);
    debug(msg);

            
    // Check if we need new values
            
    if ( old ){
                    
    debug("new values\n");
                    
    req_tot++;
                    
    uptime+=100;
            }

            
    // set Flag
            
    old  true;

    sprintf(msg"rtot: end: old =  %d, req_tot = %d\n"oldreq_tot);
    debug(msg);

            return 
    req_tot;
    }


    int getUp(charserver){
    char msg[255];
    sprintf(msg"UP: old = %d, uptime = %d\n"olduptime);
    debug(msg);

            return 
    uptime;


  • zhjim
    Junior Member
    • Jan 2012
    • 8

    #2
    I found out what the problem with the approach I'm taking is. Its the threads. In default configuration you have 3 agent threads running and each of them gets called in turn. So the initial values are set on all 3 threads. Then I ask for my item and thread one answers it and has its value set to the new values. Next time I ask its thread 2 turn but he has the initial values from module load so he returns those and not the values I expected.

    If one would only use one agent thread it all goes well. At least it did with my tests.

    Is there anyway to have the threads refer to the same variables? I guess this would be a change either to how modules are loaded or how the threads get created.

    Comment

    Working...