gotk4
gotk4 copied to clipboard
Custom glib.LogSetWriter
I'm trying to use a custom log writer that uses zerolog, but I'm getting Error: GLib: g_log_set_writer_func() called multiple times
because of this code in pkg/glib/v2/gmessages.go:
func init() {
if os.Getenv("G_DEBUG") == "" {
LogUseDefaultLogger() // see gotk4's gendata.go
}
}
I agree with the note in gir/cmd/gir-generate/gendata/gendata.go that this is referring to
// This one might be subjective, but I think most can agree that having a
// library dumping stuff into the console isn't the best idea. Not only
// would this make logging more consistently-looking, it would also allow
// the user to blot out all logging using Go's stdlib log.
//
// Somewhere down the line, a user might complain that a gotk4 application
// isn't obeying environment variables that GLib made up on its own. And
// that's understandable. Pull requests can be made to improve the piece of
// code written below, but consistency is still more ideal, I think.
p.Line(`
func init() {
if os.Getenv("G_DEBUG") == "" {
LogUseDefaultLogger() // see gotk4's gendata.go
}
}
`)
but having that set in an ìnit` function with no way to disable it permanently from inside the application (even putting an init function in main.go that sets the variable doesn't work) isn't the best approach, as this effectively makes it impossible to use a custom logger afaik. Is there a way around this currently that I'm not seeing or does this need improvement?
This likely needs improvements, but init()s behave weirdly. I'm not sure how to allow this; maybe I should move this to outside init(). I'm not sure where though, maybe gtk_init()?
I think that makes sense, as gtk_init() should be called before any GTK API is used
Right, it should work. However, there are other ways to initialize GTK without calling Go's gtk.Init() function, e.g. by doing gtk.NewApplication or by calling adw.Init().
Maybe using an internal variable that checks if the logger has been added before and then adding it in all of those if it hasnt already been added?
That could work, but init()'s ordering is pretty much undefined. It would be hacky to inject a logger beforehand, but it could look something like:
var _ = glib.DontInjectLogger()
I was more thinking of
var logWriterAdded = false
And then inside the body of LogSetWriter
if logWriterAdded {
return
}
logWriterAdded = true
// Rest of the body
}
And then putting the function that sets the default logger at the starz of every method that allows starting the gtk application, but that would also work
And then putting the function that sets the default logger at the starz of every method that allows starting the gtk application
This is hard if not impossible to figure out. You can try and guess it, but other C libraries (e.g. libadwaita) may call the C function on its own and bypass the Go call anyway.
Another method could just be introducing our own callback that the user can swap out manually in their main().
Both of those should be good, the first one would probably be the simplest to handle ig