业务日志扩展
🥛 目前机制 Bugreport 抓取时默认不抓取业务扩展日志!!!
业务日志抓取支持的方式:
- 远程日志抓取(指定模块)
- 与用户反馈应用中模块绑定,当用户反馈此模块问题时捞取。
扩展日志接入到 Bugreport 介绍
业务扩展日志接入要求
- 业务需在应用中实现
ContentProvider#openFile(uri: Uri, mode: String)方法。 - 日志文件对应的 Uri path 固定为
/main;例如:content://com.example.logdemo.logprovider/main - ContentProvider
android:permission固定为:"com.mi.car.permission.READ_APP_LOG",此权限已在 CarService 中声明。 - 业务日志文件大小控制在 2M 以内。
- 业务方需使用 protobuf 压缩 Log,protobuf 可以去掉 log 中重复的 Metadata,极大的压缩数据。
- 业务进程启动和文件的生成控制在 1 秒内返回
ParcelFileDescriptor,避免系统卡。
2.1 用户反馈配置
应用实现扩展日志 ContentProvider 后需要通知用户反馈进行相关配置。需要提供的配置信息如下:
- ContentProvider
android:authorities - ContentProvider
android:singleUser
以上信息必须提供。相关配置可以联系:Haitao3 Liu 刘海涛、邓国涛。
LogProvider.java
class LogProvider : ContentProvider {
var mUriMatcher: UriMatcher
constructor() {
mUriMatcher = UriMatcher(UriMatcher.NO_MATCH)
mUriMatcher.addURI(AUTHRITY, LOG_MAIN_PATH, URL_MATCHED_MAIN_LOG_URI)
}
override fun onCreate(): Boolean {
return true
}
...........................
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? {
when (mUriMatcher.match(uri)) {
URL_MATCHED_MAIN_LOG_URI -> {
/**
* uri: content://com.example.logdemo.logprovider/main 约定不变
*/
val modeBits = ParcelFileDescriptor.parseMode("r")
/**
格式:建议使用 protobuf,剔除原数据,压缩
大小:2MB 以内
*/
var logFile = getLogFile()
return ParcelFileDescriptor.open(logFile, modeBits)
}
}
return super.openFile(uri, mode)
}
companion object {
/**
authrity 要求:
1. 格式建议:包名+.logprovider
2. 日志 contentProvider 的 uri authrity 必须和 com.android.car 中配置的应用的 authriry 一致。
*/
const val AUTHRITY = "com.example.logdemo.logprovider"
/**
uri path
应用扩展日志文件在 bugreport 中存放在 bugreport/app_logs.zip/包名/main 中。
注意:在 bugreport 中不会区分文件格式,会直接放到文件名为 main 的文件中。
*/
const val LOG_MAIN_PATH = "main"
const val URL_MATCHED_MAIN_LOG_URI = 1
}
}AndroidManifest.xml
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.LogDemo"
tools:targetApi="31">
....................
<!-- LogProvider 配置 -->
<provider
android:name=".LogProvider"
<!-- 配置权限,请将权限配置为:com.mi.car.permission.READ_APP_LOG -->
<!-- com.mi.car.permission.READ_APP_LOG 权限已经在 com.android.car 中声明, -->
<!-- 扩展日志 contentProvider 必须使用此权限 -->
android:permission="com.mi.car.permission.READ_APP_LOG"
android:authorities="com.example.logdemo.logprovider"
<!-- 可根据业务情况决定是否运行在 User0 中 -->
android:singleUser="false"
android:exported="true" />
</application>Bugreport 样例
📷 截图
📎 [附件: Bugreport 样例 zip — file_token: R7MAbe8Ciovrd1xcSLnc7REqn9f](下载 403,仅占位)
动态日志开关
统一业务详细日志开关,减少用户的操作成本。
开关通过 Android 原生的 log 机制,persist.log.tag.XXX 设置参数。
比如语音:
persist.log.tag.VoiceMainpersist.log.tag.VoiceWakeup
persist.log.tag.VoiceMain D // 打开 Debug
persist.log.tag.VoiceWakeup D // 打开 Debug统一的日志设置界面(位置:用户反馈 → 日志设置,暂定)。
📷 [图片: 统一日志设置界面 diagram (doxcn72QhU3oKAbiI3imNmQQZLc)]
关闭时机
- 3 天后自动关闭,进入 STR 时关闭(暂定)。
业务接入
通过 Android Log 标准接口判断 TAG 是否打开了业务 Debug 开关,Log.d 输出,即使系统级别是 I 也是可以输出。
Java 和 Native 都支持,下面是 Java 示例代码:
public class ActiveAppManager {
private static final String TAG = "VoiceMain";
public void setConfig(String value) {
if (Log.isLoggable(TAG, Log.DEBUG)) { // 性能比较好,建议用此方式
Log.d(TAG, "setConfig: " + value);
}
Log.d(TAG, "setConfig1: " + value); // 性能较差,Log 闭合时也会有字符串拼接
}
}业务登记
| 业务 | TAG |
|---|---|
| 语音 | VoiceMain / VoiceWakeup |
| 地图 | MapD |
| 手车互联 | ICT-PCD |
| 车家互联 | ICT-CHD |
| Wi-Fi | WifiD |
| 蓝牙 | BluetoothD |
📥 抓取自飞书 wiki 空间 7541192071952990209,obj_token: XJ5bdARVAoo5Dpx3cjCcXV1KnQd 🔗 日志系列:本系列为”日志”飞书父级节点的子页面