Files
sicspsi/sicslogquery.c
Koennecke Mark 2caac1016f Fixed a bug with the eiger monochromator not driving mt when mcv did not drive
Fixed expression searching in sicslogquery
Added proton monitot to tasscan output
Chnaged SICS scripts to reflect the switch from TRICS to ZEBRA
2016-07-01 10:51:37 +02:00

215 lines
5.5 KiB
C

/**
* 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
*/
optind = 1;
while((c = getopt(argc,argv,"s:l:f:t:i:e:c:h")) != -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 'h':
snprintf(
lastError,sizeof(lastError),
"Options: \n-s subsystem\n-l last(h,d)\n-f fromtime\n-t totime\n-i instrument\n-c severity\n%s",
"-e search-expression");
return 1;
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\": {\"$lte\": %d}",
from,to,severity);
if(sub != NULL){
snprintf(subQuery,sizeof(subQuery),", \"sub\" : \"%s\"", sub);
strncat(jsonQuery,subQuery,sizeof(jsonQuery));
}
if(exp != NULL){
snprintf(subQuery,sizeof(subQuery),", \"message\" : {\"$regex\": \"%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;
}