mirror of
https://github.com/eddyem/small_tel.git
synced 2026-06-19 10:26:25 +03:00
little fixes
This commit is contained in:
@@ -66,6 +66,19 @@ meteologger -n <node> -o <directory> [options]
|
||||
| `-i` | `--interval` | `0.5` | Request interval in seconds. Allowed range: `[0.2, 900]`. |
|
||||
| `-t` | `--timeout` | `1.0` | Network timeout for server responses (seconds). Allowed range: `[0.1, 30]`. |
|
||||
|
||||
### Rotation of database files
|
||||
|
||||
The daemon keeps all DB files opened during its work, so for correct log rotation after renaming
|
||||
all files (like `rename log log00 *.log`) you should send SIGUSR1 or SIGUSR2 to daemon, like
|
||||
|
||||
```bash
|
||||
kill -USR1 $(cat /tmp/meteologger.pid)
|
||||
```
|
||||
|
||||
After receiving of this signal daemon will open new DB files and you will be able to compress old
|
||||
files.
|
||||
|
||||
|
||||
### Examples
|
||||
|
||||
1. Connect to a local daemon on port 5555 and store data in `/var/log/weather`:
|
||||
|
||||
@@ -53,6 +53,7 @@ void signals(int signo){
|
||||
kill(childpid, signo);
|
||||
LOGMSG("Send received signal %d to child", signo);
|
||||
if(signo != SIGUSR1) catchsig = signo;
|
||||
else signal(signo, signals);
|
||||
}else catchsig = signo;
|
||||
}
|
||||
}
|
||||
@@ -76,7 +77,10 @@ int main(int argc, char **argv){
|
||||
signal(SIGINT, signals);
|
||||
signal(SIGQUIT, signals);
|
||||
signal(SIGPIPE, SIG_IGN); // for sockets
|
||||
signal(SIGSTOP, SIG_IGN);
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
signal(SIGUSR1, signals); // reload DB
|
||||
signal(SIGUSR2, signals); // reload DB
|
||||
#ifndef EBUG
|
||||
if(sl_daemonize()) ERRX("Can't daemonize");
|
||||
#endif
|
||||
|
||||
@@ -38,8 +38,8 @@ static const char *key_timestamp = "TWEATH";
|
||||
|
||||
// sensor's db filename mask: DBpath/weatherXX.log
|
||||
static const char *dbfilename_mask = "%s/weather%02d.log";
|
||||
// and search regex
|
||||
static const char *dbfilename_regex = "weather[[:digit:]]{2}\\.log";
|
||||
// and search regex inside DB directory
|
||||
static const char *dbfilename_regex = "^weather[[:digit:]]{2}\\.log$";
|
||||
|
||||
static volatile atomic_bool isrunning = true;
|
||||
static volatile atomic_bool logreinit = false;
|
||||
@@ -189,6 +189,7 @@ static ssize_t get_answer_line(sl_sock_t *sock, char *buf, size_t buflen){
|
||||
// @return false if failed
|
||||
bool reinit_logs(){
|
||||
FNAME();
|
||||
LOGMSG("Got 'reinit' command");
|
||||
logreinit = true;
|
||||
return true;
|
||||
}
|
||||
@@ -217,8 +218,9 @@ static bool find_old_file(senslog_t *sensor){
|
||||
if(sensor->fd > -1){
|
||||
DBG("found opened file %s with fd %d -> close", sensor->path, sensor->fd);
|
||||
close(sensor->fd);
|
||||
sensor->fd = -1;
|
||||
}
|
||||
|
||||
LOGMSG("Try to find old file");
|
||||
regex_t regex;
|
||||
// Compile regex
|
||||
if(regcomp(®ex, dbfilename_regex, REG_EXTENDED | REG_NOSUB) != 0){
|
||||
@@ -235,16 +237,16 @@ static bool find_old_file(senslog_t *sensor){
|
||||
// Check if filename matches regex
|
||||
if(regexec(®ex, dir->d_name, 0, NULL, 0) == 0){
|
||||
DBG("Found: %s", dir->d_name);
|
||||
char fname[PATH_MAX], line[BUFSIZ];
|
||||
snprintf(fname, PATH_MAX, "%s/%s", DBpath, dir->d_name);
|
||||
FILE *fp = fopen(fname, "r");
|
||||
char line[BUFSIZ];
|
||||
snprintf(sensor->path, PATH_MAX, "%s/%s", DBpath, dir->d_name);
|
||||
FILE *fp = fopen(sensor->path, "r");
|
||||
if(!fp){
|
||||
LOGERR("Cannot open %s for reading: %s", fname, strerror(errno));
|
||||
LOGWARN("Cannot open %s for reading: %s", sensor->path, strerror(errno));
|
||||
DBG("Can't open");
|
||||
continue;
|
||||
}
|
||||
if(fgets(line, sizeof(line), fp) == NULL){
|
||||
LOGWARN("Found empty BD file %s - WTF???", fname);
|
||||
LOGWARN("Found empty BD file %s - WTF???", sensor->path);
|
||||
fclose(fp);
|
||||
continue;
|
||||
}
|
||||
@@ -252,18 +254,19 @@ static bool find_old_file(senslog_t *sensor){
|
||||
int len = strlen(line);
|
||||
if(len > 0 && line[len-1] == '\n') line[len-1] = 0; // remove trailing newline
|
||||
if(line[0] != '#' || line[1] != ' '){ // should starts from comment with station's name
|
||||
LOGWARN("Found broken database file: %s", fname);
|
||||
LOGWARN("Found broken database file: %s", sensor->path);
|
||||
continue;
|
||||
}
|
||||
const char *stname = line + 2; // station name from comment
|
||||
DBG("Check name: '%s' and '%s'", stname, sensor->sensname);
|
||||
if(0 == strcmp(stname, sensor->sensname)){ // good, we found this file!
|
||||
DBG("Found existant file %s -> append to it", fname);
|
||||
int newfd = open(fname, O_WRONLY | O_APPEND);
|
||||
DBG("Found existant file %s -> append to it", sensor->path);
|
||||
int newfd = open(sensor->path, O_WRONLY | O_APPEND);
|
||||
if(newfd < 0){
|
||||
LOGERR("Can't open existant BD file %s for append, try to create new", fname);
|
||||
LOGWARN("Can't open existant BD file %s for append, try to create new", sensor->path);
|
||||
continue;
|
||||
}
|
||||
LOGMSG("Station '%s': opened existant DB file '%s'", sensor->sensname, sensor->path);
|
||||
sensor->fd = newfd;
|
||||
ret = true;
|
||||
break;
|
||||
@@ -274,6 +277,7 @@ static bool find_old_file(senslog_t *sensor){
|
||||
}else{
|
||||
LOGERR("Can't open %s: %s", DBpath, strerror(errno));
|
||||
}
|
||||
if(sensor->fd < 0) LOGERR("Error opening DB file for '%s'", sensor->sensname);
|
||||
regfree(®ex);
|
||||
return ret;
|
||||
}
|
||||
@@ -286,12 +290,12 @@ static bool create_db_file(senslog_t *sensor){
|
||||
WARNX("create_db_file() should be called only with fully initialized `sensor`");
|
||||
return false;
|
||||
}
|
||||
LOGMSG("Try to create new DB file for '%s'", sensor);
|
||||
int num = sensor->idx; // try to start from sensor's index
|
||||
char path[PATH_MAX];
|
||||
for(; num <= 99; ++num){
|
||||
snprintf(path, PATH_MAX, dbfilename_mask, DBpath, num);
|
||||
snprintf(sensor->path, PATH_MAX, dbfilename_mask, DBpath, num);
|
||||
DBG("Try to create %s", path);
|
||||
if(access(path, F_OK) != 0) break; // no such file
|
||||
if(access(sensor->path, F_OK) != 0) break; // no such file
|
||||
}
|
||||
if(num > 99){
|
||||
LOGERR("Can't find free filename for station '%s', all numbers from 0 to 99 are busy! WTF???",
|
||||
@@ -300,29 +304,30 @@ static bool create_db_file(senslog_t *sensor){
|
||||
return false;
|
||||
}
|
||||
// create and open write-only
|
||||
int newfd = open(path, O_WRONLY | O_CREAT, 0644);
|
||||
int newfd = open(sensor->path, O_WRONLY | O_CREAT, 0644);
|
||||
if(newfd < 0){
|
||||
LOGERR("Can't open file %s for station %s: %s", path, sensor->sensname, strerror(errno));
|
||||
WARNX("Can't open %s", path);
|
||||
LOGERR("Can't open file %s for station %s: %s", sensor->path, sensor->sensname, strerror(errno));
|
||||
WARNX("Can't open %s", sensor->path);
|
||||
return false;
|
||||
}
|
||||
DBG("OK, %s opened, try to write header", path);
|
||||
sensor->fd = newfd;
|
||||
ssize_t len = snprintf(path, PATH_MAX, "# %s\n", sensor->sensname);
|
||||
char path[2*PATH_MAX];
|
||||
ssize_t len = snprintf(path, 2*PATH_MAX, "# %s\n", sensor->sensname);
|
||||
if(!write2fd(sensor, path, len)) return false;
|
||||
len = snprintf(path, PATH_MAX, "# Station #%d, format: KEYWORD[level],...\n# TIMESTAMP, ", sensor->idx);
|
||||
len = snprintf(path, 2*PATH_MAX, "# Station #%d, format: KEYWORD[level],...\n# TIMESTAMP, ", sensor->idx);
|
||||
if(!write2fd(sensor, path, len)) return false;
|
||||
char *ptr = path;
|
||||
len = 0;
|
||||
for(int i = 0; i < sensor->nvalues; ++i){
|
||||
ssize_t L = snprintf(ptr, PATH_MAX-len, "%s%s[%d]", i ? ", " : "", sensor->keys[i], sensor->levels[i]);
|
||||
ssize_t L = snprintf(ptr, 2*PATH_MAX-len, "%s%s[%d]", i ? ", " : "", sensor->keys[i], sensor->levels[i]);
|
||||
len += L;
|
||||
ptr += L;
|
||||
}
|
||||
len += snprintf(ptr, PATH_MAX-len, "\n");
|
||||
len += snprintf(ptr, 2*PATH_MAX-len, "\n");
|
||||
if(!write2fd(sensor, path, len)) return false;
|
||||
DBG("%s now have descriptor %d: %s", sensor->sensname, newfd, path);
|
||||
|
||||
DBG("%s now have descriptor %d: %s", sensor->sensname, newfd, sensor->path);
|
||||
LOGMSG("OK, data for '%s' now will be stored @ '%s'", sensor->sensname, sensor->path);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -335,6 +340,7 @@ static bool create_db_file(senslog_t *sensor){
|
||||
static bool get_sensor_keys(senslog_t *sensor, sl_sock_t *sock){
|
||||
if(!sensor || !sock) return false;
|
||||
char str[BUFSIZ], key[SL_KEY_LEN], value[SL_VAL_LEN];
|
||||
LOGMSG("Send request to receive all keys for sensors");
|
||||
snprintf(str, BUFSIZ, "%s=%d\n", commands[CMD_CHKLEVEL], sensor->idx);
|
||||
if(!send_request(sock, str)){
|
||||
LOGERR("Can't send request '%s'", commands[CMD_CHKLEVEL]);
|
||||
@@ -376,6 +382,7 @@ static bool get_sensor_keys(senslog_t *sensor, sl_sock_t *sock){
|
||||
// this function called at start and on any logs reinit
|
||||
static bool prepare_files(sl_sock_t *sock){
|
||||
if(!sock || !DBpath || Nsensors < 1) return false;
|
||||
LOGMSG("Prepare files for DB");
|
||||
for(int i = 0; i < Nsensors; ++i){
|
||||
senslog_t *sensor = &sensors[i];
|
||||
if(!sensor->initialized && !get_sensor_keys(sensor, sock)) return false;
|
||||
@@ -387,6 +394,8 @@ static bool prepare_files(sl_sock_t *sock){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
sensor->buflen = 0;
|
||||
sensor->lastvalidx = -1;
|
||||
}
|
||||
DBG("All ready!");
|
||||
return true;
|
||||
@@ -458,7 +467,7 @@ static bool analyse_list(sl_sock_t *sock){
|
||||
if(sensor->nvalues < 1){
|
||||
LOGWARN("Zero keys for station %s", sensor->sensname);
|
||||
ans = false; break;
|
||||
}
|
||||
}else LOGMSG("Found station '%s' with %d keys", sensor->sensname, sensor->nvalues);
|
||||
}
|
||||
if(ans) ans = prepare_files(sock);
|
||||
if(ans == false) sensors_delete();
|
||||
@@ -477,6 +486,7 @@ static bool prepare_logfiles(sl_sock_t *sock, const char *path){
|
||||
return false;
|
||||
}
|
||||
DBG("Store files in %s; send `list` request", DBpath);
|
||||
LOGMSG("Store files in %s; send `list` request", DBpath);
|
||||
snprintf(buf, 255, "%s\n", commands[CMD_LIST]);
|
||||
if(!send_request(sock, buf)){
|
||||
LOGERR("Can't send inited request");
|
||||
|
||||
@@ -41,6 +41,7 @@ static const val_t values[NAMOUNT] = {
|
||||
static void *mainthread(void *s){
|
||||
FNAME();
|
||||
sensordata_t *sensor = (sensordata_t *)s;
|
||||
double t0 = sl_dtime();
|
||||
while(sensor->fdes > -1){
|
||||
if(check_shm_block(&sdat)){
|
||||
//DBG("Got next");
|
||||
@@ -57,7 +58,8 @@ static void *mainthread(void *s){
|
||||
pthread_mutex_unlock(&sensor->valmutex);
|
||||
if(sensor->freshdatahandler) sensor->freshdatahandler(sensor);
|
||||
}else break; // no connection?
|
||||
sleep(1);
|
||||
while(sl_dtime() - t0 < sensor->tpoll) usleep(500);
|
||||
t0 = sl_dtime();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ static void *mainthread(void *s){
|
||||
sensordata_t *sensor = (sensordata_t *)s;
|
||||
while(sensor->fdes > -1){
|
||||
time_t tnow = time(NULL);
|
||||
if(tnow - tpoll > sensor->tpoll){
|
||||
if(tnow - tpoll > sensor->tpoll){ // tpoll + 1 second
|
||||
int dlen = sprintf(buf, "%s0\n%s1\n", commands[CMD_DISTANCE], commands[CMD_DISTANCE]);
|
||||
if(dlen != write(sensor->fdes, buf, dlen)){
|
||||
WARN("Can't ask new data from lightning monitor");
|
||||
@@ -144,15 +144,19 @@ static void *mainthread(void *s){
|
||||
int idx = parse_string(buf, &val, &nsens);
|
||||
if(idx > -1){
|
||||
DBG("Got index=%d", idx);
|
||||
gotfresh = TRUE;
|
||||
if(idx == NINTERRUPT && val == ANS_LIGHTNING){
|
||||
DBG("Interrupt: lightning");
|
||||
sensor->values[NSENSNO].value.u = nsens;
|
||||
sensor->values[NSENSNO].time = tnow;
|
||||
|
||||
}
|
||||
sensor->values[idx].value.u = val;
|
||||
sensor->values[idx].time = tnow;
|
||||
if(idx == NDISTANCE && val == 63){
|
||||
// do nothing: this is just polling signal
|
||||
}else{
|
||||
gotfresh = TRUE;
|
||||
sensor->values[idx].value.u = val;
|
||||
sensor->values[idx].time = tnow;
|
||||
}
|
||||
}
|
||||
}else break;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ static void *mainthread(void *s){
|
||||
sensordata_t *sensor = (sensordata_t *)s;
|
||||
while(sensor->fdes > -1){
|
||||
time_t tnow = time(NULL);
|
||||
if(tnow - tpoll > sensor->tpoll){
|
||||
if(tnow - tpoll >= sensor->tpoll){
|
||||
if(4 != write(sensor->fdes, "?U\r\n", 4)){
|
||||
WARN("Can't ask new data");
|
||||
break;
|
||||
|
||||
@@ -126,7 +126,7 @@ static void *mainthread(void *s){
|
||||
sensordata_t *sensor = (sensordata_t *)s;
|
||||
while(sensor->fdes > -1){
|
||||
time_t tnow = time(NULL);
|
||||
if(tnow - tpoll > sensor->tpoll){
|
||||
if(tnow - tpoll >= sensor->tpoll){
|
||||
if(6 != write(sensor->fdes, "!0R0\r\n", 6)){
|
||||
WARN("Can't ask new data");
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user