Annotation of embedaddon/bmon/src/out_rrd.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * out_rrd.c           RRD Output
        !             3:  *
        !             4:  * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch>
        !             5:  *
        !             6:  * Permission is hereby granted, free of charge, to any person obtaining a
        !             7:  * copy of this software and associated documentation files (the "Software"),
        !             8:  * to deal in the Software without restriction, including without limitation
        !             9:  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
        !            10:  * and/or sell copies of the Software, and to permit persons to whom the
        !            11:  * Software is furnished to do so, subject to the following conditions:
        !            12:  *
        !            13:  * The above copyright notice and this permission notice shall be included
        !            14:  * in all copies or substantial portions of the Software.
        !            15:  *
        !            16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        !            17:  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        !            19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
        !            21:  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
        !            22:  * DEALINGS IN THE SOFTWARE.
        !            23:  */
        !            24: 
        !            25: #include <bmon/bmon.h>
        !            26: #include <bmon/node.h>
        !            27: #include <bmon/output.h>
        !            28: #include <bmon/graph.h>
        !            29: #include <bmon/input.h>
        !            30: #include <bmon/utils.h>
        !            31: #include <inttypes.h>
        !            32: 
        !            33: #define MAX_RRA 128
        !            34: 
        !            35: static const char *c_path = "./";
        !            36: static char *c_step = "1";
        !            37: static char *c_heartbeat = "2";
        !            38: static char *c_rra[MAX_RRA];
        !            39: static int c_rra_index;
        !            40: static int c_update_interval = 1;
        !            41: 
        !            42: static void create_rrd(char *file, item_t *it)
        !            43: {
        !            44:        char *argv[256];
        !            45:        char nows[32];
        !            46:        int i, m, ul;
        !            47: 
        !            48:        memset(argv, 0, sizeof(argv));
        !            49: 
        !            50:        snprintf(nows, sizeof(nows), "%lld", (unsigned long long) (time(0) - 1));
        !            51: 
        !            52:        argv[0] = "create";
        !            53:        argv[1] = file;
        !            54:        argv[2] = "--start";
        !            55:        argv[3] = nows;
        !            56:        argv[4] = "--step";
        !            57:        argv[5] = c_step;
        !            58: 
        !            59:        i = 6;
        !            60: 
        !            61:        for (m = 0; m < ATTR_HASH_MAX;  m++) {
        !            62:                stat_attr_t *a;
        !            63:                for (a = it->i_attrs[m]; a; a = a->a_next) {
        !            64:                        char ds[128];
        !            65:                        if (i >= (253 - c_rra_index))
        !            66:                                goto overflow;
        !            67:                        snprintf(ds, sizeof(ds), "DS:%s_rx:%s:%s:U:U",
        !            68:                            type2name(a->a_type),
        !            69:                            a->a_flags & ATTR_FLAG_IS_RATE ? "GAUGE" : "COUNTER",
        !            70:                            c_heartbeat);
        !            71:                        argv[i++] = strdup(ds);
        !            72: 
        !            73:                        if (i >= (253 - c_rra_index))
        !            74:                                goto overflow;
        !            75:                        snprintf(ds, sizeof(ds), "DS:%s_tx:%s:%s:U:U",
        !            76:                            type2name(a->a_type),
        !            77:                            a->a_flags & ATTR_FLAG_IS_RATE ? "GAUGE" : "COUNTER",
        !            78:                            c_heartbeat);
        !            79:                        argv[i++] = strdup(ds);
        !            80:                }
        !            81:        }
        !            82:        
        !            83:        ul = i;
        !            84: 
        !            85:        if (i + c_rra_index >= 255)
        !            86:                goto overflow;
        !            87: 
        !            88:        for (m = 0; m < c_rra_index; m++)
        !            89:                argv[i++] = c_rra[m];
        !            90: 
        !            91:        optind = 0; /* What a nice undocumented precondition */
        !            92:        opterr = 0;
        !            93: 
        !            94:        if (rrd_create(i, argv) < 0)
        !            95:                fprintf(stderr, "rrd_create failed: %s\n", rrd_get_error());
        !            96: 
        !            97:        for (i = 6; i < ul && argv[i]; i++)
        !            98:                free(argv[i]);
        !            99: 
        !           100:        return;
        !           101: 
        !           102: overflow:
        !           103:        quit("Argument overflow, blame the RRD API\n");
        !           104: }
        !           105: 
        !           106: static void update_rrd(char *file, item_t *it)
        !           107: {
        !           108:        char *argv[6];
        !           109:        char template[256];
        !           110:        char data[1024];
        !           111:        int m;
        !           112: 
        !           113:        memset(argv, 0, sizeof(argv));
        !           114: 
        !           115:        argv[0] = "update";
        !           116:        argv[1] = file;
        !           117:        argv[2] = "--template";
        !           118: 
        !           119:        memset(template, 0, sizeof(template));
        !           120: 
        !           121:        for (m = 0; m < ATTR_HASH_MAX; m++) {
        !           122:                stat_attr_t *a;
        !           123:                for (a = it->i_attrs[m]; a; a = a->a_next) {
        !           124:                        if (template[0])
        !           125:                                strncat(template, ":",
        !           126:                                    sizeof(template) - strlen(template) - 1);
        !           127:                        strncat(template, type2name(a->a_type),
        !           128:                            sizeof(template) - strlen(template) - 1);
        !           129:                        strncat(template, "_rx",
        !           130:                            sizeof(template) - strlen(template) - 1);
        !           131:                        strncat(template, ":",
        !           132:                            sizeof(template) - strlen(template) - 1);
        !           133:                        strncat(template, type2name(a->a_type),
        !           134:                            sizeof(template) - strlen(template) - 1);
        !           135:                        strncat(template, "_tx",
        !           136:                            sizeof(template) - strlen(template) - 1);
        !           137:                }
        !           138:        }
        !           139: 
        !           140:        argv[3] = template;
        !           141: 
        !           142:        snprintf(data, sizeof(data), "%lld",
        !           143:            rtiming.rt_last_read.tv_sec);
        !           144: 
        !           145:        for (m = 0; m < ATTR_HASH_MAX; m++) {
        !           146:                stat_attr_t *a;
        !           147:                for (a = it->i_attrs[m]; a; a = a->a_next) {
        !           148:                        char valuepair[64];
        !           149:                        snprintf(valuepair, sizeof(valuepair),
        !           150:                            "%s%lld:%lld",
        !           151:                            data[0] ? ":" : "", attr_get_rx(a),
        !           152:                            attr_get_tx(a));
        !           153: 
        !           154:                        strncat(data, valuepair,
        !           155:                            sizeof(data) - strlen(data) - 1);
        !           156:                }
        !           157:        }
        !           158: 
        !           159:        argv[4] = data;
        !           160: 
        !           161:        for (m = 0; m < 5; m++)
        !           162:                printf("%s ", argv[m]);
        !           163:        printf("\n");
        !           164: 
        !           165:        optind = 0; /* What a nice undocumented precondition */
        !           166:        opterr = 0;
        !           167: 
        !           168:        rrd_update(5, argv);
        !           169: }
        !           170: 
        !           171: static void write_per_item(item_t *it, void *arg)
        !           172: {
        !           173:        node_t *node = (node_t *) arg;
        !           174:        char file[FILENAME_MAX];
        !           175: 
        !           176:        snprintf(file, sizeof(file), "%s/%s_%d.rrd", c_path, node->n_name, it->i_index);
        !           177: 
        !           178:        if (access(file, W_OK) != 0)
        !           179:                create_rrd(file, it);
        !           180: 
        !           181:        if (access(file, W_OK) == 0)
        !           182:                update_rrd(file, it);
        !           183: }
        !           184: 
        !           185: static void write_per_node(node_t *node, void *arg)
        !           186: {
        !           187:        foreach_item(node, write_per_item, (void *) node);
        !           188: }
        !           189: 
        !           190: void rrd_draw(void)
        !           191: {
        !           192:        static int rem = 1;
        !           193: 
        !           194:        if (--rem)
        !           195:                return;
        !           196:        else
        !           197:                rem = c_update_interval;
        !           198: 
        !           199:        foreach_node(write_per_node, NULL);
        !           200: }
        !           201: 
        !           202: static void print_module_help(void)
        !           203: {
        !           204:        printf(
        !           205:        "RRD - RRD Output\n" \
        !           206:        "\n" \
        !           207:        "  Writes updated to RRD databases. Databases are created if needed\n" \
        !           208:        "  and non-existent\n" \
        !           209:        "  Author: Thomas Graf <tgraf@suug.ch>\n" \
        !           210:        "\n" \
        !           211:        "  Options:\n" \
        !           212:        "    path=PATH        Output directory\n" \
        !           213:        "    step=SECS        Interval RRD expects updates (default: 1 second)\n" \
        !           214:        "    heartbeat=SECS   Maximum interval until RRD throws away an\n" \
        !           215:        "                     update (default: 2 seconds)\n" \
        !           216:        "    interval=NUM     Update interval in read interval cycles\n" \
        !           217:        "    rra=RRA_DEF      RRA definition (default: RRA:AVERAGE:0.5:1:86400)\n");
        !           218: }
        !           219: 
        !           220: static void rrd_set_opts(tv_t *attrs)
        !           221: {
        !           222:        static int first_rra = 1;
        !           223: 
        !           224:        while (attrs) {
        !           225:                if (!strcasecmp(attrs->type, "path") && attrs->value)
        !           226:                        c_path = attrs->value;
        !           227:                else if (!strcasecmp(attrs->type, "step") && attrs->value)
        !           228:                        c_step = attrs->value;
        !           229:                else if (!strcasecmp(attrs->type, "heartbeat") && attrs->value)
        !           230:                        c_heartbeat = attrs->value;
        !           231:                else if (!strcasecmp(attrs->type, "interval") && attrs->value)
        !           232:                        c_update_interval = strtol(attrs->value, NULL, 0);
        !           233:                else if (!strcasecmp(attrs->type, "rra") && attrs->value) {
        !           234:                        if (first_rra) {
        !           235:                                c_rra_index = 0;
        !           236:                                first_rra = 0;
        !           237:                        }
        !           238:                        if (c_rra_index < MAX_RRA)
        !           239:                                c_rra[c_rra_index++] = attrs->value;
        !           240:                } else if (!strcasecmp(attrs->type, "help")) {
        !           241:                        print_module_help();
        !           242:                        exit(0);
        !           243:                }
        !           244:                
        !           245:                attrs = attrs->next;
        !           246:        }
        !           247: }
        !           248: 
        !           249: static int rrd_probe(void)
        !           250: {
        !           251:        return 1;
        !           252: }
        !           253: 
        !           254: static struct output_module rrd_ops = {
        !           255:        .om_name = "rrd",
        !           256:        .om_draw = rrd_draw,
        !           257:        .om_set_opts = rrd_set_opts,
        !           258:        .om_probe = rrd_probe,
        !           259: };
        !           260: 
        !           261: static void __init save_init(void)
        !           262: {
        !           263:        c_rra[0] = "RRA:AVERAGE:0.5:1:86400";
        !           264:        c_rra_index = 1;
        !           265:        register_secondary_output_module(&rrd_ops);
        !           266: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>