aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-10-02 16:53:46 +0200
committerLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-10-02 16:58:31 +0200
commitea509702b6ed88951a1b7b109b5dc597ee81112d (patch)
tree241b9732e7094ef22e7860a9e97a9f67b5b63509
parentperf(web): split off CodeMirror chunks (diff)
downloadrefinery-ea509702b6ed88951a1b7b109b5dc597ee81112d.tar.gz
refinery-ea509702b6ed88951a1b7b109b5dc597ee81112d.tar.zst
refinery-ea509702b6ed88951a1b7b109b5dc597ee81112d.zip
feat(web): add client-side logging support
Also modified langauge-web/src/main/js/xtext/ServiceBuilder.js to make sure the new logger is used as soon as xtext is initialized.
-rw-r--r--language-web/package.json5
-rw-r--r--language-web/src/main/js/editor/EditorArea.tsx3
-rw-r--r--language-web/src/main/js/editor/EditorStore.ts13
-rw-r--r--language-web/src/main/js/global.d.ts6
-rw-r--r--language-web/src/main/js/logging.tsx49
-rw-r--r--language-web/src/main/js/xtext/ServiceBuilder.js27
-rw-r--r--language-web/webpack.config.js8
-rw-r--r--language-web/yarn.lock15
8 files changed, 114 insertions, 12 deletions
diff --git a/language-web/package.json b/language-web/package.json
index ddb00f57..79e63342 100644
--- a/language-web/package.json
+++ b/language-web/package.json
@@ -1,5 +1,5 @@
1{ 1{
2 "name": "language-web", 2 "name": "refinery",
3 "version": "0.0.0", 3 "version": "0.0.0",
4 "description": "Web frontend for VIATRA-Generator", 4 "description": "Web frontend for VIATRA-Generator",
5 "main": "index.js", 5 "main": "index.js",
@@ -58,6 +58,7 @@
58 "webpack-subresource-integrity": "^5.0.0-rc.1" 58 "webpack-subresource-integrity": "^5.0.0-rc.1"
59 }, 59 },
60 "dependencies": { 60 "dependencies": {
61 "ansi-styles": "^6.1.0",
61 "@babel/runtime": "^7.15.0", 62 "@babel/runtime": "^7.15.0",
62 "@emotion/react": "^11.4.1", 63 "@emotion/react": "^11.4.1",
63 "@emotion/styled": "^11.3.0", 64 "@emotion/styled": "^11.3.0",
@@ -67,6 +68,8 @@
67 "@material-ui/icons": "5.0.0-beta.4", 68 "@material-ui/icons": "5.0.0-beta.4",
68 "codemirror": "^5.62.3", 69 "codemirror": "^5.62.3",
69 "jquery": "^3.6.0", 70 "jquery": "^3.6.0",
71 "loglevel": "^1.7.1",
72 "loglevel-plugin-prefix": "^0.8.4",
70 "mobx": "^6.3.2", 73 "mobx": "^6.3.2",
71 "mobx-react-lite": "^3.2.0", 74 "mobx-react-lite": "^3.2.0",
72 "react": "^17.0.2", 75 "react": "^17.0.2",
diff --git a/language-web/src/main/js/editor/EditorArea.tsx b/language-web/src/main/js/editor/EditorArea.tsx
index f07a0ad8..531a57c9 100644
--- a/language-web/src/main/js/editor/EditorArea.tsx
+++ b/language-web/src/main/js/editor/EditorArea.tsx
@@ -15,8 +15,7 @@ export const EditorArea = observer(() => {
15 onChange={(e) => editorStore.updateValue(e.target.value)} 15 onChange={(e) => editorStore.updateValue(e.target.value)}
16 ref={fallbackTextarea} 16 ref={fallbackTextarea}
17 className={`problem-fallback-editor cm-s-${editorStore.codeMirrorTheme}`} 17 className={`problem-fallback-editor cm-s-${editorStore.codeMirrorTheme}`}
18 > 18 />
19 </textarea>
20 ); 19 );
21 } 20 }
22 21
diff --git a/language-web/src/main/js/editor/EditorStore.ts b/language-web/src/main/js/editor/EditorStore.ts
index 1ac2e79f..8b9432dd 100644
--- a/language-web/src/main/js/editor/EditorStore.ts
+++ b/language-web/src/main/js/editor/EditorStore.ts
@@ -8,8 +8,11 @@ import {
8import type { IXtextOptions, IXtextServices } from 'xtext/xtext-codemirror'; 8import type { IXtextOptions, IXtextServices } from 'xtext/xtext-codemirror';
9 9
10import type { IEditorChunk } from './editor'; 10import type { IEditorChunk } from './editor';
11import { getLogger } from '../logging';
11import type { ThemeStore } from '../theme/ThemeStore'; 12import type { ThemeStore } from '../theme/ThemeStore';
12 13
14const log = getLogger('EditorStore');
15
13const xtextLang = 'problem'; 16const xtextLang = 'problem';
14 17
15const xtextOptions: IXtextOptions = { 18const xtextOptions: IXtextOptions = {
@@ -52,12 +55,20 @@ export class EditorStore {
52 xtextServices: observable.ref, 55 xtextServices: observable.ref,
53 initialSelection: false, 56 initialSelection: false,
54 }); 57 });
58 this.loadChunk();
59 }
60
61 private loadChunk(): void {
62 const loadingStartMillis = Date.now();
63 log.info('Requesting editor chunk');
55 import('./editor').then(({ editorChunk }) => { 64 import('./editor').then(({ editorChunk }) => {
56 runInAction(() => { 65 runInAction(() => {
57 this.chunk = editorChunk; 66 this.chunk = editorChunk;
58 }); 67 });
68 const loadingDurationMillis = Date.now() - loadingStartMillis;
69 log.info('Loaded editor chunk in', loadingDurationMillis, 'ms');
59 }).catch((error) => { 70 }).catch((error) => {
60 console.warn('Error while loading editor', error); 71 log.error('Error while loading editor', error);
61 }); 72 });
62 } 73 }
63 74
diff --git a/language-web/src/main/js/global.d.ts b/language-web/src/main/js/global.d.ts
index 39bda7f3..0533a46e 100644
--- a/language-web/src/main/js/global.d.ts
+++ b/language-web/src/main/js/global.d.ts
@@ -1,3 +1,9 @@
1declare const DEBUG: boolean;
2
3declare const PACKAGE_NAME: string;
4
5declare const PACKAGE_VERSION: string;
6
1declare module '*.module.scss' { 7declare module '*.module.scss' {
2 const cssVariables: { [key in string]?: string }; 8 const cssVariables: { [key in string]?: string };
3 // eslint-disable-next-line import/no-default-export 9 // eslint-disable-next-line import/no-default-export
diff --git a/language-web/src/main/js/logging.tsx b/language-web/src/main/js/logging.tsx
new file mode 100644
index 00000000..25f50f19
--- /dev/null
+++ b/language-web/src/main/js/logging.tsx
@@ -0,0 +1,49 @@
1import styles, { CSPair } from 'ansi-styles';
2import log from 'loglevel';
3import * as prefix from 'loglevel-plugin-prefix';
4
5const colors: Record<string, CSPair> = {
6 TRACE: styles.magenta,
7 DEBUG: styles.cyan,
8 INFO: styles.blue,
9 WARN: styles.yellow,
10 ERROR: styles.red,
11};
12
13prefix.reg(log);
14
15if (DEBUG) {
16 log.setLevel(log.levels.DEBUG);
17} else {
18 log.setLevel(log.levels.WARN);
19}
20
21if ('chrome' in window) {
22 // Only Chromium supports console ANSI escape sequences.
23 prefix.apply(log, {
24 format(level, name, timestamp) {
25 const formattedTimestamp = `${styles.gray.open}[${timestamp.toString()}]${styles.gray.close}`;
26 const levelColor = colors[level.toUpperCase()] || styles.red;
27 const formattedLevel = `${levelColor.open}${level}${levelColor.close}`;
28 const formattedName = `${styles.green.open}(${name || 'root'})${styles.green.close}`;
29 return `${formattedTimestamp} ${formattedLevel} ${formattedName}`;
30 },
31 });
32} else {
33 prefix.apply(log, {
34 template: '[%t] %l (%n)',
35 });
36}
37
38const appLogger = log.getLogger(PACKAGE_NAME);
39
40appLogger.info('Version:', PACKAGE_NAME, PACKAGE_VERSION);
41appLogger.info('Debug mode:', DEBUG);
42
43export function getLoggerFromRoot(name: string | symbol): log.Logger {
44 return log.getLogger(name);
45}
46
47export function getLogger(name: string | symbol): log.Logger {
48 return getLoggerFromRoot(`${PACKAGE_NAME}.${name.toString()}`);
49}
diff --git a/language-web/src/main/js/xtext/ServiceBuilder.js b/language-web/src/main/js/xtext/ServiceBuilder.js
index 38b08ecc..57fcb310 100644
--- a/language-web/src/main/js/xtext/ServiceBuilder.js
+++ b/language-web/src/main/js/xtext/ServiceBuilder.js
@@ -18,10 +18,11 @@ define([
18 'xtext/services/ContentAssistService', 18 'xtext/services/ContentAssistService',
19 'xtext/services/HoverService', 19 'xtext/services/HoverService',
20 'xtext/services/OccurrencesService', 20 'xtext/services/OccurrencesService',
21 'xtext/services/FormattingService' 21 'xtext/services/FormattingService',
22 '../logging',
22], function(jQuery, XtextService, LoadResourceService, SaveResourceService, HighlightingService, 23], function(jQuery, XtextService, LoadResourceService, SaveResourceService, HighlightingService,
23 ValidationService, UpdateService, ContentAssistService, HoverService, OccurrencesService, 24 ValidationService, UpdateService, ContentAssistService, HoverService, OccurrencesService,
24 FormattingService) { 25 FormattingService, logging) {
25 26
26 /** 27 /**
27 * Builder class for the Xtext services. 28 * Builder class for the Xtext services.
@@ -179,12 +180,22 @@ define([
179 }); 180 });
180 } 181 }
181 182
182 services.successListeners = []; 183 const log = logging.getLoggerFromRoot('xtext.XtextService');
184 services.successListeners = [function(serviceType, result) {
185 if (log.getLevel() <= log.levels.TRACE) {
186 log.trace('service', serviceType, 'request success', JSON.parse(JSON.stringify(result)));
187 }
188 }];
183 services.errorListeners = [function(serviceType, severity, message, requestData) { 189 services.errorListeners = [function(serviceType, severity, message, requestData) {
184 if (options.showErrorDialogs) 190 const messageParts = ['service', serviceType, 'failed:', message || '(no message)'];
185 window.alert('Xtext service \'' + serviceType + '\' failed: ' + message); 191 if (requestData) {
186 else 192 messageParts.push(JSON.parse(JSON.stringify(requestData)));
187 console.log('Xtext service \'' + serviceType + '\' failed: ' + message); 193 }
194 if (severity === 'warning') {
195 log.warn(...messageParts);
196 } else {
197 log.error(...messageParts);
198 }
188 }]; 199 }];
189 } 200 }
190 201
@@ -271,4 +282,4 @@ define([
271 } 282 }
272 283
273 return ServiceBuilder; 284 return ServiceBuilder;
274}); \ No newline at end of file 285});
diff --git a/language-web/webpack.config.js b/language-web/webpack.config.js
index 1bd0edb2..c51d55d6 100644
--- a/language-web/webpack.config.js
+++ b/language-web/webpack.config.js
@@ -1,11 +1,14 @@
1const fs = require('fs'); 1const fs = require('fs');
2const path = require('path'); 2const path = require('path');
3 3
4const { DefinePlugin } = require('webpack');
4const HtmlWebpackPlugin = require('html-webpack-plugin'); 5const HtmlWebpackPlugin = require('html-webpack-plugin');
5const HtmlWebpackInjectPreload = require('@principalstudio/html-webpack-inject-preload'); 6const HtmlWebpackInjectPreload = require('@principalstudio/html-webpack-inject-preload');
6const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 7const MiniCssExtractPlugin = require('mini-css-extract-plugin');
7const { SubresourceIntegrityPlugin } = require('webpack-subresource-integrity'); 8const { SubresourceIntegrityPlugin } = require('webpack-subresource-integrity');
8 9
10const packageInfo = require('./package.json');
11
9const currentNodeEnv = process.env.NODE_ENV || 'development'; 12const currentNodeEnv = process.env.NODE_ENV || 'development';
10const devMode = currentNodeEnv !== 'production'; 13const devMode = currentNodeEnv !== 'production';
11const outputPath = path.resolve(__dirname, 'build/webpack', currentNodeEnv); 14const outputPath = path.resolve(__dirname, 'build/webpack', currentNodeEnv);
@@ -194,6 +197,11 @@ module.exports = {
194 }, 197 },
195 }, 198 },
196 plugins: [ 199 plugins: [
200 new DefinePlugin({
201 'DEBUG': JSON.stringify(devMode),
202 'PACKAGE_NAME': JSON.stringify(packageInfo.name),
203 'PACKAGE_VERSION': JSON.stringify(packageInfo.version),
204 }),
197 new MiniCssExtractPlugin({ 205 new MiniCssExtractPlugin({
198 filename: '[name].[contenthash].css', 206 filename: '[name].[contenthash].css',
199 chunkFilename: '[name].[contenthash].css', 207 chunkFilename: '[name].[contenthash].css',
diff --git a/language-web/yarn.lock b/language-web/yarn.lock
index 3aac4633..a307229f 100644
--- a/language-web/yarn.lock
+++ b/language-web/yarn.lock
@@ -1739,6 +1739,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
1739 dependencies: 1739 dependencies:
1740 color-convert "^2.0.1" 1740 color-convert "^2.0.1"
1741 1741
1742ansi-styles@^6.1.0:
1743 version "6.1.0"
1744 resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3"
1745 integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==
1746
1742anymatch@~3.1.2: 1747anymatch@~3.1.2:
1743 version "3.1.2" 1748 version "3.1.2"
1744 resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 1749 resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
@@ -4967,6 +4972,16 @@ logalot@^2.0.0, logalot@^2.1.0:
4967 figures "^1.3.5" 4972 figures "^1.3.5"
4968 squeak "^1.0.0" 4973 squeak "^1.0.0"
4969 4974
4975loglevel-plugin-prefix@^0.8.4:
4976 version "0.8.4"
4977 resolved "https://registry.yarnpkg.com/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz#2fe0e05f1a820317d98d8c123e634c1bd84ff644"
4978 integrity sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==
4979
4980loglevel@^1.7.1:
4981 version "1.7.1"
4982 resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
4983 integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
4984
4970longest-streak@^2.0.0: 4985longest-streak@^2.0.0:
4971 version "2.0.4" 4986 version "2.0.4"
4972 resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" 4987 resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"