After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 770717 - log() should print the current extension, if applicable
log() should print the current extension, if applicable
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other All
: Normal enhancement
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on: 771598
Blocks:
 
 
Reported: 2016-09-01 19:31 UTC by Jonh Wendell
Modified: 2016-10-11 13:26 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Proposed patch (2.30 KB, patch)
2016-09-01 19:32 UTC, Jonh Wendell
none Details | Review
extensionUtils: Allow getCurrentExtension() to be called from anyone (1.47 KB, patch)
2016-09-18 02:45 UTC, Jonh Wendell
none Details | Review
log(): Reimplement on top of GLib.log_structured (1.89 KB, patch)
2016-09-18 02:46 UTC, Jonh Wendell
none Details | Review
log(): Reimplement on top of GLib.log_structured (2.31 KB, patch)
2016-10-03 23:13 UTC, Jonh Wendell
committed Details | Review
extensionUtils: Allow getCurrentExtension() to be called from anyone (2.36 KB, patch)
2016-10-03 23:14 UTC, Jonh Wendell
committed Details | Review

Description Jonh Wendell 2016-09-01 19:31:31 UTC
It would useful mainly for extension developers. They could easily see their logs in the journal by grepping for their extension uuid, for instance.
Comment 1 Jonh Wendell 2016-09-01 19:32:51 UTC
Created attachment 334609 [details] [review]
Proposed patch
Comment 2 Ray Strode [halfline] 2016-09-01 20:07:12 UTC
Review of attachment 334609 [details] [review]:

::: js/misc/extensionUtils.js
@@ +25,3 @@
+    let stack = (new Error()).stack.split('\n');
+    let extensionStackLine;
+

I think the changes in this file should be a separate commit, since strictly speaking, they aren't just about logging.

::: js/ui/environment.js
@@ +69,3 @@
+        try {
+            let extension = imports.misc.extensionUtils.getCurrentExtension();
+            args = '[' + extension.uuid + '] ' + args;

i think a better approach would be to change the logging function to use Shell.Global.log_structured instead of window.log then pass the uuid as a separate metadata item so it's query-able by journalctl
Comment 3 Jonh Wendell 2016-09-01 20:46:27 UTC
(In reply to Ray Strode [halfline] from comment #2)
> Review of attachment 334609 [details] [review] [review]:
> 
> ::: js/misc/extensionUtils.js
> @@ +25,3 @@
> +    let stack = (new Error()).stack.split('\n');
> +    let extensionStackLine;
> +
> 
> I think the changes in this file should be a separate commit, since strictly
> speaking, they aren't just about logging.

Indeed.

> ::: js/ui/environment.js
> @@ +69,3 @@
> +        try {
> +            let extension =
> imports.misc.extensionUtils.getCurrentExtension();
> +            args = '[' + extension.uuid + '] ' + args;
> 
> i think a better approach would be to change the logging function to use
> Shell.Global.log_structured instead of window.log then pass the uuid as a
> separate metadata item so it's query-able by journalctl

That would be a great addition. We could even think on a priority field for log(): (warning, error, debug, etc).

However, three things come on my mind:

1) Systems that don't have systemd: The implementation is just a printf(message). We lose the metadata anyway.

2) Cases where gnome-shell is started 'by hand': We don't get the output in the same console as we started gnome-shell. We have to open another terminal and run journalctl from there.

3) Social aspect: It's "easier" for users to run something like 'tail -f <file> | grep sth' than using journalctl to filter for metadata.

What do you think?
Comment 4 Ray Strode [halfline] 2016-09-06 14:45:24 UTC
(In reply to Jonh Wendell from comment #3)
> However, three things come on my mind:
> 
> 1) Systems that don't have systemd: The implementation is just a
> printf(message). We lose the metadata anyway.
> 
> 2) Cases where gnome-shell is started 'by hand': We don't get the output in
> the same console as we started gnome-shell. We have to open another terminal
> and run journalctl from there.
> 
> 3) Social aspect: It's "easier" for users to run something like 'tail -f
> <file> | grep sth' than using journalctl to filter for metadata.
> 
> What do you think?

