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. C语言程序设计-笔记9-函数与程序结构

    C语言程序设计-笔记9-函数与程序结构 例10-1    有序表的增删查操作.首先输入一个无重复元素的.从小到大排列的有序表,并在屏幕上显示以下菜单(编号和选项),用户可以反复对该有序表进行插入.删除 ...

  2. Util 应用框架 UI 全新升级

    Util UI 已经开发多年, 并在多家公司的项目使用. 不过一直以来, Util UI 存在一些缺陷, 始终未能解决. 最近几个月, Util 团队下定决心, 终于彻底解决了所有已知缺陷. Util ...

  3. 【Python Web】flask视频流

    这篇文档,完全借鉴miguelgrinberg的博客. https://blog.miguelgrinberg.com/post/flask-video-streaming-revisited 想看具 ...

  4. rubymineIDE配置启动

    debug启动 debug启动 安装插件 报错: 网络问题 下载 ruby-debug-ide-2.3.1 解压到 /home/haima/.rvm/gems/ruby-2.3.8/gems/

  5. ShareConnect即将寿终正寝 Splashtop远程桌面会是最好的替代品

    大家好,我是没有感情的翻译机器人,又见面了.同类产品ShareConnect即将退市,官方大大搞了个新闻稿.君叫臣翻,臣不得不翻.------没有感情的分割线------ShareConnect的使用 ...

  6. Chart.js (v2.9.4)--如何像高版本一样支持skipNull

    项目开发中,用到Chart.js展示图表,用起来也非常方便,配置很灵活,很好用,给个数据集,设置一些配置值,实例化一个Chart出来,图表就非常丝滑地展现出来了. 但是作为开发人员都知道的一个真理,永 ...

  7. Validate插件的自定义验证方法入门(结合Ajax实现用户名的数据库查重)

    概述 本文介绍Validate自定义表单校验方式.Validate插件虽然提供了丰富的验证规则,但在很多时候仍然很难满足我们的开发需求,在注册页面我们需要通过ajax验证用户输入的用户名是否已经被他人 ...

  8. Linux之SELinux

    1.什么是SELinux? 安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统. SELi ...

  9. zabbix笔记_005 zabbix自动发现

    自动发现 [消耗资源较大] 1.1 自动发现监控主机 自动发现的好处: 快速发现,并自动添加主机,省去管理员配置的麻烦. 管理简单高效 zabbix监控构建速度更高效 1.2 自动发现的原理 自动发现 ...

  10. 鼠标悬浮显示鼠标停留数据的内容 elementui + vue

    先看效果图 直接上代码 <el-tabs v-model="activeName" @tab-click="handleClick"> <el ...