Skip to content

Conversation

@award999
Copy link
Contributor

@award999 award999 commented Jul 3, 2025

  • Add winston dependency (MIT license) to handle logging setup
  • Have an LogOutputChannel to log user facing information, errors, warnings
  • Write a debug session logs under the provided logUri to capture further diagnostics when the lldb-dap.captureSessionLogs setting is enabled. Note the lldb-dap.log-path setting takes precedence when set
    Issue: LLDB-DAP extension should provide better logging to diagnose issues #146880

@award999
Copy link
Contributor Author

award999 commented Jul 3, 2025

This PR illustrates my proposal for issue #146880

@award999 award999 force-pushed the lldb-dap-ext-logging branch from 87be6e7 to 53e2d9d Compare July 22, 2025 12:59
@award999 award999 marked this pull request as ready for review July 22, 2025 17:27
@award999 award999 requested a review from JDevlieghere as a code owner July 22, 2025 17:27
@llvmbot
Copy link
Member

llvmbot commented Jul 22, 2025

@llvm/pr-subscribers-lldb

Author: None (award999)

Changes
  • Add winston dependency (MIT license) to handle logging setup
  • Have an OutputChannel to log user facing information, errors, warnings
  • Write a verose log under the provided logUri to capture further diagnostics
  • Introduce verboseLogging setting to increase OutputChannel verbosity and write DAP session logs

Issue: #146880


Patch is 29.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/146884.diff

7 Files Affected:

  • (modified) lldb/tools/lldb-dap/package-lock.json (+235-7)
  • (modified) lldb/tools/lldb-dap/package.json (+8-1)
  • (modified) lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts (+35-1)
  • (modified) lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts (+8-1)
  • (modified) lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts (+12-1)
  • (modified) lldb/tools/lldb-dap/src-ts/extension.ts (+15-6)
  • (added) lldb/tools/lldb-dap/src-ts/logger.ts (+90)
diff --git a/lldb/tools/lldb-dap/package-lock.json b/lldb/tools/lldb-dap/package-lock.json
index af90a9573aee6..f9f071ae7e41a 100644
--- a/lldb/tools/lldb-dap/package-lock.json
+++ b/lldb/tools/lldb-dap/package-lock.json
@@ -15,7 +15,9 @@
         "@vscode/vsce": "^3.2.2",
         "prettier": "^3.4.2",
         "prettier-plugin-curly": "^0.3.1",
-        "typescript": "^5.7.3"
+        "typescript": "^5.7.3",
+        "winston": "^3.17.0",
+        "winston-transport": "^4.9.0"
       },
       "engines": {
         "vscode": "^1.75.0"
@@ -318,6 +320,28 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@colors/colors": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
+      "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.1.90"
+      }
+    },
+    "node_modules/@dabh/diagnostics": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
+      "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "colorspace": "1.1.x",
+        "enabled": "2.0.x",
+        "kuler": "^2.0.0"
+      }
+    },
     "node_modules/@isaacs/cliui": {
       "version": "8.0.2",
       "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -399,6 +423,13 @@
         "undici-types": "~5.26.4"
       }
     },
+    "node_modules/@types/triple-beam": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
+      "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/@types/vscode": {
       "version": "1.75.0",
       "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.75.0.tgz",
@@ -642,6 +673,13 @@
       "dev": true,
       "license": "Python-2.0"
     },
+    "node_modules/async": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+      "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -858,6 +896,17 @@
         "node": ">=16"
       }
     },
+    "node_modules/color": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
+      "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^1.9.3",
+        "color-string": "^1.6.0"
+      }
+    },
     "node_modules/color-convert": {
       "version": "1.9.3",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -873,6 +922,28 @@
       "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
       "dev": true
     },
+    "node_modules/color-string": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+      "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
+    "node_modules/colorspace": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
+      "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "color": "^3.1.3",
+        "text-hex": "1.0.x"
+      }
+    },
     "node_modules/combined-stream": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -1114,6 +1185,13 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/enabled": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
+      "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/end-of-stream": {
       "version": "1.4.4",
       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -1207,6 +1285,20 @@
         "pend": "~1.2.0"
       }
     },
+    "node_modules/fecha": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
+      "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/fn.name": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
+      "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/foreground-child": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
@@ -1494,8 +1586,7 @@
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true,
-      "optional": true
+      "dev": true
     },
     "node_modules/ini": {
       "version": "1.3.8",
@@ -1504,6 +1595,13 @@
       "dev": true,
       "optional": true
     },
+    "node_modules/is-arrayish": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/is-docker": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
@@ -1530,6 +1628,19 @@
         "node": ">=8"
       }
     },
