您的位置:首页 > 移动开发 > IOS开发

iOS日志获取和实时浏览器显示日志

2016-06-17 12:15 686 查看


2016-06-16 07:20 编辑: yohunl 分类:iOS开发 来源:yohunl
投稿

13 1977

日志系统iOS动态展示日志

招聘信息:

C++开发工程师(cocos2d)
iOS中级开发工程师
资深iOS开发工程师
iOS高级开发工程师
Mac开发工程师
服务器端高级工程师
iOS手机软件开发工程师
iOS开发工程师(实习)
iOS Developer
Cocos2d-x游戏客户端开发
[苏州]前端+后端 资深开发工程师



投稿文章,作者:yohunl(微博

平时我们写代码的时候,为了调试方便,总是会在代码中写入很多的NSLog(也可能是其它的日志框架等,例如大名鼎鼎的CocoaLumberjack),但是我们对于NSLog到底了解多少?NSLog的信息为什么Xcode能够获取的到?我们能自己写个程序获取所有的NSlog么?NSLog写入的信息到底在哪里?

NSLog输出到哪?

我们都知道,NSLog是一个C函数,它的函数声明是

系统对其说明是:Logs an error message to the Apple System Log facility.,它是用来输出信息到标准的Error控制台上去.其内部其实是使用Apple System Log(ASL:苹果自己实现的输出日志的一套接口)的API.在iOS真机设备上,使用ASL记录的log被缓存在一个文件中,直到设备被重启。

这里提到的ASL,都是放在ash.h这个头文件中,这套api可以获取指定的日志数据,具体可以参考ASL参考

从上面可以直到,NSLog默认被系统输出到了一个文件中,这个文件是哪个呢?NSLog默认的输出到了系统的 /var/log/syslog这个文件中,当然了,如果你的机器没有越狱,你是查看不了这个文件的.我手机是越狱的,于是乎验证了下,使用iTools等工具将真机的/var/log/syslog文件导出,下面就是这个文件的部分内容的截取 log.png 从中,我们可以看到,所有的APP的NSLog全部都是写到这个文件中的!!!



标准的err控制台

我们现在了解到了NSLog就是输出到文件syslog中,既然要往文件中写,那么肯定就有文件的句柄了,这个文件的句柄是多少呢? 在C语言中,我们有三个默认的句柄

其对应的iOS系统层面的上述三个句柄其实也就是下面的三个

我们的NSLog输出的是到 STDERR_FILENO 上,我们可以使用c语言的输出到文件的fprintf来验证一下

在Xcode的控制台可以看到输出

由于fprintf并不会像NSLog那样,在内部调用ASL接口,所以只是单纯的输出信息,并没有添加日期,进程名,进程id等,也不会自动换行。

NSLog的重定向

既然NSLog是写到STDERR_FILENO中去的,那么根据Unix的知识,我们可以重定向这个文件,让NSLog直接写到文件中去

利用c语言的freopen函数,进行重定向,将写往stderr的内容重定向到我们制定的文件中去,一旦执行了上述代码,那么在这个之后的NSLog将不会在控制台显示了,会直接输出在文件mylog.log中! 在模拟器中,我们可以使用终端的tail命令(tail -f mylog.log)对这个文件进行实时查看,就如同我们在xcode的输出窗口中看到的那样,你还可以结合grep命令进行实时过滤查看,非常方便在大量的日志信息中迅速定位到我们要的日志信息



在真机中,这种重定向有什么用处呢? 由于重定向到的文件是我们沙盒中的文件,那么就可以在我们的程序中写一段代码将这个文件发送给我们,远程的用户app出了问题,把日志发送给我们,我们就可以根据日志信息,找寻可能的问题所在!

也可以开启app的文件夹itunse共享。

配置共享文件夹:

在应用程序的Info.plist文件中添加UIFileSharingEnabled键,并将键值设置为YES。将您希望共享的文件放在应用程序的Documents目录。一旦设备插入到用户计算机,iTunes 9.1就会在选中设备的Apps标签中显示一个File Sharing区域。此后,用户就可以向该目录添加文件或者将文件移动到桌面计算机中

就是说,一旦设备连接上电脑,可以通过iTune查看指定应用程序的共享文件夹,将文件拷贝到你的电脑上看

一般我们都会在应用中放置一个开关,开启或者关闭Log日志的重定向,在上面,我们使用标准C的freopen将stderr重定向到我们的文件中了,那么问题来了,怎么重定向回去呢???

要想重定向回去,那么我们需要知道stderr原来的文件路径,很遗憾,这个在不同平台中是不一样的,在iOS平台,由于沙盒机制,我们也并不能直接使用沙盒外的文件 对此,freopen将无能为力,要重定向回去,只能使用Unix的方法dup和dup2!

其它重定向STDERR_FILENO的方式集锦

方式一 采用dup2的重定向方式

(选自:http://lizaochengwen.iteye.com/blog/1476080)

使用的时候

就可以将NSLOg的输出重定向到我们的通知中去!!!

方式二 使用GCD的dispatch Source

使用的时候

记得,要自己保留返回的dispatchsourcet对象,不然其释放了,你就获取不到了!

ASL读取日志

以上的方式,都是重定向文件,一旦重定向后,那么NSLog就不会再写到系统的syslog中去了,也就意味着不能使用ASL接口获取到重定向后的数据了。

不重定向NSLog,怎么读取所有的log呢?

ASL读取log的核心代码

ASL的好处是没有重定向文件,所以不会影响Xcode等控制台的输出,它是一种非侵入式的读取的方式,类似于我们读取数据库的文件,我们只是读取数据,并没有将原来的数据库文件删除。

在app中内置一个小型的http web服务器

上面的方式,当测试,或者平时我们没有连接XCode时,想查看日志信息,还是不太方便,试想,如果我们在需要的时候,可以直接用浏览器查看输出的log信息那该多好?

结合上面的ASL和一个小型的web服务器,我们就可以实现了,

对于httpserver github上比较知名的有

CocoaHTTPServer,这个已经三年没更新了,不推荐使用 GCDWebServer 作者一直在维护,据说性能也不错,推荐使用这个,下面的demo也使用的这个

摘录其中的部分代码如下:

使用的时候,开启webserver服务,在同一个局域网下, 使用 http://机子的ip:8080来请求 演示2.gif



上述演示代码下载 TestLog

几个优秀的第三方日志框架

CocoaLumberjack

另一个日志替代品XLFacility,其中实现了本地存储,重定向,web服务等,是本demo的重要参考代码

CCLogSystem

ASL的swift版本的封装CleanroomASLswift

轻量级的iOS和mac上的http serverCocoaHTTPServer

轻量级的iOS和mac上的http serverGCDWebServer

参考

官方的ASL说明

freopen实现

read-log-messages-posted-to-the-device-console

readout-at-runtime-in-an-application

how-to-nslog-into-a-file
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: