App技术选型--Xlog

作者: 海南鸡 | 来源:发表于2018-08-14 11:51 被阅读56次

    title: App技术选型--日志框架--- **版 本 历 史**| **版本** | **责任人** | **日期** | **备注** ||----------|------------|------------|------------|| V1.0 | 曾维铭 | 2017-04-12 | 创建文档。 |日志对于开发来说是非常重要的,不管是调试数据查看、bug问题追踪定位、数据信息收集统计,日常工作运行维护等等,都大量的使用到。# 功能需求* 线程的信息* 类的信息* 方法的信息* 格式打印JSON、XML等* 点击链接跳转到源码打印处* 拥有默认TAG和自定义TAG* release包中不能泄漏Log* 使用友好,使用高效* 日志持久化到本地* 日志框架的扩展性# [Xlog](https://github.com/Tencent/mars/wiki/Mars-Android-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97)mars 是微信官方的终端基础组件,是一个使用C编写的业务性无关,平台性无关的基础组件。Xlog是mars中可以独立使用的日志模块。**优势:** * 性能好:使用了中间层,减少了读写磁盘的次数。使用mmap进行逻辑内存对磁盘文件进行映射,中间只是进行映射没有任何拷贝操作,避免了写文件的数据拷贝,操作内存就相当于在操作文件,避免了内核空间和用户空间的频繁切换。占用内存CPU资源少。* 功能丰富:与原生Log使用几乎一致,但增加了写入文件功能,同时自带加密* 稳定:腾讯微信团队正在使用,久经考验。**面临的问题:*** Xlog是用C写的,出问题调试起来不太友好。 * so库比较大,导入后APK增大1.5M。**解决方案:*** 只能通过 xlog 输出的信息进行排查。不过日志作为辅助系统,出问题可能性低,而且问题影响不大。* 如果很在乎APK包大小的话,可以只集成armeabi的so包。 # 持久化的实现为了提高日志的性能,Xlog引入了 mmap作为中间buff层,当buff层满足一定条件时,才将日志写到存储空间。# 日志存储位置初始化时,写在logPath中。logPath = Environment.getExternalStorageDirectory().getAbsolutePath()/sdcard/PhiComm/app name/logs# 日志文件命名APP名_日期# 日志格式一般内容:[日志级别][日期][PID][TAG(类名)][线程---日志内容]方法栈:[日志级别][日期][PID][TAG(类名)][线程---方法栈]# 日志使用策略每次启动时会删除过期文件,只保留十天内的日志文件(该值定义在appender.cc中的 kMaxLogAliveTime ),所以给 Xlog 的目录请使用单独目录,防止误删其他文件。目前不会根据文件大小进行清理。如若想自定义清理逻辑请自行更改appender.cc中的 __del_timeout_file 函数。 # 日志使用级别

    debugrelease

    控制台持久化控制台持久化

    v程序说明nullnull程序说明

    d需要调试的代码nullnullnull

    i程序正常运行时日志程序正常运行时日志null程序正常运行时日志

    w会出现潜在错误的情形会出现潜在错误的情形null会出现潜在错误的情形

    ecatch块中,程序状态检查语句catch块中,程序状态检查语句nullcatch块中,程序状态检查语句

    # 日志混淆问题类名,方法名等参数使用的是Java lang包下的StackTraceElement和Throwable获得。具体混淆策略需要在原型中测试后才能确定。# LogUtils由于Xlog提供的功能有限,为了满足使用需求,这里对Xlog进行了封装。实现的功能:* 支持打印字符串,集合,JSON,日志级别,日期,线程ID,线程名,异常信息,堆栈信息,源代码跳转。* 日志持久化到外部存储,自动清理过期日志,保存最近十天的日志文件。## 使用指南### 1.添加读写权限``````

    ### 2.在Application的onCreate中初始化

    初始化:

    ```

    LogUtils.init();

    ```

    **注:**

    1. 为了不造成混乱,这里初始化时不提供自定义配置。如日志默认TAG,保存路径,日志方法栈打印数量等在代码中写死。

    2. 根据BuildConfig.DEBUG参数,debug下会打印到控制台,release下控制台输出关闭。

    ### 3.打印日志

    ```

        public static void d(Object message)

        public static void d(Object message, boolean isPrStack)

        public static void d(String tag, Object message, boolean isPrStack) {

        public static void d(String tag,final String message, boolean isPrStack, final Object... args)

    public static void json(String json, boolean isPrStack)

    public static void log(int priority, String tag, Object message, boolean isPrStack, @Nullable Throwable throwable, Object...args)

    ```

    **注:**

    1. message为打印内容,可接收任意参数。

    2. isPrStack控制是否打印堆栈信息。

    3. 支持对日志字符串格式化,args为参数。内部会调用String.format(String format, Object args)。

    3. JSON输出的缩进默认为2,可自行修改。

    4. 打印异常信息可调用log,传入Throwable。

    5. 堆栈打印的方法数通过METHOD_CCOUNT控制,默认为8。可以自行修改(可能要考虑线程安全问题,不过影响也不大)。

    打印JSON结果

    ```

    [I][2017-04-20 +8.0 15:52:40.412][12502, 1*][PhiComm][, , 0][Thread:main---{

      "name": "BeJson",

      "url": "http:\/\/www.bejson.com",

      "page": 88,

      "isNonProfit": true,

      "address": {

        "street": "科技园路.",

        "city": "江苏苏州",

        "country": "中国"

      },

      "links": [

        {

          "name": "Google",

          "url": "http:\/\/www.google.com"

        },

        {

          "name": "Baidu",

          "url": "http:\/\/www.baidu.com"

        },

        {

          "name": "SoSo",

          "url": "http:\/\/www.SoSo.com"

        }

      ]

    }

    ```

    字符串,堆栈,Throwable打印结果

    ```

    [D][2017-04-20 +8.0 15:52:40.411][12502, 1*][Throw][, , 0][Thread:main---{i=zwm, love=joyce}

    VMStack.java/dalvik.system.VMStack/getThreadStackTrace/-2

    Thread.java/java.lang.Thread/getStackTrace/580

    LogUtils.java/com.example.weimingzeng.myapplication.LogUtils/getThreadStack/206

    LogUtils.java/com.example.weimingzeng.myapplication.LogUtils/log/232

    MainActivity.java/com.example.weimingzeng.myapplication.MainActivity/onCreate/31

    Activity.java/android.app.Activity/performCreate/6323

    Instrumentation.java/android.app.Instrumentation/callActivityOnCreate/1108

    ActivityThread.java/android.app.ActivityThread/performLaunchActivity/2385:java.lang.Throwable

    at com.example.weimingzeng.myapplication.MainActivity.onCreate(MainActivity.java:31)

    at android.app.Activity.performCreate(Activity.java:6323)

    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)

    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2385)

    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2492)

    at android.app.ActivityThread.access$900(ActivityThread.java:153)

    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1358)

    at android.os.Handler.dispatchMessage(Handler.java:102)

    at android.os.Looper.loop(Looper.java:148)

    at android.app.ActivityThread.main(ActivityThread.java:5458)

    ```

    在程序退出时反初始化:

    ```

    LogUtils.unLoad();

    ```

    ### 4.解析Log

    Log生成完毕后,会在指定的路径下生成相应的日志文件:

    ```

    shell@R7:/sdcard/marssample/log $ ll

    -rw-rw---- root    sdcard_r  153600 2016-12-30 17:06 MarsSample.mmap2

    -rw-rw---- root    sdcard_r    29633 2016-12-30 17:06 MarsSample_20161230.xlog

    ```

    由于使用缓存,日志只有在应用退出时才会将日志写入外部存储。其中MarsSample.mmap2是缓存文件,不用关心,我们需要的是.xlog文件,我们把这个文件pull出来,使用Mars提供的Python脚本进行解密。

    找到Mars源码log/crypt/decode_mars_log_file.py下的这个文件,用python执行,生成log文件:

    ```

    mars_xlog_sdk python decode_mars_log_file.py ~/Downloads/log/MarsSample_20161230.xlog

    ```

    相关文章

      网友评论

        本文标题:App技术选型--Xlog

        本文链接:https://www.haomeiwen.com/subject/jopiottx.html