+    "node_modules/is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/is-wsl": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
@@ -1673,6 +1784,13 @@
         "prebuild-install": "^7.0.1"
       }
     },
+    "node_modules/kuler": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
+      "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/leven": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -1741,6 +1859,24 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/logform": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz",
+      "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@colors/colors": "1.6.0",
+        "@types/triple-beam": "^1.3.2",
+        "fecha": "^4.2.0",
+        "ms": "^2.1.1",
+        "safe-stable-stringify": "^2.3.1",
+        "triple-beam": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
     "node_modules/lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -1951,6 +2087,16 @@
         "wrappy": "1"
       }
     },
+    "node_modules/one-time": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
+      "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fn.name": "1.x.x"
+      }
+    },
     "node_modules/open": {
       "version": "8.4.2",
       "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
@@ -2200,7 +2346,6 @@
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
       "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
       "dev": true,
-      "optional": true,
       "dependencies": {
         "inherits": "^2.0.3",
         "string_decoder": "^1.1.1",
@@ -2230,6 +2375,16 @@
         }
       ]
     },
+    "node_modules/safe-stable-stringify": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+      "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/sax": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz",
@@ -2410,6 +2565,26 @@
         "simple-concat": "^1.0.0"
       }
     },
+    "node_modules/simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-arrayish": "^0.3.1"
+      }
+    },
+    "node_modules/stack-trace": {
+      "version": "0.0.10",
+      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/stoppable": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
@@ -2426,7 +2601,6 @@
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
       "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
       "dev": true,
-      "optional": true,
       "dependencies": {
         "safe-buffer": "~5.2.0"
       }
@@ -2587,6 +2761,13 @@
         "node": ">=6"
       }
     },
+    "node_modules/text-hex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
+      "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/tmp": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
@@ -2597,6 +2778,16 @@
         "node": ">=14.14"
       }
     },
+    "node_modules/triple-beam": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
+      "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 14.0.0"
+      }
+    },
     "node_modules/tslib": {
       "version": "2.8.1",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -2683,8 +2874,7 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
       "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
-      "dev": true,
-      "optional": true
+      "dev": true
     },
     "node_modules/uuid": {
       "version": "8.3.2",
@@ -2712,6 +2902,44 @@
         "node": ">= 8"
       }
     },
+    "node_modules/winston": {
+      "version": "3.17.0",
+      "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
+      "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@colors/colors": "^1.6.0",
+        "@dabh/diagnostics": "^2.0.2",
+        "async": "^3.2.3",
+        "is-stream": "^2.0.0",
+        "logform": "^2.7.0",
+        "one-time": "^1.0.0",
+        "readable-stream": "^3.4.0",
+        "safe-stable-stringify": "^2.3.1",
+        "stack-trace": "0.0.x",
+        "triple-beam": "^1.3.0",
+        "winston-transport": "^4.9.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/winston-transport": {
+      "version": "4.9.0",
+      "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz",
+      "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "logform": "^2.7.0",
+        "readable-stream": "^3.6.2",
+        "triple-beam": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
     "node_modules/wrap-ansi": {
       "version": "8.1.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 801abe73edd7d..fb49b430554e2 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -34,7 +34,9 @@
     "@vscode/vsce": "^3.2.2",
     "prettier": "^3.4.2",
     "prettier-plugin-curly": "^0.3.1",
-    "typescript": "^5.7.3"
+    "typescript": "^5.7.3",
+    "winston": "^3.17.0",
+    "winston-transport": "^4.9.0"
   },
   "activationEvents": [
     "onDebug",
@@ -110,6 +112,11 @@
             "additionalProperties": {
               "type": "string"
             }
+          },
+          "lldb-dap.verboseLogging": {
+            "type": "boolean",
+            "description": "Enable verbose logging to the \"LLDB-DAP\" output channel for the running debug session. Also will write LLDB-DAP session logs to the Extension's log folder if the `lldb-dap.log-path` setting is not explicitly set.",
+            "default": false
           }
         }
       },
diff --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
index b5db45b56d6a6..4c34fad817e9e 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts
@@ -5,6 +5,7 @@ import * as child_process from "child_process";
 import * as fs from "node:fs/promises";
 import { ConfigureButton, OpenSettingsButton } from "./ui/show-error-message";
 import { ErrorWithNotification } from "./ui/error-with-notification";
+import { Logger } from "./logger";
 
 const exec = util.promisify(child_process.execFile);
 
@@ -156,16 +157,34 @@ async function getDAPArguments(
     .get<string[]>("arguments", []);
 }
 
