Is it possible to log to a file on the iPhone (or get at the console output somehow) to read it later, or perhaps directly from the phone?
I need to debug an app that is using a cable-connected accessory device, so it cannot be connected to XCode at the same time.
You can make use of PonyDebugger.
I've been using it a lot to debug networking and CoreData resources, but it also allows logging to the console with PDLog.
PonyDebugger is a remote debugging toolset. It is a client library and gateway server combination that uses Chrome Developer Tools on your browser to debug your application's network traffic and managed object contexts.
Some recommendations:
It works better in Safari than Chrome.
Look into repo issues for making it work in your OSX version if needed. I have it working on El Capitan.
Automatic connection didn't work for me, try using local IP gateway address instead:
e.g. [debugger connectToURL:[NSURL URLWithString:#"ws://192.168.0.12:9000/device"]];
Kevin Xi's approach is OK. You can also redirect NSLog output to the file using following code in AppDelegate's didFinishLaunchingWithOptions method:
NSArray *allPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [allPaths objectAtIndex:0];
NSString *pathForLog = [documentsDirectory stringByAppendingPathComponent:#"log.txt"];
freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding],"a+", stderr);
It is really a pity that Apple doesn't provide WiFi debugging for Xcode, but for your question, the answer is YES, you can definitely redirect NSLog to a log file, you can try this approach:
// this will redirect all NSLog in your project, add it to PCH file.
#define NSLog(args...) writeLog(__PRETTY_FUNCTION__, __LINE__, args)
void writeLog(const char *function, int lineNumber, NSString *format, ...) {
// basic log content.
va_list ap;
va_start (ap, format);
NSString *msg = [[NSString alloc] initWithFormat:format arguments:ap];
va_end (ap);
// add function name, and line number.
NSString *log = [NSString stringWithFormat:#"%s line %d $ %#", function, lineNumber, msg];
// add your own code to write `log` into a text file.
....
}
Note: if you are using some libraries which also write logs to Console, this macro won't redirect those logs to your log file, it will only work with NSLog in your own source files.
As far as I know, this is not possible.
You can eventually use a free and excellent solution like bugfender which will allow you to get the data logged by NSLog remotely. This could help you.
Related
I am working on an iOS library project and need to create an API that takes an NSString parameter which is a path, and the library will write some debugging messages to a file in that path.
I've done some research about logging onto a file in iPhone's file system, one approach is using
freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
This will redirect any following NSLog to a file...
While this seems easy, I have a question: Will this also redirect the API consumer's application(calling application)'s NSLog to the file? I don't want this behavior because I want to be able to control what goes in there as a library..
If that is the behavior, what other approach I can use to achieve my requirement? Thanks.
If I understood correctly, the desired functionality is to pass a path and write some debugging info to a file on that path? If that is so, I don't think you should redirect all your NSLog calls to a file; just using the NSString writeToFile: would be enough:
-(void)writeToFile:(NSString*)path {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:path];
NSError *error=nil;
NSString *myMessage="This is the data to write to the file";
[myMessage writeToFile:fileName atomically:YES encoding:NSUTF8StringEncoding error:&error];
}
If you want to append to that file, you can use the NSFileHandle functionality - check the docs here.
I'm willing to put a bounty on this question. I already added one, but it expired without an answer to award it to. So if you know an answer, give me a hint and I will put another bounty on this.
If I understand things correctly, asl is used behind NSLog calls. So I read the man pages and used google and eventually got the impression, that I could add an extra file to collect logging output with asl_add_log_file (man page). As with other questions found using google, my output file is empty and no log messages appear there.
The usual solution so far seems to be to freopen the stderr to a file. I ran some tests and wanted to implement a trivial log rotation. When doing another freopen to a new file, some NSLog messages are lost. So I am looking for another solution.
To test it on Mac OS X, I created a console application in Xcode and added this code to main:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(#"docdir = %#", documentsDirectory);
NSString *fileName =[NSString stringWithFormat:#"asl-created-%#.log",[NSDate date]];
NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:fileName];
NSLog(#"logFilePath = %#", logFilePath);
int asl_fd = open([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], O_CREAT | O_APPEND);
if (asl_fd==-1) {
NSLog(#"could not open output file");
}
asl_object_t asl;
asl = asl_open(NULL, NULL, 0);
asl_add_log_file(asl, asl_fd);
NSLog(#"test output");
/* EDIT: added this */
NSLog(#"YEAH! test output");
asl_log(asl, NULL, ASL_LEVEL_ERR, "asl_log output");
aslmsg asl_msg = asl_new(ASL_TYPE_MSG);
asl_set(asl_msg, ASL_KEY_MSG, "asl test output");
asl_set(asl_msg, ASL_KEY_HOST, "somehost");
asl_send(asl, asl_msg);
asl_free(asl_msg);
/* (EDIT: added this) */
asl_remove_log_file(asl, asl_fd);
close(asl_fd);
EDIT: However, as mentioned, the log file is empty. I would have expected, that "test output" appears in there.
I added some asl log calls to test whether or not it works when using asl directly. The two messages logged via asl_log and asl_send do appear in the created file. However, the NSLog based log messages do not appear.
Is it possible to use asl_add_log_file to adjust the NSLog "backend"?
I would like to create a word document or a pdf of the NSLog output that I have running right now. Is there a way to do that simply or at all? I have googled the crap out of the issue and have been unable to find a result short of going into xcode and then organizer to find the output. I would prefer to not have to do that.
example:
NSLog(#"X: %.3f Y: %.3f", accelerometer.x, accelerometer.y);
//move this output straight into a word document or something of that nature that can then be pulled from the device later.
Thanks
You can write your NSLogs to a file using a method like this:
- (void)redirectNSLogToDocuments
{
NSArray *allPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [allPaths objectAtIndex:0];
NSString *pathForLog = [documentsDirectory stringByAppendingPathComponent:#"yourFile.txt"];
freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}
Then you can convert that file to whatever format you want.
How about this: https://github.com/robbiehanson/CocoaLumberjack
There's a built in file logger that outputs to txt files.
It also offers a lot more control over NSLog and you can easily stop logging without having to comment all the calls out
I actually ended up using CocoaLumberJack which will put it into a .txt document. Now to figure out a way to programmatically move the text file to my hd in linux. :(
I have a couple of NSLog statements in my app. In Xcode we can track NSLog() in console. When my client runs the app one of the label value is not displaying in UI. The problem is i am not able to replicate that issue at all.
Now i want the client to send log when he faces that issue. I know how to get crash logs. But i want the log which will have the result of all NSLog() statements when my client runs the app in his iPhone.
Hope my above problem is clear. Is there a way to get such logs?Any Suggestions guys?
Thanks.
Got a breakthrough!!. We need to re-direct NSLog to a file like this and then access the file.
- (void)redirectNSLogToDocumentFolder{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName =[NSString stringWithFormat:#"%#.log",[NSDate date]];
NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:fileName];
freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}
http://objcolumnist.com/2009/12/19/redirecting-nslog-to-a-log-file/
I've made a debug library that can be used to view your application logs from within. Also it has ability to send logs via email, so you can easily grab logs from your client. Hope this will help someone.
DVFloatingWindow
I got bored earlier and wondered if you could execute terminal commands on the iOS platform. Surely enough, just like OSX you can. This is really awesome, but how do I output what the terminal outputs to a text area or something similar? It's nothing serious, just a fun project.
I am using system("") to do it.
This, my friend is one of the downsides to using system. I also hope you understand that system is unavailable on a non-jailbroken iDevice, so unless you are installing it as instructed on the #1 answer on iPhone App Minus App Store, then you can't use it.
Now, moving forward, you have a few options.
Pipe the output of the command to a file, and read that file in your application. Your code should look something like this:
system("myCommand -f \"/path/to/my/file\" > output.txt")
NSString *results = [NSString stringWithContentsOfFile:#"output.txt" usedEncoding:nil error:nil];
NSLog(#"%#", results);
Create the process with the popen function, and then pipe the output directly into your application:
NSFileHandle *openProcessRead(const char *command)
{
FILE *fPtr = popen(command, "r");
NSFileHandle *fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileno(fPtr) closeOnDealloc:YES];
return fileHandle;
}
You can now use the NSFileHandle docs to do what you need.