From 28899932b90c904e2478a46cc318fe9ac554392c Mon Sep 17 00:00:00 2001 From: ajbt200128 Date: Wed, 5 Jun 2024 14:47:21 -0700 Subject: [PATCH 1/3] properly make log path --- src/telemetry/sentry.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/telemetry/sentry.ts b/src/telemetry/sentry.ts index 69c8b74..0476408 100644 --- a/src/telemetry/sentry.ts +++ b/src/telemetry/sentry.ts @@ -177,6 +177,8 @@ export class ProxyOutputChannel implements vscode.OutputChannel { this.baseOutputChannel = baseOutputChannel; this.name = baseOutputChannel.name; this.logFile = `${logPath}/lsp-output.log`; + // ensure parent directory exists + fs.mkdirSync(logPath, { recursive: true }); // create/clear log file fs.writeFileSync(this.logFile, ""); } From debaf18723c57bad9d14e11e4f8412af8cef344c Mon Sep 17 00:00:00 2001 From: ajbt200128 Date: Wed, 5 Jun 2024 15:02:34 -0700 Subject: [PATCH 2/3] Error handle around writing log file --- src/constants.ts | 5 ++++- src/env.ts | 7 ++----- src/lsp.ts | 8 +++++--- src/telemetry/sentry.ts | 38 +++++++++++++++++++++++++++++++------- src/utils.ts | 10 ++-------- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index e3338bd..9d448d1 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,13 +1,16 @@ +import { tmpdir } from "os"; import { SemVer } from "semver"; +import { Uri } from "vscode"; export const SEMGREP_BINARY = "semgrep"; export const DIAGNOSTIC_COLLECTION_NAME = "semgrep-findings"; export const CLIENT_ID = "semgrep"; export const CLIENT_NAME = "Semgrep"; export const DEFAULT_RULESET = "p/r2c"; -export const LSP_LOG_FILE = "semgrep_lsp.log"; export const VSCODE_CONFIG_KEY = "semgrep"; export const VSCODE_EXT_NAME = CLIENT_NAME; +export const DEFAULT_LSP_LOG_FOLDER = Uri.file(tmpdir()); + export type VersionInfo = { latest: SemVer; min: SemVer; diff --git a/src/env.ts b/src/env.ts index 89b8ecc..850b028 100644 --- a/src/env.ts +++ b/src/env.ts @@ -1,14 +1,13 @@ import { ExtensionContext, OutputChannel, - Uri, WorkspaceConfiguration, } from "vscode"; import { window, workspace } from "vscode"; import * as fs from "fs"; -import { LSP_LOG_FILE, VSCODE_CONFIG_KEY, VSCODE_EXT_NAME } from "./constants"; -import { DEFAULT_LSP_LOG_URI, Logger } from "./utils"; +import { VSCODE_CONFIG_KEY, VSCODE_EXT_NAME } from "./constants"; +import { Logger } from "./utils"; import { SemgrepDocumentProvider } from "./showAstDocument"; import { LanguageClient } from "vscode-languageclient/node"; import { EventEmitter } from "stream"; @@ -40,7 +39,6 @@ export class Config { } export class Environment { - semgrep_log: Uri = DEFAULT_LSP_LOG_URI; public semgrepVersion: string | undefined; /* The scan ID is the (hopefully) unique identifier associated to each @@ -64,7 +62,6 @@ export class Environment { // rulesRefreshedEmitter is used to notify if rules are refreshed, i.e. after startup, a login, or a manual refresh private rulesRefreshedEmitter: EventEmitter = new EventEmitter(), ) { - this.semgrep_log = Uri.joinPath(context.logUri, LSP_LOG_FILE); setSentryContext(this); } diff --git a/src/lsp.ts b/src/lsp.ts index cd95093..d893acb 100644 --- a/src/lsp.ts +++ b/src/lsp.ts @@ -199,9 +199,11 @@ async function lspOptions( env.channel, env.globalStoragePath, ); - const errorHandler = new SentryErrorHandler(5, () => [ - outputChannel.logAsAttachment(), - ]); + const errorHandler = new SentryErrorHandler(5, () => { + const attachment = outputChannel.logAsAttachment(); + + return attachment ? [attachment] : []; + }); const clientOptions: LanguageClientOptions = { diagnosticCollectionName: DIAGNOSTIC_COLLECTION_NAME, // TODO: should we limit to support languages and keep the list manually updated? diff --git a/src/telemetry/sentry.ts b/src/telemetry/sentry.ts index 0476408..1183525 100644 --- a/src/telemetry/sentry.ts +++ b/src/telemetry/sentry.ts @@ -11,6 +11,7 @@ import { } from "vscode-languageclient"; import { Environment } from "../env"; import * as fs from "fs"; +import { DEFAULT_LSP_LOG_FOLDER } from "../constants"; // global here so if user opts out the functions below don't do anything let sentryEnabled = false; @@ -170,22 +171,41 @@ export class SentryErrorHandler implements ErrorHandler { export class ProxyOutputChannel implements vscode.OutputChannel { readonly name: string; private logFile: string; + private writeLog = true; constructor( public readonly baseOutputChannel: vscode.OutputChannel, - private readonly logPath: string, + logPath: string, ) { this.baseOutputChannel = baseOutputChannel; this.name = baseOutputChannel.name; + // Check if logPath exists, if not create a random one + if (!fs.existsSync(logPath)) { + logPath = DEFAULT_LSP_LOG_FOLDER.fsPath; + // ensure logPath exists + if (!fs.existsSync(logPath)) { + fs.mkdirSync(logPath); + } + } this.logFile = `${logPath}/lsp-output.log`; - // ensure parent directory exists - fs.mkdirSync(logPath, { recursive: true }); // create/clear log file - fs.writeFileSync(this.logFile, ""); + try { + fs.writeFileSync(this.logFile, ""); + } catch (e) { + if (sentryEnabled) { + Sentry.captureException(e); + } + console.error(`Failed to write to log file: ${e}`); + this.writeLog = false; + } } - logAsAttachment(): Attachment { + logAsAttachment(): Attachment | null { + if (!this.writeLog) { + return null; + } const timestamp = new Date().toISOString(); const filename = `lsp-output-${timestamp}.log`; + const data = fs.readFileSync(this.logFile, "utf8"); const attachment = { filename, @@ -200,13 +220,17 @@ export class ProxyOutputChannel implements vscode.OutputChannel { append(value: string): void { this.baseOutputChannel.append(value); // write to log file - fs.appendFileSync(this.logFile, value); + if (this.writeLog) { + fs.appendFileSync(this.logFile, value); + } } appendLine(value: string): void { this.baseOutputChannel.appendLine(value); // write to log file - fs.appendFileSync(this.logFile, `${value}\n`); + if (this.writeLog) { + fs.appendFileSync(this.logFile, `${value}\n`); + } } clear = this.baseOutputChannel.clear; diff --git a/src/utils.ts b/src/utils.ts index 68ae7d1..804dd46 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,15 +1,9 @@ -import { tmpdir } from "os"; -import { OutputChannel, Uri } from "vscode"; +import { OutputChannel } from "vscode"; import * as vscode from "vscode"; -import { getVersionInfo, LSP_LOG_FILE } from "./constants"; import { ViewResults } from "./webview-ui/src/types/results"; import * as semver from "semver"; - -export const DEFAULT_LSP_LOG_URI = Uri.joinPath( - Uri.file(tmpdir()), - LSP_LOG_FILE, -); +import { getVersionInfo } from "./constants"; export class Logger { enabled: boolean; From 0c5126717a33afde16934f87b624ec1326564334 Mon Sep 17 00:00:00 2001 From: ajbt200128 Date: Wed, 5 Jun 2024 15:13:06 -0700 Subject: [PATCH 3/3] Fix maybe? --- CHANGELOG.md | 2 ++ src/constants.ts | 3 --- src/telemetry/sentry.ts | 2 +- src/utils.ts | 5 +++++ 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22722f1..c7657ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Extension no longer errors out if a log can't be written + ## v1.8.0 - 2024-06-05 ### Added diff --git a/src/constants.ts b/src/constants.ts index 9d448d1..5f8851f 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,6 +1,4 @@ -import { tmpdir } from "os"; import { SemVer } from "semver"; -import { Uri } from "vscode"; export const SEMGREP_BINARY = "semgrep"; export const DIAGNOSTIC_COLLECTION_NAME = "semgrep-findings"; @@ -9,7 +7,6 @@ export const CLIENT_NAME = "Semgrep"; export const DEFAULT_RULESET = "p/r2c"; export const VSCODE_CONFIG_KEY = "semgrep"; export const VSCODE_EXT_NAME = CLIENT_NAME; -export const DEFAULT_LSP_LOG_FOLDER = Uri.file(tmpdir()); export type VersionInfo = { latest: SemVer; diff --git a/src/telemetry/sentry.ts b/src/telemetry/sentry.ts index 1183525..d439173 100644 --- a/src/telemetry/sentry.ts +++ b/src/telemetry/sentry.ts @@ -11,7 +11,7 @@ import { } from "vscode-languageclient"; import { Environment } from "../env"; import * as fs from "fs"; -import { DEFAULT_LSP_LOG_FOLDER } from "../constants"; +import { DEFAULT_LSP_LOG_FOLDER } from "../utils"; // global here so if user opts out the functions below don't do anything let sentryEnabled = false; diff --git a/src/utils.ts b/src/utils.ts index 804dd46..230d514 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,8 @@ +import { tmpdir } from "os"; +import { Uri } from "vscode"; +// Can't put this in constants for some reason?? +export const DEFAULT_LSP_LOG_FOLDER = Uri.file(tmpdir()); + import { OutputChannel } from "vscode"; import * as vscode from "vscode";