+/**
+ * Formats the given date as a string in the form "YYYYMMdd".
+ *
+ * @param date The date to format as a string.
+ * @returns The formatted date.
+ */
+function formatDate(date: Date): string {
+    const year = date.getFullYear().toString().padStart(4, "0");
+    const month = (date.getMonth() + 1).toString().padStart(2, "0");
+    const day = date.getDate().toString().padStart(2, "0");
+    const hour = date.getHours().toString().padStart(2, "0");
+    const minute = date.getMinutes().toString().padStart(2, "0");
+    const seconds = date.getSeconds().toString().padStart(2, "0");
+    return `${year}${month}${day}T${hour}${minute}${seconds}`;
+}
+
 /**
  * Creates a new {@link vscode.DebugAdapterExecutable} based on the provided workspace folder and
  * debug configuration. Assumes that the given debug configuration is for a local launch of lldb-dap.
  *
+ * @param logger The {@link Logger} to get default session log location
  * @param workspaceFolder The {@link vscode.WorkspaceFolder} that the debug session will be launched within
  * @param configuration The {@link vscode.DebugConfiguration} that will be launched
  * @throws An {@link ErrorWithNotification} if something went wrong
  * @returns The {@link vscode.DebugAdapterExecutable} that can be used to launch lldb-dap
  */
 export async function createDebugAdapterExecutable(
+  logger: Logger,
   workspaceFolder: vscode.WorkspaceFolder | undefined,
   configuration: vscode.DebugConfiguration,
 ): Promise<vscode.DebugAdapterExecutable> {
@@ -174,6 +193,8 @@ export async function createDebugAdapterExecutable(
   let env: { [key: string]: string } = {};
   if (log_path) {
     env["LLDBDAP_LOG"] = log_path;
+  } else if (vscode.workspace.getConfiguration("lldb-dap").get("verboseLogging", false)) {
+    env["LLDBDAP_LOG"] = logger.logFilePath(`lldb-dap-session-${formatDate(new Date())}.log`);
   }
   const configEnvironment =
     config.get<{ [key: string]: string }>("environment") || {};
@@ -188,6 +209,11 @@ export async function createDebugAdapterExecutable(
   };
   const dbgArgs = await getDAPArguments(workspaceFolder, configuration);
 
+  logger.info(`lldb-dap path: ${dapPath}`);
+  logger.info(`lldb-dap args: ${dbgArgs}`);
+  logger.info(`cwd: ${dbgOptions.cwd}`);
+  logger.info(`env: ${JSON.stringify(configEnvironment)}`);
+
   return new vscode.DebugAdapterExecutable(dapPath, dbgArgs, dbgOptions);
 }
 
@@ -198,18 +224,25 @@ export async function createDebugAdapterExecutable(
 export class LLDBDapDescriptorFactory
   implements vscode.DebugAdapterDescriptorFactory
 {
+  constructor(private readonly logger: Logger) {}
+
   async createDebugAdapterDescriptor(
     session: vscode.DebugSession,
     executable: vscode.DebugAdapterExecutable | undefined,
   ): Promise<vscode.DebugAdapterDescriptor | undefined> {
+    this.logger.info(`Creating debug adapter for session "${session.name}"`);
+    this.logger.debug(`Session "${session.name}" debug configuration:\n` + JSON.stringify(session.configuration, undefined, 2));
     if (executable) {
-      throw new Error(
+      const error = new Error(
         "Setting the debug adapter executable in the package.json is not supported.",
       );
+      this.logger.error(error);
+      throw error;
     }
 
     // Use a server connection if the debugAdapterPort is provided
     if (session.configuration.debugAdapterPort) {
+      this.logger.info(`Spawning debug adapter server on port ${session.configuration.debugAdapterPort}`);
       return new vscode.DebugAdapterServer(
         session.configuration.debugAdapterPort,
         session.configuration.debugAdapterHostname,
@@ -217,6 +250,7 @@ export class LLDBDapDescriptorFactory
     }
 
     return createDebugAdapterExecutable(
+      this.logger,
       session.workspaceFolder,
       session.configuration,
     );
diff --git a/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts b/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts
index 316ffaf47c3d2..19012443ca06d 100644
--- a/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts
+++ b/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts
@@ -5,6 +5,7 @@ import { LLDBDapServer } from "./lldb-dap-server";
 import { createDebugAdapterExecutable } from "./debug...
[truncated]

Copy link

@rbenegal rbenegal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks for this!

@award999 award999 marked this pull request as draft July 28, 2025 16:00
@award999
Copy link
Contributor Author

OK this is not ready yet, looks like there is a bug when it is bundled in a VSIX winstonjs/winston-transport#274

@ashgti
Copy link
Contributor

ashgti commented Jul 28, 2025

Could we use the LogOutputChannel for creating the logger without a new dep?

We could have a simple logger interface like

interface Logger {
  debug(message: string, ...args: any[]): void
  error(error: string | Error, ...args: any[]): void
  info(message: string, ...args: any[]): void
  trace(message: string, ...args: any[]): void
  warn(message: string, ...args: any[]): void
}

That should be compatible with LogOutputChannel to abstract this some.

VSCode internally handles backing the output channel by a file on disk and rotating the file if its to large, so I'm not sure if we need a new dep for those capabilities.

@award999
Copy link
Contributor Author

@ashgti The reason I don't want to use the LogOutputChannel is to always write the debug or trace levels to a log file. For the most part the Output channels are user facing and the users wouldn't often want to see the verbose logging. But if an issue happens, it would be beneficial to have those trace events in a log. And since the log file is in the same logUri folder, you get the same history and rollover data.

award999 added 7 commits July 29, 2025 09:54
- Add `winston` dependency (MIT license) to handle logging setup
- Have an `OutputChannel` to log user facing information, errors, warnings
- Write a verose log under the provided `logUri` to capture further diagnostics
- Introduce `verboseLogging` setting to increase `OutputChannel` verbosity and write DAP session logs

Issue: llvm#146880
@award999 award999 force-pushed the lldb-dap-ext-logging branch from 12ce178 to 0dc70d0 Compare July 29, 2025 15:18
@award999 award999 marked this pull request as ready for review July 29, 2025 15:19
@award999
Copy link
Contributor Author

@ashgti do you have a different view or does that perspective sway you?

@ashgti
Copy link
Contributor

ashgti commented Jul 29, 2025

If you create an output logger then you can use the output UI to set the log level and view / save logs.

For example, creating an output channel called 'lldb-dap'

const logger = vscode.window.createOutputChannel('lldb-dap', {log: true});
logger.info("Info...");
logger.onDidChangeLogLevel((level) => {
  logger.debug('level changed to...', level);
});

This allows you to set the log level in the UI like so:

Screenshot 2025-07-29 at 9 45 49 AM

And includes options for users to save / export logs:

Screenshot 2025-07-29 at 9 45 54 AM

@award999
Copy link
Contributor Author

Yes but then the log file misses the debug messages until you change the log level after the fact

@ashgti
Copy link
Contributor

ashgti commented Jul 29, 2025

Sure, but thats true of most logging systems.

You can set the default for a logging level if your running into an issue and want the additional logs. VSCode cleans up these log files automatically, so including things a the .info level should be fine.

@award999
Copy link
Contributor Author

So the approach in this PR still makes use of VSCode log rotation and persisting, where the log file goes in the same folder as LogOutputChannel would put it. So really the biggest difference I see is the verbosity of the file log vs. introducing a dependency. As long as you're fine with me moving all this to the ".info" level then I'll make that change to get something in place. Where this whole PR started was us trying to diagnose an intermittent Swift debugging failure which we have not been able to reproduce, and by the time we are able to video chat and see their screen they can not readily reproduce, but it has popped up often enough from numerous developers over the last year that something is clearly going wrong. My main concern is capturing the logging to diagnose intermittent failures without needing to configure after the fact. This approach using Winston has worked very well on numerous extensions I've worked on, but I can appreciate other developers including yourself may feel like LLDB DAP may not derive the same value from this, and for this OSS project less code to maintain is more attractive. So I'll start reverting out the dependency but at least want to move some messages from the "debug" to "info" level that would help diagnose this issue.

@award999
Copy link
Contributor Author

@ashgti @JDevlieghere I did some more testing this morning, this PR is ready to land pending any further comments

Copy link
Contributor

@ashgti ashgti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@JDevlieghere JDevlieghere merged commit ae7be39 into llvm:main Aug 5, 2025
9 checks passed
JDevlieghere added a commit to swiftlang/llvm-project that referenced this pull request Oct 8, 2025
- ~Add `winston` dependency (MIT license) to handle logging setup~
- Have an `LogOutputChannel` to log user facing information, errors,
warnings
- Write a debug session logs under the provided `logUri` to capture
further diagnostics when the `lldb-dap.captureSessionLogs` setting is
enabled. *Note* the `lldb-dap.log-path` setting takes precedence when
set
Issue: llvm#146880

---------

Co-authored-by: Jonas Devlieghere <[email protected]>
(cherry picked from commit ae7be39)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants