Android日志系统(logging system)

背景

不管是做Android应用还是做Android中间层和底层,在做一些调试工作的时候,使用adb logcat非常关键。特意学习了一下安卓的log系统。

adb logcat -v time -b all

原文(有删改)出处不详。

参考文档:

概览

Android提供了一个灵活的logging系统,允许应用程序和系统组件等整个系统记录logging信息,它是独立于Linux Kernel的一个logging系统,kernel是通过”pr_info”、”printk”等存储,通过“dmesg”或“cat /proc/kmsg”获取。

不过,Android logging 系统也是将信息存在内核缓存区。

 

Logging system由如下几部分组成:

  • 实现loging信息存储的kernel驱动和缓存区
  • C,C++和Java 类添加与读取log
  • 一个单独浏览log信息的程序(logcat)
  • 能够查看和过滤来自主机的log信息(通过Android Studio 或者 DDMS)

其在kernel中为系统的不同部分提供了四个不同log缓存区,可以通过/dev/log查看这些不同的设备节点,如下:

  • /dev/log/mian : 主应用程序log,除了下三个外,其他用户空间log将写入此节点,包括System.out.print及System.erro.print等
  • /dev/log/events : 系统事件信息,二进制log信息将写入此节点,需要程序解析
  • /dev/log/radio : 射频通话相关信息,tag 为"HTC_RIL" "RILJ" "RILC" "RILD" "RIL" "AT" "GSM" "STK"的log信息将写入此节点
  • /dev/log/system : 低等级系统信息和debugging,为了防止mian缓存区溢出,而从中分离出来

log中的每条信息主要由四部分组成,如下:

  • Tag
  • 时间戳
  • log信息level(或者event的优先级)
  • log信息

Android logger

logging的kernel driver部分被称作”logger”,其为系统日志提供支持,代码路径: kernel/drivers/staging/android/logger.c,此文件对4种logging缓存区加以支持。

驱动

Log的读写是通过正常Linux文件读写方式完成的,write path被很好的优化过,所以能很快的open()、write()及close(),这样就避免了logging在系统中有太多的开销,影响速度。  

Reading

在用户空间,一个正常的read操作通常读取从log读取一个条目,每read一次返回一个log条目或者阻塞等待下一个log条目。设备可以打开非阻塞模式。每一个read请求应该至少请求LOGGER_ENTRY_MAX_LEN (4096)长度的数据。  

Writing

当系统写数据到log时,driver将为每一个log条目保存pid(进程ID),tgid(线程组ID),timestamp(时间戳),这些信息将出现在用户空间的level,tag和message中。  

Ioctl

Ioctl函数支持如下cmd:

  • LOGGER_GET_LOG_BUF_SIZE : log条目缓存区的大小

  • LOGGER_GET_LOG_LEN : log数据的长度

  • LOGGER_GET_NEXT_ENTRY_LEN: 下一log条目的大小

  • LOGGER_FLUSH_LOG : 清除log数据

  • LOGGER_GET_VERSION : 获得logger版本

  • LOGGER_GET_VERSION : 设置logger版本

设备节点

当一个用户空间执行的程序用合适的主设备号和次设备号打开设备节点后,设备节点就处于活动状态,这些设备节点如下:

root@msm8916_32:/ # ls -al dev/log
ls -al dev/log
crw-rw-rw- root log 10, 61 1970-01-09 02:14 events
crw-rw-rw- root log 10, 62 1970-01-09 02:14 main
crw-rw-rw- root log 10, 60 1970-01-09 02:14 radio
crw-rw-rw- root log 10, 59 1970-01-09 02:14 system

所有的log信息在Java类中定义并做相应处理,最终一个格式化的消息通过C/C++库传递到内核驱动程序,然后再将消息存储在适当的缓冲区中。

App log

App通过导入android.util.Log包来引入Log类,然后通过log方法写不同优先级的相关信息到log。

Java类定义传递到log方法的tag为字符串常量,log方法通过这些字符串来获知信息的重要性,这样,当我们用log查看工具(如logcat)时,就可以过滤tag或者优先级来获取我们想要的信息。如下:

root@msm8916_32:/ # logcat
logcat
--------- beginning of system
I/Vold ( 265): Vold 2.1 (the revenge) firing up
D/Vold ( 265): Volume sdcard1 state changing -1 (Initializing) -> 0 (No-Media)
D/Vold ( 265): Volume uicc0 state changing -1 (Initializing) -> 0 (No-Media) D/Vold ( 265): Volume usbotg state changing -1 (Initializing) -> 0 (No-Media) D/Vold ( 265): Volume uicc1 state changing -1 (Initializing) -> 0 (No-Media)
I/Cryptfs ( 265): Check if PFE is activated on Boot
E/Cryptfs ( 265): Bad magic for real block device /dev/block/bootdevice/by-name/userdata
E/Cryptfs ( 265): Error getting crypt footer and key
I/irsc_util( 316): irsc tool created:0xb70ff688
I/irsc_util( 316): Starting irsc tool
I/irsc_util( 316): Trying to open sec config file

Event log

Event logs是在android.util.EventLog.class中创建二进制log信息。

Log条目由二进制tag代码和二进制参数构成。

Event logs 文件存储在system/etc/event-log-tags中,通过cat system/etc/event-log-tags能查看其信息。

如下:

root@msm8916_32:/ # cat system/etc/event-log-tags
cat system/etc/event-log-tags
42 answer (to life the universe etc|3)
314 pi
1003 auditd (avc|3)
2718 e
2719 configuration_changed (config mask|1|5)
2720 sync (id|3),(event|1|5),(source|1|5),(account|1|5)
2721 cpu (total|1|6),(user|1|6),(system|1|6),(iowait|1|6),(irq|1|6),(softirq|1|6)
2722 battery_level (level|1|6),(voltage|1|1),(temperature|1|1)
2723 battery_status (status|1|5),(health|1|5),(present|1|5),(plugged|1|5),(technology|3)
2724 power_sleep_requested (wakeLocksCleared|1|1)
2725 power_screen_broadcast_send (wakelockCount|1|1)
2726 power_screen_broadcast_done (on|1|5),(broadcastDuration|2|3),(wakelockCount|1|1)
2727 power_screen_broadcast_stop (which|1|5),(wakelockCount|1|1)
2728 power_screen_state (offOrOn|1|5),(becauseOfUser|1|5),(totalTouchDownTime|2|3),(touchCycles|1|1)
2729 power_partial_wake_state (releasedorAcquired|1|5),(tag|3)
2730 battery_discharge (duration|2|3),(minLevel|1|6),(maxLevel|1|6)
2740 location_controller

System log

framework层的许多类通过使用system log 来与app的log信息区分开来。System log在android.util.Slog.clash中实现。

log命令行工具

log命令行工具能用来给任意程序穿件log条目,此工具是内建与toolbox的多功能程序。在adb shell中输入log则会提示其用法,如下:

C:\Users\Administrator>adb shell
root@msm8916_32:/ # log
log
USAGE: log [-p priorityChar] [-t tag] message
priorityChar should be one of:
v,d,i,w,e

toolbox: 具有管理内存、备份和数据清除功能的一个系统文件,用来对手机性能进行设置,需要root权限,能被软件调用。 

logwrapper

logwrapper工具是用来捕捉stdout信息的,当需要从本地应用捕捉stdout信息到log时,它将十分有用。

源码路径:system/core/logwrapper/logwrapper.c;用法如下:

root@msm8916_32:/ # logwrapper
logwrapper
Usage: logwrapper [-a] [-d] [-k] BINARY [ARGS ...] Forks and executes BINARY ARGS, redirecting stdout and stderr to
the Android logging system. Tag is set to BINARY, priority is
always LOG_INFO. -a: Causes logwrapper to do abbreviated logging.
This logs up to the first 4K and last 4K of the command
being run, and logs the output when the command exits
-d: Causes logwrapper to SIGSEGV when BINARY terminates
fault address is set to the status of wait()
-k: Causes logwrapper to log to the kernel log instead of
the Android system log

Logcat命令

我们可以通过logcat命令查看log,这个命令文件在文件系统的system/bin目录下,所以我们可以到文件系统中执行logcat,或者直接adb logcat,都能查看log。

  • 每一个有tag和优先级的log信息
  • 可以通过tag和log等级过滤log信息
  • 可以通过系统属性指定程序将stdout和stderr内容写入日志

在启动阶段默认打开Logcat

Android logging和kernel logging是完全不同的两种日志系统,另补充一点,kernel日志支持直接在用户空间向/dev/kmsg写入log条目。groups.google.com中介绍了如何在启动阶段launch Logcat,如下:

it can be launched via init.rc as below.. 

service logcat /system/bin/logcat -f /dev/kmsg
oneshot

