Unless you're being forced by some ancient programmer to use an 8-space indent you should probably switch to a more up-to-date 4-space indent.
Your spacing between function paraemters is inconsistent. Sometimes you put a space, sometimes you don't. I suggest always putting a space. You also occasionally put a space between the function name and the opening paren, but usually you don't. Be consistent.
Macro constants are always in UPPERCASE in common C styles. And there's no reason for you logfile name to not be a macro constant (but see below).
genVars is a terrible name! logVars is better. And you will still need to pass it around all over the place. The best solution is to make it a static global in the logger code file. Then it's only visible in that file. Any modifications to its data needed by other files could be done through setter/getter functions. You could pass in your min/max log levels and even the log file name when initializing the logger.
You forgot to use va_end. That's important!
There's not much point in making sev a const int in logr. People don't tend to use const like that. It's more for promising the caller that you won't change his data, which is impossible in that case since you get your own copy.
I find it odd that your severity levels are 0 to 3 but your log level and max log level are (apparently) 1 to 4. You should make them the same and alter your comparisons as necessary.
Code:
//// logger.h
#ifndef LOGGER_H_
#define LOGGER_H_
void initLogger(const char *logfile, int min_lvl, int max_lvl);
void logr(int sev, const char *msg, ...);
void termLogger(void);
#endif
//// logger.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
struct LogVars{
FILE * fp;
int min_lvl;
int max_lvl;
};
static struct LogVars logVars;
void initLogger(const char *logfile, int min_lvl, int max_lvl){
logVars.fp = fopen(logfile, "a");
if (logVars.fp == NULL){
fprintf(stderr, "Error opening log file '%s'\n", logfile);
exit(EXIT_FAILURE);
}
logVars.min_lvl = min_lvl;
logVars.max_lvl = max_lvl;
}
void termLogger(void) {
fclose(logVars.fp);
}
void logr(int sev, const char *msg, ...){
const char *sevs[] = {
"debug", "info", "warn", "crit"
};
char buf[256];
va_list args;
va_start(args, msg);
vsnprintf(buf, sizeof buf, msg, args);
va_end(args);
time_t t = time(NULL);
char timeBuf[50];
strftime(timeBuf, sizeof timeBuf, "%c", localtime(&t));
if (sev >= logVars.min_lvl && sev <= logVars.max_lvl){
fprintf(logVars.fp, "%s :: %-6s %s\n", timeBuf, sevs[sev], buf);
printf( "%s :: %-6s %s\n", timeBuf, sevs[sev], buf);
}
}
//// main.c
//#include "logger.h" // commented out in this all-in-one-file example
#define LOGFILE "tcp_pthread_coban.log"
int main(void){
initLogger(LOGFILE, 1, 3);
logr(0, "shouldn't see this one");
logr(2, "logmsg with one param, string: %s", "strinLitValue");
logr(3, "logmsg with two parameters, string/int: %s, %d",
"AnotherstringLitValue", 4312);
termLogger();
return 0;
}
It just occurred to me that you could also use an enum in logger.h for you log levels.
Code:
enum {LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_CRIT};
Also, the min/max log levels should be range-tested in the init function.