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. Git实战技巧:恢复被强制push -f失踪的代码

    前言 Git是一个易学难精的分布式版本控制系统,被我们码农常用于代码的管理.如果你还不了解Git,建议先通过廖雪峰的Git教程进行了解,再来看本文,因为本文以使用技巧为主,不会在基础名词上做过多解释. ...

  2. 程序是怎样跑起来的_第一章-对程序员来说CPU是什么

    通过对第一章的学习,我了解了大体上CPU可以说是电脑的"大脑",即中央处理器.从功能来看可以分为寄存器,控制器,运算器和时钟.在这四个部分中,寄存器是最值得程序员注意的.总的来说, ...

  3. pde复习笔记 第一章 波动方程 第三节 分离变量法

    教材 谷超豪<数学物理方程>第四版,虽然我们老师用的第三版,但是除了页码对不上,习题多了一点,也似乎没有多少区别. 打算开个新栏专门总结一下pde的各种计算问题,在图书馆算的手麻了,但是习 ...

  4. Linux基础-02:Linux目录操作命令

    Linux中目前可以识别的命令有上万条,如果没有分类,那么学习起来一定痛苦不堪. 所以我们把命令分门别类,主要是为了方便学习和记忆. 下面我们先来学习最为常用的和目录相关的操作命令 最近无意间获得一份 ...

  5. vue中render函数和h函数

    "render"函数是Vue组件的一个重要方法,它用于描述组件的视图结构,并负责渲染虚拟DOM树."render"函数是一个JavaScript函数,它接受一个 ...

  6. 网络安全—SSL安全访问应用

    文章目录 网络拓扑 部署CA服务器颁发证书 开启Web服务 安装IIS服务 修改Web默认网页 申请Web证书 前提准备 申请文件生成 申请web证书 开始安装web证书 客户机访问web默认网站 使 ...

  7. MATLAB txt文件抽稀并分为多个txt文件

    chouxi.m a = load("file.txt"); % len = length(a); interval = 9;%间隔+1 b = a(1:interval:end, ...

  8. IIS 部署 Python 环境

    1.安装IIS 勾选特殊CGI程序2.Python 环境 (环境变量配置)3.如果没有pip命令 先下载安装pip python setup.py install4.pip install wfast ...

  9. 上位机开发福利!快速掌握.NET中的Modbus通信

    安装nuget包 Wesky.Net.OpenTools  1.0.8或以上版本.支持.net framework 4.6以上版本,以及所有.net core以及以上版本引用. 开发一个简单的Winf ...

  10. php的下载与安装

    一,进入到php的官方网站   https://www.php.net/   ,进入到下载页面: 选择 PHP 7.2.30 的Windows版本 具体的下载页面版本区分: 下载后,得到如下压缩包到如 ...