| # Recording a Session Communications Log | |
| This document explains how to record a session communications log from a | |
| running Dart Analysis Server (DAS) process. | |
| ## What is a session communications log? | |
| A session communications log records all communications (requests, responses, | |
| and notifications) between a client (such as VS Code or IntelliJ / Android | |
| Studio) and DAS. | |
| These logs are particularly helpful when: | |
| * reporting or diagnosing bugs in the analysis server, | |
| * capturing a sequence of editor actions (e.g. code completion, refactorings, | |
| diagnostics) for reproduction, | |
| * providing test cases for SDK developers to replay sessions and verify fixes. | |
| There are two ways to record a session communications log: | |
| 1. [Interactively via the Analyzer Insights web page](#record-via-the-analyzer-insights-web-page) | |
| (recommended for capturing specific editor interactions). | |
| 2. [At startup via the `--session-log` command-line option](#record-via-the---session-log-command-line-option) | |
| (captures all communications from the moment the server launches). | |
| ## Record via the Analyzer Insights web page | |
| The Analyzer Insights website served by DAS includes a **Session communications | |
| log** page. Even before you click "Start capturing", the server maintains a | |
| small in-memory cache of critical startup messages (initialization requests, | |
| workspace configurations, and opened documents). When you start capturing, | |
| subsequent editor interactions are added to the buffer, ensuring the resulting | |
| log contains the context needed to reproduce the session. | |
| 1. Open the Analyzer Insights pages in your browser (see | |
| [Open the analyzer insights (diagnostics) pages](instrumentation.md#open-the-analyzer-insights-diagnostics-pages)). | |
| 2. In the left-hand navigation menu of the insights page, select **Session | |
| communications log**. | |
| 3. When you are ready to perform the actions you wish to record, click the | |
| **Start capturing entries** button. | |
| 4. Switch to your editor and reproduce the issue or perform the workflow (for | |
| example, triggering code completion, typing code, applying a quick fix, or | |
| renaming a symbol). | |
| 5. Return to the browser page and click **Stop capturing entries**. | |
| 6. Click **Download** to save the log as a JSON file, or click | |
| **Copy to Clipboard** to copy the log contents and paste into a | |
| .json file. | |
| 7. Attach the file to your issue report. | |
| ## Record via the `--session-log` command-line option | |
| If you need to record every communication from server startup (or cannot use the | |
| web UI), you can pass the `--session-log` flag to DAS. The server will stream | |
| log entries line-by-line to the specified file on disk. | |
| ### VS Code | |
| 1. Open your VS Code settings (`Preferences: Open User Settings (JSON)` or | |
| `Preferences: Open Workspace Settings (JSON)`). | |
| 2. Add the `--session-log` option to `dart.analyzerAdditionalArgs`: | |
| ```json | |
| "dart.analyzerAdditionalArgs": [ | |
| "--session-log=/path/to/session_log.json" | |
| ] | |
| ``` | |
| 3. Restart the analysis server by opening the command palette and running | |
| **Dart: Restart Analysis Server**. | |
| 4. Perform the actions you want to capture. | |
| 5. When done, remove the argument from your settings and restart the server | |
| again so the log file stops growing. | |
| ### IntelliJ IDEA / Android Studio | |
| 1. Click **Help** > **Find Action**, type "Registry" and open **Registry...**. | |
| 2. Find the property `dart.server.additional.arguments`. | |
| 3. Add `--session-log=/path/to/session_log.json` to the property's value | |
| (separated from any other arguments by a space). | |
| 4. In the **Dart Analysis** window, click the **Restart Dart Analysis Server** | |
| button. | |
| 5. When finished recording, remove the argument from the registry property and | |
| restart the server. | |
| ### Direct server execution | |
| When running the analysis server or language server directly from the command | |
| line: | |
| ```bash | |
| dart language-server --protocol=lsp --session-log=/path/to/session_log.json | |
| ``` | |
| ## Log format | |
| The recorded file contains line-delimited JSON (JSON Lines format, often saved | |
| as `.json` or `.txt`). Each line is an independent, self-contained JSON object | |
| representing a single event: | |
| - `time`: Milliseconds since epoch when the event occurred. | |
| - `kind`: The type of event (e.g., `commandLine` or `message`). | |
| - `sender`: The source process (e.g., `ide`, `server`, `watcher`, or `dtd`). | |
| - `receiver`: The destination process. | |
| - `message`: The JSON-RPC payload sent between the processes. | |
| ## Inspecting request latencies in the log | |
| You can evaluate the duration of any request/response interaction directly from | |
| the log: | |
| 1. Find the client request line (where `"sender": "ide"` and `"receiver": "server"`). | |
| Note its `"id"` and its timestamp (`"time"` or `"clientRequestTime"` within | |
| `"message"`). | |
| 2. Find the corresponding server response line with the matching `"id"` (where | |
| `"sender": "server"` and `"receiver": "ide"`). | |
| 3. The round-trip duration is the difference: | |
| `response.time - request.time` (or `response.time - request.message.clientRequestTime`). | |
| > [!NOTE] | |
| > **Cold start vs. warm server**: When an IDE first opens a workspace, the | |
| > server initializes and analyzes files in the background (tracked via | |
| > `$/progress` notifications). Requests sent before initial analysis finishes | |
| > will wait in the server's queue, so their response time includes initial | |
| > workspace analysis. Subsequent requests executed once the server is idle | |
| > reflect actual handler computation time. | |
| ## Privacy and path anonymization | |
| Recorded session logs contain file paths on your machine (e.g. | |
| `/Users/$USER/...`) as well as file contents for documents opened or edited | |
| during the session. | |
| If you are sharing a log file publicly (such as on the Dart SDK issue tracker): | |
| 1. Review the log file to ensure it does not include sensitive or proprietary | |
| source code. | |
| 2. You can normalize machine-specific paths into generic placeholders | |
| (`{{workspaceFolder-0}}`, `{{dartSdkRoot}}`, etc.) using `normalize.dart`: | |
| ```bash | |
| dart pkg/analysis_server/tool/log_player/normalize.dart \ | |
| -i /path/to/session_log.json \ | |
| -o /path/to/normalized_log.json \ | |
| -r /path/to/workspace/root | |
| ``` | |
| ## Next steps | |
| Once you have recorded a log file: | |
| 1. Attach the file to your Dart SDK or IDE extension issue report. | |
| 2. SDK contributors can normalize, replay, and profile the log using the tools | |
| in [`pkg/analysis_server/tool/log_player`](../tool/log_player/README.md). |