So, all three things would be fixed if we used the native glib logging apis.  Unfortunately, we can't at the moment because of this problem:

https://mail.gnome.org/archives/desktop-devel-list/2016-August/msg00002.html

Do you want/have time to tackle the solution proposed on that thread?

--Ray
Comment 5 Jonh Wendell 2016-09-09 20:02:49 UTC
Now that we have g_log_variant() available, I have some questions...

1) Are we going to reimplement window.log() method on top of GLib.log_variant()?

 1.1) And, in the context of this bug, pass the extension as a field if the caller is an extension?

2) Can we depend on GLib 2.50 already?
Comment 6 Ray Strode [halfline] 2016-09-09 20:26:20 UTC
(In reply to Jonh Wendell from comment #5)
> Now that we have g_log_variant() available, I have some questions...
> 
> 1) Are we going to reimplement window.log() method on top of
> GLib.log_variant()?
Well, ideally, we'd get the convenience wrapper, GLib.log_structured(), I mentioned in the thread added to gjs first, and then use that instead of GLib.log_variant() directly. Of course what i put in the thread was just untested pseudocode, to illustrate the idea, but it's probably close to right.
 
>  1.1) And, in the context of this bug, pass the extension as a field if the
> caller is an extension?
makes sense to me.

> 2) Can we depend on GLib 2.50 already?
IMO, depending on latest glib is fine for core modules like gjs and gnome-shell.

One hiccup is hard code freeze is monday, so this may have to wait a bit, unless we all really scramble.  But if we do miss the train, I don't think it's that urgent anyway (unless you disagree?)
Comment 7 Jonh Wendell 2016-09-18 02:45:50 UTC
Created attachment 335786 [details] [review]
extensionUtils: Allow getCurrentExtension() to be called from anyone

Currently it's assumed only an extension can call this method. However
it can be useful if any part of the shell want to know if it was invoked
by an extension.
Comment 8 Jonh Wendell 2016-09-18 02:46:04 UTC
Created attachment 335787 [details] [review]
log(): Reimplement on top of GLib.log_structured

This allows us to pass metadata fields besides the message
to log. So, if the log() call is made from an extension,
pass the extension name and UUID to the logger.

This is useful for extension developers to debug their code
as well as to instruct their users to send debug info to them
by running something like this:

journalctl GNOME_SHELL_EXTENSION_UUID=<extension@uuid>
Comment 9 Jonh Wendell 2016-09-18 02:48:29 UTC
btw, if this gets in, can we drop shell_global_log_structured()?
Comment 10 Ray Strode [halfline] 2016-09-20 18:59:25 UTC
Review of attachment 335786 [details] [review]:

looks right to me

::: js/misc/extensionUtils.js
@@ +26,3 @@
+    let extensionStackLine;
+
+    // Search for an occurrence of an extension stack frame

maybe say (we skip i = 0, since that's the stack frame of this function)

@@ +35,2 @@
     if (!extensionStackLine)
         throw new Error('Could not find current extension');

might better to return null instead of throw if the expectation is now that it can be called from anywhere?
Comment 11 Ray Strode [halfline] 2016-09-20 19:20:44 UTC
Review of attachment 335787 [details] [review]:

thanks, looks close.  Of course we can't land this until a gjs release

::: js/ui/environment.js
@@ +74,3 @@
+        }
+
+        GLib.log_structured(null, GLib.LogLevelFlags.LEVEL_MESSAGE, fields);

this should probably pass "GnomeShell" or something like that as the log domain (or maybe it should use the extension name as the domain ?)

@@ +83,3 @@
     window.global = Shell.Global.get();
 
+    window.log = _makeLoggingFunc();

i don't think you need this _makeLoggingFunc() wrapper anymore.
I think you can just do somethilng like

window.log = _loggingFunc;

