Skip to content

Commit bc64dd4

Browse files
authored
Merge pull request #536 from highcharts/feat/disabling-logging
feat/disabling-logging
2 parents 478aec3 + 87ea9d4 commit bc64dd4

File tree

9 files changed

+140
-71
lines changed

9 files changed

+140
-71
lines changed

.env.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ POOL_BENCHMARKING = false
6262
LOGGING_LEVEL = 4
6363
LOGGING_FILE = highcharts-export-server.log
6464
LOGGING_DEST = log/
65+
LOGGING_TO_CONSOLE = true
66+
LOGGING_TO_FILE = true
6567

6668
# UI CONFIG
6769
UI_ENABLE = true

README.md

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ The format, along with its default values, is as follows (using the recommended
111111
"map",
112112
"gantt",
113113
"exporting",
114-
"export-data",
115114
"parallel-coordinates",
116115
"accessibility",
117116
"annotations-advanced",
@@ -169,14 +168,17 @@ The format, along with its default values, is as follows (using the recommended
169168
"marker-clusters",
170169
"hollowcandlestick",
171170
"heikinashi",
172-
"flowmap"
171+
"flowmap",
172+
"export-data",
173+
"navigator",
174+
"textpath"
173175
],
174176
"indicatorScripts": [
175177
"indicators-all"
176178
],
177179
"customScripts": [
178-
"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js",
179-
"https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.34/moment-timezone-with-data.min.js"
180+
"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js",
181+
"https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data.min.js"
180182
],
181183
"forceFetch": false,
182184
"cachePath": ".cache"
@@ -246,7 +248,9 @@ The format, along with its default values, is as follows (using the recommended
246248
"logging": {
247249
"level": 4,
248250
"file": "highcharts-export-server.log",
249-
"dest": "log/"
251+
"dest": "log/",
252+
"toConsole": true,
253+
"toFile": true
250254
},
251255
"ui": {
252256
"enable": false,
@@ -350,8 +354,10 @@ These variables are set in your environment and take precedence over options fro
350354
### Logging Config
351355

352356
- `LOGGING_LEVEL`: The logging level to be used. Can be **0** - silent, **1** - error, **2** - warning, **3** - notice, **4** - verbose or **5** benchmark (defaults to `4`).
353-
- `LOGGING_FILE`: The name of a log file. The `logDest` option also needs to be set to enable file logging (defaults to `highcharts-export-server.log`).
354-
- `LOGGING_DEST`: The path to store log files. This also enables file logging (defaults to `log/`).
357+
- `LOGGING_FILE`: The name of a log file. The `logToFile` and `logDest` options also need to be set to enable file logging (defaults to `highcharts-export-server.log`).
358+
- `LOGGING_DEST`: The path to store log files. The `logToFile` option also needs to be set to enable file logging (defaults to `log/`).
359+
- `LOGGING_TO_CONSOLE`: Enables or disables showing logs in the console (defaults to `true`).
360+
- `LOGGING_TO_FILE`: Enables or disables creation of the log directory and saving the log into a .log file (defaults to `true`).
355361

356362
### UI Config
357363

@@ -431,8 +437,10 @@ _Available options:_
431437
- `--reaperInterval`: The duration, in milliseconds, after which the check for idle resources to destroy is triggered (defaults to `1000`).
432438
- `--poolBenchmarking`: Indicate whether to show statistics for the pool of resources or not (defaults to `false`).
433439
- `--logLevel`: The logging level to be used. Can be **0** - silent, **1** - error, **2** - warning, **3** - notice, **4** - verbose or **5** - benchmark (defaults to `4`).
434-
- `--logFile`: The name of a log file. The `--logDest` option also needs to be set to enable file logging (defaults to `highcharts-export-server.log`).
435-
- `--logDest`: The path to store log files. This also enables file logging (defaults to `log/`).
440+
- `--logFile`: The name of a log file. The `logToFile` and `logDest` options also need to be set to enable file logging (defaults to `highcharts-export-server.log`).
441+
- `--logDest`: The path to store log files. The `logToFile` option also needs to be set to enable file logging (defaults to `log/`).
442+
- `--logToConsole`: Enables or disables showing logs in the console (defaults to `true`).
443+
- `--logToFile`: Enables or disables creation of the log directory and saving the log into a .log file (defaults to `true`).
436444
- `--enableUi`: Enables or disables the user interface (UI) for the Export Server (defaults to `false`).
437445
- `--uiRoute`: The endpoint route to which the user interface (UI) should be attached (defaults to `/`).
438446
- `--nodeEnv`: The type of Node.js environment (defaults to `production`).

lib/envs.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ export const Config = z.object({
194194
.transform((value) => (value !== '' ? parseFloat(value) : undefined)),
195195
LOGGING_FILE: v.string(),
196196
LOGGING_DEST: v.string(),
197+
LOGGING_TO_CONSOLE: v.boolean(),
198+
LOGGING_TO_FILE: v.boolean(),
197199

198200
// ui
199201
UI_ENABLE: v.boolean(),

lib/logger.js

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ See LICENSE file in root for details.
1414

1515
import { appendFile, existsSync, mkdirSync } from 'fs';
1616

17-
import { defaultConfig } from './schemas/config.js';
18-
1917
// The available colors
2018
const colors = ['red', 'yellow', 'blue', 'gray', 'green'];
2119

@@ -52,11 +50,6 @@ let logging = {
5250
listeners: []
5351
};
5452

55-
// Gather init logging options
56-
for (const [key, option] of Object.entries(defaultConfig.logging)) {
57-
logging[key] = option.value;
58-
}
59-
6053
/**
6154
* Logs the provided texts to a file, if file logging is enabled. It creates
6255
* the necessary directory structure if not already created and appends the
@@ -66,28 +59,26 @@ for (const [key, option] of Object.entries(defaultConfig.logging)) {
6659
* @param {string} prefix - An optional prefix to be added to each log entry.
6760
*/
6861
const logToFile = (texts, prefix) => {
69-
if (logging.toFile) {
70-
if (!logging.pathCreated) {
71-
// Create if does not exist
72-
!existsSync(logging.dest) && mkdirSync(logging.dest);
62+
if (!logging.pathCreated) {
63+
// Create if does not exist
64+
!existsSync(logging.dest) && mkdirSync(logging.dest);
7365

74-
// We now assume the path is available, e.g. it's the responsibility
75-
// of the user to create the path with the correct access rights.
76-
logging.pathCreated = true;
77-
}
66+
// We now assume the path is available, e.g. it's the responsibility
67+
// of the user to create the path with the correct access rights.
68+
logging.pathCreated = true;
69+
}
7870

79-
// Add the content to a file
80-
appendFile(
81-
`${logging.dest}${logging.file}`,
82-
[prefix].concat(texts).join(' ') + '\n',
83-
(error) => {
84-
if (error) {
85-
console.log(`[logger] Unable to write to log file: ${error}`);
86-
logging.toFile = false;
87-
}
71+
// Add the content to a file
72+
appendFile(
73+
`${logging.dest}${logging.file}`,
74+
[prefix].concat(texts).join(' ') + '\n',
75+
(error) => {
76+
if (error) {
77+
console.log(`[logger] Unable to write to log file: ${error}`);
78+
logging.toFile = false;
8879
}
89-
);
90-
}
80+
}
81+
);
9182
};
9283

9384
/**
@@ -102,7 +93,7 @@ export const log = (...args) => {
10293
const [newLevel, ...texts] = args;
10394

10495
// Current logging options
105-
const { level, levelsDesc } = logging;
96+
const { levelsDesc, level } = logging;
10697

10798
// Check if log level is within a correct range or is a benchmark log
10899
if (
@@ -132,7 +123,9 @@ export const log = (...args) => {
132123
}
133124

134125
// Log to file
135-
logToFile(texts, prefix);
126+
if (logging.toFile) {
127+
logToFile(texts, prefix);
128+
}
136129
};
137130

138131
/**
@@ -189,7 +182,9 @@ export const logWithStack = (newLevel, error, customMessage) => {
189182
});
190183

191184
// Log to file
192-
logToFile(texts, prefix);
185+
if (logging.toFile) {
186+
logToFile(texts, prefix);
187+
}
193188
};
194189

195190
/**
@@ -231,17 +226,22 @@ export const enableFileLogging = (logDest, logFile) => {
231226
/**
232227
* Initializes logging with the specified logging configuration.
233228
*
234-
* @param {Object} logging - The logging configuration object.
229+
* @param {Object} loggingOptions - The logging configuration object.
235230
*/
236-
export const initLogging = (logging) => {
231+
export const initLogging = (loggingOptions) => {
232+
// Set all the logging options on our logging module object
233+
for (const [key, value] of Object.entries(loggingOptions)) {
234+
logging[key] = value;
235+
}
236+
237237
// Set the log level
238-
setLogLevel(logging && parseInt(logging.level));
238+
setLogLevel(loggingOptions && parseInt(loggingOptions.level));
239239

240240
// Set the log file path and name
241-
if (logging && logging.dest) {
241+
if (loggingOptions && loggingOptions.dest && loggingOptions.toFile) {
242242
enableFileLogging(
243-
logging.dest,
244-
logging.file || 'highcharts-export-server.log'
243+
loggingOptions.dest,
244+
loggingOptions.file || 'highcharts-export-server.log'
245245
);
246246
}
247247
};
@@ -255,22 +255,11 @@ export const listen = (fn) => {
255255
logging.listeners.push(fn);
256256
};
257257

258-
/**
259-
* Toggles the standard output (console) logging.
260-
*
261-
* @param {boolean} enabled - If true, enables console logging; if false,
262-
* disables it.
263-
*/
264-
export const toggleSTDOut = (enabled) => {
265-
logging.toConsole = enabled;
266-
};
267-
268258
export default {
269259
log,
270260
logWithStack,
271261
setLogLevel,
272262
enableFileLogging,
273263
initLogging,
274-
listen,
275-
toggleSTDOut
264+
listen
276265
};

lib/sanitize.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ import DOMPurify from 'dompurify';
3131
export function sanitize(input) {
3232
const window = new JSDOM('').window;
3333
const purify = DOMPurify(window);
34-
/// return purify.sanitize(input, { ADD_TAGS: ['foreignObject'] });
35-
return purify.sanitize(input);
34+
return purify.sanitize(input, { ADD_TAGS: ['foreignObject'] });
3635
}
3736

3837
export default sanitize;

lib/schemas/config.js

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ export const scriptsNames = {
8383
'navigator',
8484
'textpath'
8585
],
86-
indicators: ['indicators-all']
86+
indicators: ['indicators-all'],
87+
custom: [
88+
'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js',
89+
'https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data.min.js'
90+
]
8791
};
8892

8993
// This is the configuration object with all options and their default values,
@@ -176,10 +180,7 @@ export const defaultConfig = {
176180
description: 'The indicators of Highcharts to fetch.'
177181
},
178182
customScripts: {
179-
value: [
180-
'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js',
181-
'https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.34/moment-timezone-with-data.min.js'
182-
],
183+
value: scriptsNames.custom,
183184
type: 'string[]',
184185
description: 'Additional custom scripts or dependencies to fetch.'
185186
},
@@ -567,15 +568,30 @@ export const defaultConfig = {
567568
envLink: 'LOGGING_FILE',
568569
cliName: 'logFile',
569570
description:
570-
'The name of a log file. The logDest option also needs to be set to enable file logging.'
571+
'The name of a log file. The `logToFile` and `logDest` options also need to be set to enable file logging.'
571572
},
572573
dest: {
573574
value: 'log/',
574575
type: 'string',
575576
envLink: 'LOGGING_DEST',
576577
cliName: 'logDest',
577578
description:
578-
'The path to store log files. This also enables file logging.'
579+
'The path to store log files. The `logToFile` option also needs to be set to enable file logging.'
580+
},
581+
toConsole: {
582+
value: true,
583+
type: 'boolean',
584+
envLink: 'LOGGING_TO_CONSOLE',
585+
cliName: 'logToConsole',
586+
description: 'Enables or disables showing logs in the console.'
587+
},
588+
toFile: {
589+
value: true,
590+
type: 'boolean',
591+
envLink: 'LOGGING_TO_FILE',
592+
cliName: 'logToFile',
593+
description:
594+
'Enables or disables creation of the log directory and saving the log into a .log file.'
579595
}
580596
},
581597
ui: {
@@ -1001,14 +1017,27 @@ export const promptsConfig = {
10011017
{
10021018
type: 'text',
10031019
name: 'file',
1004-
message: 'A log file name. Set with the --logDest to enable file logging',
1020+
message:
1021+
'A log file name. Set with --toFile and --logDest to enable file logging',
10051022
initial: defaultConfig.logging.file.value
10061023
},
10071024
{
10081025
type: 'text',
10091026
name: 'dest',
1010-
message: 'The path to log files. Enables file logging',
1027+
message: 'The path to a log file when the file logging is enabled',
10111028
initial: defaultConfig.logging.dest.value
1029+
},
1030+
{
1031+
type: 'toggle',
1032+
name: 'toConsole',
1033+
message: 'Enable logging to the console',
1034+
initial: defaultConfig.logging.toConsole.value
1035+
},
1036+
{
1037+
type: 'toggle',
1038+
name: 'toFile',
1039+
message: 'Enables logging to a file',
1040+
initial: defaultConfig.logging.toFile.value
10121041
}
10131042
],
10141043
ui: [

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"http-tests-single": "node ./tests/http/http_test_runner_single.js",
3535
"node-tests": "node ./tests/node/node_test_runner.js",
3636
"node-tests-single": "node ./tests/node/node_test_runner_single.js",
37-
"prepare": "husky install || true",
37+
"prepare": "husky || true",
3838
"build": "rollup -c",
3939
"unit:test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
4040
},

tests/unit/sanitize.test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,44 @@ describe('sanitize', () => {
4444
const output = sanitize(input);
4545
expect(output).toBe('');
4646
});
47+
48+
it('removes standalone foreignObject element', () => {
49+
const input = '<foreignObject>The foreignObject element</foreignObject>';
50+
const output = sanitize(input);
51+
expect(output).toBe('');
52+
});
53+
54+
it('removes foreignObject element along with the containing iframe and b tags', () => {
55+
const input =
56+
"<foreignObject><iframe src=''></iframe><b>Hello</b></foreignObject>";
57+
const output = sanitize(input);
58+
expect(output).toBe('');
59+
});
60+
61+
it('does not remove foreignObject element from SVG', () => {
62+
const input =
63+
'<svg><foreignObject>The foreignObject tag</foreignObject></svg>';
64+
const output = sanitize(input);
65+
expect(output).toBe(
66+
'<svg><foreignObject>The foreignObject tag</foreignObject></svg>'
67+
);
68+
});
69+
70+
it('does not remove foreignObject with HTML tag inside from SVG', () => {
71+
const input =
72+
'<svg><foreignObject><span>HTML element</span></foreignObject></svg>';
73+
const output = sanitize(input);
74+
expect(output).toBe(
75+
'<svg><foreignObject><span>HTML element</span></foreignObject></svg>'
76+
);
77+
});
78+
79+
it('removes iframe tag and leaves b tag inside foreignObject element from SVG', () => {
80+
const input =
81+
"<svg><foreignObject><iframe src='<internal AWS UP>'></iframe><b>Hello</b></foreignObject></svg>";
82+
const output = sanitize(input);
83+
expect(output).toBe(
84+
'<svg><foreignObject><b>Hello</b></foreignObject></svg>'
85+
);
86+
});
4787
});

0 commit comments

Comments
 (0)