不推荐这样做,这样会增加打印开销,使系统卡顿 

Android日志系统(logging system)的更多相关文章

  1. Android日志系统驱动程序Logger源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6595744 我们知道,在Android系统中, ...

  2. Android日志系统Logcat源代码简要分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6606957 在前面两篇文章Android日志系 ...

  3. Android应用程序框架层和系统运行库层日志系统源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6598703 在开发Android应用程序时,少 ...

  4. Android日志监听工具logcat命令详解(转)

    Android日志系统提供了记录和查看系统调试信息的功能.日志都是从各种软件和一些系统的缓冲区中记录下来的,缓冲区可以通过logcat命令来查看和使用. 在使用logcat之前,请确保手机的USB调试 ...

  5. ACE日志系统

    引用于:http://blog.csdn.net/focusonace/article/details/3108873 http://peirenlei.iteye.com/blog/305036 介 ...

  6. Android源码——Logger日志系统

    Android的Logger日志系统是基于内核中的Logger日志驱动程序实现的. 日志保存在内核空间中 缓冲区保存日志   分类方法:日志的类型  +   日志的输出量   日志类型:   main ...

  7. Android Logger日志系统

    文件夹 文件夹 前言 执行时库层日志库liblog 源代码分析 CC日志写入接口 Java日志写入接口 logcat工具分析 基础数据结构 初始化过程 日志记录的读取过程 前言 该篇文章是我的读书和实 ...

  8. 图解Android - System Service 概论 和 Android GUI 系统

    通过 图解Android - Binder 和 Service 一文中,我们已经分析了Binder 和 Service的工作原理.接下来,我们来简要分析Android 系统里面都有哪些重要的Servi ...

  9. 图解Android - Android GUI 系统 (5) - Android的Event Input System

    Android的用户输入处理 Android的用户输入系统获取用户按键(或模拟按键)输入,分发给特定的模块(Framework或应用程序)进行处理,它涉及到以下一些模块: Input Reader: ...

  10. Python logging日志系统

    写我小小的日志系统 配置logging有以下几种方式: 1)使用Python代码显式的创建loggers, handlers和formatters并分别调用它们的配置函数: 2)创建一个日志配置文件, ...

随机推荐

  1. VSCode+VUE+ESLint以达到保存自动格式化

    首先打开VSCode在.eslintrc.js中加入以下代码(不知道怎么找可以ctrl+shift+p进行搜索),添加 vscode 终端启动服务 // 添加⾃定义规则 'prettier/prett ...

  2. Mybatis的逆向工程(generator)

    Tips:Mybatis generator官网 http://www.mybatis.org/generator/configreference/commentGenerator.html Myba ...

  3. ffmpeg7.0常用命令笔记 windows下

    1.多媒体格式转换 ffmpeg -i input.mov -acodec copy -vcodec copy out.mp4 2.从多媒体文件中抽取音频 ffmpeg -i input.mov -v ...

  4. Data Lake_理解数据湖

    Pentaho首席技术官James Dixon创造了"数据湖"一词.它把数据集市描述成一瓶水(清洗过的,包装过的和结构化易于使用的).而数据湖更像是在自然状态下的水,数据流从源系统 ...

  5. docker多主机管理docker-machine

    docker-machine https://docs.docker.com/machine/ https://www.runoob.com/docker/docker-machine.html ht ...

  6. python 实现限流

    固定窗口 固定窗口就是记录一个固定的时间窗口内的操作次数,操作次数超过阈值则进行限流. def fix_window_limit(redis_obj, period, max_count): &quo ...

  7. .NET 基础知识 单文件部署和可执行文件 剪裁独立部署和可执行文件

    单文件部署和可执行文件 https://docs.microsoft.com/zh-cn/dotnet/core/deploying/single-file     剪裁独立部署和可执行文件 http ...

  8. 使用Docker安装Odoo 17(非Docker Compose)

    使用Docker安装Odoo 17(非Docker Compose) 前言 最近在学习Odoo,先是windows 安装企业版,多年不用windows的服务器操作系统,一看windows的ECS那么贵 ...

  9. 006. Gitlab组件介绍

    Gitlab组件 [root@master tools]# gitlab-ctl status #检查服务状态 run: gitaly: (pid 26704) 2201s; run: log: (p ...

  10. 容器化tomcat9.0

    #启动tomcat容器: docker run -d --name tomcat9.0 -p 8080:8080 registry.cn-hangzhou.aliyuncs.com/chenleile ...