- 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

View File

@ -243,6 +243,8 @@ int exeBufProcessErrList(pExeBuf self, SicsInterp *pSics,
static int weWantLogging = 1; static int weWantLogging = 1;
char *cmd; char *cmd;
char cmdName[128]; char cmdName[128];
char *error;
char msg[132];
char *ende; char *ende;
int l; int l;
@ -260,6 +262,9 @@ int exeBufProcessErrList(pExeBuf self, SicsInterp *pSics,
status = Tcl_Eval(pTcl,cmd); status = Tcl_Eval(pTcl,cmd);
if(status != TCL_OK){ if(status != TCL_OK){
LLDstringAppend(errList,cmd); LLDstringAppend(errList,cmd);
error = (char *)Tcl_GetStringResult(pTcl);
snprintf(msg, sizeof msg, "#ERR: %s\n", error);
LLDstringAppend(errList,msg);
} }
DeleteDynString(command); DeleteDynString(command);
if(SCGetInterrupt(pCon) >= eAbortBatch){ if(SCGetInterrupt(pCon) >= eAbortBatch){

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;
}

27
logger.h Normal file
View File

@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------
logger.h
Markus Zolliker, Sept 2004
----------------------------------------------------------------------------
*/
#ifndef LOGGER_H
#define LOGGER_H
#include <time.h>
typedef struct Logger Logger;
Logger *LoggerMake(char *name, int period, int exact);
void LoggerKill(Logger *log);
int LoggerWrite(Logger *log, time_t now, int period, char *value);
char *LoggerName(Logger *log);
void LoggerSetNumeric(Logger *log, int numeric);
void LoggerSetDir(char *dirarg);
void LoggerWriteOld(Logger *log, time_t now);
time_t LoggerLastTime(Logger *log);
int LoggerPeriod(Logger *log);
int LoggerVarPath(char *dir, char *path, int pathLen, char *name);
void LoggerFreeAll(void);
#endif

492
logreader.c Normal file
View File

@ -0,0 +1,492 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fortify.h>
#include <errno.h>
#include <dirent.h>
#include "logger.h"
#include "sics.h"
#define LOGGER_NAN -999999.
#define ONE_YEAR (366*24*3600)
#define LLEN 1024
typedef enum { NUMERIC, TEXT } CompType;
typedef struct {
SConnection *pCon;
char var[1024];
int exact;
CompType type;
time_t step;
time_t tlim;
time_t tmin, tmax, tlast, told;
float ymin, ymax, ylast, yold;
char slast[LLEN];
/* char set[LLEN]; */
int np;
char *none;
} Compressor;
static char *dir = NULL;
static char *dir2 = NULL;
static void InitCompressor(Compressor *c, SConnection *pCon, time_t step) {
c->pCon = pCon;
c->step = step;
c->tmin = -2;
c->tmax = 0;
c->tlast = 0;
c->tlim = 0;
c->told = 0;
c->slast[0]='\0';
c->ylast = LOGGER_NAN;
}
static void OutString(Compressor *c, time_t t, char *str) {
char line[LLEN];
/* printf("out %ld %g\n", t, y); */
if (0 != strcmp(str, c->slast)) {
snprintf(line, sizeof line, "%ld %s\n", (long)(t - c->tlast), str);
c->tlast = t;
c->slast[0]='\0';
strncat(c->slast, str, sizeof c->slast - 1);
SCWrite(c->pCon, line, eWarning);
c->np--;
}
}
static void OutFloat(Compressor *c, time_t t, float y) {
char line[80];
/* printf("out %ld %g\n", t, y); */
if (y != c->ylast || (!c->exact && t != c->tlast)) {
c->ylast = y;
if (y == LOGGER_NAN) {
if (c->none) {
snprintf(line, sizeof line, "%ld %s\n", (long)(t - c->tlast), c->none);
} else {
snprintf(line, sizeof line, "%ld\n", (long)(t - c->tlast));
}
} else {
snprintf(line, sizeof line, "%ld %g\n", (long)(t - c->tlast), y);
}
/* printf("-%s\n", line); */
c->tlast = t;
SCWrite(c->pCon, line, eWarning);
c->np--;
}
}
static void PutValue(Compressor *c, time_t t, char *value) {
char *p;
double y;
if (c->var[0]) {
SCPrintf(c->pCon, eWarning, "*%s exact %d\n", c->var, c->exact);
c->var[0] = 0;
}
if (c->type == NUMERIC) {
if (t == 0) { /* finish */
t = c->tlim + 3 * c->step;
y = 0;
} else {
y = strtod(value, &p);
if (p == value) {
y = LOGGER_NAN;
} else {
if (y == LOGGER_NAN) y *= 1.0000002;
}
}
/* printf("put %ld %g\n", t, y); */
if (c->tlim == 0) goto first;
if (t >= c->tlim) {
c->tlim += c->step;
if (c->tmin > c->tmax) {
OutFloat(c, c->tmax, c->ymax);
c->ymax = c->ymin;
c->tmax = c->tmin;
} else {
OutFloat(c, c->tmin, c->ymin);
if (c->tmin == c->tmax) goto first;
c->ymin = c->ymax;
c->tmin = c->tmax;
}
if (t >= c->tlim) {
OutFloat(c, c->tmin, c->ymin);
if (t >= c->tlim + c->step) {
OutFloat(c, c->told, c->yold);
}
goto first;
}
}
if (y <= c->ymin) {
c->ymin = y;
c->tmin = t;
} else if (y > c->ymax) {
c->ymax = y;
c->tmax = t;
}
c->yold = y;
c->told = t;
return;
first:
c->tlim = t + 2 * c->step;
c->tmin = t;
c->tmax = t;
c->ymin = y;
c->ymax = y;
return;
} else if (c->type == TEXT) {
if (t != 0) OutString(c, t, value);
}
}
/*--------------------------------------------------------------------------*/
static long getOpt(char *line, int *isdst, int *exact) {
long lxs;
char *opt;
opt = strstr(line, "isdst");
if (opt) {
sscanf(opt, "isdst %d", isdst);
}
opt = strstr(line, "exact");
if (opt) {
sscanf(opt, "exact %d", exact);
}
opt = strstr(line, "period");
if (opt) {
sscanf(opt, "period %ld", &lxs);
return lxs;
} else {
return -1;
}
}
/*--------------------------------------------------------------------------*/
static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) {
/* Usage:
graph <start time> <end time> [ none <none value> ] np <number of points> <variable> [<variable> ...]
graph <start time> <end time> text <variable>
graph <start time> <end time> <step> <variable> [<variable> ...]
<start time> and <end time> are seconds since epoch (unix time) or, if the value
is below one day, a time relative to the actual time
The <none value> is optional. if not given, unknown values are returned as empty strings
<number of points> is the maximal number of points to be returned. If more values
are present and the values are numeric, the data is reduced. If the data is not
numeric, the last values may be skipped in order to avoid overflow.
<variable> is the name of a variable (several vaiables may be given).
Note that slashes are converted to dots, and that the first slash is ignored.
The seconds variant is for text values, which can not be reduced. In any case, all values
are returned.
The third variant is old style and can be replaced by the first variant, where
<number of points> = (<start time> - <end time>) / <step> + 2
Output format:
First line: returning the actual time on the server (this time is used for relative times)
For each variable which has data in the given interval,
the variable name is returned preceeded by a '*', followed by some options* separated with
blanks.
After the header line for every data point a line follows with
a time relative to the last point and the value.
The first time value relative to zero, e.g. absolute.
The data value is valid until the next datapoint. Empty values are returned as an
empty string or as the <none value>.
At the very end *<loss> <overflow> is returned.
<loss> is 1, when the data had to be reduced, 0 else
<overflow> is 1, when overflow occured, 0 else. Overflow may happen only
when np is given and a text variable was demanded.
*actually only one option exists (you might ignore it):
exact <value>
<value> is 1 when the value is exact, i.e. an integer.
<value> is 0 else.
*/
time_t from, to, step, xs, lastt, now;
long lxs;
char *p, *varp;
int i, j, iarg, l, iret, loss, np;
int inRange;
int yday=0;
time_t t, startim;
struct tm tm;
char stim[32], path[LLEN], line[LLEN], lastval[LLEN];
char *lin, *val, *stp;
FILE *fil;
Compressor c={0};
float yy, lasty;
CompType type0;
DIR *dr;
char *opt;
int isdst;
int overflow;
/* argtolower(argc, argv); */
if (argc < 4) goto illarg;
now = time(NULL);
from = strtol(argv[1], &p, 0); /* unix time, not year 2038 safe */
if (p == argv[1]) goto illarg;
to = strtol(argv[2], &p, 0);
if (p == argv[2]) goto illarg;
if (from < ONE_YEAR) {
from += now;
}
if (to < ONE_YEAR) {
to += now;
}
iarg = 3;
while (1) {
if (iarg>=argc) goto illarg;
if (strcasecmp(argv[iarg],"text") == 0) { /* non-numeric values */
iarg++;
step = 1;
type0 = TEXT;
np = to - from + 2;
break;
} else if (strcasecmp(argv[iarg],"none") == 0) { /* none */
iarg++;
if (iarg >= argc) goto illarg;
c.none = argv[iarg];
iarg++;
} else if (strcasecmp(argv[iarg],"np") == 0) { /* max. number of points */
iarg++;
if (iarg >= argc) goto illarg;
type0 = NUMERIC;
np = strtol(argv[iarg], &p, 0);
if (p == argv[iarg]) goto illarg;
iarg++;
if (to <= from) {
step = 1;
} else if (np <= 2) {
step = to - from;
} else {
step = (to - from) / (np - 2) + 1;
}
break;
} else {
step = strtol(argv[iarg], &p, 0);
if (p == argv[iarg]) goto illarg;
iarg++;
if (step <= 0) step = 1;
type0 = NUMERIC;
np = (from - to) / step + 2;
}
}
if (step <= 0) step = 1;
snprintf(line, sizeof line, "%ld\n", (long)now);
SCWrite(pCon, line, eWarning);
if (dir == NULL) {
dir = IFindOption(pSICSOptions, "LoggerDir");
if (dir == NULL) {
SCWrite(pCon, "ERROR: LoggerDir not found", eError);
return 0;
}
LoggerSetDir(dir);
}
if (dir2 == NULL) {
dir2 = IFindOption(pSICSOptions, "LoggerDir2");
if (dir2 == NULL) dir2="";
}
loss = 0;
overflow = 0;
for (i=iarg; i<argc; i++) {
startim = from;
t = 0;
lastt = 0;
inRange = 0;
xs = step;
InitCompressor(&c, pCon, step);
/* convert slashes to dots */
varp = argv[i];
if (*varp == '/') varp++;
for (j = 0; j < sizeof(c.var) && *varp != 0; j++, varp++) {
if (*varp == '/') {
c.var[j] = '.';
} else {
c.var[j] = *varp;
}
}
c.type = type0;
c.np = np;
l = LoggerVarPath(dir, path, sizeof path, c.var);
dr = opendir(path);
if (dr) {
closedir(dr);
} else {
l = LoggerVarPath(dir2, path, sizeof path, c.var);
dr = opendir(path);
if (dr) {
closedir(dr);
}
}
isdst = -1;
fil = NULL;
while (startim <= to && c.tlast <= to) {
tm = *localtime(&startim);
if (tm.tm_yday != yday) {
if (fil != NULL) { /* close file if day changed */
fclose(fil);
fil=NULL;
}
}
if (fil == NULL) {
yday = tm.tm_yday;
strftime(path + l, sizeof path - l, "%m-%d.log", &tm);
fil = fopen(path, "r");
if (fil != NULL) { /* check if file is from the given year */
strftime(stim, sizeof stim, "#%Y-%m-%d", &tm);
fgets(line, sizeof line, fil);
if (0 != strncmp(line, stim, 11)) {
fclose(fil);
fil = NULL;
} else {
lxs = getOpt(line, &isdst, &c.exact);
if (lxs >= 0) {
if (lxs == 0) {
c.type = TEXT;
} else {
c.type = type0;
xs = lxs;
}
if (xs < step) {
loss = 1;
xs = step;
}
}
}
}
}
if (fil == NULL) {
lin = NULL;
} else {
do {
lin = fgets(line, sizeof line, fil);
/* printf("%s\n", line); */
if (lin == NULL) break;
if (line[0] == '#') {
lxs = getOpt(line, &isdst, &c.exact);
if (lxs >= 0) {
if (lxs == 0) {
c.type = TEXT;
} else {
c.type = type0;
xs = lxs;
}
if (xs < step) {
loss = 1;
xs = step;
}
}
lin[0]='\0';
} else {
p = strchr(line, '\n'); if (p) *p='\0';
p = strchr(line, '#'); if (p) *p='\0';
}
} while (lin[0] == '\0');
}
if (lin != NULL) {
/* printf(" %s\n", line); */
p = strchr(line, '\t');
if (p) {
*p='\0';
val = p+1;
} else {
val = "";
}
p = strchr(val, '\t');
if (p) {
stp = p+1;
*p='\0';
iret = sscanf(stp, "%ld", &lxs);
if (iret == 1) {
if (lxs == 0) {
c.type = TEXT;
} else {
c.type = type0;
xs = lxs;
}
if (xs < step) {
loss = 1;
xs = step;
}
}
}
iret = sscanf(line, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
if (iret != 3) {
lin = NULL;
} else {
tm.tm_isdst = isdst;
t=mktime(&tm);
if (!inRange) {
if (t < startim) {
lastval[0]='\0';
strncat(lastval, val, sizeof lastval - 1);
lastt = t;
} else {
inRange=1;
if (lastt != 0) {
PutValue(&c, lastt, lastval);
}
PutValue(&c, t, val);
}
} else {
PutValue(&c, t, val);
}
}
}
if (lin == NULL) {
tm.tm_hour = 24; /* try next day */
tm.tm_min = 0;
tm.tm_sec = 0;
tm.tm_isdst = -1;
startim=mktime(&tm);
continue;
}
}
if (!inRange) {
if (lastt != 0) {
PutValue(&c, lastt, lastval);
}
}
c.ylast = LOGGER_NAN; /* force output of last value */
PutValue(&c, 0, ""); /* finish */
if (fil) {
fclose(fil);
fil = NULL;
}
if (c.np < 0) overflow = 1;
}
snprintf(line, sizeof line, "*%d %d\n", loss, overflow);
SCWrite(pCon, line, eWarning);
return 1;
illarg:
SCWrite(pCon, "illegal argument(s)", eError);
return 0;
}
/*--------------------------------------------------------------------------*/
static void KillLogReader(void *data) {
Logger *p, *next;
KillDummy(data);
LoggerFreeAll();
}
/*--------------------------------------------------------------------------*/
void LogReaderInit(void) {
AddCommand(pServ->pSics,"Graph",LogReader,KillLogReader,NULL);
}

86
logsetup.c Normal file
View File

@ -0,0 +1,86 @@
#include "logger.h"
#include "sics.h"
#include "sicshipadaba.h"
static int LoggerUpdateCallback(void *user, void *conn, pHdb node, hdbValue value) {
Logger *logger = user;
pDynString str;
str = formatValue(value, node);
LoggerWrite(logger, time(NULL), LoggerPeriod(logger), GetCharArray(str));
DeleteDynString(str);
return 1;
}
static int LogSetup(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) {
pHdb node;
pHdbCallback cb;
static char basepath[1024]="/";
char buf[1024];
char *p, *name;
static char *loggerDir=NULL;
int numeric, period;
Logger *logger;
if (argc < 2) {
SCPrintf(pCon, eError, "ERROR: should be: logsetup <node> [<period> [<filename>]]");
return 0;
}
if (strcasecmp(argv[1], "basepath") == 0) {
if (argc > 2) {
snprintf(basepath, sizeof basepath, "%s", argv[2]);
}
SCPrintf(pCon, eValue, "%s", basepath);
return 1;
}
if (loggerDir == NULL) {
loggerDir = IFindOption(pSICSOptions, "LoggerDir");
if (loggerDir == NULL) loggerDir="./";
LoggerSetDir(loggerDir);
}
if (strcasecmp(argv[1], "directory") == 0) {
if (argc > 2) {
loggerDir = strdup(argv[2]);
}
SCPrintf(pCon, eValue, "%s", loggerDir);
return 1;
}
node = FindHdbNode(basepath, argv[1], pCon);
if (node == NULL) {
SCPrintf(pCon, eError, "ERROR: %s not found", argv[1]);
return 0;
}
period = 0;
if (argc > 2) {
period = atoi(argv[2]);
}
if (argc > 3) {
snprintf(buf, sizeof buf, "%s", argv[3]);
} else {
snprintf(buf, sizeof buf, "%s", argv[1]);
}
for (p = buf; *p != '\0'; p++) {
if (*p =='/') *p = '.';
}
if (buf[0] == '.') {
name = buf+1;
} else {
name = buf;
}
if (node->value.dataType == HIPFLOAT) {
numeric = 1;
} else {
numeric = 0;
}
logger = LoggerMake(name, period, !numeric);
LoggerSetNumeric(logger, numeric);
cb = MakeHipadabaCallback(LoggerUpdateCallback, logger, (void (*)(void *))LoggerKill, -1, NULL);
assert(cb);
AppendHipadabaCallback(node, HCBUPDATE, cb);
return 1;
}
void LogSetupInit(void) {
AddCmd("LogSetup",LogSetup);
}

8
ofac.c
View File

@ -281,7 +281,6 @@
AddCommand(pInter,"MakeCounter",MakeCounter,NULL,NULL); AddCommand(pInter,"MakeCounter",MakeCounter,NULL,NULL);
AddCommand(pInter,"MakeO2T",CreateO2T,NULL,NULL); AddCommand(pInter,"MakeO2T",CreateO2T,NULL,NULL);
AddCommand(pInter,"SicsAlias",SicsAlias,NULL,NULL); AddCommand(pInter,"SicsAlias",SicsAlias,NULL,NULL);
AddCommand(pInter,"SicsAlias",DefineAlias,NULL,NULL);
AddCommand(pInter,"DefineAlias",DefineAlias,NULL,NULL); /* M.Z. */ AddCommand(pInter,"DefineAlias",DefineAlias,NULL,NULL); /* M.Z. */
AddCommand(pInter,"MakeHM",MakeHistMemory,NULL,NULL); AddCommand(pInter,"MakeHM",MakeHistMemory,NULL,NULL);
AddCommand(pInter,"VelocitySelector",VelSelFactory,NULL,NULL); AddCommand(pInter,"VelocitySelector",VelSelFactory,NULL,NULL);
@ -343,6 +342,7 @@
AddCommand(pInter,"MakeAsyncProtocol",AsyncProtocolFactory,NULL,NULL); AddCommand(pInter,"MakeAsyncProtocol",AsyncProtocolFactory,NULL,NULL);
AddCommand(pInter,"MakeAsyncQueue",AsyncQueueFactory,NULL,NULL); AddCommand(pInter,"MakeAsyncQueue",AsyncQueueFactory,NULL,NULL);
AddCommand(pInter,"MakeSicsObj",InstallSICSOBJ,NULL,NULL); AddCommand(pInter,"MakeSicsObj",InstallSICSOBJ,NULL,NULL);
AddCommand(pInter,"DynSicsObj",InstallSICSOBJ,NULL,NULL);
AddCommand(pInter,"MakeHdbQueue",MakeHDBQueue,NULL,NULL); AddCommand(pInter,"MakeHdbQueue",MakeHDBQueue,NULL,NULL);
AddCommand(pInter,"MakeGenController",GenControllerFactory,NULL,NULL); AddCommand(pInter,"MakeGenController",GenControllerFactory,NULL,NULL);
AddCommand(pInter,"genconfigure",GenControllerConfigure,NULL,NULL); AddCommand(pInter,"genconfigure",GenControllerConfigure,NULL,NULL);
@ -435,10 +435,14 @@
/* insert here initialization routines ... */ /* insert here initialization routines ... */
INIT(SiteInit); /* site specific initializations */
INIT(StatisticsInit); INIT(StatisticsInit);
INIT(InitializerInit);
INIT(SaveHdbInit); /* must be after InitializerInit */
INIT(SctStartup); INIT(SctStartup);
INIT(LogReaderInit);
INIT(LogSetupInit);
INIT(SiteInit); /* site specific initializations */
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
int InitObjectCommands(pServer pServ, char *file) int InitObjectCommands(pServer pServ, char *file)

91
savehdb.c Normal file
View File

@ -0,0 +1,91 @@
#include <stdio.h>
#include "dynstring.h"
#include "sicshipadaba.h"
static pDummy creationCommands = NULL;
static int saveit = 0;
static void SaveHdbBranch(pHdb node, FILE *fil) {
pHdb child;
char prop[16];
pDynString dyn;
char path[1024];
if (GetHdbProperty(node, "save", prop, sizeof prop)) {
if (strcmp(prop, "me") == 0) {
dyn = formatValue(node->value, node);
GetHdbPath(node, path, sizeof path);
fprintf(fil, "hupdate %s %s\n", path, GetCharArray(dyn));
DeleteDynString(dyn);
}
for (child = node->child; child != NULL; child = child->next) {
SaveHdbBranch(child, fil);
}
}
}
static int SaveHdbTree(void *object, char *name, FILE *fil) {
pHdb node;
SaveHdbBranch(GetHipadabaRoot(), fil);
return 1;
}
static int SaveHdbCallback(void *user, void *conn, pHdb node, hdbValue value) {
saveit = 1;
return 1;
}
static int SaveHdbEnable(SConnection *con, SicsInterp *sics,
void *data, int argc, char *argv[]) {
pHdb node;
char prop[16];
pHdbCallback cb;
if (argc < 2) {
SCPrintf(con, eError, "ERROR: should be: %s <path>", argv[0]);
return 0;
}
node = FindHdbNode(NULL, argv[1], con);
if (!node) {
SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
return 0;
}
cb = MakeHipadabaCallback(SaveHdbCallback, NULL, NULL, -1, NULL);
assert(cb);
AppendHipadabaCallback(node, HCBUPDATE, cb);
SetHdbProperty(node, "save", "me");
for (node = node->mama; node != NULL; node = node->mama) {
if (!GetHdbProperty(node, "save", prop, sizeof prop)) {
SetHdbProperty(node, "save", "kids");
}
}
saveit = 1;
return 1;
}
int SaveHdbTask(void *data) {
char *pFile = NULL;
if (saveit) {
saveit = 0;
assert(pServ->pSics);
pFile = IFindOption(pSICSOptions,"statusfile");
if (pFile) {
WriteSicsStatus(pServ->pSics,pFile,0);
}
}
return 1;
}
void SaveHdbInit(void) {
pDummy hs = NULL;
hs = CreateDummy("hdb saver");
hs->pDescriptor->SaveStatus = SaveHdbTree;
AddCommandWithFlag(pServ->pSics, "hsave", SaveHdbEnable, KillDummy, hs, 0);
TaskRegister(pServ->pTasker, SaveHdbTask, NULL, NULL, NULL, 0);
}