From 13be4a333f9153d1ef3827e1ff0ee2f664f76afa Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 10 Aug 2023 22:04:13 +1000 Subject: [PATCH] Move to slog logger for application and log plugin --- .../go-webview2/webviewloader/env_create.go | 1 + v3/V3 Changes.md | 6 +- v3/go.mod | 7 +- v3/go.sum | 17 ++++ v3/pkg/application/application.go | 42 ++-------- v3/pkg/application/logger_default.go | 17 ++++ v3/pkg/application/logger_windows.go | 19 +++++ v3/pkg/application/options_application.go | 17 ++-- v3/pkg/application/webview_window.go | 31 +++---- v3/plugins/log/plugin.go | 82 +++---------------- v3/plugins/log/plugin.js | 54 ------------ 11 files changed, 102 insertions(+), 191 deletions(-) create mode 100644 v3/pkg/application/logger_default.go create mode 100644 v3/pkg/application/logger_windows.go diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go index 892189a4a..18bb26f71 100644 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go +++ b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go @@ -14,6 +14,7 @@ import ( ) func init() { + // TODO: Set a flag here and output this message only if the flag is set in the application startup fmt.Println("DEB | Using go webview2loader") preventEnvAndRegistryOverrides() } diff --git a/v3/V3 Changes.md b/v3/V3 Changes.md index b66156d0d..89201f952 100644 --- a/v3/V3 Changes.md +++ b/v3/V3 Changes.md @@ -47,7 +47,11 @@ Hooks can be registered at the application level or at the window level using `R ### Logging -There was a lot of requests for different types of logging in v2 so for v3 we have simplified things to make it as customisable as you want. There is now a single call `Log` that takes a LogMessage object. This object contains the message, the level, and the source, the log message and any data to be printed out. The default logger is the Console logger, however any number of outputs to log to can be added. Simply add custom loggers to the `options.Application.Logger.CustomLoggers` slice. The default logger does not have log level filtering, however custom loggers can be added that do. +Logging in v2 was confusing as both application logs and system (internal) logs were using the same logger. We have simplified this as follows: + +- Internal logs are now handled using the standard Go `slog` logger. This is configured using the `logger` option in the application options. By default, this uses the [tint](https://github.com/lmittmann/tint) logger. +- Application logs can now be achieved through the new `log` plugin which utilises `slog` under the hood. This plugin provides a simple API for logging to the console. It is available in both Go and JS. + ### Developer notes diff --git a/v3/go.mod b/v3/go.mod index c9ba87fff..fd395bbe5 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -1,6 +1,6 @@ module github.com/wailsapp/wails/v3 -go 1.19 +go 1.21 require ( github.com/bep/debounce v1.2.1 @@ -17,8 +17,11 @@ require ( github.com/leaanthony/clir v1.6.0 github.com/leaanthony/gosod v1.0.3 github.com/leaanthony/winicon v1.0.0 + github.com/lmittmann/tint v1.0.0 github.com/markbates/goth v1.77.0 github.com/matryer/is v1.4.0 + github.com/mattn/go-colorable v0.1.13 + github.com/mattn/go-isatty v0.0.19 github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 github.com/pkg/errors v0.9.1 github.com/pterm/pterm v0.12.51 @@ -55,8 +58,6 @@ require ( github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/leaanthony/slicer v1.5.0 // indirect github.com/lithammer/fuzzysearch v1.1.5 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-zglob v0.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect diff --git a/v3/go.sum b/v3/go.sum index 5344107db..72dedf374 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -1,4 +1,5 @@ atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg= +atomicgo.dev/assert v0.0.2/go.mod h1:ut4NcI3QDdJtlmAxQULOmA13Gz6e2DWbSAS8RUOmNYQ= atomicgo.dev/cursor v0.1.1 h1:0t9sxQomCTRh5ug+hAMCs59x/UmC9QL6Ci5uosINKD4= atomicgo.dev/cursor v0.1.1/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU= atomicgo.dev/keyboard v0.2.8 h1:Di09BitwZgdTV1hPyX/b9Cqxi8HVuJQwWivnZUEqlj4= @@ -47,6 +48,7 @@ github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzX github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c= github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= github.com/MarvinJWendt/testza v0.5.1 h1:a9Fqx6vQrHQ4CyiaLhktfTTelwGotmFWy8MNhyaohw8= +github.com/MarvinJWendt/testza v0.5.1/go.mod h1:L7csM8IBqCc0HH4TRYZSPCIRg6zJeqzM1pm3FSYZBso= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= @@ -71,6 +73,7 @@ github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARu github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -88,6 +91,7 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= +github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= @@ -160,6 +164,7 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -209,11 +214,13 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -237,6 +244,8 @@ github.com/lestrrat-go/jwx v1.2.21/go.mod h1:9cfxnOH7G1gN75CaJP2hKGcxFEx5sPh1abR github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMrOBEp1c= github.com/lithammer/fuzzysearch v1.1.5/go.mod h1:1R1LRNk7yKid1BaQkmuLQaHruxcC4HmAH30Dh61Ih1Q= +github.com/lmittmann/tint v1.0.0 h1:fzEj70K1L58uyoePQxKe+ezDZJ5pybiWGdA0JeFvvyw= +github.com/lmittmann/tint v1.0.0/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA= github.com/markbates/goth v1.77.0 h1:s3scqnWv/Zq/a5M766V0FKsLfOdFNdh/HEkuWCKbvT8= github.com/markbates/goth v1.77.0/go.mod h1:X6xdNgpapSENS0O35iTBBcMHoJDQDfI9bJl+APCkYMc= @@ -251,6 +260,7 @@ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM= github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -292,6 +302,7 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97 h1:3RPlVWzZ/PDqmVuf/FKHARG5EMid/tl7cv54Sw/QRVY= +github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY= github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo= github.com/samber/lo v1.37.0 h1:XjVcB8g6tgUp8rsPsJ2CvhClfImrpL04YpQHXeHPhRw= @@ -306,6 +317,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -315,6 +327,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tc-hib/winres v0.1.6 h1:qgsYHze+BxQPEYilxIz/KCQGaClvI2+yLBAZs+3+0B8= github.com/tc-hib/winres v0.1.6/go.mod h1:pe6dOR40VOrGz8PkzreVKNvEKnlE8t4yR8A8naL+t7A= github.com/tmclane/purego v0.0.0-20230601213035-1f25e70d7b01 h1:oQwu3iNDywGp1Hry+PDvz+grwbCGpzY+ckSnWKCnX5Y= @@ -663,7 +676,9 @@ modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw= modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY= modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= @@ -677,9 +692,11 @@ modernc.org/sqlite v1.21.0/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws= +modernc.org/tcl v1.15.1/go.mod h1:aEjeGJX2gz1oWKOLDVZ2tnEWLUrIn8H+GFu+akoDhqs= modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg= modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE= +modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ= mvdan.cc/sh/v3 v3.7.0 h1:lSTjdP/1xsddtaKfGg7Myu7DnlHItd3/M2tomOcNNBg= mvdan.cc/sh/v3 v3.7.0/go.mod h1:K2gwkaesF/D7av7Kxl0HbF5kGOd2ArupNTX3X44+8l8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 0c4ca969b..1d1caee7a 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -3,6 +3,7 @@ package application import ( "encoding/json" "log" + "log/slog" "net/http" "os" "runtime" @@ -21,7 +22,6 @@ import ( wailsruntime "github.com/wailsapp/wails/v3/internal/runtime" "github.com/wailsapp/wails/v3/pkg/events" - "github.com/wailsapp/wails/v3/pkg/logger" ) var globalApplication *App @@ -60,14 +60,14 @@ func New(appOptions Options) *App { applicationEventListeners: make(map[uint][]*EventListener), windows: make(map[uint]*WebviewWindow), systemTrays: make(map[uint]*SystemTray), - log: logger.New(appOptions.Logger.CustomLoggers...), contextMenus: make(map[string]*Menu), + logger: appOptions.Logger, pid: os.Getpid(), } globalApplication = result - if !appOptions.Logger.Silent { - result.log.AddOutput(&logger.Console{}) + if result.logger == nil { + result.logger = DefaultLogger() } result.Events = NewWailsEventProcessor(result.dispatchEventToWindows) @@ -251,7 +251,7 @@ type App struct { clipboard *Clipboard Events *EventProcessor - log *logger.Logger + logger *slog.Logger contextMenus map[string]*Menu contextMenusLock sync.Mutex @@ -338,37 +338,17 @@ func (a *App) GetPID() int { } func (a *App) info(message string, args ...any) { - a.Log(&logger.Message{ - Level: "INFO", - Message: message, - Data: args, - Sender: "Wails", - }) + a.logger.Info(message, args...) } func (a *App) fatal(message string, args ...any) { - msg := "************** FATAL **************\n" - msg += message - msg += "***********************************\n" - - a.Log(&logger.Message{ - Level: "FATAL", - Message: msg, - Data: args, - Sender: "Wails", - }) - - a.log.Flush() + msg := "A FATAL ERROR HAS OCCURRED: " + message + a.logger.Error(msg, args...) os.Exit(1) } func (a *App) error(message string, args ...any) { - a.Log(&logger.Message{ - Level: "ERROR", - Message: message, - Data: args, - Sender: "Wails", - }) + a.logger.Error(message, args...) } func (a *App) NewWebviewWindowWithOptions(windowOptions WebviewWindowOptions) *WebviewWindow { @@ -683,10 +663,6 @@ func (a *App) Show() { } } -func (a *App) Log(message *logger.Message) { - a.log.Log(message) -} - func (a *App) RegisterContextMenu(name string, menu *Menu) { a.contextMenusLock.Lock() defer a.contextMenusLock.Unlock() diff --git a/v3/pkg/application/logger_default.go b/v3/pkg/application/logger_default.go new file mode 100644 index 000000000..853b1f211 --- /dev/null +++ b/v3/pkg/application/logger_default.go @@ -0,0 +1,17 @@ +//go:build !windows + +package application + +import ( + "github.com/lmittmann/tint" + "log/slog" + "os" + "time" +) + +func DefaultLogger() *slog.Logger { + return slog.New(tint.NewHandler(os.Stderr, &tint.Options{ + TimeFormat: time.Kitchen, + NoColor: !isatty.IsTerminal(os.Stderr.Fd()), + })) +} diff --git a/v3/pkg/application/logger_windows.go b/v3/pkg/application/logger_windows.go new file mode 100644 index 000000000..fb1facd4a --- /dev/null +++ b/v3/pkg/application/logger_windows.go @@ -0,0 +1,19 @@ +//go:build windows + +package application + +import ( + "github.com/lmittmann/tint" + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" + "log/slog" + "os" + "time" +) + +func DefaultLogger() *slog.Logger { + return slog.New(tint.NewHandler(colorable.NewColorable(os.Stderr), &tint.Options{ + TimeFormat: time.Kitchen, + NoColor: !isatty.IsTerminal(os.Stderr.Fd()), + })) +} diff --git a/v3/pkg/application/options_application.go b/v3/pkg/application/options_application.go index 56c5b6252..32a152798 100644 --- a/v3/pkg/application/options_application.go +++ b/v3/pkg/application/options_application.go @@ -1,8 +1,8 @@ package application import ( - "github.com/wailsapp/wails/v3/pkg/logger" "io/fs" + "log/slog" "net/http" ) @@ -13,18 +13,17 @@ type Options struct { Mac MacOptions Windows WindowsApplicationOptions Bind []any - Logger struct { - Silent bool - CustomLoggers []logger.Output - } - Assets AssetOptions - Plugins map[string]Plugin - Flags map[string]any + Logger *slog.Logger + Assets AssetOptions + Plugins map[string]Plugin + Flags map[string]any // PanicHandler is a way to register a custom panic handler PanicHandler func(any) - // ProductionOverrides allows you to override any option in production builds + // ProductionOverrides allows you to have different options in production builds + // We would love if we could merge the options, but we can't because of the way + // Go handles zero values. ProductionOverrides *Options } diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 6abb979aa..04d5685da 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -4,14 +4,10 @@ import ( "errors" "fmt" "github.com/samber/lo" + "github.com/wailsapp/wails/v3/pkg/events" "runtime" "strings" "sync" - "time" - - "github.com/wailsapp/wails/v3/pkg/logger" - - "github.com/wailsapp/wails/v3/pkg/events" ) type ( @@ -914,24 +910,17 @@ func (w *WebviewWindow) dispatchWindowEvent(id uint) { } func (w *WebviewWindow) info(message string, args ...any) { - - globalApplication.Log(&logger.Message{ - Level: "INFO", - Message: message, - Data: args, - Sender: w.Name(), - Time: time.Now(), - }) + var messageArgs []interface{} + messageArgs = append(messageArgs, args...) + messageArgs = append(messageArgs, "sender", w.Name()) + globalApplication.info(message, messageArgs...) } -func (w *WebviewWindow) error(message string, args ...any) { - globalApplication.Log(&logger.Message{ - Level: "ERROR", - Message: message, - Data: args, - Sender: w.Name(), - Time: time.Now(), - }) +func (w *WebviewWindow) error(message string, args ...any) { + var messageArgs []interface{} + messageArgs = append(messageArgs, args...) + messageArgs = append(messageArgs, "sender", w.Name()) + globalApplication.error(message, messageArgs...) } func (w *WebviewWindow) handleDragAndDropMessage(event *dragAndDropMessage) { diff --git a/v3/plugins/log/plugin.go b/v3/plugins/log/plugin.go index 704c842f9..e325a5233 100644 --- a/v3/plugins/log/plugin.go +++ b/v3/plugins/log/plugin.go @@ -2,11 +2,8 @@ package log import ( _ "embed" - "fmt" - "io" - "os" - "github.com/wailsapp/wails/v3/pkg/application" + "log/slog" ) //go:embed plugin.js @@ -17,29 +14,9 @@ var pluginJS string // It must implement the application.Plugin interface. // Both the Init() and Shutdown() methods are called synchronously when the app starts and stops. -type LogLevel = float64 - -const ( - Trace LogLevel = iota + 1 - Debug - Info - Warning - Error - Fatal -) - type Config struct { - // Where the logs are written to. Defaults to os.Stderr - // If you want to write to a file, use os.OpenFile() - // e.g. os.OpenFile("mylog.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) - // Closes the writer when the app shuts down - Writer io.WriteCloser - - // The initial log level. Defaults to Debug - Level LogLevel - - // Disables the log level prefixes - DisablePrefix bool + // Logger is the logger to use. If not set, a default logger will be used. + Logger *slog.Logger // Handles errors that occur when writing to the log ErrorHandler func(err error) @@ -48,19 +25,16 @@ type Config struct { type Plugin struct { config *Config app *application.App - level LogLevel } func NewPluginWithConfig(config *Config) *Plugin { - if config.Level == 0 { - config.Level = Debug - } - if config.Writer == nil { - config.Writer = os.Stderr + + if config.Logger == nil { + config.Logger = application.DefaultLogger() } + return &Plugin{ config: config, - level: config.Level, } } @@ -70,9 +44,7 @@ func NewPlugin() *Plugin { // Shutdown is called when the app is shutting down // You can use this to clean up any resources you have allocated -func (p *Plugin) Shutdown() { - p.config.Writer.Close() -} +func (p *Plugin) Shutdown() {} // Name returns the name of the plugin. // You should use the go module format e.g. github.com/myuser/myplugin @@ -88,13 +60,10 @@ func (p *Plugin) Init(app *application.App) error { // CallableByJS returns a list of methods that can be called from the frontend func (p *Plugin) CallableByJS() []string { return []string{ - "Trace", "Debug", "Info", "Warning", "Error", - "Fatal", - "SetLevel", } } @@ -108,45 +77,18 @@ func (p *Plugin) InjectJS() string { // You can also return any type that is JSON serializable. // See https://golang.org/pkg/encoding/json/#Marshal for more information. -func (p *Plugin) write(prefix string, level LogLevel, message string, args ...any) { - if level >= p.level { - if !p.config.DisablePrefix { - message = prefix + " " + message - } - _, err := fmt.Fprintln(p.config.Writer, fmt.Sprintf(message, args...)) - if err != nil && p.config.ErrorHandler != nil { - p.config.ErrorHandler(err) - } - } -} - -func (p *Plugin) Trace(message string, args ...any) { - p.write("[Trace]", Trace, message, args...) -} - func (p *Plugin) Debug(message string, args ...any) { - p.write("[Debug]", Debug, message, args...) + p.config.Logger.Debug(message, args...) } func (p *Plugin) Info(message string, args ...any) { - p.write("[Info]", Info, message, args...) + p.config.Logger.Info(message, args...) } func (p *Plugin) Warning(message string, args ...any) { - p.write("[Warning]", Warning, message, args...) + p.config.Logger.Warn(message, args...) } func (p *Plugin) Error(message string, args ...any) { - p.write("[Error]", Error, message, args...) -} - -func (p *Plugin) Fatal(message string, args ...any) { - p.write("[FATAL]", Fatal, message, args...) -} - -func (p *Plugin) SetLevel(newLevel LogLevel) { - if newLevel == 0 { - newLevel = Debug - } - p.level = newLevel + p.config.Logger.Error(message, args...) } diff --git a/v3/plugins/log/plugin.js b/v3/plugins/log/plugin.js index 16811d5d1..7b740a341 100644 --- a/v3/plugins/log/plugin.js +++ b/v3/plugins/log/plugin.js @@ -2,16 +2,6 @@ // This file should contain helper functions for the that can be used by the frontend. // Below are examples of how to use JSDoc to define the Hashes struct and the exported functions. -/** - * Log at the Trace level. - * @param input {string} - The message in printf format. - * @param args {...any} - The arguments for the log message. - * @returns {Promise} - */ -function Trace(input, ...args) { - return wails.Plugin("log", "Trace", input, ...args); -} - /** * Log at the Debug level. * @param input {string} - The message in printf format. @@ -52,47 +42,3 @@ function Warning(input, ...args) { function Error(input, ...args) { return wails.Plugin("log", "Error", input, ...args); } - -/** - * Log at the Fatal level. - * @param input {string} - The message in printf format. - * @param args {...any} - The arguments for the log message. - * @returns {Promise} - */ -function Fatal(input, ...args) { - return wails.Plugin("log", "Fatal", input, ...args); -} - -/** - * SetLevel sets the logging level - * @param level {Level} The log level to set - * @returns {Promise} - */ -function SetLevel(level) { - return wails.Plugin("log", "SetLevel", level); -} - -/** - * Log Level. - * @readonly - * @enum {number} - */ -let Level = { - Trace: 1, - Debug: 2, - Info: 3, - Warning: 4, - Error: 5, - Fatal: 6, -}; - -window.Logger = { - Trace, - Debug, - Info, - Warning, - Error, - Fatal, - SetLevel, - Level, -}