Create output range like interface in Logger

This way any logger can choose to implement `logHeader`, `logMsgPart` and `finishLogMsg` which can be implemented without memory allocation for some loggers. If the logger does not overwrite these functions they construct a string with an `appender` and call `writeLogMsg` just like before this commit.

This is just as efficient as `std.string.format`, as `std.string.format` internally uses `appender` + `formattedWrite` as well.

`MsgRange` is used as a thin adapter which any reasonable compiler should remove/inline. The reason is that we might have to introduce another `OutputRange` interface for structured logging so we can't have two `put` methods with potentially the same parameter types.


Also  ported filelogger, stdiologger to the API.
Right now only implemented if the default logging format is used. In theory the API can work with any format string. We need to figure out what part of the header needs to be logged before the message and log it in `logHeader`, then log the message, then log the rest of the header in `finishLogMsg`.

Note: This can be merged as is. But you might want to have a look at `logHeader`. I'm not sure what the original intention was with `thisTid` and `Clock.currTime` in `logMessage`. This right now means that any logger overwriting `logHeader` will have to import `std.datetime` and `std.concurrency`. In theory these calls could be moved out of `logHeader` and `logHeader` could accept these as parameters.