then drop the outer _makeLoggingFunc above and name the anonymous function above to _logginFunc (or whatever)
Comment 12 Jonh Wendell 2016-09-20 19:30:36 UTC
(In reply to Ray Strode [halfline] from comment #10)
> Review of attachment 335786 [details] [review] [review]:
> 
> looks right to me
> 
> ::: js/misc/extensionUtils.js
> @@ +26,3 @@
> +    let extensionStackLine;
> +
> +    // Search for an occurrence of an extension stack frame
> 
> maybe say (we skip i = 0, since that's the stack frame of this function)
> 
> @@ +35,2 @@
>      if (!extensionStackLine)
>          throw new Error('Could not find current extension');
> 
> might better to return null instead of throw if the expectation is now that
> it can be called from anywhere?

Thought like this too; theoretically it might break some extension relying on this exception... although I cannot see how that would happen...
Comment 13 Jonh Wendell 2016-09-20 19:32:37 UTC
(In reply to Ray Strode [halfline] from comment #11)
> Review of attachment 335787 [details] [review] [review]:
> 
> thanks, looks close.  Of course we can't land this until a gjs release
> 
> ::: js/ui/environment.js
> @@ +74,3 @@
> +        }
> +
> +        GLib.log_structured(null, GLib.LogLevelFlags.LEVEL_MESSAGE, fields);
> 
> this should probably pass "GnomeShell" or something like that as the log
> domain (or maybe it should use the extension name as the domain ?)

Liked it. "GNOME Shell" by default; Extension name if present.

> @@ +83,3 @@
>      window.global = Shell.Global.get();
>  
> +    window.log = _makeLoggingFunc();
> 
> i don't think you need this _makeLoggingFunc() wrapper anymore.
> I think you can just do somethilng like
> 
> window.log = _loggingFunc;
> 
> then drop the outer _makeLoggingFunc above and name the anonymous function
> above to _logginFunc (or whatever)

Hmm, I tried that but got lots of errors; shell crashing on the startup... Will try again with more attention.
Comment 14 Jonh Wendell 2016-10-03 23:13:48 UTC
Created attachment 336846 [details] [review]
log(): Reimplement on top of GLib.log_structured

This allows us to pass metadata fields besides the message
to log. So, if the log() call is made from an extension,
pass the extension name and UUID to the logger.

This is useful for extension developers to debug their code
as well as to instruct their users to send debug info to them
by running something like this:

journalctl GNOME_SHELL_EXTENSION_UUID=<extension@uuid>
Comment 15 Jonh Wendell 2016-10-03 23:14:30 UTC
Created attachment 336847 [details] [review]
extensionUtils: Allow getCurrentExtension() to be called from anyone

Currently it's assumed only an extension can call this method. However
it can be useful if any part of the shell want to know if it was invoked
by an extension.
Comment 16 Ray Strode [halfline] 2016-10-04 19:15:24 UTC
Review of attachment 336846 [details] [review]:

++
Comment 17 Ray Strode [halfline] 2016-10-04 19:17:04 UTC
Review of attachment 336847 [details] [review]:

++
Comment 18 Ray Strode [halfline] 2016-10-04 19:17:44 UTC
thanks for all the hard work and yak shaving on this!
Comment 19 Florian Müllner 2016-10-04 19:28:24 UTC
Just a small reminder that gnome-shell hasn't branched yet - I plan to do that after rolling the 3.22.1 release next week. It's probably best to wait for that, so that we don't need to bump the gjs requirement in a micro version.
Comment 20 Ray Strode [halfline] 2016-10-04 19:37:21 UTC
yea, we were actually having a discussion about this on #gnome-shell !
Comment 21 Jonh Wendell 2016-10-11 13:26:27 UTC
Attachment 336846 [details] pushed as 70526a8 - log(): Reimplement on top of GLib.log_structured
Attachment 336847 [details] pushed as c405081 - extensionUtils: Allow getCurrentExtension() to be called from anyone