Commit a650f379 authored by Shawn Webb's avatar Shawn Webb
Browse files

Implement SQLite3-based logging



The name of the table is passed in to the logger's init function.

The SQLite3 logger will create the following table if it doesn't already
exist:

CREATE TABLE IF NOT EXISTS <table> (
	timesec BIGINT NOT NULL,
	timeusec BIGINT NOT NULL,
	msgtype TEXT NOT NULL,
	msg TEXT NOT NULL
)

Of course, replace `<table>` with the name of the table.
Signed-off-by: Shawn Webb's avatarShawn Webb <shawn.webb@hardenedbsd.org>
parent b6fe87af
......@@ -6,6 +6,7 @@ SRCS+= config.c
SRCS+= log-dummy.c
SRCS+= log-main.c
SRCS+= log-stdio.c
SRCS+= log-sqlite3.c
SRCS+= log-syslog.c
SRCS+= sqlite3.c
......
......@@ -263,6 +263,17 @@ void lattutil_log_dummy_init(lattutil_log_t *);
*/
bool lattutil_log_stdio_init(lattutil_log_t *);
/**
* Initialize sqlite3-based logging
*
* @param Logging object
* @param lattutil SQLite3 context object
* @param name of the table to use, the table is created on first use
* @return True on success, false otherwise
*/
bool lattutil_log_sqlite_init(lattutil_log_t *, lattutil_sqlite_ctx_t *,
const char *);
/**
* Determine if the logging subsystem is ready to receive messages
*
......@@ -532,6 +543,16 @@ ssize_t lattutil_log_stdio_info(lattutil_log_t *, int,
ssize_t lattutil_log_stdio_warn(lattutil_log_t *, int,
const char *, ...);
void lattutil_log_stdio_close(lattutil_log_t *);
ssize_t lattutil_log_sqlite_debug(lattutil_log_t *, int,
const char *, ...);
ssize_t lattutil_log_sqlite_err(lattutil_log_t *, int,
const char *, ...);
ssize_t lattutil_log_sqlite_info(lattutil_log_t *, int,
const char *, ...);
ssize_t lattutil_log_sqlite_warn(lattutil_log_t *, int,
const char *, ...);
void lattutil_log_sqlite_close(lattutil_log_t *);
#endif /* _lattutil_internal */
#ifdef __cplusplus
......
/*-
* Copyright (c) 2021 Shawn Webb <shawn.webb@hardenedbsd.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include "liblattutil.h"
typedef struct _log_sqlite3_aux {
lattutil_sqlite_ctx_t *lsc_sqlctx;
char *lsc_table;
} log_sqlite3_ctx_t;
EXPORTED_SYM
bool
lattutil_log_sqlite_init(lattutil_log_t *logp,
lattutil_sqlite_ctx_t *sqlctx, const char *table)
{
lattutil_sqlite_query_t *query;
log_sqlite3_ctx_t *ctx;
char *create_query;
if (logp == NULL || sqlctx == NULL || table == NULL) {
return (false);
}
create_query = NULL;
asprintf(&create_query, "CREATE TABLE IF NOT EXISTS %s ("
" timesec BIGINT NOT NULL, "
" timeusec BIGINT NOT NULL,"
" msgtype TEXT NOT NULL,"
" msg TEXT NOT NULL"
")", table);
if (create_query == NULL) {
return (false);
}
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) {
free(create_query);
return (false);
}
ctx->lsc_sqlctx = sqlctx;
ctx->lsc_table = strdup(table);
if (ctx->lsc_table == NULL) {
free(create_query);
free(ctx);
lattutil_sqlite_query_free(&query);
return (false);
}
query = lattutil_sqlite_prepare(sqlctx, create_query);
if (lattutil_sqlite_exec(query) == false) {
free(ctx->lsc_table);
free(create_query);
free(ctx);
lattutil_sqlite_query_free(&query);
return (false);
}
logp->ll_log_close = lattutil_log_sqlite_close;
logp->ll_log_debug = lattutil_log_sqlite_debug;
logp->ll_log_err = lattutil_log_sqlite_err;
logp->ll_log_info = lattutil_log_sqlite_info;
logp->ll_log_warn = lattutil_log_sqlite_warn;
lattutil_log_set_aux(logp, ctx, sizeof(*ctx));
free(create_query);
lattutil_sqlite_query_free(&query);
return (true);
}
ssize_t
lattutil_log_sqlite_debug(lattutil_log_t *logp, int verbose,
const char *fmt, ...)
{
lattutil_sqlite_query_t *query;
log_sqlite3_ctx_t *ctx;
char *msg, *querystr;
struct timeval tv;
va_list args;
size_t len;
if (logp == NULL || fmt == NULL) {
return (-1);
}
memset(&tv, 0, sizeof(tv));
gettimeofday(&tv, NULL);
query = NULL;
querystr = NULL;
va_start(args, fmt);
if (verbose == -1 || verbose >= logp->ll_verbosity) {
len = 0;
ctx = lattutil_log_get_aux(logp, &len);
if (ctx == NULL || len != sizeof(*ctx)) {
len = -1;
goto end;
}
msg = NULL;
vasprintf(&msg, fmt, args);
if (msg == NULL) {
len = -1;
goto end;
}
len = strlen(msg);
querystr = NULL;
asprintf(&querystr, "INSERT INTO %s ("
"timesec, timeusec, msgtype, msg) VALUES (?, ?, ?, ?)",
ctx->lsc_table);
if (querystr == NULL) {
len = -1;
goto end;
}
query = lattutil_sqlite_prepare(ctx->lsc_sqlctx, querystr);
if (query == NULL) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_int(query, 1, tv.tv_sec) == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_int(query, 2, tv.tv_usec) == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_string(query, 3, "DEBUG") == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_string(query, 4, msg) == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_exec(query) == false) {
len = -1;
goto end;
}
free(msg);
}
va_end(args);
end:
lattutil_sqlite_query_free(&query);
free(querystr);
return (len);
}
ssize_t
lattutil_log_sqlite_err(lattutil_log_t *logp, int verbose,
const char *fmt, ...)
{
lattutil_sqlite_query_t *query;
log_sqlite3_ctx_t *ctx;
char *msg, *querystr;
struct timeval tv;
va_list args;
size_t len;
if (logp == NULL || fmt == NULL) {
return (-1);
}
memset(&tv, 0, sizeof(tv));
gettimeofday(&tv, NULL);
query = NULL;
querystr = NULL;
va_start(args, fmt);
if (verbose == -1 || verbose >= logp->ll_verbosity) {
len = 0;
ctx = lattutil_log_get_aux(logp, &len);
if (ctx == NULL || len != sizeof(*ctx)) {
len = -1;
goto end;
}
msg = NULL;
vasprintf(&msg, fmt, args);
if (msg == NULL) {
len = -1;
goto end;
}
len = strlen(msg);
querystr = NULL;
asprintf(&querystr, "INSERT INTO %s ("
"timesec, timeusec, msgtype, msg) VALUES (?, ?, ?, ?)",
ctx->lsc_table);
if (querystr == NULL) {
len = -1;
goto end;
}
query = lattutil_sqlite_prepare(ctx->lsc_sqlctx, querystr);
if (query == NULL) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_int(query, 1, tv.tv_sec) == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_int(query, 2, tv.tv_usec) == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_string(query, 3, "ERROR") == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_string(query, 4, msg) == false) {
len = -1;
goto end;
}
lattutil_sqlite_exec(query);
free(msg);
}
va_end(args);
end:
lattutil_sqlite_query_free(&query);
free(querystr);
return (len);
}
ssize_t
lattutil_log_sqlite_info(lattutil_log_t *logp, int verbose,
const char *fmt, ...)
{
lattutil_sqlite_query_t *query;
log_sqlite3_ctx_t *ctx;
char *msg, *querystr;
struct timeval tv;
va_list args;
size_t len;
if (logp == NULL || fmt == NULL) {
return (-1);
}
memset(&tv, 0, sizeof(tv));
gettimeofday(&tv, NULL);
query = NULL;
querystr = NULL;
va_start(args, fmt);
if (verbose == -1 || verbose >= logp->ll_verbosity) {
len = 0;
ctx = lattutil_log_get_aux(logp, &len);
if (ctx == NULL || len != sizeof(*ctx)) {
len = -1;
goto end;
}
msg = NULL;
vasprintf(&msg, fmt, args);
if (msg == NULL) {
len = -1;
goto end;
}
len = strlen(msg);
querystr = NULL;
asprintf(&querystr, "INSERT INTO %s ("
"timesec, timeusec, msgtype, msg) VALUES (?, ?, ?, ?)",
ctx->lsc_table);
if (querystr == NULL) {
len = -1;
goto end;
}
query = lattutil_sqlite_prepare(ctx->lsc_sqlctx, querystr);
if (query == NULL) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_int(query, 1, tv.tv_sec) == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_int(query, 2, tv.tv_usec) == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_string(query, 3, "INFO") == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_string(query, 4, msg) == false) {
len = -1;
goto end;
}
lattutil_sqlite_exec(query);
free(msg);
}
va_end(args);
end:
lattutil_sqlite_query_free(&query);
free(querystr);
return (len);
}
ssize_t
lattutil_log_sqlite_warn(lattutil_log_t *logp, int verbose,
const char *fmt, ...)
{
lattutil_sqlite_query_t *query;
log_sqlite3_ctx_t *ctx;
char *msg, *querystr;
struct timeval tv;
va_list args;
size_t len;
if (logp == NULL || fmt == NULL) {
return (-1);
}
memset(&tv, 0, sizeof(tv));
gettimeofday(&tv, NULL);
query = NULL;
querystr = NULL;
va_start(args, fmt);
if (verbose == -1 || verbose >= logp->ll_verbosity) {
len = 0;
ctx = lattutil_log_get_aux(logp, &len);
if (ctx == NULL || len != sizeof(*ctx)) {
len = -1;
goto end;
}
msg = NULL;
vasprintf(&msg, fmt, args);
if (msg == NULL) {
len = -1;
goto end;
}
len = strlen(msg);
querystr = NULL;
asprintf(&querystr, "INSERT INTO %s ("
"timesec, timeusec, msgtype, msg) VALUES (?, ?, ?, ?)",
ctx->lsc_table);
if (querystr == NULL) {
len = -1;
goto end;
}
query = lattutil_sqlite_prepare(ctx->lsc_sqlctx, querystr);
if (query == NULL) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_int(query, 1, tv.tv_sec) == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_int(query, 2, tv.tv_usec) == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_string(query, 3, "WARNING") == false) {
len = -1;
goto end;
}
if (lattutil_sqlite_bind_string(query, 4, msg) == false) {
len = -1;
goto end;
}
lattutil_sqlite_exec(query);
free(msg);
}
va_end(args);
end:
lattutil_sqlite_query_free(&query);
free(querystr);
return (len);
}
void
lattutil_log_sqlite_close(lattutil_log_t *logp)
{
log_sqlite3_ctx_t *ctx;
size_t sz;
if (logp == NULL) {
return;
}
sz = 0;
ctx = lattutil_log_get_aux(logp, &sz);
if (ctx == NULL || sz != sizeof(*ctx)) {
return;
}
free(ctx->lsc_table);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment