Exemplo n.º 1
0
/*
 * Example callback that returns a list of forms.
 */
static enum conflate_mgmt_cb_result process_ping_test(void *opaque,
                                                      conflate_handle_t *handle,
                                                      const char *cmd,
                                                      bool direct,
                                                      kvpair_t *form,
                                                      conflate_form_result *r)
{
    kvpair_t *servers_p = find_kvpair(form, "servers");
    if (!servers_p) {
        return RV_BADARG;
    }
    char **servers = servers_p->values;

    for (int i = 0; servers[i]; i++) {
        /* For each result we wish to send back, we begin a field set */
        conflate_next_fieldset(r);

        /* All fields added now fall within the current fieldset */
        conflate_add_field(r, "-set-", servers[i]);

        const char *vals[3] = { "val1", "val2", NULL };
        conflate_add_field_multi(r, "test1", vals);

        conflate_add_field(r, "test2", "some val");
    }

    return RV_OK;
}
Exemplo n.º 2
0
static enum conflate_mgmt_cb_result process_get_private(void *opaque,
                                                        conflate_handle_t *handle,
                                                        const char *cmd,
                                                        bool direct,
                                                        kvpair_t *form,
                                                        conflate_form_result *r)
{
    /* Only direct stat requests are handled. */
    assert(direct);
    enum conflate_mgmt_cb_result rv = RV_ERROR;

    char *key = get_simple_kvpair_val(form, "key");

    if (key) {
        /* Initialize the form so there's always one there */
        conflate_init_form(r);
        char *value = conflate_get_private(handle, key,
                                           handle->conf->save_path);
        if (value) {
            conflate_add_field(r, key, value);
            free(value);
        }

        rv = RV_OK;
    } else {
        rv = RV_BADARG;
    }

    return rv;
}
Exemplo n.º 3
0
/*
 * Example callback with a simple form result.
 */
static enum conflate_mgmt_cb_result process_stats(void *opaque,
                                                  conflate_handle_t *handle,
                                                  const char *cmd,
                                                  bool direct,
                                                  kvpair_t *form,
                                                  conflate_form_result *r)
{
    /* Only direct stat requests are handled. */
    assert(direct);

    char *subtype = get_simple_kvpair_val(form, "-subtype-");

    fprintf(stderr, "Handling stats request with subtype:  %s\n",
            subtype ? subtype : "(null)");

    conflate_add_field(r, "stat1", "val1");
    conflate_add_field(r, "stat2", "val2");

    return RV_OK;
}
Exemplo n.º 4
0
static void ping_server(char *server_name,
                        struct ping_test_recipe *recipes,
                        proxy_behavior *behavior,
                        conflate_form_result *r) {
#ifdef MOXI_USE_LIBMEMCACHED
    assert(server_name);
    assert(behavior);
    assert(r);

    if (strlen(behavior->host) <= 0 ||
        behavior->port <= 0)
        return;

    memcached_st         mst;
    memcached_server_st *mservers;

    struct timeval timing;

    conflate_next_fieldset(r);
    conflate_add_field(r, "-set-", server_name);

    char  buf[300] = { 0x00 };

#define dbl_report(name, dval)                  \
    snprintf(buf, sizeof(buf), "%f", dval);     \
    conflate_add_field(r, name, buf);

#define int_report(name, ival)                  \
    snprintf(buf, sizeof(buf), "%d", ival);     \
    conflate_add_field(r, name, buf);

#define tv_report(name, mark, val)                  \
    timeval_subtract(&timing, &val, &mark);         \
    dbl_report(name, timeval_to_double(timing));

#define stat_report(buf, buflen, name, type, dval)  \
    snprintf(buf, buflen, "%s_%s", name, type);     \
    dbl_report(buf, dval);

    if (memcached_create(&mst) != NULL) {
        memcached_behavior_set(&mst, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
        memcached_behavior_set(&mst, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);

        snprintf(buf, sizeof(buf),
                 "%s:%u",
                 behavior->host,
                 behavior->port);

        mservers = memcached_servers_parse(buf);
        if (mservers != NULL) {
            memcached_server_push(&mst, mservers);
            memcached_server_list_free(mservers);
            mservers = NULL;

            int nconns = memcached_server_count(&mst);
            bool connected  = false;

            for (int i = 0; i < nconns; i++) {
                if (settings.verbose > 1)
                    moxi_log_write("ping_test connecting %d\n", i);

                struct timeval start;
                gettimeofday(&start, NULL);

                mcs_server_st *st = mcs_server_index((void *) &mst, i);
                mcs_return rc = mcs_server_st_connect(st, NULL, true);
                if (rc == MCS_SUCCESS) {
                    struct timeval tv_conn;
                    gettimeofday(&tv_conn, NULL);
                    tv_report("conn", start, tv_conn);

                    if (cproxy_auth_downstream(st, behavior,
                                               mcs_server_st_fd(st)) &&
                        cproxy_bucket_downstream(st, behavior,
                                                 mcs_server_st_fd(st))) {
                        struct timeval tv_auth;
                        gettimeofday(&tv_auth, NULL);
                        tv_report("auth", tv_conn, tv_auth);

                        // Flag whether to proceed if we connected
                        connected = true;
                    }
                }
            }

            if (connected) {
                for (int j = 0; recipes[j].name; j++) {
                    struct moxi_stats recipe_stats = { .min = 0.0 };
                    int failures = 0;

                    perform_ping_test(recipes[j], &mst,
                                      &recipe_stats, &failures);
                    int vlen = strlen(recipes[j].name) + 8;
                    char val_name[vlen];

                    stat_report(val_name, vlen, recipes[j].name,
                                "min", recipe_stats.min);
                    stat_report(val_name, vlen, recipes[j].name,
                                "avg", recipe_stats.avg);
                    stat_report(val_name, vlen, recipes[j].name,
                                "max", recipe_stats.max);
                    stat_report(val_name, vlen, recipes[j].name,
                                "stddev", recipe_stats.stddev);
                    stat_report(val_name, vlen, recipes[j].name,
                                "95th", recipe_stats.ninetyfifth);


                    snprintf(val_name, vlen, "%s_fail", recipes[j].name);
                    int_report(val_name, failures);
                }
            }
        } else {