Skip to content

Commit 9d6027e

Browse files
Init logging mechanism (#56)
* Init logger and "Open log file" command * Add caller information to logger * Explain how to attach log file to GitHub issue * Capitalize open log file command Many VSCode commands are actually capitalized. * add the MacOS option: "Reveal in Finder" * Also match line number & other case in Logger * Add "Reset log level" as last step to Readme * Make RegEx more stable --------- Co-authored-by: Vladimir Fokow <[email protected]>
1 parent 2b8c86b commit 9d6027e

File tree

4 files changed

+149
-1
lines changed

4 files changed

+149
-1
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,16 @@ The resulting workflow can look like Grant's 🥳
7171
- [contributing](https://github.com/bhoov/manim-notebook/blob/main/CONTRIBUTING.md)
7272

7373
- [wiki](https://github.com/bhoov/manim-notebook/wiki)
74+
75+
<br /><br />
76+
77+
## Troubleshooting
78+
79+
If you encounter an issue, search for some related keywords first in the [issues](https://github.com/bhoov/manim-notebook/issues). If you can't find anything, feel free to open a new issue. To analyze the problem, we need a **log file** from you:
80+
81+
- Reload the VSCode window. This is important for us such that only important log messages are included in the log file and not unrelated ones.
82+
- Open the command palette `Ctrl+Shift+P` (or `Cmd+Shift+P`). Use the command `Developer: Set Log Level...`, click on `Manim Notebook` and set the log level to `Trace`.
83+
- Now reproduce the issue, e.g. by running a command that causes the problem.
84+
- Open the command palette again and use the command `Manim Notebook: Open Log File`.
85+
- Attach the log file to your GitHub issue. To do so, right-click on the opened log file header (the tab pane that shows the filename at the top of the editor) and select `Reveal In File Explorer` (or `Reveal in Finder`). Then drag and drop the file into the GitHub issue text field.
86+
- Last, but not least, don't forget to set the log level back to `Info` to avoid performance issues. `Developer: Set Log Level...` -> `Manim Notebook` -> `Info`.

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
"command": "manim-notebook.clearScene",
4646
"title": "Remove all objects from scene",
4747
"category": "Manim Notebook"
48+
},
49+
{
50+
"command": "manim-notebook.openLogFile",
51+
"title": "Open Log File",
52+
"category": "Manim Notebook"
4853
}
4954
],
5055
"keybindings": [

src/extension.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { ManimCell } from './manimCell';
55
import { ManimCellRanges } from './manimCellRanges';
66
import { previewCode } from './previewCode';
77
import { startScene, exitScene } from './startStopScene';
8+
import { loggerName } from './logger';
9+
import Logger from './logger';
810

911
export function activate(context: vscode.ExtensionContext) {
1012

@@ -40,14 +42,22 @@ export function activate(context: vscode.ExtensionContext) {
4042
}
4143
);
4244

45+
const openLogFileCommand = vscode.commands.registerCommand(
46+
'manim-notebook.openLogFile', async () => {
47+
openLogFile(context);
48+
});
49+
4350
context.subscriptions.push(
4451
previewManimCellCommand,
4552
previewSelectionCommand,
4653
startSceneCommand,
4754
exitSceneCommand,
48-
clearSceneCommand
55+
clearSceneCommand,
56+
openLogFileCommand
4957
);
5058
registerManimCellProviders(context);
59+
60+
Logger.info("Manim Notebook activated");
5161
}
5262

5363
export function deactivate() { }
@@ -167,3 +177,34 @@ function registerManimCellProviders(context: vscode.ExtensionContext) {
167177
manimCell.applyCellDecorations(window.activeTextEditor);
168178
}
169179
}
180+
181+
/**
182+
* Opens the Manim Notebook log file in a new editor.
183+
*
184+
* @param context The extension context.
185+
*/
186+
function openLogFile(context: vscode.ExtensionContext) {
187+
const logFilePath = vscode.Uri.joinPath(context.logUri, `${loggerName}.log`);
188+
vscode.window.withProgress({
189+
location: vscode.ProgressLocation.Notification,
190+
title: "Opening Manim Notebook log file...",
191+
cancellable: false
192+
}, async (progressIndicator, token) => {
193+
await new Promise<void>(async (resolve) => {
194+
try {
195+
const doc = await vscode.workspace.openTextDocument(logFilePath);
196+
await vscode.window.showTextDocument(doc);
197+
} catch {
198+
vscode.window.showErrorMessage("Could not open Manim Notebook log file");
199+
} finally {
200+
resolve();
201+
}
202+
203+
// I've also tried to open the log file in the OS browser,
204+
// but didn't get it to work via:
205+
// commands.executeCommand("revealFileInOS", logFilePath);
206+
// For a sample usage, see this:
207+
// https://github.com/microsoft/vscode/blob/9de080f7cbcec77de4ef3e0d27fbf9fd335d3fba/extensions/typescript-language-features/src/typescriptServiceClient.ts#L580-L586
208+
});
209+
});
210+
}

src/logger.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { window } from 'vscode';
2+
import * as path from 'path';
3+
4+
export const loggerName = 'Manim Notebook';
5+
const logger = window.createOutputChannel(loggerName, { log: true });
6+
7+
export default class Logger {
8+
9+
public static trace(message: string) {
10+
logger.trace(`${Logger.getFormattedCallerInformation()} ${message}`);
11+
}
12+
13+
public static debug(message: string) {
14+
logger.debug(`${Logger.getFormattedCallerInformation()} ${message}`);
15+
}
16+
17+
public static info(message: string) {
18+
logger.info(`${Logger.getFormattedCallerInformation()} ${message}`);
19+
}
20+
21+
public static warn(message: string) {
22+
logger.warn(`${Logger.getFormattedCallerInformation()} ${message}`);
23+
}
24+
25+
public static error(message: string) {
26+
logger.error(`${Logger.getFormattedCallerInformation()} ${message}`);
27+
}
28+
29+
/**
30+
* Returns formatted caller information in the form of
31+
* "[filename] [methodname]".
32+
*
33+
* It works by creating a stack trace and extracting the file name from the
34+
* third line of the stack trace, e.g.
35+
*
36+
* Error:
37+
* at Logger.getCurrentFileName (manim-notebook/out/logger.js:32:19)
38+
* at Logger.info (manim-notebook/out/logger.js:46:39)
39+
* at activate (manim-notebook/out/extension.js:37:21)
40+
* ...
41+
*
42+
* where "extension.js:37:21" is the file that called the logger method
43+
* and "activate" is the respective method.
44+
*
45+
* Another example where the Logger is called in a Promise might be:
46+
*
47+
* Error:
48+
* at Function.getFormattedCallerInformation (manim-notebook/src/logger.ts:46:23)
49+
* at Function.info (manim-notebook/src/logger.ts:18:31)
50+
* at manim-notebook/src/extension.ts:199:12
51+
*
52+
* where "extension.ts:199:12" is the file that called the logger method
53+
* and the method is unknown.
54+
*/
55+
private static getFormattedCallerInformation(): string {
56+
const error = new Error();
57+
const stack = error.stack;
58+
59+
const unknownString = "[unknown] [unknown]";
60+
61+
if (!stack) {
62+
return unknownString;
63+
}
64+
65+
const stackLines = stack.split('\n');
66+
if (stackLines.length < 4) {
67+
return unknownString;
68+
}
69+
70+
const callerLine = stackLines[3];
71+
if (!callerLine) {
72+
return unknownString;
73+
}
74+
75+
const fileMatch = callerLine.match(/(?:[^\(\s])*?:\d+:\d+/);
76+
let fileName = 'unknown';
77+
if (fileMatch && fileMatch[0]) {
78+
fileName = path.basename(fileMatch[0]);
79+
}
80+
81+
const methodMatch = callerLine.match(/at (\w+) \(/);
82+
let methodName = 'unknown';
83+
if (methodMatch && methodMatch[1]) {
84+
methodName = methodMatch[1];
85+
}
86+
87+
return `[${fileName}] [${methodName}]`;
88+
}
89+
}

0 commit comments

Comments
 (0)