34

Xcode's debugger console makes it easy to see any debugging messages my app sends out using NSLog(), but it always sticks a timestamp prefix on them:

2009-08-30 04:54:48.128 MyApp[94652:a0f] some log message
2009-08-30 04:54:50.647 MyApp[94652:a0f] another log message
...

I have no use for this prefix, and it takes up a lot of room. I have a feeling it is hard-coded into Apple's logging system, but just in case there is a solution out there:

Can I have the debugger console show me log messages without the timestamp prefix?

Something like this would be perfect:

some log message
another log message
...
Cœur
  • 37,241
  • 25
  • 195
  • 267
e.James
  • 116,942
  • 41
  • 177
  • 214

8 Answers8

27

NSLog() is what is doing that, not the debugger console.

The easiest way to avoid it is to not use NSLog at all. You could use fprintf(), but that is a pain in that it doesn't support %@ format types.

I generally write a function for this:

void MyLog(NSString *format, ...) {
    va_list args;
    va_start(args, format);
    NSString *formattedString = [[NSString alloc] initWithFormat: format
                                                  arguments: args];
    va_end(args);
    [[NSFileHandle fileHandleWithStandardOutput]
        writeData: [formattedString dataUsingEncoding: NSNEXTSTEPStringEncoding]];

}

Obviously, modify it to add a newline or use a shorter prefix, etc...

(Fixed the stray ctrl-b)

Paul Solt
  • 8,375
  • 5
  • 41
  • 46
bbum
  • 162,346
  • 23
  • 271
  • 359
  • 1
    I had to use `[NSFileHandle fileHandleWithStandardOutput]` to make it work, but it definitely did the trick. Thank you! – e.James Aug 30 '09 at 20:21
  • Sorry about that -- I hit ctrl-b in the middle of typing. Fixed. :) – bbum Sep 03 '09 at 19:53
  • `NSNEXTSTEPStringEncoding`? Not `NSUTF8StringEncoding`? – Peter Hosey Sep 03 '09 at 20:04
  • An anachronism; take your pick. I've found -- in the past -- that the NeXTSTEP encoding would spew fewer unprintable characters. But UTF8 support in the toolchain is much better these days. – bbum Feb 07 '10 at 17:19
  • @bbum : I've added that code, but when called (tried by replacing just one NSLog), it does not show anything in the console output, and no NSLog is anymore shown in the console... As if there were no NSlog or MyNSLog call. – Oliver Aug 14 '11 at 12:30
  • It is likely that stout is redirected somewhere in your process. Try fileHandleWithStandardError instead. iOS? – bbum Aug 14 '11 at 15:50
  • @bbum : that does the same. First NSlog is displayed, then nothing more when the MyLog is reached. Even not further NSLogs. Yes, iOS. I do not play with stout in my process. – Oliver Aug 14 '11 at 16:48
  • iOS might, though. I suspect that the mechanism via which NSLog() spews output has changed. Have a look in the console of the Devices panel in Xcode and see if the spew shows up there. If it does, then I'll need to revise my answer as the rules changed (as they sometimes do :) ). – bbum Aug 14 '11 at 18:05
  • @bbum : I'm running onto the simulator and I'm not ready to run on the device. – Oliver Aug 14 '11 at 18:17
  • The simulator may exhibit the same behavior; check the system console. – bbum Aug 14 '11 at 22:41
  • 1
    there's a `]` missing after `...StringEncoding]` – TKAB Oct 09 '13 at 07:16
13

Define a macro

#if __has_feature(objc_arc)
  #define MDLog(format, ...) CFShow((__bridge CFStringRef)[NSString stringWithFormat:format, ## __VA_ARGS__]);
#else
  #define MDLog(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]);
#endif

And use this macro in you code like

NSLog(@"some log message");
MDLog(@"some log message");

Here is the output of console

NSLog->2014-01-28 10:43:17.873 TestApp[452:60b] some log message
MDLog -> some log message


P.S.

If anyone wants Custom Logs which gives you more info like method name / line number etc. can download the open source MLog.h on GitHub.

Community
  • 1
  • 1
Inder Kumar Rathore
  • 39,458
  • 17
  • 135
  • 184
9

put in this one line code in your .pch file and you are done

#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);

notice the ## part

