diff options
| author | David Sommerseth <davids@redhat.com> | 2009-10-21 16:32:23 +0200 |
|---|---|---|
| committer | David Sommerseth <davids@redhat.com> | 2009-10-21 16:32:23 +0200 |
| commit | 9526e7d8844a47faadcd00e81ceb0a504a09124c (patch) | |
| tree | c5e1d4a0245cae309a7b8cc4f86e5b901c82be5a /server/parser | |
| parent | 4cbd21f2ae3b4dbbe881ebf8e5d5b6dcf59ec67b (diff) | |
First cut at implementing a generic logger
Diffstat (limited to 'server/parser')
| -rw-r--r-- | server/parser/configparser.c | 24 | ||||
| -rw-r--r-- | server/parser/configparser.h | 2 | ||||
| -rw-r--r-- | server/parser/eurephia_nullsafe.c | 8 | ||||
| -rw-r--r-- | server/parser/eurephia_nullsafe.h | 4 | ||||
| -rw-r--r-- | server/parser/eurephia_values.c | 12 | ||||
| -rw-r--r-- | server/parser/eurephia_values.h | 2 | ||||
| -rw-r--r-- | server/parser/eurephia_values_struct.h | 3 | ||||
| -rw-r--r-- | server/parser/eurephia_xml.c | 6 | ||||
| -rw-r--r-- | server/parser/eurephia_xml.h | 2 | ||||
| -rw-r--r-- | server/parser/parsethread.c | 77 | ||||
| -rw-r--r-- | server/parser/pgsql.c | 236 | ||||
| -rw-r--r-- | server/parser/pgsql.h | 11 | ||||
| -rw-r--r-- | server/parser/rteval_parserd.c | 89 | ||||
| -rw-r--r-- | server/parser/xmlparser.c | 57 | ||||
| -rw-r--r-- | server/parser/xmlparser.h | 10 |
15 files changed, 309 insertions, 234 deletions
diff --git a/server/parser/configparser.c b/server/parser/configparser.c index 3b5597f..dc01984 100644 --- a/server/parser/configparser.c +++ b/server/parser/configparser.c @@ -38,6 +38,8 @@ #include <eurephia_nullsafe.h> #include <eurephia_values.h> +#include <configparser.h> +#include <log.h> /** * Parse one single configuration line into a eurephiaVALUES key/value pair. It will also ignore @@ -49,7 +51,7 @@ * @return eurephiaVALUES pointer containing the parsed result. On error or if no valid config * line was found, NULL is returned. */ -static inline eurephiaVALUES *parse_config_line(const char *line) { +static inline eurephiaVALUES *parse_config_line(LogContext *log, const char *line) { char *cp = NULL, *key = NULL, *val = NULL, *ptr = NULL;; eurephiaVALUES *ret = NULL; @@ -95,7 +97,7 @@ static inline eurephiaVALUES *parse_config_line(const char *line) { *ptr = '\0'; // Put key/value into a eurephiaVALUES struct and return it - ret = eCreate_value_space(20); + ret = eCreate_value_space(log, 20); ret->key = strdup(key); ret->val = strdup(val); @@ -104,10 +106,10 @@ static inline eurephiaVALUES *parse_config_line(const char *line) { } -static inline eurephiaVALUES *default_cfg_values() { +static inline eurephiaVALUES *default_cfg_values(LogContext *log) { eurephiaVALUES *cfg = NULL; - cfg = eCreate_value_space(20); + cfg = eCreate_value_space(log, 20); eAdd_value(cfg, "datadir", "/var/lib/rteval"); eAdd_value(cfg, "xsltpath", "/usr/share/rteval"); eAdd_value(cfg, "db_server", "localhost"); @@ -129,7 +131,7 @@ static inline eurephiaVALUES *default_cfg_values() { * @return Returns a pointer to an eurephiaVALUES stack containing the configuration on success, * otherwise NULL. */ -eurephiaVALUES *read_config(const char *cfgname, const char *section) { +eurephiaVALUES *read_config(LogContext *log, const char *cfgname, const char *section) { FILE *fp = NULL; char *buf = NULL, *sectmatch = NULL; int sectfound = 0; @@ -137,20 +139,20 @@ eurephiaVALUES *read_config(const char *cfgname, const char *section) { struct stat fi; if( stat(cfgname, &fi) == -1 ) { - fprintf(stderr, "Could not open the config file: %s\n", cfgname); + writelog(log, LOG_EMERG, "Could not open the config file: %s\n", cfgname); return NULL; } if( (fp = fopen(cfgname, "r")) == NULL ) { - fprintf(stderr, "Could not open the config file: %s\n", cfgname); + writelog(log, LOG_EMERG, "Could not open the config file: %s\n", cfgname); return NULL; } - buf = (char *) malloc_nullsafe(fi.st_size+2); - sectmatch = (char *) malloc_nullsafe(strlen_nullsafe(section)+4); + buf = (char *) malloc_nullsafe(log, fi.st_size+2); + sectmatch = (char *) malloc_nullsafe(log, strlen_nullsafe(section)+4); sprintf(sectmatch, "[%s]", section); - cfg = default_cfg_values(); + cfg = default_cfg_values(log); while( fgets(buf, fi.st_size, fp) != NULL ) { if( strncmp(buf, "[", 1) == 0 ) { sectfound = (!sectfound && (strncmp(buf, sectmatch, strlen(sectmatch)) == 0)); @@ -158,7 +160,7 @@ eurephiaVALUES *read_config(const char *cfgname, const char *section) { } if( sectfound ) { - eurephiaVALUES *prm = parse_config_line(buf); + eurephiaVALUES *prm = parse_config_line(log, buf); if( prm != NULL ) { cfg = eUpdate_valuestruct(cfg, prm, 1); } diff --git a/server/parser/configparser.h b/server/parser/configparser.h index 268b658..a047d83 100644 --- a/server/parser/configparser.h +++ b/server/parser/configparser.h @@ -33,6 +33,6 @@ #ifndef _CONFIGPARSER_H #define _CONFIGPARSER_H -eurephiaVALUES *read_config(const char *cfgname, const char *section); +eurephiaVALUES *read_config(LogContext *log, const char *cfgname, const char *section); #endif diff --git a/server/parser/eurephia_nullsafe.c b/server/parser/eurephia_nullsafe.c index 7dd8465..24ded87 100644 --- a/server/parser/eurephia_nullsafe.c +++ b/server/parser/eurephia_nullsafe.c @@ -37,6 +37,8 @@ #include <stdio.h> #include <stdlib.h> +#include <log.h> + #if __GNUC__ >= 3 #define __malloc__ __attribute__((malloc)) #else /* If not GCC 3 or newer, disable optimisations */ @@ -52,13 +54,13 @@ * * @return Returns a void pointer to the memory region on success, otherwise NULL */ -__malloc__ void *malloc_nullsafe(size_t sz) { +__malloc__ void *malloc_nullsafe(LogContext *log, size_t sz) { void *buf = NULL; buf = calloc(1, sz); /* Using calloc, also gives a zero'd memory region */ if( !buf ) { - fprintf(stderr, "** FATAL ERROR ** " - "Could not allocate memory region for %ld bytes\n", sz); + writelog(log, LOG_EMERG, "** FATAL ERROR ** " + "Could not allocate memory region for %ld bytes\n", sz); exit(9); } return buf; diff --git a/server/parser/eurephia_nullsafe.h b/server/parser/eurephia_nullsafe.h index b812b8c..e0b2f32 100644 --- a/server/parser/eurephia_nullsafe.h +++ b/server/parser/eurephia_nullsafe.h @@ -37,6 +37,8 @@ #ifndef EUREPHIA_NULLSAFE_H_ #define EUREPHIA_NULLSAFE_H_ +#include <log.h> + /** * atoi() wrapper. Converts any string into a integer * @@ -79,7 +81,7 @@ #define strlen_nullsafe(str) (str != NULL ? strlen(str) : 0) -void *malloc_nullsafe(size_t); +void *malloc_nullsafe(LogContext *, size_t); /** * Null safe free(). It will not attempt to free a pointer which is NULL. diff --git a/server/parser/eurephia_values.c b/server/parser/eurephia_values.c index 79d6ecf..66375b2 100644 --- a/server/parser/eurephia_values.c +++ b/server/parser/eurephia_values.c @@ -117,14 +117,12 @@ char *eGet_value(eurephiaVALUES *vls, const char *key) * * @return Returns an empty eurephiaVALUES struct on success, otherwise NULL. */ -eurephiaVALUES *eCreate_value_space(int evgid) +eurephiaVALUES *eCreate_value_space(LogContext *log, int evgid) { eurephiaVALUES *ptr = NULL; - ptr = (eurephiaVALUES *) malloc_nullsafe(sizeof(eurephiaVALUES) + 2); - if( ptr == NULL ) { - return NULL; - } + ptr = (eurephiaVALUES *) malloc_nullsafe(log, sizeof(eurephiaVALUES) + 2); + ptr->log = log; ptr->evgid = evgid; return ptr; } @@ -178,9 +176,9 @@ void eAdd_value(eurephiaVALUES *vls, const char *key, const char *val) assert(vls != NULL); // Allocate buffer and save values - ptr = eCreate_value_space(vls->evid); + ptr = eCreate_value_space(vls->log, vls->evid); if( ptr == NULL ) { - fprintf(stderr, "**ERROR** Failed to add value to the value chain\n"); + writelog(vls->log, LOG_EMERG, "**ERROR** Failed to add value to the value chain\n"); exit(9); } ptr->key = strdup_nullsafe(key); diff --git a/server/parser/eurephia_values.h b/server/parser/eurephia_values.h index 97ca64f..c63eb4c 100644 --- a/server/parser/eurephia_values.h +++ b/server/parser/eurephia_values.h @@ -39,7 +39,7 @@ eurephiaVALUES *eGet_valuestruct(eurephiaVALUES *vls, const char *key); char *eGet_value(eurephiaVALUES *vls, const char *key); -eurephiaVALUES *eCreate_value_space(int evid); +eurephiaVALUES *eCreate_value_space(LogContext *log, int evid); void eAdd_valuestruct(eurephiaVALUES *vls, eurephiaVALUES *newval); void eAdd_value(eurephiaVALUES *vls, const char *key, const char *val); diff --git a/server/parser/eurephia_values_struct.h b/server/parser/eurephia_values_struct.h index 6fb82fc..7eb8b74 100644 --- a/server/parser/eurephia_values_struct.h +++ b/server/parser/eurephia_values_struct.h @@ -31,6 +31,8 @@ #ifndef EUREPHIA_VALUES_STRUCT_H_ # define EUREPHIA_VALUES_STRUCT_H_ +#include <log.h> + /** * eurephiaVALUES is a pointer chain with key/value pairs. If having several * such pointer chains, they can be given different group IDs to separate them, @@ -38,6 +40,7 @@ * */ typedef struct __eurephiaVALUES { + LogContext *log; /**< Pointer to an established log context, used for logging */ unsigned int evgid; /**< Group ID, all elements in the same chain should have the same value */ unsigned int evid; /**< Unique ID per element in a pointer chain */ char *key; /**< The key name of a value */ diff --git a/server/parser/eurephia_xml.c b/server/parser/eurephia_xml.c index b29f439..bda8f33 100644 --- a/server/parser/eurephia_xml.c +++ b/server/parser/eurephia_xml.c @@ -131,13 +131,13 @@ inline char *xmlGetNodeContent(xmlNode *node, const char *key) { * @return Returns a pointer to a new buffer containing the serialised data. This buffer must be freed * after usage */ -char *xmlNodeToString(xmlNode *node) { +char *xmlNodeToString(LogContext *log, xmlNode *node) { xmlBuffer *buf = NULL; xmlSaveCtxt *serctx = NULL; char *ret = NULL; if( node == NULL ) { - fprintf(stderr, "** ERROR ** Input data is NULL\n"); + writelog(log, LOG_ALERT, "** ERROR ** Input data is NULL\n"); return NULL; } @@ -148,7 +148,7 @@ char *xmlNodeToString(xmlNode *node) { assert( serctx != NULL ); if( xmlSaveTree(serctx, node) < 0 ) { - fprintf(stderr, "** ERROR ** Failed to serialise xmlNode\n"); + writelog(log, LOG_ALERT, "** ERROR ** Failed to serialise xmlNode\n"); return NULL; } xmlSaveClose(serctx); diff --git a/server/parser/eurephia_xml.h b/server/parser/eurephia_xml.h index 6dbfe98..dea72eb 100644 --- a/server/parser/eurephia_xml.h +++ b/server/parser/eurephia_xml.h @@ -51,6 +51,6 @@ xmlNode *xmlFindNode(xmlNode *node, const char *key); inline char *xmlExtractContent(xmlNode *n); inline char *xmlGetNodeContent(xmlNode *node, const char *key); -char *xmlNodeToString(xmlNode *node); +char *xmlNodeToString(LogContext *log, xmlNode *node); #endif /* !EUREPHIA_XML_H_ */ diff --git a/server/parser/parsethread.c b/server/parser/parsethread.c index 9d604c8..02d20aa 100644 --- a/server/parser/parsethread.c +++ b/server/parser/parsethread.c @@ -34,6 +34,7 @@ #include <eurephia_nullsafe.h> #include <parsethread.h> #include <pgsql.h> +#include <log.h> #include <threadinfo.h> #include <statuses.h> @@ -46,7 +47,7 @@ * * @return Returns 1 on success, otherwise -1 */ -static int make_report_dir(const char *fname) { +static int make_report_dir(LogContext *log, const char *fname) { char *fname_cp = NULL, *dname = NULL, *chkdir = NULL; char *tok = NULL, *saveptr = NULL; int ret = 0; @@ -59,8 +60,7 @@ static int make_report_dir(const char *fname) { fname_cp = strdup(fname); assert( fname_cp != NULL ); dname = dirname(fname_cp); - chkdir = malloc_nullsafe(strlen(dname)+8); - assert( chkdir != NULL ); + chkdir = malloc_nullsafe(log, strlen(dname)+8); if( dname[0] == '/' ) { chkdir[0] = '/'; @@ -79,17 +79,17 @@ static int make_report_dir(const char *fname) { case ENOENT: // If the directory do not exist, create it if( mkdir(chkdir, 0755) < 0 ) { // If creating dir failed, report error - fprintf(stderr, - "** ERROR ** Could not create directory: %s\n" - "** ERROR ** %s\n", chkdir, strerror(errno)); + writelog(log, LOG_ALERT, + "** ERROR ** Could not create directory: %s\n" + "** ERROR ** %s\n", chkdir, strerror(errno)); ret = -1; goto exit; } break; default: // If other failure, report that and exit - fprintf(stderr, - "** ERROR ** Could not access directory: %s\n" - "** ERROR ** %s\n", chkdir, strerror(errno)); + writelog(log, LOG_ALERT, + "** ERROR ** Could not access directory: %s\n" + "** ERROR ** %s\n", chkdir, strerror(errno)); ret = -1; goto exit; } @@ -115,7 +115,9 @@ static int make_report_dir(const char *fname) { * * @return Returns a pointer to a string with the new full path filename on success, otherwise NULL. */ -static char *get_destination_path(const char *destdir, parseJob_t *job, const int rterid) { +static char *get_destination_path(LogContext *log, const char *destdir, + parseJob_t *job, const int rterid) +{ char *newfname = NULL; int retlen = 0; @@ -124,8 +126,7 @@ static char *get_destination_path(const char *destdir, parseJob_t *job, const in } retlen = strlen_nullsafe(job->clientid) + strlen(destdir) + 24; - newfname = malloc_nullsafe(retlen+2); - assert( newfname != NULL ); + newfname = malloc_nullsafe(log, retlen+2); snprintf(newfname, retlen, "%s/%s/report-%i.xml", destdir, job->clientid, rterid); @@ -165,21 +166,24 @@ inline int parse_report(dbconn *dbc, xsltStylesheet *xslt, pthread_mutex_t *mtx_ repxml = xmlParseFile(job->filename); if( !repxml ) { - fprintf(stderr, "** ERROR ** Could not parse XML file: %s\n", job->filename); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Could not parse XML file: %s\n", job->filename); return STAT_XMLFAIL; } pthread_mutex_lock(mtx_sysreg); syskey = db_register_system(dbc, xslt, repxml); if( syskey < 0 ) { - fprintf(stderr, "** ERROR ** Failed to register system (XML file: %s)\n", job->filename); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Failed to register system (XML file: %s)\n", job->filename); rc = STAT_SYSREG; goto exit; } rterid = db_get_new_rterid(dbc); if( rterid < 0 ) { - fprintf(stderr, "** ERROR ** Failed to register rteval run (XML file: %s)\n", + writelog(dbc->log, LOG_ERR, + "** ERROR ** Failed to register rteval run (XML file: %s)\n", job->filename); rc = STAT_RTERIDREG; goto exit; @@ -192,9 +196,10 @@ inline int parse_report(dbconn *dbc, xsltStylesheet *xslt, pthread_mutex_t *mtx_ } // Create a new filename of where to save the report - destfname = get_destination_path(destdir, job, rterid); + destfname = get_destination_path(dbc->log, destdir, job, rterid); if( !destfname ) { - fprintf(stderr, "** ERROR ** Failed to generate local report filename for (%i) %s\n", + writelog(dbc->log, LOG_ERR, + "** ERROR ** Failed to generate local report filename for (%i) %s\n", job->submid, job->filename); db_rollback(dbc); rc = STAT_UNKNFAIL; @@ -202,32 +207,35 @@ inline int parse_report(dbconn *dbc, xsltStylesheet *xslt, pthread_mutex_t *mtx_ } if( db_register_rtevalrun(dbc, xslt, repxml, job->submid, syskey, rterid, destfname) < 0 ) { - fprintf(stderr, "** ERROR ** Failed to register rteval run (XML file: %s)\n", - job->filename); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Failed to register rteval run (XML file: %s)\n", + job->filename); db_rollback(dbc); rc = STAT_RTEVRUNS; goto exit; } if( db_register_cyclictest(dbc, xslt, repxml, rterid) != 1 ) { - fprintf(stderr, "** ERROR ** Failed to register cyclictest data (XML file: %s)\n", - job->filename); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Failed to register cyclictest data (XML file: %s)\n", + job->filename); db_rollback(dbc); rc = STAT_CYCLIC; goto exit; } // When all database registrations are done, move the file to it's right place - if( make_report_dir(destfname) < 1 ) { // Make sure report directory exists + if( make_report_dir(dbc->log, destfname) < 1 ) { // Make sure report directory exists db_rollback(dbc); rc = STAT_REPMOVE; goto exit; } if( rename(job->filename, destfname) < 0 ) { // Move the file - fprintf(stderr, "** ERROR ** Failed to move report file from %s to %s\n" - "** ERROR ** %s\n", - job->filename, destfname, strerror(errno)); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Failed to move report file from %s to %s\n" + "** ERROR ** %s\n", + job->filename, destfname, strerror(errno)); db_rollback(dbc); rc = STAT_REPMOVE; goto exit; @@ -256,7 +264,7 @@ void *parsethread(void *thrargs) { threadData_t *args = (threadData_t *) thrargs; parseJob_t jobinfo; - fprintf(stderr, "** Starting thread %i\n", args->id); + writelog(args->dbc->log, LOG_DEBUG, "** Starting thread %i\n", args->id); while( !*(args->shutdown) ) { int len = 0; unsigned int prio = 0; @@ -266,8 +274,9 @@ void *parsethread(void *thrargs) { errno = 0; len = mq_receive(args->msgq, (char *)&jobinfo, sizeof(parseJob_t), &prio); if( (len < 0) && errno != EAGAIN ) { - fprintf(stderr, "** ERROR ** Could not receive the message from queue: %s\n", - strerror(errno)); + writelog(args->dbc->log, LOG_CRIT, + "** ERROR ** Could not receive the message from queue: %s\n", + strerror(errno)); pthread_exit((void *) 1); } @@ -275,8 +284,9 @@ void *parsethread(void *thrargs) { if( (errno != EAGAIN) && (len > 0) ) { int res = 0; - fprintf(stderr, "** Thread %i: Job recieved, submid: %i\n", - args->id, jobinfo.submid); + writelog(args->dbc->log, LOG_DEBUG, + "** Thread %i: Job recieved, submid: %i\n", + args->id, jobinfo.submid); // Mark the job as "in progress", if successful update, continue parsing it if( db_update_submissionqueue(args->dbc, jobinfo.submid, STAT_INPROG) ) { @@ -285,14 +295,15 @@ void *parsethread(void *thrargs) { // Set the status for the submission db_update_submissionqueue(args->dbc, jobinfo.submid, res); } else { - fprintf(stderr, "** ERROR ** Failed to mark submid %i as STAT_INPROG\n", - jobinfo.submid); + writelog(args->dbc->log, LOG_CRIT, + "** ERROR ** Failed to mark submid %i as STAT_INPROG\n", + jobinfo.submid); } } else { // If no message was retrieved, sleep for a little while sleep(5); } } - fprintf(stderr, "** Thread %i shut down\n", args->id); + writelog(args->dbc->log, LOG_DEBUG, "** Thread %i shut down\n", args->id); pthread_exit((void *) 0); } diff --git a/server/parser/pgsql.c b/server/parser/pgsql.c index 4ed1ae0..fbf6052 100644 --- a/server/parser/pgsql.c +++ b/server/parser/pgsql.c @@ -41,6 +41,7 @@ #include <configparser.h> #include <xmlparser.h> #include <pgsql.h> +#include <log.h> #include <statuses.h> /** @@ -48,12 +49,15 @@ * * @param cfg eurephiaVALUES containing the configuration * - * @return Returns a database handler + * @return Returns a database connection context */ -void *db_connect(eurephiaVALUES *cfg) { - PGconn *dbc = NULL; +dbconn *db_connect(eurephiaVALUES *cfg, LogContext *log) { + dbconn *ret = NULL; - dbc = PQsetdbLogin(eGet_value(cfg, "db_server"), + ret = (dbconn *) malloc_nullsafe(log, sizeof(dbconn)+2); + ret->log = log; + + ret->db = PQsetdbLogin(eGet_value(cfg, "db_server"), eGet_value(cfg, "db_port"), NULL, /* pgopt */ NULL, /* pgtty */ @@ -61,17 +65,20 @@ void *db_connect(eurephiaVALUES *cfg) { eGet_value(cfg, "db_username"), eGet_value(cfg, "db_password")); - if( !dbc ) { - fprintf(stderr, "** ERROR ** Could not connect to the database (unknown reason)\n"); - exit(2); + if( !ret->db ) { + writelog(log, LOG_EMERG, + "** ERROR ** Could not connect to the database (unknown reason)\n"); + free_nullsafe(ret); + return NULL; } - if( PQstatus(dbc) != CONNECTION_OK ) { - fprintf(stderr, "** ERROR ** Failed to connect to the database\n%s\n", - PQerrorMessage(dbc)); - exit(2); + if( PQstatus(ret->db) != CONNECTION_OK ) { + writelog(log, LOG_EMERG, "** ERROR ** Failed to connect to the database\n%s\n", + PQerrorMessage(ret->db)); + free_nullsafe(ret); + return NULL; } - return dbc; + return ret; } @@ -81,7 +88,10 @@ void *db_connect(eurephiaVALUES *cfg) { * @param dbc Pointer to the database handle to be disconnected. */ void db_disconnect(dbconn *dbc) { - PQfinish((PGconn *) dbc); + if( dbc && dbc->db ) { + PQfinish(dbc->db); + dbc->db = NULL; + } } @@ -144,7 +154,7 @@ void db_disconnect(dbconn *dbc) { * the defined field name will be returned. If one of the INSERT queries fails, it will abort * further processing and the function will return NULL. */ -eurephiaVALUES *pgsql_INSERT(PGconn *dbc, xmlDoc *sqldoc) { +eurephiaVALUES *pgsql_INSERT(dbconn *dbc, xmlDoc *sqldoc) { xmlNode *root_n = NULL, *fields_n = NULL, *recs_n = NULL, *ptr_n = NULL, *val_n = NULL; char **field_ar = NULL, *fields = NULL, **value_ar = NULL, *values = NULL, *table = NULL, tmp[20], *sql = NULL, *key = NULL; @@ -152,17 +162,19 @@ eurephiaVALUES *pgsql_INSERT(PGconn *dbc, xmlDoc *sqldoc) { PGresult *dbres = NULL; eurephiaVALUES *res = NULL; - assert( sqldoc != NULL ); + assert( (dbc != NULL) && (sqldoc != NULL) ); root_n = xmlDocGetRootElement(sqldoc); if( !root_n || (xmlStrcmp(root_n->name, (xmlChar *) "sqldata") != 0) ) { - fprintf(stderr, "** ERROR ** Input XML document is not a valid sqldata document\n"); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Input XML document is not a valid sqldata document\n"); return NULL; } table = xmlGetAttrValue(root_n->properties, "table"); if( !table ) { - fprintf(stderr, "** ERROR ** Input XML document is missing table reference\n"); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Input XML document is missing table reference\n"); return NULL; } @@ -171,8 +183,8 @@ eurephiaVALUES *pgsql_INSERT(PGconn *dbc, xmlDoc *sqldoc) { fields_n = xmlFindNode(root_n, "fields"); recs_n = xmlFindNode(root_n, "records"); if( !fields_n || !recs_n ) { - fprintf(stderr, - "** ERROR ** Input XML document is missing either <fields/> or <records/>\n"); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Input XML document is missing either <fields/> or <records/>\n"); return NULL; } @@ -198,8 +210,8 @@ eurephiaVALUES *pgsql_INSERT(PGconn *dbc, xmlDoc *sqldoc) { // Generate strings with field names and value place holders // for a prepared SQL statement - fields = malloc_nullsafe(3); - values = malloc_nullsafe(6*(fieldcnt+1)); + fields = malloc_nullsafe(dbc->log, 3); + values = malloc_nullsafe(dbc->log, 6*(fieldcnt+1)); strcpy(fields, "("); strcpy(values, "("); int len = 3; @@ -222,12 +234,13 @@ eurephiaVALUES *pgsql_INSERT(PGconn *dbc, xmlDoc *sqldoc) { strcat(values, ")"); // Build up the SQL query - sql = malloc_nullsafe( strlen_nullsafe(fields) - + strlen_nullsafe(values) - + strlen_nullsafe(table) - + strlen_nullsafe(key) - + 34 /* INSERT INTO VALUES RETURNING*/ - ); + sql = malloc_nullsafe(dbc->log, + strlen_nullsafe(fields) + + strlen_nullsafe(values) + + strlen_nullsafe(table) + + strlen_nullsafe(key) + + 34 /* INSERT INTO VALUES RETURNING*/ + ); sprintf(sql, "INSERT INTO %s %s VALUES %s", table, fields, values); if( key ) { strcat(sql, " RETURNING "); @@ -235,17 +248,18 @@ eurephiaVALUES *pgsql_INSERT(PGconn *dbc, xmlDoc *sqldoc) { } // Create a prepared SQL query - dbres = PQprepare(dbc, "", sql, fieldcnt, NULL); + dbres = PQprepare(dbc->db, "", sql, fieldcnt, NULL); if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) { - fprintf(stderr, "** ERROR ** Failed to prepare SQL query\n%s\n", - PQresultErrorMessage(dbres)); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** Failed to prepare SQL query\n%s\n", + PQresultErrorMessage(dbres)); PQclear(dbres); goto exit; } PQclear(dbres); // Loop through all records and generate SQL statements - res = eCreate_value_space(1); + res = eCreate_value_space(dbc->log, 1); foreach_xmlnode(recs_n->children, ptr_n) { if( ptr_n->type != XML_ELEMENT_NODE ) { continue; @@ -271,15 +285,15 @@ eurephiaVALUES *pgsql_INSERT(PGconn *dbc, xmlDoc *sqldoc) { if( (fid_s == NULL) || (fid < 0) ) { continue; } - value_ar[field_idx[i]] = sqldataExtractContent(val_n); + value_ar[field_idx[i]] = sqldataExtractContent(dbc->log, val_n); i++; } // Insert the record into the database - // fprintf(stderr, "."); - dbres = PQexecPrepared(dbc, "", fieldcnt, (const char * const *)value_ar, NULL, NULL, 0); + dbres = PQexecPrepared(dbc->db, "", fieldcnt, + (const char * const *)value_ar, NULL, NULL, 0); if( PQresultStatus(dbres) != (key ? PGRES_TUPLES_OK : PGRES_COMMAND_OK) ) { - fprintf(stderr, "** ERROR ** Failed to do SQL INSERT query\n%s\n", + writelog(dbc->log, LOG_ALERT, "** ERROR ** Failed to do SQL INSERT query\n%s\n", PQresultErrorMessage(dbres)); PQclear(dbres); eFree_values(res); @@ -329,10 +343,11 @@ eurephiaVALUES *pgsql_INSERT(PGconn *dbc, xmlDoc *sqldoc) { int db_begin(dbconn *dbc) { PGresult *dbres = NULL; - dbres = PQexec((PGconn *) dbc, "BEGIN"); + dbres = PQexec(dbc->db, "BEGIN"); if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) { - fprintf(stderr, "** ERROR ** Failed to do prepare a transaction (BEGIN)\n%s\n", - PQresultErrorMessage(dbres)); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** Failed to do prepare a transaction (BEGIN)\n%s\n", + PQresultErrorMessage(dbres)); PQclear(dbres); return -1; } @@ -351,10 +366,11 @@ int db_begin(dbconn *dbc) { int db_commit(dbconn *dbc) { PGresult *dbres = NULL; - dbres = PQexec((PGconn *) dbc, "COMMIT"); + dbres = PQexec(dbc->db, "COMMIT"); if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) { - fprintf(stderr, "** ERROR ** Failed to do commit a database transaction (COMMIT)\n%s\n", - PQresultErrorMessage(dbres)); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** Failed to do commit a database transaction (COMMIT)\n%s\n", + PQresultErrorMessage(dbres)); PQclear(dbres); return -1; } @@ -373,10 +389,11 @@ int db_commit(dbconn *dbc) { int db_rollback(dbconn *dbc) { PGresult *dbres = NULL; - dbres = PQexec((PGconn *) dbc, "ROLLBACK"); + dbres = PQexec(dbc->db, "ROLLBACK"); if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) { - fprintf(stderr, "** ERROR ** Failed to do abort/rollback a transaction (ROLLBACK)\n%s\n", - PQresultErrorMessage(dbres)); + writelog(dbc->log, LOG_CRIT, + "** ERROR ** Failed to do abort/rollback a transaction (ROLLBACK)\n%s\n", + PQresultErrorMessage(dbres)); PQclear(dbres); return -1; } @@ -401,14 +418,15 @@ int db_wait_notification(dbconn *dbc, const int *shutdown, const char *listenfor fd_set input_mask; char *sql = NULL; - sql = malloc_nullsafe(strlen_nullsafe(listenfor) + 12); + sql = malloc_nullsafe(dbc->log, strlen_nullsafe(listenfor) + 12); assert( sql != NULL ); // Initiate listening sprintf(sql, "LISTEN %s\n", listenfor); - dbres = PQexec((PGconn *) dbc, sql); + dbres = PQexec(dbc->db, sql); if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) { - fprintf(stderr, "** ERROR ** SQL %s\n", PQresultErrorMessage(dbres)); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** SQL %s\n", PQresultErrorMessage(dbres)); free_nullsafe(sql); PQclear(dbres); return -1; @@ -417,7 +435,7 @@ int db_wait_notification(dbconn *dbc, const int *shutdown, const char *listenfor // Start listening and waiting while( ret == 0 ) { - sock = PQsocket((PGconn *) dbc); + sock = PQsocket(dbc->db); if (sock < 0) { // shouldn't happen ret = -1; @@ -432,7 +450,8 @@ int db_wait_notification(dbconn *dbc, const int *shutdown, const char *listenfor // report errors if we're not shutting down, or else exit normally with // successful waiting. if( *shutdown == 0 ) { - fprintf(stderr, "** ERROR ** select() failed: %s\n", strerror(errno)); + writelog(dbc->log, LOG_CRIT, + "** ERROR ** select() failed: %s\n", strerror(errno)); ret = -1; } else { ret = 1; @@ -441,11 +460,12 @@ int db_wait_notification(dbconn *dbc, const int *shutdown, const char *listenfor } // Process the event - PQconsumeInput((PGconn *) dbc); - while ((notify = PQnotifies((PGconn *) dbc)) != NULL) { + PQconsumeInput(dbc->db); + while ((notify = PQnotifies(dbc->db)) != NULL) { // If a notification was received, inform and exit with success. - fprintf(stderr, "** INFO ** Received notfication from pid %d\n", - notify->be_pid); + writelog(dbc->log, LOG_DEBUG, + "** INFO ** Received notfication from pid %d\n", + notify->be_pid); PQfreemem(notify); ret = 1; break; @@ -454,9 +474,9 @@ int db_wait_notification(dbconn *dbc, const int *shutdown, const char *listenfor // Stop listening when we exit sprintf(sql, "UNLISTEN %s\n", listenfor); - dbres = PQexec((PGconn *) dbc, sql); + dbres = PQexec(dbc->db, sql); if( PQresultStatus(dbres) != PGRES_COMMAND_OK ) { - fprintf(stderr, "** ERROR ** SQL %s\n", PQresultErrorMessage(dbres)); + writelog(dbc->log, LOG_ALERT, "** ERROR ** SQL %s\n", PQresultErrorMessage(dbres)); free_nullsafe(sql); ret = -1; } @@ -481,11 +501,7 @@ parseJob_t *db_get_submissionqueue_job(dbconn *dbc, pthread_mutex_t *mtx) { PGresult *res = NULL; char sql[4098]; - job = (parseJob_t *) malloc_nullsafe(sizeof(parseJob_t)); - if( !job ) { - fprintf(stderr, "** ERROR ** Failed to allocate memory for a new parsing job\n"); - return NULL; - } + job = (parseJob_t *) malloc_nullsafe(dbc->log, sizeof(parseJob_t)); // Get the first available submission memset(&sql, 0, 4098); @@ -496,12 +512,14 @@ parseJob_t *db_get_submissionqueue_job(dbconn *dbc, pthread_mutex_t *mtx) { " ORDER BY submid" " LIMIT 1", STAT_NEW); + pthread_mutex_lock(mtx); - res = PQexec((PGconn *) dbc, sql); + res = PQexec(dbc->db, sql); if( PQresultStatus(res) != PGRES_TUPLES_OK ) { pthread_mutex_unlock(mtx); - fprintf(stderr, "** ERROR ** Failed to query submission queue (SELECT)\n%s\n", - PQresultErrorMessage(res)); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** Failed to query submission queue (SELECT)\n%s\n", + PQresultErrorMessage(res)); PQclear(res); free_nullsafe(job); return NULL; @@ -516,8 +534,8 @@ parseJob_t *db_get_submissionqueue_job(dbconn *dbc, pthread_mutex_t *mtx) { // Update the submission queue status if( db_update_submissionqueue(dbc, job->submid, STAT_ASSIGNED) < 1 ) { pthread_mutex_unlock(mtx); - fprintf(stderr, - "** ERROR ** Failed to update submission queue statis to STAT_ASSIGNED\n"); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** Failed to update submission queue statis to STAT_ASSIGNED\n"); free_nullsafe(job); return NULL; } @@ -573,20 +591,22 @@ int db_update_submissionqueue(dbconn *dbc, unsigned int submid, int status) { default: case STAT_NEW: - fprintf(stderr, "** ERROR ** Invalid status (%i) attempted to set on submid %i\n", - status, submid); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Invalid status (%i) attempted to set on submid %i\n", + status, submid); return 0; } - res = PQexec(dbc, sql); + res = PQexec(dbc->db, sql); if( !res ) { - fprintf(stderr, "** ERROR ** Unkown error when updating submid %i to status %i\n", - submid, status); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** Unkown error when updating submid %i to status %i\n", + submid, status); return -1; } else if( PQresultStatus(res) != PGRES_COMMAND_OK ) { - fprintf(stderr, - "** ERROR ** Failed to UPDATE submissionqueue (submid: %i, status: %i)\n%s\n", - submid, status, PQresultErrorMessage(res)); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** Failed to UPDATE submissionqueue (submid: %i, status: %i)\n%s\n", + submid, status, PQresultErrorMessage(res)); PQclear(res); return -1; } @@ -619,15 +639,16 @@ int db_register_system(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml) { memset(&prms, 0, sizeof(parseParams)); prms.table = "systems"; - sysinfo_d = parseToSQLdata(xslt, summaryxml, &prms); + sysinfo_d = parseToSQLdata(dbc->log, xslt, summaryxml, &prms); if( !sysinfo_d ) { - fprintf(stderr, "** ERROR ** Could not parse the input XML data\n"); + writelog(dbc->log, LOG_ERR, "** ERROR ** Could not parse the input XML data\n"); syskey= -1; goto exit; } - sysid = sqldataGetValue(sysinfo_d, "sysid", 0); + sysid = sqldataGetValue(dbc->log, sysinfo_d, "sysid", 0); if( !sysid ) { - fprintf(stderr, "** ERROR ** Could not retrieve the sysid field from the input XML\n"); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Could not retrieve the sysid field from the input XML\n"); syskey= -1; goto exit; } @@ -635,10 +656,11 @@ int db_register_system(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml) { memset(&sqlq, 0, 4098); snprintf(sqlq, 4096, "SELECT syskey FROM systems WHERE sysid = '%.256s'", sysid); free_nullsafe(sysid); - dbres = PQexec((PGconn *) dbc, sqlq); + dbres = PQexec(dbc->db, sqlq); if( PQresultStatus(dbres) != PGRES_TUPLES_OK ) { - fprintf(stderr, "** ERROR ** SQL query failed: %s\n** ERROR ** %s\n", - sqlq, PQresultErrorMessage(dbres)); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** SQL query failed: %s\n** ERROR ** %s\n", + sqlq, PQresultErrorMessage(dbres)); PQclear(dbres); syskey= -1; goto exit; @@ -647,32 +669,32 @@ int db_register_system(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml) { if( PQntuples(dbres) == 0 ) { // No record found, need to register this system PQclear(dbres); - dbdata = pgsql_INSERT((PGconn *) dbc, sysinfo_d); + dbdata = pgsql_INSERT(dbc, sysinfo_d); if( !dbdata ) { syskey= -1; goto exit; } if( (eCount(dbdata) != 1) || !dbdata->val ) { // Only one record should be registered - fprintf(stderr, "** ERRORR ** Failed to register the system\n"); + writelog(dbc->log, LOG_ALERT, "** ERROR ** Failed to register the system\n"); eFree_values(dbdata); syskey= -1; goto exit; } syskey = atoi_nullsafe(dbdata->val); - hostinfo_d = sqldataGetHostInfo(xslt, summaryxml, syskey, &hostname, &ipaddr); + hostinfo_d = sqldataGetHostInfo(dbc->log, xslt, summaryxml, syskey, &hostname, &ipaddr); if( !hostinfo_d ) { syskey = -1; goto exit; } eFree_values(dbdata); - dbdata = pgsql_INSERT((PGconn *) dbc, hostinfo_d); + dbdata = pgsql_INSERT(dbc, hostinfo_d); syskey = (dbdata ? syskey : -1); eFree_values(dbdata); } else if( PQntuples(dbres) == 1 ) { // System found - check if the host IP is known or not syskey = atoi_nullsafe(PQgetvalue(dbres, 0, 0)); - hostinfo_d = sqldataGetHostInfo(xslt, summaryxml, syskey, &hostname, &ipaddr); + hostinfo_d = sqldataGetHostInfo(dbc->log, xslt, summaryxml, syskey, &hostname, &ipaddr); if( !hostinfo_d ) { syskey = -1; goto exit; @@ -684,25 +706,26 @@ int db_register_system(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml) { "SELECT syskey FROM systems_hostname" " WHERE hostname='%.256s' AND ipaddr='%.64s'", hostname, ipaddr); - - dbres = PQexec((PGconn *) dbc, sqlq); + dbres = PQexec(dbc->db, sqlq); if( PQresultStatus(dbres) != PGRES_TUPLES_OK ) { - fprintf(stderr, "** ERROR ** SQL query failed: %s\n** ERROR ** %s\n", - sqlq, PQresultErrorMessage(dbres)); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** SQL query failed: %s\n** ERROR ** %s\n", + sqlq, PQresultErrorMessage(dbres)); PQclear(dbres); syskey= -1; goto exit; } if( PQntuples(dbres) == 0 ) { // Not registered, then register it - dbdata = pgsql_INSERT((PGconn *) dbc, hostinfo_d); + dbdata = pgsql_INSERT(dbc, hostinfo_d); syskey = (dbdata ? syskey : -1); eFree_values(dbdata); } PQclear(dbres); } else { // Critical -- system IDs should not be registered more than once - fprintf(stderr, "** CRITICAL ERROR ** Multiple systems registered (%s)", sqlq); + writelog(dbc->log, LOG_CRIT, + "** CRITICAL ERROR ** Multiple systems registered (%s)", sqlq); syskey= -1; } @@ -730,7 +753,7 @@ int db_get_new_rterid(dbconn *dbc) { PGresult *dbres = NULL; int rterid = 0; - dbres = PQexec((PGconn *)dbc, "SELECT nextval('rtevalruns_rterid_seq')"); + dbres = PQexec(dbc->db, "SELECT nextval('rtevalruns_rterid_seq')"); if( (PQresultStatus(dbres) != PGRES_TUPLES_OK) || (PQntuples(dbres) != 1) ) { rterid = -1; } else { @@ -738,10 +761,11 @@ int db_get_new_rterid(dbconn *dbc) { } if( rterid < 1 ) { - fprintf(stderr, "** ERROR ** Failed to retrieve a new rterid value\n"); + writelog(dbc->log, LOG_CRIT, + "** ERROR ** Failed to retrieve a new rterid value\n"); } if( rterid < 0 ) { - fprintf(stderr, "SQL %s\n", PQresultErrorMessage(dbres)); + writelog(dbc->log, LOG_ALERT, "SQL %s\n", PQresultErrorMessage(dbres)); } PQclear(dbres); return rterid; @@ -776,22 +800,22 @@ int db_register_rtevalrun(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml, prms.rterid = rterid; prms.submid = submid; prms.report_filename = report_fname; - rtevalrun_d = parseToSQLdata(xslt, summaryxml, &prms); + rtevalrun_d = parseToSQLdata(dbc->log, xslt, summaryxml, &prms); if( !rtevalrun_d ) { - fprintf(stderr, "** ERROR ** Could not parse the input XML data\n"); + writelog(dbc->log, LOG_ERR, "** ERROR ** Could not parse the input XML data\n"); ret = -1; goto exit; } // Register the rteval run information - dbdata = pgsql_INSERT((PGconn *) dbc, rtevalrun_d); + dbdata = pgsql_INSERT(dbc, rtevalrun_d); if( !dbdata ) { ret = -1; goto exit; } if( eCount(dbdata) != 1 ) { - fprintf(stderr, "** ERROR ** Failed to register the rteval run\n"); + writelog(dbc->log, LOG_ALERT, "** ERROR ** Failed to register the rteval run\n"); ret = -1; eFree_values(dbdata); goto exit; @@ -802,15 +826,16 @@ int db_register_rtevalrun(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml, memset(&prms, 0, sizeof(parseParams)); prms.table = "rtevalruns_details"; prms.rterid = rterid; - rtevalrundets_d = parseToSQLdata(xslt, summaryxml, &prms); + rtevalrundets_d = parseToSQLdata(dbc->log, xslt, summaryxml, &prms); if( !rtevalrundets_d ) { - fprintf(stderr, "** ERROR ** Could not parse the input XML data (rtevalruns_details)\n"); + writelog(dbc->log, LOG_ERR, + "** ERROR ** Could not parse the input XML data (rtevalruns_details)\n"); ret = -1; goto exit; } // Register the rteval_details information - dbdata = pgsql_INSERT((PGconn *) dbc, rtevalrundets_d); + dbdata = pgsql_INSERT(dbc, rtevalrundets_d); if( !dbdata ) { ret = -1; goto exit; @@ -818,7 +843,7 @@ int db_register_rtevalrun(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml, // Check that only one record was inserted if( eCount(dbdata) != 1 ) { - fprintf(stderr, "** ERROR ** Failed to register the rteval run\n"); + writelog(dbc->log, LOG_ALERT, "** ERROR ** Failed to register the rteval run details\n"); ret = -1; } eFree_values(dbdata); @@ -859,10 +884,10 @@ int db_register_cyclictest(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml // Register the cyclictest data for( i = 0; cyclictables[i]; i++ ) { prms.table = cyclictables[i]; - cyclic_d = parseToSQLdata(xslt, summaryxml, &prms); + cyclic_d = parseToSQLdata(dbc->log, xslt, summaryxml, &prms); if( cyclic_d && cyclic_d->children ) { // Insert SQL data which was found and generated - dbdata = pgsql_INSERT((PGconn *) dbc, cyclic_d); + dbdata = pgsql_INSERT(dbc, cyclic_d); if( !dbdata ) { result = -1; xmlFreeDoc(cyclic_d); @@ -882,7 +907,8 @@ int db_register_cyclictest(dbconn *dbc, xsltStylesheet *xslt, xmlDoc *summaryxml // Report error if not enough cyclictest data is registered. if( cyclicdata > 1 ) { - fprintf(stderr, "** ERROR ** No cyclictest raw data or histogram data registered\n"); + writelog(dbc->log, LOG_ALERT, + "** ERROR ** No cyclictest raw data or histogram data registered\n"); result = -1; } else { result = 1; diff --git a/server/parser/pgsql.h b/server/parser/pgsql.h index e9bf8a2..d0b35d3 100644 --- a/server/parser/pgsql.h +++ b/server/parser/pgsql.h @@ -28,13 +28,20 @@ #include <libxml/parser.h> #include <libxslt/transform.h> +#include <log.h> #include <eurephia_values.h> #include <parsethread.h> -typedef PGconn dbconn; /**< Wrapper definition, for a more generic DB API */ +/** + * A unified database abstraction layer, providing log support + */ +typedef struct { + LogContext *log; /**< Initialised log context */ + PGconn *db; /**< Database connection handler */ +} dbconn; /* Generic database function */ -void *db_connect(eurephiaVALUES *cfg); +dbconn *db_connect(eurephiaVALUES *cfg, LogContext *log); void db_disconnect(dbconn *dbc); int db_begin(dbconn *dbc); int db_commit(dbconn *dbc); diff --git a/server/parser/rteval_parserd.c b/server/parser/rteval_parserd.c index c0f9453..7ffbc52 100644 --- a/server/parser/rteval_parserd.c +++ b/server/parser/rteval_parserd.c @@ -41,7 +41,8 @@ #define DEFAULT_MSG_MAX 5 /**< Default size of the message queue */ #define XMLPARSER_XSL "xmlparser.xsl" /**< rteval report parser XSLT, parses XML into database friendly data*/ -static int shutdown = 0; /**< Global variable indicating if the program should shutdown */ +static int shutdown = 0; /**< Variable indicating if the program should shutdown */ +static LogContext *logctx = NULL; /**< Initialsed log context, to be used by sigcatch() */ /** * Simple signal catcher. Used for SIGINT and SIGTERM signals, and will set the global shutdown @@ -53,9 +54,9 @@ static int shutdown = 0; /**< Global variable indicating if the program should void sigcatch(int sig) { if( shutdown == 0 ) { shutdown = 1; - fprintf(stderr, "** SIGNAL ** Starting shutting down\n"); + writelog(logctx, LOG_INFO, "** SIGNAL ** Starting shutting down\n"); } else { - fprintf(stderr, "** SIGNAL ** Shutdown in progress ... please be patient ...\n"); + writelog(logctx, LOG_INFO, "** SIGNAL ** Shutdown in progress ... please be patient ...\n"); } // re-enable signals, to avoid brute force exits. @@ -71,31 +72,31 @@ void sigcatch(int sig) { * * @return Returns the system msg_max value, or DEFAULT_MSG_MAX on failure to read the setting. */ -unsigned int get_mqueue_msg_max() { +unsigned int get_mqueue_msg_max(LogContext *log) { FILE *fp = NULL; char buf[130]; unsigned int msg_max = DEFAULT_MSG_MAX; fp = fopen("/proc/sys/fs/mqueue/msg_max", "r"); if( !fp ) { - fprintf(stderr, + writelog(log, LOG_NOTICE, "** ERROR ** Could not open /proc/sys/fs/mqueue/msg_max, defaulting to %i\n", msg_max); - fprintf(stderr, "** ERROR ** %s\n", strerror(errno)); + writelog(log, LOG_DEBUG, "** ERROR ** %s\n", strerror(errno)); return msg_max; } memset(&buf, 0, 130); if( fread(&buf, 1, 128, fp) < 1 ) { - fprintf(stderr, + writelog(log, LOG_NOTICE, "** ERROR ** Could not read /proc/sys/fs/mqueue/msg_max, defaulting to %i\n", msg_max); - fprintf(stderr, "** ERROR ** %s\n", strerror(errno)); + writelog(log, LOG_DEBUG, "** ERROR ** %s\n", strerror(errno)); } else { msg_max = atoi_nullsafe(buf); if( msg_max < 1 ) { msg_max = DEFAULT_MSG_MAX; - fprintf(stderr, + writelog(log, LOG_NOTICE, "** ERROR ** Failed to parse /proc/sys/fs/mqueue/msg_max," "defaulting to %i\n", msg_max); } @@ -123,7 +124,8 @@ int process_submission_queue(dbconn *dbc, mqd_t msgq) { // Fetch an available job job = db_get_submissionqueue_job(dbc, &mtx_submq); if( !job ) { - fprintf(stderr, "** ERROR ** Failed to get submission queue job - shutting down\n"); + writelog(dbc->log, LOG_EMERG, + "** ERROR ** Failed to get submission queue job - shutting down\n"); shutdown = 1; rc = 1; goto exit; @@ -131,7 +133,8 @@ int process_submission_queue(dbconn *dbc, mqd_t msgq) { if( job->status == jbNONE ) { free_nullsafe(job); if( db_wait_notification(dbc, &shutdown, "rteval_submq") < 1 ) { - fprintf(stderr, "** ERROR ** Failed to wait for DB notification\n"); + writelog(dbc->log, LOG_EMERG, + "** ERROR ** Failed to wait for DB notification - shutting down\n"); shutdown = 1; rc = 1; goto exit; @@ -140,19 +143,21 @@ int process_submission_queue(dbconn *dbc, mqd_t msgq) { } // Send the job to the queue - fprintf(stderr, "** New job: submid %i, %s\n", job->submid, job->filename); + writelog(dbc->log, LOG_NOTICE, "** New job: submid %i, %s\n", job->submid, job->filename); do { int res; errno = 0; res = mq_send(msgq, (char *) job, sizeof(parseJob_t), 1); if( (res < 0) && (errno != EAGAIN) ) { - fprintf(stderr, "** ERROR ** Could not send parse job to the queue\n"); + writelog(dbc->log, LOG_EMERG, + "** ERROR ** Could not send parse job to the queue " + "- shutting down\n"); shutdown = 1; rc = 2; goto exit; } else if( errno == EAGAIN ) { - fprintf(stderr, + writelog(dbc->log, LOG_WARNING, "** WARNING ** Message queue filled up. " "Will not add new messages to queue for the next 60 seconds\n"); sleep(60); @@ -190,32 +195,41 @@ int main(int argc, char **argv) { xsltInit(); xmlInitParser(); + // Setup a log context + logctx = init_log("stderr:", LOG_DEBUG); + if( !logctx ) { + fprintf(stderr, "** ERROR ** Could not setup a log context\n"); + rc = 2; + goto exit; + } + // Fetch configuration - config = read_config("/etc/rteval.conf", "xmlrpc_parser"); + config = read_config(logctx, "/etc/rteval.conf", "xmlrpc_parser"); // Parse XSLT template snprintf(xsltfile, 512, "%s/%s", eGet_value(config, "xsltpath"), XMLPARSER_XSL); xslt = xsltParseStylesheetFile((xmlChar *) xsltfile); if( !xslt ) { - fprintf(stderr, "** ERROR ** Could not parse XSLT template: %s\n", xsltfile); + writelog(logctx, LOG_EMERG, "** ERROR ** Could not parse XSLT template: %s\n", xsltfile); rc = 2; goto exit; } // Open a POSIX MQ memset(&msgq, 0, sizeof(mqd_t)); - msgq_attr.mq_maxmsg = get_mqueue_msg_max(); + msgq_attr.mq_maxmsg = get_mqueue_msg_max(logctx); msgq_attr.mq_msgsize = sizeof(parseJob_t); msgq_attr.mq_flags = O_NONBLOCK; msgq = mq_open("/rteval_parsequeue", O_RDWR | O_CREAT | O_NONBLOCK, 0600, &msgq_attr); if( msgq < 0 ) { - fprintf(stderr, "** ERROR ** Could not open message queue: %s\n", strerror(errno)); + writelog(logctx, LOG_EMERG, + "** ERROR ** Could not open message queue: %s\n", strerror(errno)); rc = 2; goto exit; } // Get a database connection for the main thread - dbc = db_connect(config); + dbc = db_connect(config, logctx); if( !dbc ) { rc = 2; goto exit; @@ -230,17 +244,18 @@ int main(int argc, char **argv) { reportdir = eGet_value(config, "reportdir"); for( i = 0; i < max_threads; i++ ) { // Prepare thread specific data - thrdata[i] = malloc_nullsafe(sizeof(threadData_t)); + thrdata[i] = malloc_nullsafe(logctx, sizeof(threadData_t)); if( !thrdata[i] ) { - fprintf(stderr, "** ERROR ** Could not allocate memory for thread data\n"); + writelog(logctx, LOG_EMERG, + "** ERROR ** Could not allocate memory for thread data\n"); rc = 2; goto exit; } // Get a database connection for the thread - thrdata[i]->dbc = db_connect(config); + thrdata[i]->dbc = db_connect(config, logctx); if( !thrdata[i]->dbc ) { - fprintf(stderr, + writelog(logctx, LOG_EMERG, "** ERROR ** Could not connect to the database for thread %i\n", i); rc = 2; shutdown = 1; @@ -254,18 +269,20 @@ int main(int argc, char **argv) { thrdata[i]->xslt = xslt; thrdata[i]->destdir = reportdir; - thread_attrs[i] = malloc_nullsafe(sizeof(pthread_attr_t)); + thread_attrs[i] = malloc_nullsafe(logctx, sizeof(pthread_attr_t)); if( !thread_attrs[i] ) { - fprintf(stderr, "** ERROR ** Could not allocate memory for thread attributes\n"); + writelog(logctx, LOG_EMERG, + "** ERROR ** Could not allocate memory for thread attributes\n"); rc = 2; goto exit; } pthread_attr_init(thread_attrs[i]); pthread_attr_setdetachstate(thread_attrs[i], PTHREAD_CREATE_JOINABLE); - threads[i] = malloc_nullsafe(sizeof(pthread_t)); + threads[i] = malloc_nullsafe(logctx, sizeof(pthread_t)); if( !threads[i] ) { - fprintf(stderr, "** ERROR ** Could not allocate memory for pthread_t\n"); + writelog(logctx, LOG_EMERG, + "** ERROR ** Could not allocate memory for pthread_t\n"); rc = 2; goto exit; } @@ -279,8 +296,9 @@ int main(int argc, char **argv) { for( i = 0; i < max_threads; i++ ) { int thr_rc = pthread_create(threads[i], thread_attrs[i], parsethread, thrdata[i]); if( thr_rc < 0 ) { - fprintf(stderr, "** ERROR ** Failed to start thread %i: %s", - i, strerror(thr_rc)); + writelog(logctx, LOG_EMERG, + "** ERROR ** Failed to start thread %i: %s", + i, strerror(thr_rc)); rc = 3; goto exit; } @@ -291,9 +309,9 @@ int main(int argc, char **argv) { // checks the submission queue and puts unprocessed records on the POSIX MQ // to be parsed by one of the threads // - fprintf(stderr, "** Starting submission queue checker\n"); + writelog(logctx, LOG_DEBUG, "** Starting submission queue checker\n"); rc = process_submission_queue(dbc, msgq); - fprintf(stderr, "** Submission queue checker shut down\n"); + writelog(logctx, LOG_DEBUG, "** Submission queue checker shut down\n"); exit: // Clean up all threads @@ -304,8 +322,9 @@ int main(int argc, char **argv) { int j_rc; if( (j_rc = pthread_join(*threads[i], &thread_rc)) != 0 ) { - fprintf(stderr, "** ERROR ** Failed to join thread %i: %s\n", - i, strerror(j_rc)); + writelog(logctx, LOG_CRIT, + "** ERROR ** Failed to join thread %i: %s\n", + i, strerror(j_rc)); } pthread_attr_destroy(thread_attrs[i]); free_nullsafe(threads[i]); @@ -325,12 +344,12 @@ int main(int argc, char **argv) { // Close message queue errno = 0; if( mq_close(msgq) < 0 ) { - fprintf(stderr, "** ERROR ** Failed to close message queue: %s\n", + writelog(logctx, LOG_CRIT, "** ERROR ** Failed to close message queue: %s\n", strerror(errno)); } errno = 0; if( mq_unlink("/rteval_parsequeue") < 0 ) { - fprintf(stderr, "** ERROR ** Failed to remove the message queue: %s\n", + writelog(logctx, LOG_ALERT, "** ERROR ** Failed to remove the message queue: %s\n", strerror(errno)); } diff --git a/server/parser/xmlparser.c b/server/parser/xmlparser.c index bb7e7fd..66504ca 100644 --- a/server/parser/xmlparser.c +++ b/server/parser/xmlparser.c @@ -40,7 +40,7 @@ #include <eurephia_xml.h> #include <xmlparser.h> #include <sha1.h> - +#include <log.h> /** * Simple strdup() function which encapsulates the string in single quotes, @@ -93,14 +93,14 @@ static char *encapsInt(const unsigned int val) { * * @return Returns a well formed sqldata XML document on success, otherwise NULL is returned. */ -xmlDoc *parseToSQLdata(xsltStylesheet *xslt, xmlDoc *indata_d, parseParams *params) { +xmlDoc *parseToSQLdata(LogContext *log, xsltStylesheet *xslt, xmlDoc *indata_d, parseParams *params) { xmlDoc *result_d = NULL; char *xsltparams[10]; unsigned int idx = 0, idx_table = 0, idx_submid = 0, idx_syskey = 0, idx_rterid = 0, idx_repfname = 0; if( params->table == NULL ) { - fprintf(stderr, "Table is not defined\n"); + writelog(log, LOG_ERR, "Table is not defined\n"); return NULL; } @@ -137,7 +137,7 @@ xmlDoc *parseToSQLdata(xsltStylesheet *xslt, xmlDoc *indata_d, parseParams *para // Apply the XSLT template to the input XML data result_d = xsltApplyStylesheet(xslt, indata_d, (const char **)xsltparams); if( result_d == NULL ) { - fprintf(stderr, "Failed applying XSLT template to input XML\n"); + writelog(log, LOG_CRIT, "Failed applying XSLT template to input XML\n"); } // Free memory we allocated via encapsString()/encapsInt() @@ -169,7 +169,7 @@ xmlDoc *parseToSQLdata(xsltStylesheet *xslt, xmlDoc *indata_d, parseParams *para * @return Returns a pointer to a new buffer containing the value on success, otherwise NULL. * This memory buffer must be free'd after usage. */ -static inline char *sqldataValueHash(xmlNode *sql_n) { +static inline char *sqldataValueHash(LogContext *log, xmlNode *sql_n) { const char *hash = NULL; SHA1Context shactx; uint8_t shahash[SHA1_HASH_SIZE]; @@ -193,7 +193,7 @@ static inline char *sqldataValueHash(xmlNode *sql_n) { SHA1Final(&shactx, shahash); // "Convert" to a readable format - ret = malloc_nullsafe((SHA1_HASH_SIZE * 2) + 3); + ret = malloc_nullsafe(log, (SHA1_HASH_SIZE * 2) + 3); ptr = ret; for( i = 0; i < SHA1_HASH_SIZE; i++ ) { sprintf(ptr, "%02x", shahash[i]); @@ -216,7 +216,7 @@ static inline char *sqldataValueHash(xmlNode *sql_n) { * @return Returns a pointer to a new memory buffer containing the value as a string. * On errors, NULL is returned. This memory buffer must be free'd after usage. */ -char *sqldataExtractContent(xmlNode *sql_n) { +char *sqldataExtractContent(LogContext *log, xmlNode *sql_n) { const char *valtype = xmlGetAttrValue(sql_n->properties, "type"); if( !sql_n || (xmlStrcmp(sql_n->name, (xmlChar *) "value") != 0) @@ -231,9 +231,9 @@ char *sqldataExtractContent(xmlNode *sql_n) { while( chld_n && chld_n->type != XML_ELEMENT_NODE ){ chld_n = chld_n->next; } - return xmlNodeToString(chld_n); + return xmlNodeToString(log, chld_n); } else { - return sqldataValueHash(sql_n); + return sqldataValueHash(log, sql_n); } } @@ -248,17 +248,19 @@ char *sqldataExtractContent(xmlNode *sql_n) { * a value < 0 is returned. -1 if the field is not found or -2 if there are some problems * with the XML document. */ -int sqldataGetFid(xmlNode *sql_n, const char *fname) { +int sqldataGetFid(LogContext *log, xmlNode *sql_n, const char *fname) { xmlNode *f_n = NULL; if( !sql_n || (xmlStrcmp(sql_n->name, (xmlChar *) "sqldata") != 0) ) { - fprintf(stderr, "** ERROR ** Input XML document is not a valid sqldata document\n"); + writelog(log, LOG_ERR, + "** ERROR ** Input XML document is not a valid sqldata document\n"); return -2; } f_n = xmlFindNode(sql_n, "fields"); if( !f_n || !f_n->children ) { - fprintf(stderr, "** ERROR ** Input XML document does not contain a fields section\n"); + writelog(log, LOG_ERR, + "** ERROR ** Input XML document does not contain a fields section\n"); return -2; } @@ -272,7 +274,8 @@ int sqldataGetFid(xmlNode *sql_n, const char *fname) { if( strcmp(xmlExtractContent(f_n), fname) == 0 ) { char *fid = xmlGetAttrValue(f_n->properties, "fid"); if( !fid ) { - fprintf(stderr, "** ERROR ** Field node is missing 'fid' attribute\n"); + writelog(log, LOG_ERR, + "** ERROR ** Field node is missing 'fid' attribute\n"); return -2; } return atoi_nullsafe(fid); @@ -293,29 +296,30 @@ int sqldataGetFid(xmlNode *sql_n, const char *fname) { * @return Returns a pointer to a new memory buffer containing the extracted value. On errors or if * recid is higher than available records, NULL is returned. */ -char *sqldataGetValue(xmlDoc *sqld, const char *fname, int recid ) { +char *sqldataGetValue(LogContext *log, xmlDoc *sqld, const char *fname, int recid ) { xmlNode *r_n = NULL; int fid = -3, rc = 0; if( recid < 0 ) { - fprintf(stderr, "** ERROR ** sqldataGetValue() :: Invalid recid\n"); + writelog(log, LOG_ERR, "** ERROR ** sqldataGetValue() :: Invalid recid\n"); return NULL; } r_n = xmlDocGetRootElement(sqld); if( !r_n || (xmlStrcmp(r_n->name, (xmlChar *) "sqldata") != 0) ) { - fprintf(stderr, "** ERROR ** Input XML document is not a valid sqldata document\n"); + writelog(log, LOG_ERR, "** ERROR ** Input XML document is not a valid sqldata document\n"); return NULL; } - fid = sqldataGetFid(r_n, fname); + fid = sqldataGetFid(log, r_n, fname); if( fid < 0 ) { return NULL; } r_n = xmlFindNode(r_n, "records"); if( !r_n || !r_n->children ) { - fprintf(stderr, "** ERROR ** Input XML document does not contain a records section\n"); + writelog(log, LOG_ERR, + "** ERROR ** Input XML document does not contain a records section\n"); return NULL; } @@ -337,7 +341,7 @@ char *sqldataGetValue(xmlDoc *sqld, const char *fname, int recid ) { } fid_s = xmlGetAttrValue(v_n->properties, "fid"); if( fid_s && (fid == atoi_nullsafe(fid_s)) ) { - return sqldataExtractContent(v_n); + return sqldataExtractContent(log, v_n); } } } @@ -362,7 +366,7 @@ char *sqldataGetValue(xmlDoc *sqld, const char *fname, int recid ) { * On errors the function will return NULL and hostname and ipaddr will not have been touched * at all. */ -xmlDoc *sqldataGetHostInfo(xsltStylesheet *xslt, xmlDoc *summaryxml, +xmlDoc *sqldataGetHostInfo(LogContext *log, xsltStylesheet *xslt, xmlDoc *summaryxml, int syskey, char **hostname, char **ipaddr) { xmlDoc *hostinfo_d = NULL; @@ -372,26 +376,27 @@ xmlDoc *sqldataGetHostInfo(xsltStylesheet *xslt, xmlDoc *summaryxml, prms.table = "systems_hostname"; prms.syskey = syskey; - hostinfo_d = parseToSQLdata(xslt, summaryxml, &prms); + hostinfo_d = parseToSQLdata(log, xslt, summaryxml, &prms); if( !hostinfo_d ) { - fprintf(stderr, "** ERROR ** Could not parse input XML data (hostinfo)\n"); + writelog(log, LOG_ERR, + "** ERROR ** Could not parse input XML data (hostinfo)\n"); xmlFreeDoc(hostinfo_d); goto exit; } // Grab hostname from input XML - *hostname = sqldataGetValue(hostinfo_d, "hostname", 0); + *hostname = sqldataGetValue(log, hostinfo_d, "hostname", 0); if( !hostname ) { - fprintf(stderr, + writelog(log, LOG_ERR, "** ERROR ** Could not retrieve the hostname field from the input XML\n"); xmlFreeDoc(hostinfo_d); goto exit; } // Grab ipaddr from input XML - *ipaddr = sqldataGetValue(hostinfo_d, "ipaddr", 0); + *ipaddr = sqldataGetValue(log, hostinfo_d, "ipaddr", 0); if( !ipaddr ) { - fprintf(stderr, + writelog(log, LOG_ERR, "** ERROR ** Could not retrieve the IP address field from the input XML\n"); free_nullsafe(hostname); xmlFreeDoc(hostinfo_d); diff --git a/server/parser/xmlparser.h b/server/parser/xmlparser.h index 2b11d00..2c96fdf 100644 --- a/server/parser/xmlparser.h +++ b/server/parser/xmlparser.h @@ -39,10 +39,10 @@ typedef struct { unsigned int rterid; /**< References rtevalruns.rterid */ } parseParams; -xmlDoc *parseToSQLdata(xsltStylesheet *xslt, xmlDoc *indata_d, parseParams *params); -char *sqldataExtractContent(xmlNode *sql_n); -int sqldataGetFid(xmlNode *sqld, const char *fname); -char *sqldataGetValue(xmlDoc *sqld, const char *fname, int recid); -xmlDoc *sqldataGetHostInfo(xsltStylesheet *xslt, xmlDoc *summaryxml, +xmlDoc *parseToSQLdata(LogContext *log, xsltStylesheet *xslt, xmlDoc *indata_d, parseParams *params); +char *sqldataExtractContent(LogContext *log, xmlNode *sql_n); +int sqldataGetFid(LogContext *log, xmlNode *sqld, const char *fname); +char *sqldataGetValue(LogContext *log, xmlDoc *sqld, const char *fname, int recid); +xmlDoc *sqldataGetHostInfo(LogContext *log, xsltStylesheet *xslt, xmlDoc *summaryxml, int syskey, char **hostname, char **ipaddr); #endif |
