It's useful to remember that in Ethereum, the single version of the truth is the blockchain. If you have the blockchain, you always have enough information to answer any question about anything that has happened on it. If you've got a copy of the blockchain, you can validate every block, transaction-by-transaction, starting from the genesis block. Indeed this is what a full node will do when first starting up.
When a node is validating the blockchain, and encounters a transaction that emits a log message, it has a few options:
- Since log messages don't have any impact on future transactions, the node has no inherent need to store them in a readily queriable form (miners will likely do this, as they are not interested in logs and have no reason to waste the space).
- The node can store them in some sort of indexed database (possibly only including recent logs, depending on whether this is a "full" node of a "fast" node).
- Since the log bloom filters are stored in the blockchain, the node could discard logs, but store enough snapshots of the state trie that if a log is emitted in a particular block (which can be determined quickly from the raw blockchain data), it can replay to a given point reasonably quickly.
- The node could write them all to a text file, or print them out, or anything it wants.
The key point is that the log messages emitted are deterministic, and depend only on the transactions that are in the blockchain. If you've got the blockchain, you can reprocess it any of the ways detailed above (including rebuilding a full node), and get the information about the logs out.