如何在网页实时查看APP日志

5,503 阅读4分钟

写在前面

对于一个已经上线的APP,如果没有自己的Log系统。一旦线上出现问题,你就会收到各种领导微信的艾特,各种客户投诉。所以一套自己成熟的Log系统是至关重要的。本文重点还是说局域网下日志实时查看功能。

需求分析

输入

  • 支持文件写入和读取
  • 支持设置单个文件大小
  • 支持设置单个文件写入时间大小
  • 支持设置日志文件总数
  • 支持日志文件有效时间
  • 支持数据库写入和读取
  • 支持日志级别(Off、Error、Debug、Info、Verbose)
  • 支持自定义format
  • 支持控制台与console.app
  • 支持日志过滤

输出

  • 支持摇一摇日志文件分享
  • 支持局域网日志实时日志
  • 支持日志文件上传到服务器
  • 支持服务端对单个APP账号或deviceID做日志开关

系统架构

推荐方案

CocoaLumberjack,默认支持多个级别的日志输出,并可以灵活的扩展日志级别,日志format,日志过滤条件。默认支持日志文件大小,文件写入数量等等。满足了大部分需求。

功能实现

添加terminal输出

[DDLog addLogger:[DDTTYLogger sharedInstance]];

添加Apple system log

[DDLog addLogger:[DDASLLogger sharedInstance]];

使用系统版本macosx(10.4,10.12), ios(2.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0) ,用下面的代替。

[DDLog addLogger:[DDOSLogger sharedInstance]];

自定义format

自定义format需要创建一个类并遵循协议DDLogFormatter,然后实现方法。

@interface LogFormatter : NSObject<DDLogFormatter>

@end
@implementation LogFormatter

- (NSString * _Nullable)formatLogMessage:(nonnull DDLogMessage *)logMessage {
    return [NSString stringWithFormat:@"[%@]:%@ line:%@ ----%@",logMessage->_fileName,logMessage->_function,@(logMessage->_line),logMessage->_message];
}

@end

写入文件

    fileLogger = [[DDFileLogger alloc] init];
    fileLogger.maximumFileSize = 1024 * 1;  //  1kb 文件最大大小
    fileLogger.rollingFrequency = 60 * 1;       // 60 Seconds 单个文件最大写日志时间
    fileLogger.logFileManager.maximumNumberOfLogFiles = 4; //最大文件数
    [DDLog addLogger:fileLogger];

写入数据库

写入数据库需要实现自定义的Logger类,本文中使用的是官方demo的FMDBLogger

添加SQLiteLogger

    sqliteLogger = [[FMDBLogger alloc] initWithLogDirectory:logsDirectory];
    
    sqliteLogger.saveThreshold     = 500;               //当缓存到达阈值时写入
    sqliteLogger.saveInterval      = 60;               // 60 seconds 当缓存超过60秒时写入
    sqliteLogger.maxAge            = 60 * 60 * 24 * 7; //  最大保存时间
    sqliteLogger.deleteInterval    = 60 * 5;           //官方解释大概说,删除是一个很耗时的IO操作,所以设置一个时间间隔
    sqliteLogger.deleteOnEverySave = NO; 
    
    [DDLog addLogger:sqliteLogger];

局域网实时日志

大致步骤如下:

  • 基于websocket实现对日志的实时传输
  • 在APP中用js+HTML实现一个带websocket客户端的xxx.html文件
  • 在APP开启webserver,并设置xxx.html为root document
  • 在任何端用浏览器打开 http://yourIP:port,只需要浏览器支持websocket
  • APP当有websocket连接本地webserver 就拦截日志给JS的websocket客户端发送日志

HTML 代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,shrink-to-fit=no"><meta name="theme-color" content="#000000">
        <title>Live log</title>
        <script>
            var dpr,rem,docEl=document.documentElement,fontEl=document.createElement("style"),scale=(docEl.clientWidth/375).toFixed(2);dpr=window.devicePixelRatio||1,1.4<scale&&(scale=1),rem=12*scale,docEl.setAttribute("data-dpr",dpr),docEl.setAttribute("data-scale",scale),docEl.firstElementChild.appendChild(fontEl),fontEl.innerHTML="html{font-size:"+rem+"px!important;}"
            </script>
    </head>
    <body>
        <a id="openApp">打开浏览器审查元素,进入console界面</a>
        <script>
            var url = window.location.origin.replace("http","ws")+"/livelog";
            var ws = new WebSocket(url);
            ws.onclose = function (event) {
                console.log("ws close:",event.data);
            }
            ws.onerror = function (event) {
                console.log("ws error:",event.data);
            }
            ws.onmessage = function (event) {
                var data = event.data;
                console.log(data);
            }
            ws.onopen = function (event) {console.log("ws opened");}
            window.webs = ws;
            </script>

    </body>

</html>

摇一摇分享

由于涉及项目其他业务,所以只提供思路。

日志开关在摇一摇之后展示一个alert页面的上配置,一旦开关打开则开始记录日志并写入本地文件一种。在复现问题或捕捉到想要的日志后再次摇一摇选择对应的日志,使用UIDocumentInteractionController分享到微信和airdrop即可。 摇一摇分享适合在非正式下的配置日志开关,如果线上版本,可以通过下面的方式开始。

上传服务端

根据业务需求自行上传。

demo 地址

demo地址

参考

CocoaLumberjack

CocoaHTTPServer

总结

本文重点还是说局域网下日志实时查看功能: 无论在DEBUG模式下还是通过console.app都需要手机连接到MAC电脑来查看实时日志。还有一些在APP内部附带日志控件的方式,这种方式会APP的性能有一定影响,对测试结果也会有影响。所以个人觉得局域网下面再网页端直接查看APP实时日志即减少了日志控件的性能的影响,也可以对日志进行筛选、复制、导出等操作。因此个人觉得值得一试。

如果觉得好用点个star吧 Logger