Chandra

 view release on metacpan or  search on metacpan

include/chandra/chandra_log.h  view on Meta::CPAN

    for (i = 0; i < 5; i++) {
        if (strEQ(lvl, chandra_log_level_names[i])) {
            sv_catpv(out, chandra_log_level_NAMES[i]);
            break;
        }
    }
    sv_catpvs(out, ": ");
    if (msg_svp && SvOK(*msg_svp))
        sv_catsv(out, *msg_svp);
    sv_catpvs(out, "\n");
    return out;
}

static SV *
chandra_log_format_custom(pTHX_ SV *formatter, HV *entry)
{
    dSP;
    int count;
    SV *result;

    ENTER; SAVETMPS;
    PUSHMARK(SP);
    XPUSHs(newRV_noinc((SV *)entry));
    PUTBACK;
    count = call_sv(formatter, G_SCALAR);
    SPAGAIN;
    result = (count > 0) ? SvREFCNT_inc(POPs) : newSVpvs("");
    PUTBACK;
    FREETMPS; LEAVE;
    return result;
}

static SV *
chandra_log_format(pTHX_ chandra_log_ctx *ctx, HV *entry)
{
    switch (ctx->fmt_type) {
        case CHANDRA_LOG_FMT_JSON:
            return chandra_log_format_json(aTHX_ entry);
        case CHANDRA_LOG_FMT_MINIMAL:
            return chandra_log_format_minimal(aTHX_ entry);
        case CHANDRA_LOG_FMT_CUSTOM:
            /* For custom, entry HV ownership is transferred to formatter */
            return chandra_log_format_custom(aTHX_ ctx->fmt_custom,
                                             (HV *)newHVhv(entry));
        default:
            return chandra_log_format_text(aTHX_ entry);
    }
}

/* --- File rotation --- */

static void
chandra_log_maybe_rotate(pTHX_ chandra_log_ctx *ctx, const char *path)
{
    Stat_t st;
    int keep, i;
    char from[4096], to[4096];

    if (ctx->rotate_max_size <= 0)
        return;
    if (PerlLIO_stat(path, &st) != 0)
        return;
    if (st.st_size < ctx->rotate_max_size)
        return;

    keep = ctx->rotate_keep;
    if (keep > CHANDRA_LOG_MAX_KEEP)
        keep = CHANDRA_LOG_MAX_KEEP;

    /* Delete oldest */
    snprintf(to, sizeof(to), "%s.%d", path, keep);
    (void)PerlLIO_unlink(to);

    /* Shift existing */
    for (i = keep - 1; i >= 1; i--) {
        snprintf(from, sizeof(from), "%s.%d", path, i);
        snprintf(to,   sizeof(to),   "%s.%d", path, i + 1);
        (void)PerlLIO_rename(from, to);
    }

    /* Rotate current */
    snprintf(to, sizeof(to), "%s.1", path);
    (void)PerlLIO_rename(path, to);
}

/* --- Emit to a single output --- */

static void
chandra_log_emit(pTHX_ chandra_log_ctx *ctx, chandra_log_output *out,
                 int level, HV *entry, SV *formatted)
{
    /* Per-output level filter */
    if (out->level >= 0 && level < out->level)
        return;

    switch (out->type) {
        case CHANDRA_LOG_OUT_STDERR:
            {
                STRLEN len;
                const char *s = SvPV(formatted, len);
                PerlIO_write(PerlIO_stderr(), s, len);
                PerlIO_flush(PerlIO_stderr());
            }
            break;

        case CHANDRA_LOG_OUT_STDOUT:
            {
                STRLEN len;
                const char *s = SvPV(formatted, len);
                PerlIO_write(PerlIO_stdout(), s, len);
                PerlIO_flush(PerlIO_stdout());
            }
            break;

        case CHANDRA_LOG_OUT_FILE:
            {
                const char *path = SvPV_nolen(out->path);
                PerlIO *fh;

                chandra_log_maybe_rotate(aTHX_ ctx, path);



( run in 2.406 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )