logcat是Android开发中常用的一个日志工具.
日志对于一个项目来说是非常重要一环,是可以作为一个功能模块来定义的. 比如:详细的日志信息,可以帮助开发人员快速的分析和定位问题.
那么对于日志工具的使用必须要熟悉,日志的使用技巧也要熟悉.
通过对日志内容的过滤帮助研发分析和定位问题.
我的日志格式习惯:
public void function(){
Log.d("Class Name","function() ------>");
//TODO: your code at here!
Log.d("Class Name","function() <------");
}
从6个”-“,>和<这三个特征就可以直观的看书当前类执行了哪些函数,以及每个函数消耗的时间(在Android studio).
比如:直接在Android studio的过滤条件中连敲6个’-‘就直观的看出当前代码执行了哪些方法.
但是有时候代码是大家写的,有的同事可能有自己的偏好比如他的风格是这样:
public void function(){
Log.d("Class Name","function() >>>");
//TODO: your code at here!
Log.d("Class Name","function() <<<");
}
每个人习惯不同,谁都不能说服谁. 但是有时候维护的时候自己,那么这个时候就要考验自己的logcat能力.直接把日志导出到my.log文件慢慢看吧.
adb logcat -h //没有这个命令, 系统会给出一个命令列表.
logcat: invalid option -- h
Unrecognized Option
Usage: logcat [options] [filterspecs]
options include:
-s Set default filter to silent.
Like specifying filterspec '*:s'
-f Log to file. Default to stdout
-r [] Rotate log every kbytes. (16 if unspecified). Requires -f
-n <count> Sets max number of rotated logs to <count>, default 4
-v Sets the log print format, where is one of:
brief process tag thread raw time threadtime long
-c clear (flush) the entire log and exit
-d dump the log and then exit (don't block)
-t print only the most recent lines (implies -d)
-t ' <time>' print most recent lines since specified time (implies -d)
-T print only the most recent lines (does not imply -d)
-T ' <time>' print most recent lines since specified time (not imply -d)
count is pure numerical, time is 'MM-DD hh:mm:ss.mmm'
-g get the size of the log's ring buffer and exit
-b Request alternate ring buffer, 'main', 'system', 'radio',
'events', 'crash' or 'all'. Multiple -b parameters are
allowed and results are interleaved. The default is
-b main -b system -b crash.
-B output the log in binary.
-S output statistics.
-G <size> set size of log ring buffer, may suffix with K or M.
-p print prune white and ~black list. Service is specified as
UID, UID/PID or /PID. Weighed for quicker pruning if prefix
with ~, otherwise weighed for longevity if unadorned. All
other pruning activity is oldest first. Special case ~!
represents an automatic quicker pruning for the noisiest
UID as determined by the current statistics.
-P ' ...'
set prune white and ~black list, using same format as
printed above. Must be quoted.
filterspecs are a series of
[:priority]
where is a log component tag (or * for all) and priority is:
V Verbose
D Debug
I Info
W Warn
E Error
F Fatal
S Silent (supress all output)
'*' means '*:d' and by itself means :v
If not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.
If no filterspec is found, filter defaults to '*:I'
If not specified with -v, format is set from ANDROID_PRINTF_LOG
or defaults to "brief"
-s从使用说明上看就是根据TAG来过滤的,比如: “W/ContextImpl”, W就是日志的级别,”ContextImpl”就是TAG.
adb logcat -s "ContextImpl"
-v 格式化,brief process tag thread raw time threadtime long
adb logcat -v brief
adb logcat -v process
-t 打印最近的行
adb logcat -t 10 //最近10行
-t ‘MM-DD hh:mm:ss.mmm’
试过没成功,平时也需要这么用,没有研究。
adb logcat | grep "^E"
adb logcat | grep "-"
过滤包名
adb logcat | grep "^..[com.jingdong.app.mall]"
adb logcat | grep "^..[anti] \|^..[dalvik]"
adb logcat | grep "^..anti\|^..dalvik"
过滤出来包含”-“号并且是DEBUG级别的日志.
adb logcat | grep "^D.*-"
adb logcat | grep -i "^D.*-"
db logcat | grep "^.*HttpTaskRunner\|^.*-----\|^.*>>>\|^.*<<<"
db logcat | grep "^.*-----\|^.*>>>\|^.*<<<"
db logcat | grep "^.*-----\|^.*>>>\|^.*<<<" >D:\my.log
日志过滤文本框中是支持正则表达式的
|>>>|<<<|------
最广泛的使用场景大致有两个:
1.实现一个全局的日志工具类,通过变量设置支持输出日志到文件或者打印到控制台,便于随意查看和分析. 生产环境中甚至把一些非隐私性的日志输出的用户存储中,在合适的场景下把日志文件回传到服务器.
2.收到用户的反馈信息后,给用户提供一个携带日志的版本,通过这个特殊版本收集用户的app信息,然后分析定位用户的问题.
PS: 最好不要在生产环境使用第一种方式输出日志,很容易泄漏应用的信息,尽管我们可以在打包的时候把日志开关关掉,但是apk是可以解包,修改smali然后重新打包,这样会方便恶意分析人员从日志获取到有用信息.
比较安全的日志输出方法:
build.gradle中添加如下部分:
android {
buildTypes {
release {
buildConfigField "boolean", "APP_DEBUG", "true"
buildConfigField "String", "PLUGIN_VERSION", '"2.2.0"'
}
debug {
buildConfigField "boolean", "APP_DEBUG", "true"
buildConfigField "String", "PLUGIN_VERSION", '"2.2.0"'
}
}
}
然后查看app\build\generated\source\buildConfig\release\packagename\BuildConfig.java or app\build\generated\source\buildConfig\debug\packagename\BuildConfig.java
多了一个变量:
// Fields from build type: release
public static final boolean DD_DEBUG = true;
if (BuildConfig.DD_DEBUG) {
Log.d(TAG, "mothod() ------>");
}
//TODO: ....
if (BuildConfig.DD_DEBUG) {
Log.d(TAG, "mothod() <------");
}
把自己的代码反编译后对比一下: build.gradle
中 DD_DEBUG
分别设为false和true后的代码.