Android Log系统介绍

前言

日志分析是开发的核心阶段之一,开发人员经常会遇到这样那样的问题,需要借助日志分析来解决。Bug日志有助于在开发阶段识别Android应用中的Bug。一旦应用发布到市场上,开发者(或者支持工程师)也要通过分析bug日志来解决问题。可见,日志系统在开发过程中非常重要。

目录

  1. Log系统介绍
    1.1日志类型
    1.2 log系统框架
    1.3 写日志流程
    1.4 读日志流程
    1.5 接口使用
    1.6 Logd介绍
    1.7 logcat介绍
  2. 常见问题
    2.1 系统资源占用
    2.2 log信息丢失
    2.3 log信息丢失解决思路
    2.4 log信息常用的指令

1、Android Log系统介绍

Android使用的是一个集中式日志系统来记录所有的日志,应用开发者可以编写自定义日志,也可以定义日志过滤器,来打印关键日志信息来反馈程序运行状况。例如 App 中常使用的 Log.d、Log.v 、log.i等,而在 Native 层会使用 ALOGD 打印日志。对于第三方添加的 C/C++ 应用程序来说,如果希望使用 Android 的日志系统,就需要添加 liblog 库。

1.1 日志类型

在Android生态系统中有不同类型的日志: 主日志、系统日志、事件日志和Radio日志。 这四种日志分别对应着Linux内核中有四个不同的日志缓冲区。
主日志:用于应用程序,使用android.util.Log打印,设备节点/dev/log/main
Android系统日志:用于系统,使用android.util.Slog打印,设备节点dev/log/system
Events日志:用于系统事件信息,二进制格式,使用android.util.EventLog打印,设备节点/dev/log/event
Radio日志:用于电话相关信息,设备节点/dev/log/radio

1.2 log系统框架

包括一个日志写入的过程,和一个日志读取的过程。其中涉及到的几个主要的对象:log.d()、logcat、logd、liblog.so
Log.d :封装在 android.jar里,java层的使用接口
logcat:system/core/logcat,log的客户端
liblog : system/core/liblog,navtive接口库
logd : system/core/logd,log系统的服务
在这里插入图片描述

1.3 写日志流程

应用中通过android.jar调用接口,填入想要打印的日志内容。通过JNI调用到native层libandroid_runtime.so,并通过liblog.so库,最终通过dev/socket/logdw将日志写入logd的buff内
在这里插入图片描述

1.4 读日志流程

Android提供了logcat工具来实现对日志的读取。主要过程为先读入 logdr 中传入的客户端参数,然后把之前 LogBuffer 中的日志通过 flushto,最终通过 socket 的 sendDatav() 写给 logcat。
logcat 作为读取的客户端是需要先对日志进行格式解析,并拼接为命令行可见的字符串,因此有了 processBuffer 的过程。同时 logcat 打印日志超过了文件大小限制,就需要调用 rotateLogs 函数去建立新的文件。
在这里插入图片描述

1.5 接口使用

java层

Android 应用层提供日志系统的 Java 接口:Log.java、Rlog.java、Slog.java、EventLog.java。其功能类似只是写入 logd 的日志节点不同。Java 接口封装在 android.jar 中,作为 SDK 提供给开发者使用,在运行时通过 libandroid_runtime.so 中的 JNI 接口调用系统 native api;
使用方式实例如下:
在这里插入图片描述
Log的打印结果如下:
在这里插入图片描述

Native层

log系统的接口封装在Liblog.so库中供Nativie层使用,主要是封装了 logd 访问的 socket 接口。 Liblog.so最终是通过 socket 通信的方式,完成客户端日志写入 logd;
Native层的使用方式如下:
1)mk文件里引入库
在这里插入图片描述

2)C/C++程序使用
在这里插入图片描述

1.6 Logd介绍

Log系统的服务进程,开机时由 init 进程启动,属于守护进程常驻后台。logd 内部维护了四个 RAM buffer 用作日志的缓存,各个进程的日志都会写入这些缓存中。同时可以通过用户的控制参数指令,来管理日志内容的输入输出。 logd 对外维护了 3 个 socket API来与客户端进行通信 ,分别对应着读、写、控制功能。分别为:
dev/socket/logd : 用于传输控制指令
dev/socket/logw : 用于写日志
dev/socket/logr : 用于读日志

