Files
claude-code-skills-reference/windows-remote-desktop-connection-doctor/references/windows_app_log_analysis.md
daymade e481958195 Release v1.32.0: Add windows-remote-desktop-connection-doctor skill
- Add windows-remote-desktop-connection-doctor v1.0.0 for diagnosing AVD/W365
  connection quality issues with transport protocol analysis and log parsing
- Update claude-md-progressive-disclosurer SKILL.md and references
- Update marketplace to v1.32.0 (37 skills)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 04:45:31 +08:00

208 lines
7.7 KiB
Markdown

# Windows App Log Analysis Guide
Detailed patterns for parsing Windows App (Microsoft Remote Desktop) diagnostic logs on macOS.
## Contents
- Log file locations
- Log file naming and rotation
- Startup health check block
- Transport negotiation entries
- Error signatures and their meaning
- Comparing working vs broken sessions
- Filtering noise from logs
## Log File Locations
### macOS
```
~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows App/
```
Files follow the pattern:
```
com.microsoft.rdc.macos_v<version>_<YYYY-MM-DD>_<HH-mm-ss>.log
```
A new log file is created each day or when the app restarts. Multiple files may exist — sort by modification time to find the most recent:
```bash
ls -lt ~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows\ App/
```
## Startup Health Check Block
When the Windows App launches, it runs a health check sequence. A healthy startup produces entries in this order:
```
Passed: InternetConnectivity
0: 1
4: 3
AvcDecodingCheck: 0
HardwarePresenterCheck: 0
AvcHwDecodingCheck: 1
4: 4
TCP/IP Traffic Routed Through VPN: No
STUN/TURN Traffic Routed Through VPN: Yes
```
Followed by gateway reachability tests:
```
Passed URL: https://afdfp-rdgateway-r1.wvd.microsoft.com/ Attempts Made: 1 Used Ipv4: 1 HTTP Status Code: 200 Response Time: 480
Passed URL: https://rdweb.wvd.microsoft.com/ Attempts Made: 1 Used Ipv4: 1 HTTP Status Code: 200 Response Time: 613
```
### What Each Entry Means
| Entry | Description |
|-------|-------------|
| `Passed: InternetConnectivity` | General internet reachability confirmed |
| `AvcDecodingCheck` / `AvcHwDecodingCheck` | Hardware video decoding capability (0=unavailable, 1=available) |
| `HardwarePresenterCheck` | Hardware presentation capability |
| `TCP/IP Traffic Routed Through VPN` | Whether the client detects a VPN intercepting TCP traffic |
| `STUN/TURN Traffic Routed Through VPN` | Whether the client detects a VPN intercepting STUN/TURN (UDP) traffic |
| `Passed URL: ...` | Gateway reachability test with response time in ms |
### When Health Check Fails
If the startup health check block is **completely absent** from a log, the diagnostic subsystem itself failed. Check for certificate validation errors near the log start:
```
DIAGNOSTICS(ERR): Failed to validate X509CertificateChain, certificate is not trusted.
BASIX_DCT(ERR): OSSLClosingException thrown, msg=Certificate validation failed
```
This indicates TLS interception (common with ISP HTTPS proxies in China) or DNS poisoning affecting Microsoft diagnostic endpoints.
## Transport Negotiation Entries
### FetchClientOptions
This is the critical function that retrieves transport capabilities from the gateway:
```
GATEWAY(ERR): CWVDTransport::FetchClientOptions exception when attempting to fetch client options: Request timed out
wvd_transport.cpp(521): FetchClientOptions()
```
When this times out, the client cannot discover available transport options (including Shortpath). The connection will fall back to WebSocket.
### ClientOptions Controller
A separate mechanism that refreshes client properties:
```
ClientOptions_Controller(ERR): ClientOptionsController RefreshProperties attempt 1 failed: Request timed out. Retrying in 30s...
client_options.cpp(214): RefreshProperties()
```
This is less critical than `FetchClientOptions` but indicates general connectivity issues to Microsoft configuration services.
### WebRTC Session
```
A3CORE(ERR): OnRDWebRTCRedirectorRpc rtcSession not handled
```
This appears when the server sends a WebRTC session setup but the client does not process it. This may indicate incomplete Shortpath support in the client version, or a session setup that arrives after fallback.
Note: `OnRDWebRTCRedirectorRpc notifyClipRectChanged not handled` is a benign clipboard-related message, not transport-related.
## Error Signatures
### Certificate Validation Failure
```
DIAGNOSTICS(ERR): Failed to validate X509CertificateChain, certificate is not trusted.
A3CORE(ERR): ITrustDelegateAdaptorPtr is empty.
BASIX_DCT(ERR): OSSLClosingException thrown, msg=Certificate validation failed, ossl error string="error:00000000:lib(0)::reason(0)", closing error code=1002
```
**Cause**: TLS certificate for Microsoft diagnostic endpoints is not trusted. Common with ISP HTTPS proxies/MITM, DNS poisoning, or corporate proxy servers.
**Impact**: Prevents the diagnostic health check from completing, which may block transport capability discovery.
### Channel Write Failures
```
"-legacy-"(ERR): Channel::StartWrite failed
```
Multiple consecutive `StartWrite failed` errors indicate a connection disruption — the WebSocket or TCP connection to the gateway was interrupted. This is typically followed by a reconnection attempt.
### Diagnostics Flush Errors
```
DIAGNOSTICS(ERR): FlushTracesInternal() is called before BeginUpload(). we don't have a claims token yet
```
This is a benign telemetry error — the diagnostics system tried to upload traces before authentication completed. Does NOT affect connection quality.
## Comparing Working vs Broken Sessions
The most effective diagnostic approach: compare a log from when the connection was healthy (UDP transport) with the current broken log.
### Quick Comparison Script
```bash
LOG_DIR=~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows\ App
echo "=== Health check and transport entries per log file ==="
for f in "$LOG_DIR"/*.log; do
echo ""
echo "--- $(basename "$f") ---"
grep -c "InternetConnectivity" "$f" 2>/dev/null | xargs -I{} echo " InternetConnectivity checks: {}"
grep "Routed Through VPN" "$f" 2>/dev/null | head -2 | sed 's/^/ /'
grep "Passed URL:" "$f" 2>/dev/null | head -2 | sed 's/^/ /'
grep "FetchClientOptions" "$f" 2>/dev/null | head -1 | sed 's/^/ /'
grep "Certificate validation failed" "$f" 2>/dev/null | head -1 | sed 's/^/ /'
done
```
### What to Compare
| Aspect | Working (UDP) | Broken (WebSocket) |
|--------|--------------|-------------------|
| Health check block | Present, complete | Missing or incomplete |
| `TCP/IP Routed Through VPN` | Present | Missing |
| `STUN/TURN Routed Through VPN` | Present | Missing |
| `Passed URL:` | Present with response times | Missing |
| `FetchClientOptions` | No error | Timeout error |
| Certificate errors | None at startup | Present at startup |
## Filtering Noise
Windows App logs contain many repetitive entries that obscure useful information. Filter these out:
```bash
grep -v -E "BasicStateManagement|DynVC.*SendChannelClose|dynvcstat.*SerializeToJson|asynctransport\.cpp|FlushTracesInternal"
```
### Common Noise Patterns
| Pattern | What It Is | Safe to Filter |
|---------|-----------|----------------|
| `~BasicStateManagement()` | Transport object destructor | Yes |
| `SendChannelClose()` | Dynamic virtual channel cleanup | Yes |
| `SerializeToJson()` | Channel stats serialization | Yes |
| `FlushTracesInternal()` | Telemetry upload attempt | Yes |
| `Stateful object ... destructed while in state Opened` | Abrupt connection close | Context-dependent |
The last pattern (`Stateful object destructed in Opened state`) may be significant during active troubleshooting — it indicates connections being torn down unexpectedly. Keep it when investigating disconnection events.
## Activity ID Tracking
Each RDP session gets a unique activity ID (GUID). Track a specific session through the log:
```bash
# Find activity IDs from connection events
grep -E "\{[0-9a-f]{8}-" "$LOG_FILE" | grep -v "00000000-0000-0000-0000-000000000000" | head -5
# Trace a specific session
grep "<activity-id>" "$LOG_FILE" | grep -v "BasicStateManagement\|FlushTraces"
```
The null GUID `{00000000-0000-0000-0000-000000000000}` indicates background/system events, not specific RDP sessions.