nlbwmon
nlbwmon copied to clipboard
Daily accounting period?
I have set accounting period to fixed interval with start date 2022-01-01 and interval 1 days. It should reset the accounting period at 12AM every day. But i have noticed, it counts the accounting period from the last commit to database. I restart the router every morning at 6AM. And before restart, i run,
/usr/sbin/nlbw -c commit
So the accounting period for that day is counted after the commit at 6AM.
Can i somehow set accounting period from 12AM to 12AM next day?
I'm seeing the same thing on my devices.
is your timezone GMT+6 ? ( mine is GMT+2 and the daily accounting sessions end at 02:00 local - and OpenWRT system - time each day )
it seems to call the archiving function ( https://github.com/jow-/nlbwmon/blob/c7616bcfaaef440848152f4dc738c990b2d0b90b/database.c#L609 ) at 00:00 GMT
- for me is that is 2 hours "late" ie 02:00 local time ( my timezone is GMT +2 / South Africa-Johannesburg )
- presumably for you is that is 6 hours "late" ie 06:00 local time ( I assume your timezone is GMT+6 ? )
I messed around by changing my timezone on OpenWRT and found the archiving function was always called x hours late for whatever GMT+x I set. The "time(NULL); " gave the correct local time, but the function was called "late" I added a debug print in the function and then changed the time on the device to a few seconds before i expected to see the "end of accounting period" archive being created : ( I assumed it would be 00:00 local time )
Timezone set to GMT+2 / South Africa-Johannesburg, and I set the system clock to 23:59:50 waited a few minutes but nothing happened, then I changed to clock to 01:59:50, and at 02:00 the archive was made.
Fri May 3 02:00:06 2024 daemon.err nlbwmon[21031]: nlbwmon Archiving database, current TS is: 20240502, next TS is 20240503 , time() is: Fri May 3 02:00:06 2024
I made a patch that seems to work OK, but there may be better places or ways in the nlbwmon codebase to put this logic.. ( and one could use the shorthand If styles to make the patch more compact.. The archive action seems to be the one responsible to restarting counters "interval_timestamp"'s lowest time resolution is 1 day so we only need to advance it or retard it by 1 to have the counter reset happen "now" or "later". This will advance or delay the database archive action based on the local time vs time until GMT 00:00.
--- a/database.c
+++ b/database.c
@@ -608,13 +608,40 @@ database_cleanup(void)
int
database_archive(struct dbhandle *h)
{
- uint32_t next_ts = interval_timestamp(&h->db->interval, 0);
- uint32_t curr_ts = db_timestamp(h->db);
+ time_t nowGMT, nowloc;
+ nowGMT = time(NULL);
+ int tsoffset = 0;
+ struct tm * tmploc = gmtime(&nowGMT);
+ nowloc = mktime(tmploc);
+ double timeDiffS = difftime(nowGMT,nowloc); // offset in seconds from GMT ( "+" is GMT+, "-" is GMT- )
+ if(timeDiffS>0){ // local time is GMT +, run earlier
+ if( (nowGMT%86400) > (86400 - abs((int)timeDiffS) )) // "%86400 is "seconds since midnight"
+ {
+ // local time has already gone past midnight
+ tsoffset = 1;
+ }else{
+ tsoffset = 0;
+ }
+ }
+ else if(timeDiffS<0){ // local time is GMT -,run later
+ if( (nowGMT%86400) < abs((int)timeDiffS) ) // "%86400 is "seconds since midnight"
+ {
+ tsoffset = -1;
+ }else{
+ tsoffset = 0;
+ }
+ }
+ else // we are at GMT
+ {
+ tsoffset = 0;
+ }
+
+ uint32_t next_ts = interval_timestamp(&h->db->interval, tsoffset); // YYYYMMDD of "now" but needs to br adjusted based on timezone
+ uint32_t curr_ts = db_timestamp(h->db); // YYYYMMDD of when the DB was created
int err;
-
+
if (next_ts > curr_ts) {
err = database_save(h, opt.db.directory, curr_ts, opt.db.compress);
-
if (err)
return err;