- introduced logsetup and savehdb

- moved logger.c and logreader.c for sics/psi/ to sics/
- make comments in status file
This commit is contained in:
zolliker
2008-02-13 10:01:34 +00:00
parent 217de95b29
commit 2d7699ea39
7 changed files with 1080 additions and 3 deletions

372
logger.c Normal file
View File

@ -0,0 +1,372 @@
/*---------------------------------------------------------------------------
logger.c
Markus Zolliker, Sept 2004
----------------------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include <fortify.h>
#include <errno.h>
#include <ctype.h>
#include "logger.h"
struct Logger {
char *name;
char *old;
int oldsize;
int period;
time_t last;
int lastLn; /* 0 or the number chars counted from the second
last newline character. */
int overwrite; /* overwrite last line when value has not changed */
int numeric;
int exact;
double oldFloat, newFloat;
time_t newTime;
Logger *next;
};
static char *dir = NULL;
static Logger *list;
static time_t lastLife = 0;
/*--------------------------------------------------------------------------*/
char *LoggerName(Logger *log) {
return log->name;
}
/*--------------------------------------------------------------------------*/
void LoggerSetNumeric(Logger *log, int numeric) {
if (log) {
log->numeric = numeric;
}
}
/*--------------------------------------------------------------------------*/
Logger *LoggerFind(const char *name) {
Logger *p;
p = list;
while (p != NULL) {
if (0==strcasecmp(name, p->name)) {
return p;
}
p = p->next;
}
return NULL;
}
/*--------------------------------------------------------------------------*/
#define LASTLOGTXT "#last logging entry at:\n"
void LoggerSetDir(char *dirarg) {
char path[256], line[32];
FILE *fil;
dir = dirarg;
snprintf(path, sizeof path, "%s/lastlife.dat", dir);
fil = fopen(path, "r");
if (fil) {
fgets(line, sizeof line, fil);
if (strcmp(line, LASTLOGTXT) == 0) {
fgets(line, sizeof line, fil);
lastLife = atol(line);
if (lastLife < 1000000000) {
printf("bad lastLife %ld\n", (long)lastLife);
}
}
fclose(fil);
} else {
printf("can not read %s\n", path);
}
}
/*--------------------------------------------------------------------------*/
char *LoggerGetDir(void) {
char path[256];
FILE *fil;
time_t now;
static time_t last;
now = time(NULL);
if (now != last) {
snprintf(path, sizeof path, "%s/lastlife.dat", dir);
fil = fopen(path, "w");
if (fil) {
fprintf(fil, "%s%ld\n", LASTLOGTXT, (long)now);
fclose(fil);
} else {
printf("can not write %s\n", path);
}
last = now;
}
return dir;
}
/*--------------------------------------------------------------------------*/
int LoggerVarPath(char *dir, char *path, int pathLen, char *name) {
int l;
l = strlen(dir);
if (l + strlen(name) + 2 >= pathLen) {
path[0]='\0';
return 0;
}
strcpy(path, dir);
path[l] = '/'; l++;
for (;*name != '\0'; name++, l++) {
path[l] = tolower(*name);
}
path[l] = '/'; l++;
path[l] = '\0';
return l;
}
/*--------------------------------------------------------------------------*/
int LoggerWrite0(Logger *log, time_t now, int period, char *value) {
char path[256], stim[32], buf[32], chr;
struct tm *tm;
int yday;
int isdst;
int l, ext, skip, changed;
FILE *fil;
long endPos, pos1, p;
char info[80];
LoggerGetDir();
if (dir == NULL) return 0;
if (now == 0) {
printf("now==0\n");
}
tm = localtime(&log->last);
isdst = tm->tm_isdst; /* last isdst */
yday = tm->tm_yday; /* last day */
tm = localtime(&now);
if (tm->tm_yday != yday) {
log->period = -1;
}
l = LoggerVarPath(dir, path, sizeof path, log->name);
strftime(path + l, sizeof path - l, "%m-%d.log", tm);
strftime(stim, sizeof stim, "#%Y-%m-%d %H:%M:%S", tm);
fil = fopen(path, "r+");
skip = 0;
if (period <= 0) period = 1;
if (fil == NULL) { /* create new file */
fil = fopen(path, "w+");
if (fil == NULL) return 0;
fprintf(fil, "%s isdst %d period %d exact %d\n", stim, tm->tm_isdst, period, log->exact);
log->period = period;
isdst = tm->tm_isdst;
endPos = ftell(fil);
fseek(fil, -1, SEEK_CUR); /* position to newline */
} else { /* check if file is from today */
fgets(buf, sizeof buf, fil);
if (0 != strncmp(buf, stim, 11)) {
fclose(fil);
fil=fopen(path, "w+"); /* overwrite old logfile */
if (fil == NULL) return 0;
fprintf(fil, "%s isdst %d period %d exact %d\n", stim, tm->tm_isdst, period, log->exact);
log->period = period;
isdst = tm->tm_isdst;
endPos = ftell(fil);
fseek(fil, -1, SEEK_CUR); /* position to newline */
} else {
fseek(fil, -log->lastLn, SEEK_END); /* set position to last line */
endPos = ftell(fil) + log->lastLn;
if (endPos > 0 && log->lastLn == 0) {
/* find last newline in newly opened file */
fseek(fil, -1, SEEK_CUR);
chr = fgetc(fil);
while (chr != '\n' && ftell(fil) >= 2) {
fseek(fil, -2, SEEK_CUR);
chr = fgetc(fil);
}
fseek(fil, -1, SEEK_CUR); /* position to newline */
} else if (now != log->last) {
skip = 1;
}
}
}
changed = (0 != strcmp(value, log->old));
info[0]='\0';
if (period != log->period) {
log->period = period;
if (log->numeric) {
changed = 1;
snprintf(info, sizeof info, "period %d exact %d ", period, log->exact);
}
}
if (log->overwrite && !changed) {
skip = 0;
}
/* go to next newline */
chr = fgetc(fil);
while (chr != EOF) {
if (chr == '\n') {
skip--;
if (skip < 0) break;
}
chr = fgetc(fil);
}
if (chr == EOF) {
fputs("\n#no newline found\n", fil);
}
if (tm->tm_isdst != isdst || info[0] != '\0') {
fprintf(fil, "#isdst %d %s\n", tm->tm_isdst, info);
}
pos1 = ftell(fil);
strftime(stim, sizeof stim,"%H:%M:%S", tm);
fprintf(fil, "%s\t%s\n", stim, value);
for (p = ftell(fil); p < endPos; p++) { /* overwrite dirt after last line */
fprintf(fil, " ");
}
endPos = ftell(fil);
fclose(fil);
log->lastLn = (endPos - pos1) + 1;
/* overwrite next time when value has not changed */
log->overwrite = ! changed;
l = strlen(value);
if (l >= log->oldsize) {
ext = ((l - log->oldsize)/16 + 1) * 16;
if (ext < log->oldsize / 4) ext += (log->oldsize / 64) * 16;
log->oldsize += ext;
free(log->old);
log->old = calloc(1, log->oldsize);
assert(log->old);
assert(l < log->oldsize);
}
strcpy(log->old, value);
log->old[l] = '\0';
log->last = now;
return 1;
}
/*--------------------------------------------------------------------------*/
int LoggerWrite(Logger *log, time_t now, int period, char *value) {
Logger *p;
time_t h0;
static int yday = -1;
struct tm *tm;
int l;
FILE *fil;
char path[256];
char tim[256];
tm = localtime(&now);
if (tm->tm_yday != yday) {
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
h0 = mktime(tm);
yday = tm->tm_yday;
l = LoggerVarPath(dir, path, sizeof path, "debug");
strftime(path + l, sizeof path - l, "%m-%d.log", tm);
fil=fopen(path, "a");
if (fil) {
strftime(tim, sizeof tim, "h0 %m-%d %H:%M:%S\n", localtime(&h0));
fputs(tim, fil);
}
/* log old values (forced midnight log) */
p = list;
while (p != NULL) {
if (fil) {
strftime(tim, sizeof tim, "last %m-%d %H:%M:%S, ", localtime(&p->last));
fputs(tim, fil);
fprintf(fil, "period %d, name %s, old %s\n", p->period, p->name, p->old);
}
if (p->last < h0 && p->last != 0 &&
p->period >= 0 && p->old[0] != '\0') {
LoggerWrite0(p, h0, p->period, p->old);
p->overwrite = 0;
}
p = p->next;
}
if (fil) fclose(fil);
}
return LoggerWrite0(log, now, period, value);
}
/*--------------------------------------------------------------------------*/
time_t LoggerLastTime(Logger *log) {
if (log->last != 0 && log->period > 0) {
return log->last;
}
return 0;
}
/*--------------------------------------------------------------------------*/
int LoggerPeriod(Logger *log) {
return log->period;
}
/*--------------------------------------------------------------------------*/
void LoggerKill(Logger *log) {
/* we do not really free the logger, it might be reused
for the same variable later. We set the value to undefined */
if (list != NULL) { /* LoggerFreeAll not yet called */
LoggerWrite(log, time(NULL), 0, "");
}
}
/*--------------------------------------------------------------------------*/
Logger *LoggerMake(char *name, int period, int exact) {
Logger *log;
char path[256];
struct stat st;
int i;
time_t t;
LoggerGetDir();
if (dir == NULL) return NULL;
LoggerVarPath(dir, path, sizeof path, name);
i = stat(path, &st);
if (i >= 0) {
if (((st.st_mode >> 12) & 15) != 4) { /* exists, but is no directory */
return NULL;
}
} else {
i = mkdir(path, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
if (i < 0) return NULL; /* mkdir failed */
}
log = LoggerFind(name); /* look if logger already exists */
if (log == NULL) {
log = calloc(1, sizeof *log);
if (log == NULL) return NULL;
log->name = strdup(name);
if (log->name == NULL) {
free(log);
return NULL;
}
log->period = -1;
log->exact = exact;
log->old = calloc(1,12);
log->oldsize = 12;
log->last = 0;
log->lastLn = 0;
log->numeric = 1;
log->next = list;
list = log;
t = time(NULL) -1;
if (lastLife != 0 && lastLife + period < t) {
t = lastLife + period;
}
LoggerWrite(log, t, period, ""); /* value was undefined since last life of server */
}
return log;
}
/*--------------------------------------------------------------------------*/
void LoggerFreeAll(void) {
Logger *p, *next;
p = list;
while (p != NULL) {
next = p->next;
if (p->name) free(p->name);
if (p->old) free(p->old);
free(p);
p = next;
}
list = NULL;
}