5、Logcat 日志级别:Verbose、Debug、Info、Warn、Error、Assert 的使用场景
日志级别这东西,说白了就是给信息贴标签。
你想想看,开发阶段和线上阶段,我们关注的信息完全不一样。开发时恨不得把每个变量的变化都打出来,线上却只关心有没有崩溃。Logcat 的六个级别,就是帮我们做这件事的。
六个级别的核心定位
Android 定义了从低到高六个日志级别:
| 级别 | 常量值 | 含义 | 我常用的场景 |
|---|---|---|---|
| Verbose | 2 | 啰嗦模式 | 临时调试,用完就删 |
| Debug | 3 | 调试信息 | 开发阶段的关键流程 |
| Info | 4 | 普通信息 | 用户操作、状态切换 |
| Warn | 5 | 警告 | 潜在风险,但不影响运行 |
| Error | 6 | 错误 | 功能异常、崩溃前兆 |
| Assert | 7 | 断言失败 | 严重不可恢复的错误 |
嗯,这里要注意:Verbose 和 Debug 级别的日志,在 release 包中默认是不输出的。这不是玄学,是系统帮你过滤掉了。
Verbose:最啰嗦,也最危险
我个人习惯,Verbose 只用来打循环内的临时变量。比如一个列表加载了 100 条数据,我想看看每一条的 id 对不对。
Log.v("ListAdapter", "item position: " + position + ", id: " + item.getId());
这种日志,用完就删。千万别提交到版本库。我在项目中遇到过,同事把 Verbose 日志留在线上包,结果 Logcat 被刷爆,用户手机发热严重。嗯,那是一次惨痛的教训。
Debug:开发者的好帮手
Debug 级别是我用得最多的。它比 Verbose 收敛,但比 Info 详细。适合记录函数入口、出口、关键分支判断。
Log.d("LoginManager", "startLogin() called, userId=" + userId);
// ... 登录逻辑 ...
Log.d("LoginManager", "login success, token=" + token);
你想想看,如果线上出了问题,Debug 日志能帮你快速定位到是哪个环节挂了。但要注意,Debug 日志在 release 包中也是不输出的。所以别指望用它排查线上问题。
Info:用户看得懂的日志
Info 级别的日志,应该让非技术人员也能看懂。比如「用户登录成功」「文件下载完成」「页面加载完毕」。
Log.i("DownloadService", "文件下载完成,路径: " + filePath);
我个人习惯,Info 日志要写得像「事件记录」一样。不要写变量值,只写发生了什么。这样线上查问题时,扫一眼就能知道用户的操作路径。
Warn:温柔的提醒
Warn 表示「有问题,但还能跑」。比如网络超时后重试、缓存数据过期、配置项缺失使用默认值。
Log.w("ConfigManager", "配置项 'theme_color' 缺失,使用默认值 #FF6200EE");
我在项目中遇到过,某个第三方 SDK 返回的数据格式变了,但没崩溃,只是某些字段为空。这时候打 Warn 日志,既不会刷屏,又能提醒我们后续要适配。
Error:必须处理的异常
Error 意味着功能不可用。比如网络请求失败、数据库写入异常、权限被拒绝。
Log.e("NetworkClient", "请求 /api/user/info 失败,错误码: " + errorCode);
注意,Error 日志要包含足够的信息:发生了什么、在哪个模块、错误码是什么。不要只写一句「出错了」,那等于没写。
Assert:最后的防线
Assert 级别很少用,但它是最严重的。它表示「程序状态已经不可信了,继续运行只会更糟」。
Log.wtf("DataManager", "用户数据校验失败,uid=" + uid + ",数据已损坏");
Log.wtf() 是「What a Terrible Failure」的缩写。我一般只在数据完整性校验失败时用它。比如从本地数据库读出的用户余额是负数,这明显是 bug,应该直接抛异常。
如何选择正确的级别?
我总结了一个简单的判断方法:
- 这个日志,线上包需要看到吗? 不需要 → Verbose 或 Debug
- 用户操作是否正常完成? 是 → Info
- 有没有潜在风险? 有 → Warn
- 功能是否已经受损? 是 → Error
- 数据是否已经损坏? 是 → Assert
说白了,就是按「严重程度」往上走。别把 Info 当 Debug 用,也别把 Error 当 Warn 用。级别用错了,查日志时就会很痛苦。
实战中的过滤技巧
Logcat 支持按级别过滤。比如我只想看 Error 以上的日志:
adb logcat *:E
或者只看某个 tag 的 Warn 以上:
adb logcat MyApp:W *:S
这个 *:S 表示「其他所有 tag 都静默」。嗯,这个技巧很实用,我几乎每天都在用。
知识体系图
下面这张图,帮你理清六个级别的关系和使用场景:
从下往上看,Verbose 最常用但最不重要,Assert 最不常用但最重要。release 包中,只有 Info 及以上级别的日志才会输出。这个规则,你一定要记住。
好了,六个级别就讲到这里。记住一句话:用对级别,比写对日志内容更重要。级别错了,再详细的内容也是噪音。