Unicorn
Unicorn

Reputation: 2422

How to redirect the nslog output to file instead of console

I have cocoa application running on OS X. I have used NSLog for debugging purpose. Now I want to redirect the log statements to file instead of console.

I have used this method but it results logging in Console as well as in file.

- (BOOL)redirectNSLog
{
    // Create log file
    [@"" writeToFile:@"/NSLog.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
    id fileHandle = [NSFileHandle fileHandleForWritingAtPath:@"/NSLog.txt"];
    if (!fileHandle)    return NSLog(@"Opening log failed"), NO;
    [fileHandle retain];

    // Redirect stderr
    int err = dup2([fileHandle fileDescriptor], STDERR_FILENO);
    if (!err)   return  NSLog(@"Couldn't redirect stderr"), NO;

    return  YES;
}

Is it possible to not have log statement in console but only in file ??

Upvotes: 19

Views: 20663

Answers (4)

user1227928
user1227928

Reputation: 829

Recently i have faced similar requirement and this is how i have done it.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.

    [self redirectConsoleLogToDocumentFolder];


    return YES;
}

- (void) redirectConsoleLogToDocumentFolder
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.txt"];
    freopen([logPath fileSystemRepresentation],"a+",stderr);
} 

And Now if you want to this console to user

-(void)displayLog{

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths firstObject];
    NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.txt"];

    NSError *err = nil;
    NSString *fileContents = [NSString stringWithContentsOfFile:logPath
                                                       encoding:NSUTF8StringEncoding
                                                          error:&err];
    if (fileContents == nil) {
        NSLog(@"Error reading %@: %@", logPath, err);
    } else {
        self.textView.text = fileContents;
    }

}

Upvotes: 12

dbainbridge
dbainbridge

Reputation: 1202

You may be interested in CocoaLumberjack. It is a very flexible logging framework for both Mac OS X and iOS. One logging statement can be sent not only to the console but to a file simultaneously. Plus it is actually faster then NSLog. I use it in a project that has common code for both OS X and iOS.

Upvotes: 3

user745098
user745098

Reputation:

Step 1: Include following function in AppDelegate:

 - (void) redirectConsoleLogToDocumentFolder
 {
       NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                     NSUserDomainMask, YES);
       NSString *documentsDirectory = [paths objectAtIndex:0];
       NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
       freopen([logPath fileSystemRepresentation],"a+",stderr);
 }

Step 2: Call this function at the start of function applicationDidFinishLaunchingWithOptions...

Thats it, Every NSLog() will now get redirected to this console.log file, which you can find in the documents directory.

Upvotes: 72

Yuji
Yuji

Reputation: 34195

NSLog is made to log into the console. You need to define your own function MyLog or whatever, and replace all occurrences of NSLog into MyLog.

Upvotes: -9

Related Questions