Repository: valkey-io/valkey
File: src/server.c (C)

Code before:
        if (c->calls || c->failed_calls || c->rejected_calls) {
            info = sdscatprintf(info,
                                "cmdstat_%s:calls=%lld,usec=%lld,usec_per_call=%.2f"
                                ",rejected_calls=%lld,failed_calls=%lld\r\n",
                                getSafeInfoString(c->fullname, sdslen(c->fullname), &tmpsafe), c->calls,
                                c->microseconds, (c->calls == 0) ? 0 : ((float)c->microseconds / c->calls),
                                c->rejected_calls, c->failed_calls);
            if (tmpsafe != NULL) zfree(tmpsafe);
        }
        if (c->subcommands_ht) {
            info = genValkeyInfoStringCommandStats(info, c->subcommands_ht);
        }
    }
    hashtableResetIterator(&iter);

    return info;
}

/* Writes the ACL metrics to the info */
sds genValkeyInfoStringACLStats(sds info) {
    info = sdscatprintf(info,
                        "acl_access_denied_auth:%lld\r\n"
                        "acl_access_denied_cmd:%lld\r\n"
                        "acl_access_denied_key:%lld\r\n"
                        "acl_access_denied_channel:%lld\r\n"
                        "invalid_tls_cert_auth_failures:%lld\r\n",
                        server.acl_info.user_auth_failures, server.acl_info.invalid_cmd_accesses,
                        server.acl_info.invalid_key_accesses, server.acl_info.invalid_channel_accesses,
                        server.acl_info.invalid_tls_cert_auth_failures);
    return info;
}

sds genValkeyInfoStringLatencyStats(sds info, hashtable *commands) {
    hashtableIterator iter;
    void *next;
    hashtableInitIterator(&iter, commands, HASHTABLE_ITER_SAFE);
    while (hashtableNext(&iter, &next)) {
        struct serverCommand *c = next;
        char *tmpsafe;
        if (c->latency_histogram) {
            info = fillPercentileDistributionLatencies(
                info, getSafeInfoString(c->fullname, sdslen(c->fullname), &tmpsafe), c->latency_histogram);
            if (tmpsafe != NULL) zfree(tmpsafe);
        }
        if (c->subcommands_ht) {
            info = genValkeyInfoStringLatencyStats(info, c->subcommands_ht);
        }
    }
    hashtableResetIterator(&iter);

    return info;

Review comment (suggestion):
Oh, this is a new INFO field. This is also part of the user-facing API, so we should be careful.

This is not actually counting invalid certificates. Invalid certificate means that it is rejected, for example if it's expired or not trusted by the CA certs. In that case, it would be rejected in the TLS handshake. Here it can be valid but just not match an existing username.

Probably it should start with "acl" like the other fields here.

How about `"acl_access_denied_tls_cert"`? @madolson please chime in.

Code after:
        if (c->calls || c->failed_calls || c->rejected_calls) {
            info = sdscatprintf(info,
                                "cmdstat_%s:calls=%lld,usec=%lld,usec_per_call=%.2f"
                                ",rejected_calls=%lld,failed_calls=%lld\r\n",
                                getSafeInfoString(c->fullname, sdslen(c->fullname), &tmpsafe), c->calls,
                                c->microseconds, (c->calls == 0) ? 0 : ((float)c->microseconds / c->calls),
                                c->rejected_calls, c->failed_calls);
            if (tmpsafe != NULL) zfree(tmpsafe);
        }
        if (c->subcommands_ht) {
            info = genValkeyInfoStringCommandStats(info, c->subcommands_ht);
        }
    }
    hashtableResetIterator(&iter);

    return info;
}

/* Writes the ACL metrics to the info */
sds genValkeyInfoStringACLStats(sds info) {
    info = sdscatprintf(info,
                        "acl_access_denied_auth:%lld\r\n"
                        "acl_access_denied_cmd:%lld\r\n"
                        "acl_access_denied_key:%lld\r\n"
                        "acl_access_denied_channel:%lld\r\n"
                        "acl_access_denied_tls_cert:%lld\r\n",
                        server.acl_info.user_auth_failures, server.acl_info.invalid_cmd_accesses,
                        server.acl_info.invalid_key_accesses, server.acl_info.invalid_channel_accesses,
                        server.acl_info.acl_access_denied_tls_cert);
    return info;
}

sds genValkeyInfoStringLatencyStats(sds info, hashtable *commands) {
    hashtableIterator iter;
    void *next;
    hashtableInitIterator(&iter, commands, HASHTABLE_ITER_SAFE);
    while (hashtableNext(&iter, &next)) {
        struct serverCommand *c = next;
        char *tmpsafe;
        if (c->latency_histogram) {
            info = fillPercentileDistributionLatencies(
                info, getSafeInfoString(c->fullname, sdslen(c->fullname), &tmpsafe), c->latency_histogram);
            if (tmpsafe != NULL) zfree(tmpsafe);
        }
        if (c->subcommands_ht) {
            info = genValkeyInfoStringLatencyStats(info, c->subcommands_ht);
        }
    }
    hashtableResetIterator(&iter);

    return info;