@@ -11,14 +11,15 @@ import { CSharpExtensionId } from '../constants/csharpExtensionId';
1111import { commonOptions , LanguageServerOptions , languageServerOptions } from './options' ;
1212
1313export default async function reportIssue (
14- csharpExtVersion : string ,
14+ context : vscode . ExtensionContext ,
1515 getDotnetInfo : ( dotNetCliPaths : string [ ] ) => Promise < DotnetInfo > ,
1616 shouldIncludeMonoInfo : boolean ,
17+ logChannels : vscode . LogOutputChannel [ ] ,
1718 dotnetResolver : IHostExecutableResolver ,
1819 monoResolver ?: IHostExecutableResolver
1920) {
2021 // Get info for the dotnet that the language server executable is run on, not the dotnet the language server will execute user code on.
21- let fullDotnetInfo : string | undefined ;
22+ let fullDotnetInfo = '' ;
2223 try {
2324 const info = await dotnetResolver . getHostExecutableInfo ( ) ;
2425 const dotnetInfo = await getDotnetInfo ( [ dirname ( info . path ) ] ) ;
@@ -33,10 +34,11 @@ export default async function reportIssue(
3334 monoInfo = await getMonoIfPlatformValid ( monoResolver ) ;
3435 }
3536
36- const extensions = getInstalledExtensions ( ) ;
37-
37+ const csharpExtVersion = context . extension . packageJSON . version ;
3838 const useOmnisharp = commonOptions . useOmnisharpServer ;
39- const logInfo = getLogInfo ( useOmnisharp ) ;
39+ const extensionsTable = generateExtensionTable ( ) ;
40+ const optionsTable = generateOptionsTable ( ) ;
41+ const logInfo = await getLogInfo ( logChannels , context ) ;
4042
4143 const body = `## Issue Description ##
4244## Steps to Reproduce ##
@@ -45,12 +47,13 @@ export default async function reportIssue(
4547
4648## Actual Behavior ##
4749
48- ## Logs ##
50+ ` ;
4951
50- ${ logInfo }
52+ const userData = `### Logs ###
5153
52- ## Environment information ##
54+ ${ logInfo }
5355
56+ ## Environment Information ##
5457**VSCode version**: ${ vscode . version }
5558**C# Extension**: ${ csharpExtVersion }
5659**Using OmniSharp**: ${ useOmnisharp }
@@ -59,16 +62,16 @@ ${monoInfo}
5962<details><summary>Dotnet Information</summary>
6063${ fullDotnetInfo } </details>
6164<details><summary>Visual Studio Code Extensions</summary>
62- ${ generateExtensionTable ( extensions ) }
65+ ${ extensionsTable }
6366</details>
6467<details><summary>C# Settings</summary>
65- ${ generateOptionsTable ( ) }
68+ ${ optionsTable }
6669</details>
6770` ;
68-
6971 await vscode . commands . executeCommand ( 'workbench.action.openIssueReporter' , {
7072 extensionId : CSharpExtensionId ,
7173 issueBody : body ,
74+ data : userData ,
7275 } ) ;
7376}
7477
@@ -82,7 +85,8 @@ function sortExtensions(a: vscode.Extension<any>, b: vscode.Extension<any>): num
8285 return 0 ;
8386}
8487
85- function generateExtensionTable ( extensions : vscode . Extension < any > [ ] ) {
88+ function generateExtensionTable ( ) {
89+ const extensions = getInstalledExtensions ( ) ;
8690 if ( extensions . length <= 0 ) {
8791 return 'none' ;
8892 }
@@ -142,25 +146,47 @@ async function getMonoIfPlatformValid(monoResolver: IHostExecutableResolver): Pr
142146 ${ monoVersion } </details>` ;
143147}
144148
145- function getLogInfo ( useOmnisharp : boolean ) : string {
146- if ( useOmnisharp ) {
147- return `### OmniSharp log ###
148- <details>Post the output from Output-->OmniSharp log here</details>
149-
150- ### C# log ###
151- <details>Post the output from Output-->C# here</details>` ;
152- } else {
153- return `<!--
149+ async function getLogInfo ( logChannels : vscode . LogOutputChannel [ ] , context : vscode . ExtensionContext ) : Promise < string > {
150+ let logInfo = `<!--
154151If you can, it would be the most helpful to zip up and attach the entire extensions log folder. The folder can be opened by running the \`workbench.action.openExtensionLogsFolder\` command.
155152
156- Additionally, if you can reproduce the issue reliably, set the \`C#\` output window log level to 'Trace' re-run the scenario to get more detailed logs .
153+ Additionally, if you can reproduce the issue reliably, use trace logging, see https://github.com/dotnet/vscode-csharp/blob/main/SUPPORT.md#c-lsp-trace-logs and then report the issue .
157154-->
158-
159- ### C# log ###
160- <details>Post the output from Output-->C# here</details>
155+ ` ;
161156
162- ### C# LSP Trace Logs ###
163- <details>Post the output from Output-->C# LSP Trace Logs here. Requires the \`C#\` output window log level to be set to \`Trace\`</details>` ;
157+ for ( const channel of logChannels ) {
158+ const contents = await getLogOutputChannelContents ( context , channel ) ;
159+ logInfo += `### ${ channel . name } log ###
160+ <details>
161+
162+ \`\`\`
163+ ${ contents }
164+ \`\`\`
165+ </details>
166+
167+ ` ;
168+ }
169+
170+ return logInfo ;
171+ }
172+
173+ async function getLogOutputChannelContents (
174+ context : vscode . ExtensionContext ,
175+ channel : vscode . LogOutputChannel
176+ ) : Promise < string > {
177+ const logFilePath = vscode . Uri . joinPath ( context . logUri , channel . name + '.log' ) ;
178+
179+ try {
180+ const fileStat = await vscode . workspace . fs . stat ( logFilePath ) ;
181+ if ( fileStat . type !== vscode . FileType . File ) {
182+ return `Unable to find log file at ${ logFilePath } , ${ fileStat . type } ` ;
183+ }
184+
185+ const logContent = await vscode . workspace . fs . readFile ( logFilePath ) ;
186+ const contents = Buffer . from ( logContent ) . toString ( 'utf8' ) ;
187+ return contents ;
188+ } catch ( error ) {
189+ return `Error reading log file: ${ error instanceof Error ? error . message : `${ error } ` } ` ;
164190 }
165191}
166192
0 commit comments