This is a question about how to use Apple's Unified Logging framework, also known as "os_log", the function you call from Swift.
Specifically, I want to know if it is possible:
to view logs in Console.app (not with the log command line tool) ...
to see debug-level logs (not just info-level logs) ...
for an iOS app running in the Simulator (not just running on a device).
You cannot do this just by running Console.app, pointing at the Simulator, and selecting Action / Include Debug Message, which is the obvious thing to do.
This article suggests that debug-level logs don't show up because "the 'system' log level is set to info" but I can't find a discussion anywhere that explains what that means.
This appears to be a bug in the Console app when dealing with the simulator: https://forums.developer.apple.com/thread/82736
I believe a Radar has been logged: rdar://47667447
I can't see Debug level or Info level log messages in the console app when running from the the iOS simulator.
I can see Default, Error and Fault levels in the console with the simulator.
I can see all Debug, Info, Default, Error and Fault levels in the console with a real non-simulated device.
I'm using the same console app filter settings with the simulator and in a real device.
I'm using XCode 8.3.3 with a simulator running iOS 10.3.
I'm using the Unified Logging System in my iOS app, as described here:
https://developer.apple.com/documentation/os/logging
https://developer.apple.com/videos/play/wwdc2016/721/
How can I get these Debug level and Info level log messages to display when running against the simulator?
In the Console app's menu:
Action ->Include Info Messages and/or ->Include Debug Messages
Update:
If you still don't see the messages, try entering this Terminal command to configure the logging levels for your app:
sudo log config --subsystem com.mydomain.appname --mode level:debug
This turns on .debug-level logging for subsystem "com.mydomain.appname" (which includes .info and .default messages).
Separately, if you want to persist the messages, rather than the default of memory-only, turn on persistence for the three levels at the same time, like so:
sudo log config --subsystem com.mydomain.appname --mode level:debug,persist:debug
(subset of my answer at Viewing os_log messages in device console)
This seems to be the expected behaviour, unfortunately I can't point to any documentation to back this up, however the Info and Debug level log messages are sent to Xcode's console, not the Console.app.
This is so simple but: how on earth do I set the level of log messages I see in Console.app, if I am trying to use iOS10's new "Unified Logging & Activity Tracing" API?
In other words, if I have code running on iOS like so:
fileprivate let logger = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "mycategory")
fileprivate func logv(_ s:String) {
os_log("%#",log:logger,type:.info,s)
}
Then what do I need to do to see the logged messages in Console.app? By default, only log messages of type .error seem to show up.
I am wondering how to do this if I am running code on a device, not in the simulator.
Related:
Xcode 8 - os_log_debug and os_log_info logs are not displayed on new Mac console (unified logging)
Hilariously, the answer is that you just go to the Console.app's menu bar and select:
Action / Include Info Messages
Action / Include Debug Messages
Xcode 10.0 beta 6 (likely others too) won’t show debug messages logged from the simulator even after enabling Include Info Messages, Include Debug Messages in the Console.app. AFAIK there is no fix for this.
To see debug logs sent from the simulator you have to stream from a terminal instead:
xcrun simctl spawn booted log stream --debug --predicate 'subsystem == "es.com.jano.Myapp"'
when I start my app from xcode 7 I see this message
2016-01-14 13:50:13.119 Guggy[31879:] <GMR/INFO> To enable debug logging
set the following application argument: -GMRDebugEnabled (see http://goo.gl/Y0Yjwu)
I tried to follow their instructions in the link but it still show me this message.
What am I doing wrong?
You are not doing anything wrong.
The message " To enable debug logging ..." is always showing up regardless if you have the debug logging enabled or not.
If you want to check whether you enabled the debug logging, you should look for the following message: " Debug logging enabled".
Use -noGMRDebugEnabled to disable the debug logging.
I'm just getting started with Apple Watch. I found instructions from "Five Minute Watchkit", on getting the iOS app and the watch kit app both running in the simulator and both processes attached to the LLDB debugger.
What I do is launch and quit the iOS app to install a current version in the sim. Then I switch to the watchKit scheme and launch that, which displays my watch app UI on the watch simulator.
I then launch the corresponding iOS app in the simulator, then user "attach to process" in the Xcode menu to attach the debugger to the running iOS app.
This works. I can set breakpoints in either the watch kit InterfaceController or in my iOS app and the debugger breaks there when it should.
However, I'm not seeing NSLog() statements in the debug console from my iOS app. (I do see log statements from the WatchKit extension code.) If I set a breakpoint in my iOS app, it does stop at that breakpoint when it should. I assume the lack of console output from NSLog has SOMETHING to do with attaching to a running process on the sim rather than launching it from Xcode, but I don't know what that something is.
(BTW, attaching an action to a breakpoint that invokes NSLog from the breakpoint also doesn't display, but the "log message" debugger command DOES display.
Does anybody have any insights?)
EDIT:
The code in the iOS app doesn't seem to matter. In my case, it was a dirt simple IBAction that was attached to a button in the iOS app storyboard:
- (IBAction)buttonAction:(UIButton *)sender;
{
NSLog(#"Button clicked on iPhone");
}
I can set a breakpoint on that NSLog statement. The debugger stops at that line, but I don't see the log statement in the debug console.
I can reproduce that with a simple test app, sans WatchKit. The app consists of a NSTimer that prints "Timer fired" every second. (This code is 100% correct ;). Nothing shows in the log after I have manually attached to the process.
As far as I know NSLog outputs to stderr, I guess attaching the debugger does not redirect stderr to the Xcode terminal.
If you are okay with using the console app or the terminal to look at your logs you can do that. iOS8 stores simulator logs in ~/Library/Logs/CoreSimulator/<Device-UUID>. In this directory you will find a system.log, which contains all your NSLog output.
You can look at it in terminal (cat, grep, tail), or open it in the Console.app.
Apple confirms that (at least for GDB) in Technical Note TN2239: iOS Debugging Magic.
Console Output
Many programs, and indeed many system frameworks, print debugging
messages to stderr. The destination for this output is ultimately
controlled by the program: it can redirect stderr to whatever
destination it chooses. However, in most cases a program does not
redirect stderr, so the output goes to the default destination
inherited by the program from its launch environment. This is
typically one of the following:
If you launch a GUI application as it would be launched by a normal
user, the system redirects any messages printed on stderr to the
system log. You can view these messages using the techniques described
earlier.
If you run a program from within Xcode, you can see its
stderr output in Xcode's debugger Console window (choose the Console
menu item from the Run menu to see this window).
Attaching to a
running program (using Xcode's Attach to Process menu, or the attach
command in GDB) does not automatically connect the program's stderr to
your GDB window. You can do this from within GDB using the trick
described in the "Seeing stdout and stderr After Attaching" section of
Technical Note TN2030, 'GDB for MacsBug Veterans'.
The mentioned TN2030 is no longer available on their server (mirror). It showed how you can redirect stdout and stderr to the Xcode console. However, since shell tty isn't a valid command for LLDB it won't help much. But maybe there is a different way to access the tty Xcodes console uses, so I attach the important part of that TN.
Seeing stdout and stderr After Attaching
If you attach GDB to a process (as opposed to starting the process
from within GDB), you won't be able to see anything that the process
prints to stdout or stderr. Programs launched by the Finder typically
have stdout and stderr connected to "/dev/console", so the information
they print goes to the console. You can view this by launching the
Console application (in the Utilities folder), however, it's
inconvenient to have to look in a separate window. Another alternative
is to connect the process's stdout or stderr to the terminal device
for GDB's Terminal window. Listing 9 shows how to do this.
Listing 9. Connecting stdout and stderr to GDB's terminal device.
(gdb) attach 795
[... output omitted ...]
(gdb) call (void) DebugPrintMenuList()
No output )-:
Close the stdout and stderr file descriptors.
(gdb) call (void) close(1)
(gdb) call (void) close(2)
Determine the name of the terminal device for GDB itself.
(gdb) shell tty
/dev/ttyp1
Reopen stdout and stderr, but connected to GDB's terminal.
The function results should be 1 and 2; if not, something
is horribly wrong.
(gdb) call (int) open("/dev/ttyp1", 2, 0)
$1 = 1
(gdb) call (int) open("/dev/ttyp1", 2, 0)
$2 = 2
Try the DebugPrintMenuList again.
(gdb) call (void) DebugPrintMenuList()
Yay output!
Index MenuRef ID Title
----- ---------- ---- -----
<regular menus>
00001 0x767725D3 -21629 Ed
00002 0x76772627 1128 <Apple>
00003 0x767726CF 1129 File
00004 0x76772567 1130 Edit
[... remaining output omitted ...]
To add onto Filipp Keks answer, here's a visual representation of a much much simpler way to do it than the accepted answer.
From Filipp Keks's answer:
Plug in the device and open Xcode
Choose Window -> Devices from the menu bar
Under the DEVICES section in the left column, choose the device
To see the device console, click the up-triangle at the bottom left of the right hand panel
Click the down arrow on the bottom right to save the console as a file"
This screenshot was taken in Xcode 7.3.1 of the Devices window.
With Xcode Version 7.2 and iOS 9.2 etc, I found the following works:
Kill both the phone app and watch apps
Select the Watch Extension Target and hit Cmd+R (build and run)
Select the Phone target and hit Ctrl+Cmd+R (Run without building)
In my case, I have both apps up in their simulators and get NSLog output for both. I don't need to attach separately. Hope this helps.
https://developer.apple.com/library/ios/qa/qa1747/_index.html
Plug in the device and open Xcode
Choose Window -> Devices from the menu bar
Under the DEVICES section in the left column, choose the device
To see the device console, click the up-triangle at the bottom left of the right hand panel
Click the down arrow on the bottom right to save the console as a file
When your Provisioning profile is set to AdHoc or Distribution then Xcode doesnot show log, you need set development to view log
This might not solve showing up NSLog messages, but it might be helpful when debugging app started in background.
You can use the breakpoint feature that allows you to log messages.
The idea is to:
Create a breakpoint with "Automatically continue after evaluating actions" checked
add "Log message" action (you can also use expressions and print out values, for example: "Log message #variable#")
Attach debugger using anticipated process name (XCode will wait for the process to start)
Trigger app start.
Credits and details:
https://fluffy.es/how-to-debug-app-which-got-launched-push-notification/
In my case a set Automatically to see NSLog, before don't show at all
I came to this question, via this one (Xcode console empty after attaching to process) which is now closed.
My issue is that the debug console in Xcode is showing nothing (just an empty white box).
The solution for me is a tiny toggle at the bottom which changes between "variable view" and the actual debug console.