Logd系统框图

logd 进程启动后,分别启动 LogReader、LogListener、CommandListener 三个线程,监听并处理来自三个 socket 的消息。在收到消息后,会通过 LogBuffer 类保存日志到对应的 RAM buffer 中;
LogAudit 模块用于接收 Kernel selinux 信息,即可以在用户空间打印 selinux 日志信息;
LogKlog 用于接收 kernel 日志信息,通过设置 property ,可以通过 logcat 命令读取内核日志;
LogStatistics 是日志统计模块,默认开启统计数据较少,仅能以 pid/uid 纬度统计打印日志的数量。如果设置了 logd.statistic = true 。会打印更多纬度的统计信息,包括哪些 pid/uid/tid/TAG 日志量比较大,可用于日志裁剪相关
在这里插入图片描述

1.7 logcat介绍

logcat 作为读取日志的工具,相当于logd的client端,在用户使用log系统的过程中扮演着重要的角色;通过这个client完成log日志的收集,可以控制日志的输出格式等。
Log等级
目前Android系统log等级大致分为7类,V :详细,D:调试,I:信息,W:警告,E:错误,F:严重错误, S :静默。可以通过系统属性来控制系统的log输出等级:setprop persist.log.tag V
在这里插入图片描述
命令简介:
我们经常使用logcat指令来抓取日志,协助我们分析问题,logcat的指令格式:logcat [options] [fileterspecs] ;
常用的logcat指令有:
adb logcat –b all > log.txt
adb logcat –c
Adb logcat –G 8m
在这里插入图片描述
日志统计功能:
随着芯片功能愈发强大,车载android项目上新增的功能和服务也越来越多,导致系统里的日志量经常处于失控状态,非常影响系统的性能。
Log系统还提供了一个日志统计的功能,可以使用adb logcat –S进行统计查看,核心是-S 参数设置了printStatistics 标志位为 true,logcat 通过 /dev/socket/logd 向logd发送请求,打印LogStatistics模块存储的统计信息。
在设置 logd.statistics = true 的配置项后,可以打印出更多日志统计信息,包括pid/uid/tid/TAG 等统计维度的信息。
在这里插入图片描述

2. 常见问题

2.1 系统资源占用

打印日志是非常消耗资源的,原因可概括为:
① 跨进程通信的消耗:日志信息通过 socket 发送给 logd② 内存消耗:logd 中维持对应的 buffer。RAM 的消耗③ CPU 资源消耗:logd 中 ring buffer 会经常进行 pruneLogs 操作,删减日志,耗费CPU资源。④ IO 消耗:创建后台线程保存日志信息到文件里,这回导致应用或者整机卡顿

2.2 log信息丢失

经常有开发人员反馈有日志信息缺失的现象,主要是两个原因,日志量太多和logd折叠策略;
日志量太多:
导致日志读取速度<日志的写入速度,会有日志被清除掉。
logd的丢弃机制导致:
当系统log过多,打印不涣时会丢弃部分日志:
在这里插入图片描述
当某进程频繁打印相同日志时,也会丢弃部分日志:
在这里插入图片描述

2.3 log信息丢失解决思路

解决日志丢失方式,可以从以下几个方面入手:
1,系统各进程缩减log量;
2,禁用黑白名单机制,此方法适用log写入频率特别快,logd勉强能够处理;
3,利用黑白名单机制,适用log写入频率不是很快,但是还有很多log丢失
4,提高logcat的log打印等级
5,增大LogBuffer缓冲区大小

2.4 log信息常用的指令

adb shell dumpstate
查看手机系统当前状态信息(包含系统构建版本、网络相关、内存的使用、cpu的使用、进程等信息),需要root权限。
adb shell bugreport、 adb bugreport
输出过去系统的状态log,会打印出dmesg,dumpstate和dumpsys的输出。
adb shell dmesg
打印内核kernel的信息及日志,需要root权限。
adb shell dumpsys
获取并打印获取系统各项服务信息,可以在命令后面加指定的service name(比如activity,location),如果不加则默认打印出设备中所有service的信息。

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值