我正在编写一个Mobilesubstrate调整来捕获在MobileSafari上执行特定任务所涉及的功能及其调用的时间戳。我创建了这个调整并将输出重定向到NSLog并看到了以下许多消息:
process 778 exceeded 500 log message per second limit - remaining messages this second discarded
当我使用自己的日志文件而不是NSLog时,MobileSafari花了太长时间才启动并被杀死。是否可以挂钩函数并记录其函数参数(基于c的函数的logify)和使用低开销方法调用的时间/数据?是否可以在iPhone(越狱)上使用自定义日志工具,并使用ASL库等可用方法?
编辑: 我试图通过创建一个NSOperationQueue,一个名为LoggingOperation的NSOperation并将该类直接嵌入Tweak.xm文件来解决这个问题。我相信这可以减轻主线程更新UI并完成启动MobileSafari。调整可以编译但是当函数被命中时,LoggingOperation没有写入文件,导致空日志文件:
//LoggingOperation.h
@interface LoggingOperation : NSOperation {
NSString *event;
}
@property(retain) NSString *Event;
- (id)initWithEvent:(NSString*)ev;
@end
在NSOperation实施中:
//LoggingOperation.m
@implementation LoggingOperation
@synthesize Event;
- (id)initWithEvent:(NSString*)ev;
{
if (![super init]) return nil;
[self setEvent:ev];
return self;
}
- (void)dealloc {
[Event release], Event = nil;
[super dealloc];
}
- (void)main {
NSString *serverError = event;
if (![[NSFileManager defaultManager] fileExistsAtPath:@"/var/mobile/mylog.log"])
{
NSString *statusFileName = [NSString stringWithFormat:@"/var/mobile/mylog.log"];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager createFileAtPath:statusFileName contents:nil attributes:nil];
}
serverError = [serverError stringByAppendingString:@"\n"];
NSString *serverFile = [NSString stringWithFormat:@"/var/mobile/mylog.log"];
NSData *serverText= [serverError dataUsingEncoding:NSUTF8StringEncoding];
NSFileHandle *serverFileHandle = [NSFileHandle fileHandleForUpdatingAtPath:serverFile];
if (serverFileHandle)
{
[serverFileHandle seekToEndOfFile];
// this NSLog output appears in syslog but serverText is not written to mylog
NSLog(@"WRITING TO THE LOG FILE!");
[serverFileHandle writeData:serverText];
[serverFileHandle closeFile];
}
}
@end
我还为每个挂钩方法创建了一个方便的方法来调用以创建日志:
void mylog(NSString* serverError)
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
LoggingOperation *op = [[LoggingOperation alloc] initWithEvent:serverError];
[queue addOperation:op];
[op release];
}
在方法钩子中:
CGRect replaced_CGRectIntegral (CGRect rect)
{
mylog(@"CGRectIntegral(rect)");
return o_CGRectIntegral(rect);
}
我想知道为什么我要写入NSOperation中的文件而文件是空的?
答案 0 :(得分:1)
我知道这不是您正在寻找的答案,但我建议您重新考虑您的日志记录并减少生成的日志语句数量。我会问你为什么要记录这些东西?他们真的告诉你一些重要的事吗?如果您确实需要它们用于调试会话 - 您如何设置以便任务仅执行一次以进行测试?
显然,在发布版本中,您不会启用此日志记录。
我见过人们在Java世界中编写自定义记录器来挂钩方法调用并记录它们及其所有参数。在每种情况下,由于产生了大量数据并且系统减速,因此浪费时间。当有针对性时,记录非常有用。它必须简明扼要,包含有用的信息,并且仅在有值得说的东西时生成。