Cocoa 如何将nslog输出重定向到文件而不是控制台
我在OSX上运行了cocoa应用程序。我使用了NSLog进行调试。现在我想将日志语句重定向到文件而不是控制台 我使用过这种方法,但它会导致在控制台和文件中进行日志记录Cocoa 如何将nslog输出重定向到文件而不是控制台,cocoa,xcode,macos,nslog,Cocoa,Xcode,Macos,Nslog,我在OSX上运行了cocoa应用程序。我使用了NSLog进行调试。现在我想将日志语句重定向到文件而不是控制台 我使用过这种方法,但它会导致在控制台和文件中进行日志记录 - (BOOL)redirectNSLog { // Create log file [@"" writeToFile:@"/NSLog.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil]; id fileHandle = [NSFile
- (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;
}
是否可以在控制台中不包含log语句,而只包含在文件中???
NSLog
用于登录控制台。您需要定义自己的函数MyLog
或其他任何函数,并将所有出现的NSLog
替换为MyLog
步骤1:在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);
}
步骤2:在函数ApplicationIDFinishLaunchingWithOptions开始时调用此函数
就是这样,每个NSLog()现在都会被重定向到这个console.log文件,您可以在documents目录中找到它。您可能会感兴趣。它是一个非常灵活的日志框架,适用于Mac OS X和iOS。一条日志语句不仅可以发送到控制台,还可以同时发送到文件。另外,它实际上比NSLog更快。我在一个项目中使用了它,该项目对OSX和iOS都有相同的代码。最近我遇到了类似的要求,我就是这样做的
- (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);
}
现在如果你想把这个控制台给用户
-(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;
}
}
我确实定义了我的函数,并用我定义的函数替换了NSLog。但我仍然在Cosole应用程序和我创建的日志文件中看到了日志。我喜欢为日志定义自己的函数。确认文件创建工作正常。我已经测试了这段代码,它是有效的。链接的代码将文件写入根目录,我将其更改为本地主目录。肯定是比我的更好的答案:)将
cStringWithEncoding:NSASCII…
更改为fileSystemRepresentation
。人们可以在路径中使用非ASCII字母(这在~/Documents/
上不太可能),太棒了!它也适用于iOS应用程序。您将在如下目录中找到console.log:/Users/Fernando/Library/Application Support/iPhone Simulator/6.1/Applications/18FB521C-A782-44E4-9DFA-B963FD7DC44B/Documents/console.log
谢谢:-)要关闭/停止在控制台中写入输出,请使用fflush(fileP);fclose(fileP)
要获取文件指针,请使用file*fileP=freopen([logPath..
在上面的方法中,并保留此指针。通过这种方式,您可以围绕对此输出文件的特定流/nslog调用进行包装。您能解释一下为什么流来自strwhy,而不是freopen中的stdout吗?谢谢dbainbridge。我对我的应用程序使用相同的框架。CocoaLumberjack是否重定向nslog?我搜索了它的code base没有freopen的迹象。我想没有。最好用CoCoalLumberJack的正确DDLog*语句替换NSLog。CoCoalLumberJack也使用GCD,因此比简单地用另一种方法替换NSLog要快得多。这正是我快速调试所需的:-)您可以使用tail-f console.log
runtime查看日志,或者使用tail-f console.log|grep“xxx”