I'll examine this in more detail over time, but here are some initial comments...
A few things I've noticed.
The times when the month.ini drops to zero bytes correspond to nothing obvious in the log. It just appears to be a normal write. However once it is zero bytes it still gets "updated". ie the date of the file changes but nothing is written, which makes me think that the values CMX is storing internally are the problem rather than the actual writing to the file.
That is of note, quite what it means I don't know yet.
I doubt it is the source values, they are core to the functioning of MX and nothing much would work if the main weather data values were corrupt.
The time the ini drops to zero happens at different times. ie I thought it was something to do with the rollover given the backups had the zero-byte files but it happens at other times during the day and the backup just reflects the file it had at the time.
OK, so we know it is not a rollover issue.
Even though I am running b3215 and now have my station logging interval set to the same 10 mins as CMX, it still reads thousands of archive records from the station at startup. Unless I am misunderstanding the release notes for b3215.
A bug - your last data time of 09:05, got rounded to 09:10, but the time was 09:08. As 09:10 did not exist in the station logger, the station sent the whole logger contents.
If the last data time is later than the last log entry, then the download should skip the archive request.
Some high CPU threads come and go within a few minutes. Others seem to stick around. It's the ones that stick around that appear to be the problem. May I suggest that when a new background worker is started that it writes a debug log entry so we can see when the threads are started?
Maybe, it would add a lot of extra logging though.
The style of logging varies considerably in the code. eg Some log statements include the calling method, while others don't, which makes it hard to track what is going on. Other times what gets written to the debug log is a different message than what gets written to the console even though they follow each other in the code. I'm sure this is on your TODO list to fix.
I've gradually been updating the comments, most "functions" now log the function name. Some messages (mainly during start-up) do not, as the source is often self-evident.
The differences in the console messages and the log file entries are on whole intended. They serve difference audiences, different purposes.
A lot of things trigger a write to the month.ini. To narrow down where the issue is, it may be worthwhile adding a log entry in the code just before calling WriteMonthIniFile to show why it was called. See example below
I need to see why you have batches of writes every so often. The code needs optimising and some of the writes consolidating at a higher level - it will help SD disk wear for rPi users too!