125 lines
3.4 KiB
C
125 lines
3.4 KiB
C
/*
|
|
This is a module which implements output of the log to a sqlite database.
|
|
The database is much easier for searching the log
|
|
|
|
copyright: see file COPYRIGHT
|
|
|
|
Mark Koennecke, February 2016
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <logv2.h>
|
|
#include <sqlite3.h>
|
|
#include <sicsutil.h>
|
|
#include <sics.h>
|
|
|
|
static sqlite3 *db = NULL;
|
|
static char sqliteFile[1024];
|
|
static unsigned int lineCount = 0;
|
|
static unsigned int sqlActive = 0;
|
|
|
|
/*----------------------------------------------------------------------------------*/
|
|
static void SqlFlush(void)
|
|
{
|
|
char *err;
|
|
|
|
if(sqlActive == 1 && db != NULL){
|
|
sqlite3_exec(db,"END TRANSACTION",NULL,NULL,&err);
|
|
lineCount = 0;
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------------------
|
|
The callback function for entering data into the log
|
|
------------------------------------------------------------------------------------*/
|
|
static void SqliteCallback(unsigned int severity, const char *timeStamp,
|
|
const char *subsystem,
|
|
const char *message, void *userData)
|
|
{
|
|
double tVal = DoubleTime();
|
|
char sql[2024];
|
|
int status;
|
|
char *err;
|
|
|
|
if(logFilter(severity,subsystem,message) == 1) {
|
|
return;
|
|
}
|
|
|
|
if(lineCount == 0){
|
|
sqlite3_exec(db,"BEGIN TRANSACTION",NULL,NULL,&err);
|
|
}
|
|
|
|
sqlite3_snprintf(sizeof(sql),sql,"INSERT into log VALUES(%f,\"%s\",%d,\"%s\",\"%w\")",
|
|
tVal,timeStamp,severity,subsystem,message);
|
|
status = sqlite3_exec(db,sql,NULL,NULL,&err);
|
|
if(status != SQLITE_OK){
|
|
printf("Sqlite logging error: %s from %s\n", err, sql);
|
|
sqlite3_free(err);
|
|
}
|
|
lineCount++;
|
|
|
|
if(lineCount >= 1000){
|
|
SqlFlush();
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------------------------------*/
|
|
static void SqlClose(void *data)
|
|
{
|
|
char *err;
|
|
|
|
if(sqlActive == 1 && db != NULL){
|
|
sqlite3_exec(db,"END TRANSACTION",NULL,NULL,&err);
|
|
sqlite3_close(db);
|
|
RemoveLogCallback(SqliteCallback);
|
|
sqlActive = 0;
|
|
}
|
|
}
|
|
/*------------------------------------------------------------------------------------*/
|
|
static int SQLLogConfigAction(SConnection * pCon, SicsInterp * pSics,
|
|
void *pData, int argc, char *argv[])
|
|
{
|
|
int status;
|
|
|
|
if(argc < 2) {
|
|
SCWrite(pCon,"ERROR: need keyword", eError);
|
|
return 0;
|
|
}
|
|
|
|
strtolower(argv[1]);
|
|
if(strcmp(argv[1],"open") == 0){
|
|
if(argc < 3){
|
|
SCWrite(pCon,"ERROR: need dbfilename parameter for open",eError);
|
|
return 0;
|
|
}
|
|
strncpy(sqliteFile,argv[2],sizeof(sqliteFile));
|
|
status = sqlite3_open(sqliteFile,&db);
|
|
if(status){
|
|
SCPrintf(pCon,eError,"ERROR: failed to open database %s", argv[2]);
|
|
sqlite3_close(db);
|
|
return 0;
|
|
} else {
|
|
RegisterLogCallback(SqliteCallback,NULL);
|
|
sqlActive = 1;
|
|
SCSendOK(pCon);
|
|
}
|
|
} else if(strcmp(argv[1],"close") == 0) {
|
|
SqlClose(NULL);
|
|
SCSendOK(pCon);
|
|
} else if(strcmp(argv[1],"flush") == 0) {
|
|
SqlFlush();
|
|
SCSendOK(pCon);
|
|
} else if(strcmp(argv[1],"filename") == 0) {
|
|
SCPrintf(pCon,eValue,"sqlitedb = %s", sqliteFile);
|
|
} else {
|
|
SCPrintf(pCon,eError,"ERROR: keyword %s not recognised", argv[1]);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------------------*/
|
|
void SqliteLogInit(void)
|
|
{
|
|
AddCommand(pServ->pSics,"sqlconfig", SQLLogConfigAction,
|
|
SqlClose, NULL);
|
|
}
|
|
|