Ad Widget

Collapse

How can I pass the current date in a specific format to the item key parameter?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Dron.kh
    Junior Member
    • Apr 2021
    • 7

    #1

    How can I pass the current date in a specific format to the item key parameter?

    Good day. Zabbix 5.2. Monitoring windows/linux through active agents or passive agents through a proxy. There is a task to keep track of the folder size. The difficulty is that me have to keep track of a different folder every day. For example, today D:\backup\2021-04-23, tomorrow D:\backup\2021-04-24, etc. I create an item and get the folder size using the key vfs.dir.size[D:\backup\2021-04-23] without any problems. But how can I replace the date with its dynamic value in the key parameter in the folder path so that today's date is substituted in the yyyy-mm-dd format?

    I tried to use the {DATE} macro, which seems to be supposed to return a date in the yyyy.mm.dd format, and using the regsub function, return the date in the format I need using the following {DATE}.regsub(^\d{4}\.\d{2}\.\d{2}$, \1-\2-\3), but it does not work either in the macro format or in the key parameter vfs.dir.size[D:\backup\{{DATE}.regsub(^\d{4}\.\d{2}\.\d{2}$, \1-\2-\3)}] (although {DATE} should only work in notifications so I was initially not sure about this approach).

    Of course I can use UserParameter or scripts, but I would like to avoid unnecessary actions if possible.
  • Dron.kh
    Junior Member
    • Apr 2021
    • 7

    #2
    Originally posted by cyber
    I would go with external script which would update a global macro(s) daily with different formats of today (and tomorrow and yesterday if needed). Those macros can be used in key params.
    So I can use the macro in the parameters of the key? Something like fs.dir.size[D:\backup\{$MyMacro}] will work?

    And how can I change the value of a macro in a script? I am creating a script in Administration -> Scripts with the command «date +"%F"», but what to do next?


    Comment

    • Dron.kh
      Junior Member
      • Apr 2021
      • 7

      #3
      If I want to use usermacro.updateglobal to modify the global macro, how do I do it in practice?

      Comment

      • kazagz
        Junior Member
        • Nov 2021
        • 1

        #4
        I've used two approaches for this. One is for cases where you want to have single item, other if for cases where you want to have multiple items each with it's own date. You can select whatever is best for you.

        First option if single item is needed - create dummy calculated item, schedule to run it every midnight. Add "1" in formula, it doesn't matter. In Preprocessing add JavaScript step with code (formatting gets messed up when pasting text here, sorry):
        Code:
        /**
        /**
        * Get date in predefined formats
        * @param format
        * Formats allowed:
        * - ddmmyyyy
        * - yyyymmdd
        * - dd.mm.yyyy
        * - dd-mm-yyyy
        * - yyyy.mm.dd
        * - yyyy-mm-dd
        * @param relativeDay Relative day number (0 for today, -1 for yesterday, +1 for tomorrow etc.)
        */
        function getDate(format, relativeDay) {
        var today = new Date();
        if (relativeDay) {
        today.setDate(today.getDate() + relativeDay);
        }
        var dd = today.getDate();
        var mm = today.getMonth() + 1;
        var yyyy = today.getFullYear();
        if (dd < 10) {
        // @ts-ignore
        dd = '0' + dd;
        }
        if (mm < 10) {
        // @ts-ignore
        mm = '0' + mm;
        }
        if (format.match(/yyyymmdd/i)) {
        return "" + yyyy + mm + dd;
        }
        else if (format.match(/ddmmyyyy/i)) {
        return "" + dd + mm + yyyy;
        }
        else if (format.match(/dd\.mm\.yyyy/i)) {
        return dd + '.' + mm + '.' + yyyy;
        }
        else if (format.match(/dd-mm-yyyy/i)) {
        return dd + '-' + mm + '-' + yyyy;
        }
        else if (format.match(/yyyy\.mm\.dd/i)) {
        return yyyy + '.' + mm + '.' + dd;
        }
        else if (format.match(/yyyy-mm-dd/i)) {
        return yyyy + '-' + mm + '-' + dd;
        }
        throw "Wrong date format, allowed: ddmmyyyy, yyyymmdd, dd.mm.yyyy, dd-mm-yyyy, yyyy.mm.dd, yyyy-mm-dd";
        }
        
        
        /**
        * Make request to Zabbix API
        * @param payload JSON data https://www.zabbix.com/documentation/current/manual/api
        */
        function postToZabbixApi(payload) {
        var resp;
        try {
        var req = new CurlHttpRequest();
        req.AddHeader('Content-Type: application/json-rpc');
        var result = JSON.parse(req.Post(zabbix_url, JSON.stringify(payload)));
        resp = { result: result, status: req.Status() };
        }
        catch (error) {
        Zabbix.Log(3, error);
        resp = { error: "Error while calling '" + payload.method + "': " + error };
        }
        return resp;
        }
        
        
        /** Zabbix API url - will be resolved by Zabbix template level macro */
        var zabbix_url = "{$ZABBIX.API.URL}";
        /** Zabbix API username - will be resolved by Zabbix template level macro */
        var username = "{$ZABBIX.API.USERNAME}";
        /** Zabbix API password - will be resolved by Zabbix template level macro */
        var password = "{$ZABBIX.API.PASSWORD}";
        /** Global macros to update, name WITHOUT CURLY BRACES!!! */
        var macros = [
        { name: "$GLOBAL.TODAY.DDMMYYYY", format: "DDMMYYYY", day: 0 },
        { name: "$GLOBAL.TODAY.YYYYMMDD", format: "YYYYMMDD", day: 0 },
        { name: "$GLOBAL.YESTERDAY.DDMMYYYY", format: "DDMMYYYY", day: -1 },
        { name: "$GLOBAL.YESTERDAY.YYYYMMDD", format: "YYYYMMDD", day: -1 }
        ];
        var resp = {
        login: {},
        getMacro: [],
        updateMacro: [],
        logout: {}
        };
        var loginPayload = {
        jsonrpc: "2.0",
        method: "user.login",
        params: {
        user: username,
        password: password
        },
        auth: null,
        id: 1
        };
        resp.login = postToZabbixApi(loginPayload);
        if (!resp.login.result || !resp.login.result.result) {
        // @ts-ignore
        return JSON.stringify(resp);
        }
        /** Zabbix auth token */
        var auth_key = resp.login.result.result;
        macros.forEach(function (macro) {
        var getMacroPayload = {
        jsonrpc: "2.0",
        method: "usermacro.get",
        params: {
        output: "extend",
        globalmacro: true,
        filter: {
        macro: "\{" + macro.name + "\}"
        }
        },
        auth: auth_key,
        id: 1
        };
        var _res = postToZabbixApi(getMacroPayload);
        resp.getMacro.push(_res);
        if (!_res.result || !_res.result.result || _res.result.result.length > 1 || !_res.result.result[0].globalmacroid) {
        // @ts-ignore
        return JSON.stringify(resp);
        }
        var updateMacroPayload = {
        jsonrpc: "2.0",
        method: "usermacro.updateglobal",
        params: {
        globalmacroid: _res.result.result[0].globalmacroid,
        value: getDate(macro.format, macro.day)
        },
        auth: auth_key,
        id: 1
        };
        resp.updateMacro.push(postToZabbixApi(updateMacroPayload));
        });
        var logoutPayload = {
        jsonrpc: "2.0",
        method: "user.logout",
        params: [],
        auth: auth_key,
        id: 1
        };
        resp.logout = postToZabbixApi(logoutPayload);
        // @ts-ignore
        return JSON.stringify(resp);
        In my example return type is Text so you should use this as type of information. Save item. Now add macros {$ZABBIX.API.URL}, {$ZABBIX.API.USERNAME}, {$ZABBIX.API.PASSWORD} to same host/template + their values e.g. https://your-zabbix.com/zabbix/api_jsonrpc.php. Once per day Global Macro {$GLOBAL.TODAY.DDMMYYYY} + few others will be updated. Now you can use them in your items.

        Second option if you need multiple items - create discovery rule. For example, if you need date in format YYYYMMDD:
        Key: system.localtime[local]
        Preprocessing: return JSON.stringify([{"date": value.replace(/-/g, "").substring(0, 8)}])
        LLD Macro: {#DATE}
        LLD Macro JSON Path: $.date
        Item Prototype Name: Hi, I was created on {#DATE}!
        Item Prototype Key: vfs.dir.count[/some/path/{#DATE}/,,file,,0]

        Schedule discovery to run once at midnight, item update interval based on your needs. Add triggers if needed. Whenever date changes new item will be created, in my case this is exactly what's needed. I'm keeping lost discovery resources for 5d (not interested in anything older), they are deleted afterwards.

        Comment

        • cyber
          Senior Member
          Zabbix Certified SpecialistZabbix Certified Professional
          • Dec 2006
          • 4807

          #5
          DATE is not usable in key params.. These times and dates in parameters have always been a painpoint of Zabbix..
          I would go with external script which would update a global macro(s) daily with different formats of today (and tomorrow and yesterday if needed). Those macros can be used in key...

          Comment

          • cyber
            Senior Member
            Zabbix Certified SpecialistZabbix Certified Professional
            • Dec 2006
            • 4807

            #6
            You should run the script from crontab/scheduler. Script updates those global macros once a day over API.

            ...

            Comment

            Working...