libmem-release/log.c

197 lines
3.7 KiB
C
Raw Normal View History

2024-08-07 22:24:28 +00:00
/**
* @file log.c
*
* @brief Code file for logging library
*
* @copyright Copyright (C) 2024 Jackrabbit Founders LLC. All rights reserved.
*
* @date Jul 2024
* @author Barrett Edwards <code@jrlabs.io>
*/
/* INCLUDES ==================================================================*/
/* printf()
* fprintf()
* vfprintf()
* FILE
* stdout
* stderr
*/
#include <stdio.h>
/* calloc()
* free()
*/
#include <stdlib.h>
/* getpid()
*/
#include <unistd.h>
/* clock_gettime()
*/
#include <time.h>
/* va_start
* va_end
*/
#include <stdarg.h>
/* LOG_* Macros
*/
#include <syslog.h>
#include "log.h"
/* MACROS ====================================================================*/
/* ENUMERATIONS ==============================================================*/
/* STRUCTS ===================================================================*/
/* GLOBAL VARIABLES ==========================================================*/
/**
* String representation of logging levels
*/
static const char *levels[] =
{
"EMERG",
"ALERT",
"CRIT",
"ERR",
"WARNING",
"NOTICE",
"INFO",
"DEBUG",
};
static const char *log_destinations[] =
{
"STDIO",
"SYSLOG",
"NULL",
"FILE",
};
/* PROTOTYPES ================================================================*/
/* FUNCTIONS =================================================================*/
void log_to_syslog(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args)
{
vsyslog(priority, format, args);
}
void log_to_stdio(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args)
{
struct timespec ts;
FILE *fp;
if (priority >= LOG_INFO)
fp = stdout;
else
fp = stderr;
if (ctx->timestamp)
{
// Get time for entry
clock_gettime(CLOCK_REALTIME, &ts);
// print the time first
fprintf(fp, "[%10ld.%09ld] [%d] %s - ", ts.tv_sec, ts.tv_nsec, getpid(), levels[priority]);
fprintf(fp, "%s: %s:%d ", ctx->owner, fn, ln);
}
vfprintf(fp, format, args);
}
void log_to_file(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, va_list args)
{
struct timespec ts;
FILE *f = ctx->file;
if (ctx->timestamp)
{
// Get time for entry
clock_gettime(CLOCK_REALTIME, &ts);
// print the time first
fprintf(f, "[%10ld.%09ld] [%d] %s - ", ts.tv_sec, ts.tv_nsec, getpid(), levels[priority]);
fprintf(f, "%s: %s:%d ", ctx->owner, fn, ln);
}
// print the message
vfprintf(f, format, args);
// flush
fflush(f);
}
void log_submit(struct log_ctx *ctx, int priority, const char *fn, int ln, const char *format, ...)
{
va_list args;
va_start(args, format);
ctx->log_fn(ctx, priority, fn, ln, format, args);
va_end(args);
}
struct log_ctx *log_init(const char *owner, int dst, int priority, int timestamp, char *filepath)
{
struct log_ctx *l;
// Allocate memory for the log struct
l = calloc(1, sizeof(*l));
if (l == NULL)
goto end;
// Set values
l->owner = owner;
l->priority = priority;
l->timestamp = timestamp;
if (dst == LDST_SYSLOG)
l->log_fn = log_to_syslog;
else if (dst == LDST_NULL)
l->log_fn = log_to_null;
else if (dst == LDST_FILE & filepath != NULL)
{
l->file = fopen(filepath, "a");
l->log_fn = log_to_file;
}
else
l->log_fn = log_to_stdio;
end:
return l;
}
/**
* Free the memory used by struct log_ctx
*/
int log_free(struct log_ctx *ctx)
{
if (ctx->file != NULL)
fclose(ctx->file);
if (ctx != NULL)
free(ctx);
return 0;
}
const char *log_priority_to_str(int priority)
{
if (priority < 0 || priority > LOG_DEBUG)
return NULL;
return levels[priority];
}
const char *log_dst_to_str(int dst)
{
if (dst < 0 || dst > LDST_MAX)
return NULL;
return log_destinations[dst];
}