Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tail logs after running #76

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Tail logs after running #76

wants to merge 1 commit into from

Conversation

gfontenot
Copy link
Owner

Right now, we're just printing the pid for the app process after running.
That's not particularly useful, and I often find myself needing to open Xcode
just to use the app in the simulator.

I think there's more we could do here, but for right now, it probably makes
sense to at least tail the logs for the simulator wherever we ran the run
command. It's at least a more useful default behavior than doing nothing.

Right now, we're just printing the pid for the app process after running.
That's not particularly useful, and I often find myself needing to open Xcode
just to use the app in the simulator.

I think there's more we could do here, but for right now, it probably makes
sense to at _least_ tail the logs for the simulator wherever we ran the run
command. It's at least a more useful default behavior than doing nothing.
@gfontenot gfontenot mentioned this pull request Jul 19, 2016
@hoang-tran
Copy link

Hi @gfontenot,
I noticed that the Swift print("something") does not print anything to the system.log at all. Do you know where we can find the output for this?

override func viewDidLoad() {
  super.viewDidLoad()
  print("something")
}

@gfontenot
Copy link
Owner Author

Oh, right, I forgot about that. Maybe this isn't what we want to do. I wonder if it'd be a better default to run an lldb session.

@keith
Copy link
Contributor

keith commented Jul 25, 2016

I think this PR and #77 are both going to be awesome, but I think we might want to move some of this logic into the vim plugin instead. That way we could have much easier hooks around what to do in these cases. We talked about having this entire integration part in a separate plugin, which I'm not sure makes sense anymore, but I do think it would be nice to be able to customize this the way I wanted to, as far as running them in tmux splits, windows etc.

@keith
Copy link
Contributor

keith commented Jul 29, 2016

On the lldb idea here, when launching a process you can pass stdout and stderr file paths:

process launch --stop-at-entry --stdout stdout.log --stderr.log

We would need both of these if for nothing else that Swift's prints end up in stdout and NSLog ends up in stderr

In theory after setting this up we could tail both at once:

tail -f stdout.log stderr.log

@keith
Copy link
Contributor

keith commented Jul 29, 2016

I believe this is similar to what Xcode does, as the system.log tailed in this PR has a lot more info than just the specific app's logging.

@keith
Copy link
Contributor

keith commented Jul 29, 2016

Also just noticed simctl's --wait-for-debugger/-w flag that might be of some use to us..

@keith
Copy link
Contributor

keith commented Jul 29, 2016

So if you change this line:

xcrun simctl launch booted "$app_id"

To

xcrun simctl launch --wait-for-debugger booted "$app_id"

Then the process will launch, seemingly frozen in the foreground of the simulator, and if you then attach a debugger (it seems like there is a timeout for this part too) with something like:

output="$(xcrun simctl launch --wait-for-debugger booted "$app_id")"
pid="$(echo "$output" | cut -d " " -f2)"
lldb -p "$pid"

It launches!

@keith
Copy link
Contributor

keith commented Jul 29, 2016

Another possible thing we might able to utilize here is the target.output-path setting. Since we're not explicitly calling process launch we can't inject the file paths for stdout and stderr. It seems like this setting should correspond with those command line arguments

@keith
Copy link
Contributor

keith commented Jul 29, 2016

Hmm. So this variable is definitely for this use case, but it seems like setting it after the process is launched, has no effect. Which is kind of our case, since simctl is doing the actual spawning. There must be a way to force a refresh of these file descriptors, but I currently only see that in the python bridge with SetOutputFileHandle (I assuming this would do what we want)

@sharplet
Copy link
Contributor

@keith Yeah I did a bunch of experimentation around --wait-for-debugger in #77, but I could never get it to actually attach stdout/stderr to the debugging session, so it didn't seem to solve the problem of seeing print() and NSLog() output.

FWIW, Xcode exhibits this same behaviour when you attach to an app that's already running in the simulator (you don't see stdout/stderr for that process). This makes me think that launching within lldb might be the way to go.

@keith
Copy link
Contributor

keith commented Jul 29, 2016

One possible solution to this would be instead to handle the IO redirection at a lower level. As part of the script launched with lldb you could do something like this:

expr --language c -- (int)close(1)
expr --language c -- (int)close(2)
expr --language c -- (int)open("path/to/stdout", 0x201, 0777)
expr --language c -- (int)open("path/to/stderr", 0x201, 0777)

@keith
Copy link
Contributor

keith commented May 19, 2017

FWIW this is much easier now with os log

@gfontenot
Copy link
Owner Author

have a link with more info?

@keith
Copy link
Contributor

keith commented Jun 3, 2017

Hmm. Looks like there's some need for blog posts about this. But a simple example of this is:

$ log stream --predicate "subsystem == 'AppName'"

There are some things with usage about this that you have to handle, like changing the predicate to include more things if you want logs from UIKit and such (you can probably do device to but I haven't looked). But from your app if you log a specific code on launch, you can reset the logs in the terminal, and this command persists across app launches, so you can just run it, and tail logs forever, clearing each relaunch.

@@ -9,3 +9,4 @@ xcrun instruments -w "$uuid" 2>/dev/null

xcrun simctl install booted "$app_path"
xcrun simctl launch booted "$app_id"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use the --console flag?

$ xcrun simctl help launch
Usage: simctl launch [-w | --wait-for-debugger] [--console] [--stdout=<path>] [--stderr=<path>] <device> <app identifier> [<argv 1> <argv 2> ... <argv n>]

	--console Block and print the application's stdout and stderr to the current terminal.
		Signals received by simctl are passed through to the application.
		(Cannot be combined with --stdout or --stderr)
	--stdout=<path> Redirect the application's standard output to a file.
	--stderr=<path> Redirect the application's standard error to a file.
		Note: Log output is often directed to stderr, not stdout.

If you want to set environment variables in the resulting environment, set them in the calling environment with a SIMCTL_CHILD_ prefix.

@@ -9,3 +9,4 @@ xcrun instruments -w "$uuid" 2>/dev/null

xcrun simctl install booted "$app_path"
xcrun simctl launch booted "$app_id"
tail -f "$HOME/Library/Logs/CoreSimulator/$uuid/system.log"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above. --console flag works better for me as it doesn't pollute the output with non-app logs.

@gfontenot gfontenot changed the base branch from master to main June 27, 2020 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants