From 768d46060d78f63c2f4f4f9f660b893575effe66 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Fri, 22 May 2026 09:45:35 +0300 Subject: [PATCH] little fixes --- Daemons/weather_logger/Readme.md | 13 ++++ Daemons/weather_logger/main.c | 4 ++ Daemons/weather_logger/server.c | 60 +++++++++++-------- .../plugins/btameteo.c | 4 +- .../plugins/lightning.c | 12 ++-- .../plugins/reinhardt.c | 2 +- .../weatherdaemon_multimeteo/plugins/wxa100.c | 2 +- 7 files changed, 65 insertions(+), 32 deletions(-) diff --git a/Daemons/weather_logger/Readme.md b/Daemons/weather_logger/Readme.md index 62ff138..70f466b 100644 --- a/Daemons/weather_logger/Readme.md +++ b/Daemons/weather_logger/Readme.md @@ -66,6 +66,19 @@ meteologger -n -o [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`: diff --git a/Daemons/weather_logger/main.c b/Daemons/weather_logger/main.c index b19aad3..a742726 100644 --- a/Daemons/weather_logger/main.c +++ b/Daemons/weather_logger/main.c @@ -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 diff --git a/Daemons/weather_logger/server.c b/Daemons/weather_logger/server.c index 6698828..215f316 100644 --- a/Daemons/weather_logger/server.c +++ b/Daemons/weather_logger/server.c @@ -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"); diff --git a/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c b/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c index 874873e..448f678 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/btameteo.c @@ -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; } diff --git a/Daemons/weatherdaemon_multimeteo/plugins/lightning.c b/Daemons/weatherdaemon_multimeteo/plugins/lightning.c index 1b0b73a..632be47 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/lightning.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/lightning.c @@ -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; } diff --git a/Daemons/weatherdaemon_multimeteo/plugins/reinhardt.c b/Daemons/weatherdaemon_multimeteo/plugins/reinhardt.c index a91f0b0..1c430ea 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/reinhardt.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/reinhardt.c @@ -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; diff --git a/Daemons/weatherdaemon_multimeteo/plugins/wxa100.c b/Daemons/weatherdaemon_multimeteo/plugins/wxa100.c index 29cb8e6..e448092 100644 --- a/Daemons/weatherdaemon_multimeteo/plugins/wxa100.c +++ b/Daemons/weatherdaemon_multimeteo/plugins/wxa100.c @@ -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;