rwadurian/backend/mpc-system/services/service-party-android/DEBUG_LOG_GUIDE.md

399 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Android 应用调试日志抓取指南
## 当前日志配置分析
### ✅ 已有日志点
应用在关键位置使用 `android.util.Log` 记录日志:
| 日志标签 | 位置 | 日志内容 |
|---------|------|---------|
| `MainViewModel` | 所有 ViewModel 操作 | 会话创建、参与者加入、TSS进度、异常 |
| `TssRepository` | 所有 Repository 操作 | gRPC调用、TSS native调用、数据库操作 |
| `GrpcClient` | 网络通信 | gRPC连接、请求/响应、错误 |
| `TssNativeBridge` | TSS原生库 | 密钥生成、签名、错误 |
### 📋 关键日志内容
#### 1. 会话创建创建2-of-3钱包
```
MainViewModel: Creating new session: walletName=xxx, t=2, n=3
MainViewModel: Session created: sessionId=xxx, inviteCode=xxx
MainViewModel: Session status fetched: X participants already joined
MainViewModel: Participants: [partyId1, partyId2, ...]
```
#### 2. 密钥生成触发
```
MainViewModel: Session started event for keygen initiator, triggering keygen
MainViewModel: Starting keygen as initiator: sessionId=xxx, t=2, n=3
TssRepository: Starting keygen as initiator
TssNativeBridge: keygenAsInitiator called
```
#### 3. 异常捕获safeLaunch
```
MainViewModel: Caught exception in safeLaunch
[Stack trace...]
```
---
## 🔍 日志抓取命令
### 方案 1: 实时日志(推荐用于复现问题)
```bash
# 清除旧日志
adb logcat -c
# 实时查看所有应用日志(带时间戳)
adb logcat -v time | grep -E "MainViewModel|TssRepository|GrpcClient|TssNativeBridge|AndroidRuntime"
```
### 方案 2: 过滤关键标签(快速定位)
```bash
# 只看应用相关日志
adb logcat MainViewModel:D TssRepository:D GrpcClient:D TssNativeBridge:D AndroidRuntime:E *:S
```
### 方案 3: 保存完整日志到文件
```bash
# 清除旧日志
adb logcat -c
# 重现问题创建2-of-3钱包
# 保存日志到文件
adb logcat -d -v time > android_debug.log
```
---
## 🎯 重点关注的日志
### 创建 2-of-3 钱包失败时需要看到:
#### ✅ 必须有的日志(正常流程)
1. **会话创建请求**:
```
MainViewModel: Creating new session: walletName=测试钱包, t=2, n=3, participantName=xxx
```
2. **会话创建成功**:
```
MainViewModel: Session created successfully
MainViewModel: sessionId: xxxxxxxx
MainViewModel: inviteCode: ABCD1234
```
3. **获取会话状态**:
```
MainViewModel: Session status fetched: 2 participants already joined
MainViewModel: Participants: [party-id-1, party-id-2]
```
4. **收到 session_started 事件**:
```
MainViewModel: === MainViewModel received session event ===
MainViewModel: eventType: session_started
MainViewModel: sessionId: xxxxxxxx
```
5. **触发密钥生成**:
```
MainViewModel: Session started event for keygen initiator, triggering keygen
MainViewModel: Starting keygen as initiator: sessionId=xxx, t=2, n=3
```
6. **TSS 原生库调用**:
```
TssNativeBridge: keygenAsInitiator called with sessionId=xxx
TssNativeBridge: Keygen completed successfully
```
7. **进度更新**:
```
MainViewModel: Progress update: 1 / 9
MainViewModel: Progress update: 2 / 9
...
MainViewModel: Progress update: 9 / 9
```
#### ❌ 可能出现的错误日志
1. **safeLaunch 捕获的异常**:
```
MainViewModel: Caught exception in safeLaunch
java.net.SocketTimeoutException: timeout
at ...
```
2. **gRPC 连接失败**:
```
GrpcClient: Failed to connect to server
GrpcClient: Error: UNAVAILABLE: io exception
```
3. **TSS 原生库错误**:
```
TssNativeBridge: keygenAsInitiator failed: [error message]
```
4. **会话创建失败**:
```
MainViewModel: Service check failed
TssRepository: Failed to create session: [error message]
```
---
## 🚨 关键问题检查点
### 1. 检查 safeLaunch 是否吞掉了异常
搜索日志中的:
```
"Caught exception in safeLaunch"
```
如果有这行,说明异常被捕获了,查看后续的堆栈跟踪。
### 2. 检查是否有 Result.failure 未处理
搜索:
```
"onFailure"
"Failed to"
"Error:"
```
### 3. 检查 session_started 事件是否触发
搜索:
```
"Session started event for keygen initiator"
```
如果**没有这行**,说明事件回调没有触发,密钥生成没有启动。
### 4. 检查参与者计数
搜索:
```
"Session status fetched: X participants"
```
如果参与者数量 < thresholdT例如 2-of-3 需要至少2个参与者会话不会启动
---
## 📊 日志分析流程图
```
启动应用
[搜索] "Service check"
├─ 成功 → 继续
└─ 失败 → 检查数据库/网络/原生库错误
点击"创建钱包"
[搜索] "Creating new session"
├─ 有 → 继续
└─ 无 → UI事件未触发前端问题
[搜索] "Session created successfully"
├─ 有 → 继续
└─ 无 → 检查 gRPC 错误或 "onFailure"
[搜索] "Session status fetched: X participants"
├─ 有 → 检查参与者数量是否 >= thresholdT
└─ 无 → getSessionStatus 调用失败
[搜索] "Session started event"
├─ 有 → 继续
└─ 无 → WebSocket 事件未收到(服务器问题)
[搜索] "Starting keygen as initiator"
├─ 有 → 继续
└─ 无 → safeLaunch 内部异常(搜索 "Caught exception"
[搜索] "keygenAsInitiator called"
├─ 有 → 检查 "Keygen completed" 或 TSS错误
└─ 无 → 原生库调用未执行
[搜索] "Progress update"
├─ 有 → TSS 正在进行,检查是否完成
└─ 无 → TSS 未启动或卡住
[搜索] "Keygen completed successfully"
├─ 有 → 成功!
└─ 无 → 检查 TSS 错误日志
```
---
## 🛠️ 调试建议
### 如果看到 "Caught exception in safeLaunch"
**原因**: safeLaunch 捕获了异常但可能没有正确显示给用户
**临时解决方案**: 查看异常堆栈找到根本原因
**示例**:
```
MainViewModel: Caught exception in safeLaunch
java.net.SocketTimeoutException: timeout
at okhttp3.internal.connection.RealCall.execute
at ...
```
说明 gRPC 连接超时
### 如果没有 "Session started event"
**原因**: WebSocket 事件回调未触发
**可能问题**:
1. service-party 服务器未运行
2. WebSocket 连接断开
3. 服务器未广播 session_started 事件
4. 参与者数量不足< thresholdT
**检查**:
```bash
# 检查服务器日志
tail -f /path/to/service-party/logs/server.log
```
### 如果有 "Session started event" 但没有 "Starting keygen"
**原因**: safeLaunch 内部的 startKeygenAsInitiator 调用失败
**检查**:
- 搜索 "Caught exception in safeLaunch"
- 查看异常类型和堆栈
---
## 📝 日志模板(复制给我)
抓取日志后请提供以下信息
```
### 1. 操作步骤
- [ ] 启动应用
- [ ] 点击"创建钱包"
- [ ] 输入钱包名称: ___
- [ ] 选择 2-of-3
- [ ] 输入参与者名称: ___
- [ ] 点击"创建"
- [ ] 【描述具体现象】: ___
### 2. 关键日志片段
#### 会话创建
```
[粘贴包含 "Creating new session" 的日志]
```
#### 会话状态
```
[粘贴包含 "Session status fetched" 的日志]
```
#### 事件触发
```
[粘贴包含 "Session started event" 的日志]
```
#### 异常(如果有)
```
[粘贴包含 "Caught exception" 的日志]
```
### 3. 完整日志文件
[附件: android_debug.log]
```
---
## 🔧 临时调试增强(如需更详细日志)
如果标准日志不够详细可以临时添加更多日志
### 在 MainViewModel.kt 的 safeLaunch 中:
```kotlin
private fun safeLaunch(
onError: ((Exception) -> Unit)? = null,
block: suspend CoroutineScope.() -> Unit
) = viewModelScope.launch {
try {
android.util.Log.d("MainViewModel", "safeLaunch: Starting block") // 添加这行
block()
android.util.Log.d("MainViewModel", "safeLaunch: Block completed successfully") // 添加这行
} catch (e: CancellationException) {
android.util.Log.d("MainViewModel", "safeLaunch: CancellationException caught") // 添加这行
throw e
} catch (e: Exception) {
android.util.Log.e("MainViewModel", "safeLaunch: Caught exception: ${e.javaClass.simpleName}", e)
// ... 现有代码 ...
}
}
```
---
## ⚠️ 常见陷阱
### 1. 异常被吞掉但 UI 不显示错误
**症状**: 操作无反应没有错误提示
**原因**: safeLaunch 更新了 _uiState.error UI 没有订阅
**检查**: 搜索日志中的 "Caught exception"看是否有异常但 UI 没反应
### 2. Result.failure 未正确处理
**症状**: repository 返回 failure ViewModel 没有处理
**检查**: 搜索 "onFailure" "result.fold"
### 3. 协程被取消
**症状**: 操作执行到一半停止
**检查**: 搜索 "CancellationException"
---
## 📱 完整抓取命令(复制粘贴)
```bash
# 1. 清除旧日志
adb logcat -c
# 2. 开始记录(在另一个终端)
adb logcat -v time > ~/Desktop/android_debug_$(date +%Y%m%d_%H%M%S).log
# 3. 操作应用(重现问题)
# 4. 停止记录Ctrl+C
# 5. 发送日志文件给我
```
或者一步到位操作完后手动停止
```bash
adb logcat -c && adb logcat -v time | tee android_debug.log | grep --color -E "MainViewModel|TssRepository|GrpcClient|TssNativeBridge|Exception|Error"
```
---
**准备好后请执行上述命令重现创建2-of-3失败的问题然后把日志发给我**