It is easy - in your log you store POINTERS to strings.
And you then create variable on the stack (ouch) and put its address to the log.
Then you leave the function (loop) (so that variable is forgotten and can be overwritten by anything). I will not say it is luck, that nothing uses the stack enought to make a problem before the loop is called again, as it disguise the problem. The POINTER in log_lines[0] points to UNALLOCATED place (where the variable msg once was).
Then the loop allocates variable msg (at the same place, as its previous run by the chance) so the POINTER stored in log_lines[0] (still pointing to the same place) points to the variable msg (and its content). By pure (bad) luck.
Then you overwrite the variable msg with a new value, so the log_lines[0] point to that new value.
Then you move the content of log_lines up, so the log_lines[1] now points to the variable msg (and its NEW value) as well as log_lines[0].
Then you assign log_lines[0] with address of variable msg (which it accidetally already contains)
Then you wonder, why variable msg accesed via log_lines[1] is exactly same as the (same) variable msg accesed vial log_lines[0] and why it contains the last (NEW) value, which you assigned into it.
Some of possible solutions are:
1) allocate place on heap (memaloc it) in the addToLog function, copy the text into it and store pointer to THIS place (and do not forget deallocate last log_lines before overwriting it - if it is not null (as untinitialized values are all 0)) which could lead to (relativelly) expensive heap manipulations and possible memory fragmentation.
2) allocate log_lines as array of char arrays of given len, copy the content of each line in another loop inside addToLog and then copy(and possibly truncate) the text to the log_line[0]
3) keep static index of last used log_line and in addToLog just increment it (wrapping around the len of the array), then overwrite the line pointed by index with (truncated) text and in printLog just start cycle on the index and climb (wrapping around len of the array) until you are again at index (which you would not print again and stop)