Abhinav Singh
  • 7,880
  • 1
  • 23
  • 33
  • Tried this, app crashed, with error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSPlaceholderString initWithFormat:locale:arguments:]: nil argument' *** First throw call stack: (0x30af2f83 0x3b36dccf 0x30af2ec5 0x3141013f 0x31410069 0x11ae7 0x1254b 0x6748d 0x3b855833 0x3b85581f 0x3b85c49f 0x30abd8a1 0x30abc175 0x30a26ebf 0x30a26ca3 0x35980663 0x3337314d 0x1e8d7 0xd8f0) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb) – HenryRootTwo Jul 31 '14 at 02:11
  • It worked for me, I use this in production code, seeing those upvotes it must have worked for them too, I am not sure why you got exception error and fairly speaking please don't tell me you expected to convey some message by simply pasting your error call stack,without context its gibberish but code is perfect – Abhinav Singh Jul 31 '14 at 15:06
  • I put the one line of code into my .pch file and hit run, and that's what I got.'Fraid I'm not in a position to tell which part of it may explain the crash. Is one of the calls to NSLog() is responsible? Happy to look at why, if that is the case. – HenryRootTwo Aug 01 '14 at 09:19
  • @carelesslyChoosy: a great one-liner, thanks very much. This deserves to be the selected answer. – MusiGenesis Aug 10 '15 at 03:14
7

A way to keep using NSLog in conjunction with bbum's answer is to use a preprocessor macro to redefine NSLog to your own function

#define USECUSTOMLOGS 1
#if USECUSTOMLOGS
#define NSLog MyLog
#endif

This will replace NSLog with MyLog on compile time. Basically you can keep using NSLog everywhere and it will still use your custom format for the console window. You can also change it back to use NSLog at anytime by changing the 1 to a 0.

Paul Solt
  • 8,375
  • 5
  • 41
  • 46
ColdLogic
  • 7,206
  • 1
  • 28
  • 46
5

ARC Version:

void NFLog(NSString *format, ...)
{
    va_list args;
    va_start(args, format);
    NSString *formattedString = [NSString stringWithFormat:format, args];
    formattedString = [formattedString stringByAppendingString:@"\n"];
    va_end(args);
    [[NSFileHandle fileHandleWithStandardOutput] writeData: [formattedString dataUsingEncoding: NSUTF8StringEncoding]];
}

update:

What I am doing is add this code to xxx-Prefix.pch then you can use it anywhere:

#define newLine         do { [(NSFileHandle*)[NSFileHandle fileHandleWithStandardOutput] writeData:[@"\n" dataUsingEncoding: NSUTF8StringEncoding]]; } while(0);
#define NFLog(args,...) do { [(NSFileHandle*)[NSFileHandle fileHandleWithStandardOutput] writeData:[[NSString stringWithFormat:args, ##__VA_ARGS__] dataUsingEncoding: NSUTF8StringEncoding]]; } while(0); newLine

and if you want NSLog back:

#define NFLog(args,...) NSLog(args,##__VA_ARGS__)
TONy.W
  • 1,948
  • 19
  • 10
  • You'd probably want to embed the code in a fake `do {} while(0)` snippet: `#define NFLog(args,...) do{ ...code... }while(0);` – marzapower Feb 05 '13 at 14:50
  • Since it has a semicolon in the middle, it can cause problems if used in code like this: `for (NSString* str in array) NFLog(str);` – marzapower Feb 05 '13 at 14:51
  • You're right, add fake do-while will be good. code is updated. – TONy.W Feb 14 '13 at 12:30
1

In the top left corner of the console window there is a pulldown menu that says All Output / Debugger Output / Target Output.

Select Target Output. It worked on my older versions of Xcode, but to be honest with you it doesn't with my current 4.3 version.

I hope this helps you.

JR

JackRabbit
  • 11
  • 3
1

This is way more easier than the suggested solutions. Using carelesslyChoosy's solution and adding a little bit more to make it log entries on release builds only you get the macro below. Just add this macro to your header or .pch file. This macro will show log entries when the DEBUG flag is enabled, on release builds you won't see log entries.

#ifdef DEBUG
#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#define Log(x, ...) NSLog(@"%s %d: " x, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define Log(x, ...)
#endif
larod
  • 435
  • 3
  • 11
1

Clean Log Macro

Here is a macro I've made for this purpose. It works exactly like NSLog but with just your text, no extra info


Macro (paste to your .h)

#define CLog(__string, ...) fprintf(stderr, "\n%s", [([NSString stringWithFormat:__string, ##__VA_ARGS__]) UTF8String])

Example use:

CLog(@"I am %i days and %i years old", 3, 7);

Logs:

I am 3 days and 7 years old

Community
  • 1
  • 1
Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195