Added a sqlite and mongo database driver for the new logging

system.
This commit is contained in:
2016-03-01 09:51:25 +01:00
parent 972e191795
commit 1087dd6c8d
11 changed files with 1589 additions and 1 deletions

206
sicslogquery.c Normal file
View File

@ -0,0 +1,206 @@
/**
* This does the query execution for the new mongodb based sicslog.
*
* COPYRIGHT GPL
*
* Mark Koennecke, February 2016
*/
#include <sicslogquery.h>
#include <unistd.h>
#include <sys/time.h>
#include <logv2.h>
#include <approxidate.h>
static char lastError[1024];
static char mongoURL[1024];
static char inst[132];
static mongoc_client_t *client;
static mongoc_collection_t *collection;
/*--------------------------------------------------------------------------------*/
char * sicslogGetError(void)
{
/*
May be change to strdup(lastError);
*/
return lastError;
}
/*--------------------------------------------------------------------------------*/
int sicslogSetup(char *url, char *instPar)
{
memset(inst,0,sizeof(inst));
if(instPar != NULL){
strncpy(inst,instPar, sizeof(inst));
}
strncpy(mongoURL,url,sizeof(mongoURL));
mongoc_init();
client = mongoc_client_new (mongoURL);
if(!client){
snprintf(lastError,sizeof(lastError),"ERROR: failed to connect to mongodb, bad URL?");
return 1;
}
return 0;
}
/*--------------------------------------------------------------------------------*/
static unsigned int sevFromText(const char *txt)
{
static const char *severityText[] = {"fatal",
"error",
"warn",
"info",
"verbose",
"debug",
NULL
};
int sev = 0;
while(severityText[sev] != NULL){
if(strcmp(txt,severityText[sev]) == 0){
break;
}
sev++;
}
sev++; /* starting at 1 rather then 0 */
return sev;
}
/*---------------------------------------------------------------------------*/
int sicslogQuery(int argc, char *argv[], ResultCallback_t func, void *userData)
{
char c;
time_t to = time(NULL), from = to - 3600;
int severity = INFO, mult = 1, status = 0;
char *sub = NULL;
char *exp = NULL;
char *instLocal = NULL;
char *tmp, *pPtr;
char jsonQuery[2024], subQuery[132];
struct timeval tv;
mongoc_collection_t *collection = NULL;
bson_t *query;
const bson_t *doc;
mongoc_cursor_t *cursor;
bson_error_t err;
/*
parse options
*/
while((c = getopt(argc,argv,"s:l:f:t:i:e:c:")) != -1) {
switch (c){
case 's':
sub = strdup(optarg);
break;
case 'l':
tmp = strdup(optarg);
if((pPtr = strrchr(tmp,(int)'h')) != NULL){
mult = 60;
*pPtr = '\0';
} else if((pPtr = strrchr(tmp,(int)'d')) != NULL){
mult = 24*60;
*pPtr = '\0';
}
from = to - atoi(tmp)*mult*60;
free(tmp);
break;
case 'f':
if(approxidate(optarg,&tv) == 0){
from = tv.tv_sec;
} else {
snprintf(lastError,sizeof(lastError),"Failed to parse date from %s", optarg);
return 1;
}
break;
case 't':
if(approxidate(optarg,&tv) == 0){
to = tv.tv_sec;
} else {
snprintf(lastError,sizeof(lastError),"Failed to parse date from %s", optarg);
return 1;
}
break;
case 'i':
instLocal = strdup(optarg);
break;
case 'e':
exp = strdup(optarg);
break;
case 'c':
severity = sevFromText(optarg);
break;
case '?':
if( optopt == 's' || optopt == 'l' || optopt == 'f' || optopt == 't'
|| optopt == 'i' || optopt == 'e' || optopt == 'c') {
snprintf(lastError,sizeof(lastError),"Option %c requires an argument", optopt);
} else {
snprintf(lastError,sizeof(lastError),"Unknown option %c", optopt);
}
return 1;
break;
}
}
if(instLocal == NULL && strlen(inst) > 1){
instLocal = strdup(inst);
}
if(instLocal == NULL){
snprintf(lastError,sizeof(lastError),"Do not know which instrument log to query, specify with -i");
return 1;
}
/*
build the query
*/
snprintf(jsonQuery, sizeof(jsonQuery),"{ \"timestamp\" : {\"$gt\": %ld, \"$lt\": %ld}, \"severity\": {\"$lt\": %d}",
from,to,severity-1);
if(sub != NULL){
snprintf(subQuery,sizeof(subQuery),", \"sub\" : \"%s\"", sub);
strncat(jsonQuery,subQuery,sizeof(jsonQuery));
}
if(exp != NULL){
snprintf(subQuery,sizeof(subQuery),", \"message\" : {$regexp : \"/%s/\" }", exp);
strncat(jsonQuery,subQuery,sizeof(jsonQuery));
}
strncat(jsonQuery,"}",sizeof(jsonQuery));
/*
now execute the query
*/
collection = mongoc_client_get_collection(client,instLocal,"log");
if(collection == NULL){
snprintf(lastError,sizeof(lastError),"Failed to find log for %s", instLocal);
status = 1;
goto cleanup;
}
fprintf(stdout,"The query: %s\n", jsonQuery);
query = bson_new_from_json((const uint8_t *)jsonQuery,strlen(jsonQuery), &err);
if(query == NULL){
snprintf(lastError,sizeof(lastError),"Failed to parse query with %s", err.message);
status = 1;
goto cleanup;
}
cursor = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
while (mongoc_cursor_next (cursor, &doc)) {
func(doc,userData);
}
cleanup:
if(sub != NULL){
free(sub);
}
if(exp != NULL){
free(exp);
}
if(query != NULL){
bson_destroy(query);
}
if(cursor != NULL){
/* mongoc_cursor_destroy(cursor); */
}
if(collection != NULL){
mongoc_collection_destroy(collection);
}
return status;
}