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 )