#Add logging proc's using a specific logger in addition / instead the context logger only?

1 messages · Page 1 of 1 (latest)

onyx spade
#

All logging proc's (log(), logf(), info(), infof() and so on) rely on the relevant logger to be set as context logger (rather than a specific parameter).

In the (I think relatively frequent) case of a single, application-wide logger, this requires the logger to be assigned to context in main(). Still, logging setup is an obvious candidate for a sub-proc (possibly even a sub-sub-proc: main() calls init_app() calls init_log()): so, the set logger needs to be 'bubbled up' up to main() and set to context there.

But, within init_app() or init_log() themselves some logging may be needed: so, the logger has to be assigned to context in each of them. Not to mention the context juggling when different loggers are required.

Would it not make sense to add calls like log_l(logger: log.Logger, [go on as for log()] ) in which the logger is explicitly provided as a parameter (or something along these lines)?

mild sail
#

You can assign to the logger anywhere.

#
context.logger = my_logger
#

It doesn't just have to be in main, it can be done in ANY scope.

onyx spade
#

Hmmm... apparently not: if I assign it in, say, init_log(), it logs within this proc but reverts to the default log upon returning (I use a file log and the file does not receive anything more).

mild sail
#

context is SCOPE bound.

#

Which means anything outside of that scope is a different context

#

That includes things like your hypothetical init_log call.

#

You are initializing the context within that scope/stack frame and that's it.

#

It does not affect the parent scopes/stack frames.

onyx spade
#

Exactly. So, in order to have to have it 'active' everywhere, I need to assign it to context in main().

mild sail
#

Yes.

onyx spade
#

(or remember to assign it in any proc where I need to log something)

mild sail
#

But TRYING to abstract it into a separate procedure isn't actually any better nor any less lines (it's actually more)

onyx spade
#

Sorry, to abstract what? the log initialisation, the assignment to context or the actual logging operation.

mild sail
#

My guess is your previous code looked like this, right?

init_log :: proc() {
    context.logger = my_logger
}

main :: proc() {
    init_log()
}

And you were wondering why it wasn't working, right?

onyx spade
#

Kind of; the proc is longer and I eventually removed the assignment to context. Now it is:

set_logger :: proc() -> (lg.Logger, bool)
{
    hnd, err    := os.open(get_cfg_log_fname(), os.O_CREATE | os.O_APPEND | os.O_WRONLY, WRT_MODE)
    ok            := err == os.ERROR_NONE
//    defer os.close(hnd)    // NO! the handle must remain open for the log to work

    lgr: lg.Logger    = lg.create_file_logger(hnd, lg.Level.Info, lg.Default_File_Logger_Opts, LOG_ID)
    return lgr, ok
}

And main() assigns the returned logger to the context. Still, I find it kind of disturbing creating something somewhere and 'putting it into effect' somewhere else.

mossy gust
#
log_file, log_file_err := os.open(...)
assert(log_file_err == nil)
context.logger = log.create_file_logger(log_file, ...)

// rest of main
onyx spade
# mossy gust ```go log_file, log_file_err := os.open(...) assert(log_file_err == nil) context...

Yes, I know it can be done and works. It is rather a matter of style (or preferences): a non-trivial application may have many initialisations (CLI, preferences deserialisation, logging, specific libraries, etc.); they may be longer or shorter, but each contributes to the mental and visual clutter of main(); moving them out of main() (possibly each in its own sub-proc) reduces cognitive and sensorial load, simplifies (at least mentally) debugging, reduces the possibility of they messing with each other and so on (so, nothing to do with 'agile, 'clean' or whatever buzzword is fashionable nowadays: simply ease of work).

For logging this can only be done in a cumbersome and counter-intuitive way, because logging procs rely on the context. It would be more straightforward if they didn't (or didn't necessarily); then, if this is against the "language philosophy", I'll survive! 🥸