nlbwmon icon indicating copy to clipboard operation
nlbwmon copied to clipboard

Daily accounting period?

Open milindpatel63 opened this issue 2 years ago • 3 comments

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?

milindpatel63 avatar Nov 18 '22 08:11 milindpatel63

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

DanielRIOT avatar May 02 '24 06:05 DanielRIOT

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;

DanielRIOT avatar Jun 07 '24 12:06 DanielRIOT