Skip to content

Commit df4abe8

Browse files
authored
[OGUI-914] Disable debug logs for "Ops" filter (#3480)
* Disables DEBUG severity button and strips it from filters (including from an entered URL) when OPS mode is active * Updates default filter state to have OPS selected: `{"severity":{"in":"I W E F"},"level":{"max":1}}` * Sets level to OPS in default profile settings * Fixes an issue where Live mode would not reset the filters when the reset button was clicked * Adds tests for DEBUG button toggling and severity stripping * Updates existing tests to reflect new default filter criteria
1 parent 2765af7 commit df4abe8

11 files changed

Lines changed: 225 additions & 51 deletions

InfoLogger/lib/ProfileService.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class ProfileService {
5959
errsource: { match: '', exclude: '' },
6060
message: { match: '', exclude: '' },
6161
severity: { in: 'I W E F' },
62-
level: { max: null },
62+
level: { max: 1 },
6363
};
6464
}
6565

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @license
3+
* Copyright 2019-2020 CERN and copyright holders of ALICE O2.
4+
* See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
5+
* All rights not expressly granted are reserved.
6+
*
7+
* This software is distributed under the terms of the GNU General Public
8+
* License v3 (GPL Version 3), copied verbatim in the file "COPYING".
9+
*
10+
* In applying this license CERN does not waive the privileges and immunities
11+
* granted to it by virtue of its status as an Intergovernmental Organization
12+
* or submit itself to any jurisdiction.
13+
*/
14+
15+
/**
16+
* Maps each log level to the set of severity codes that are NOT available at that level.
17+
* @type {Map<number|null, string[]>}
18+
*/
19+
const DISABLED_SEVERITIES_BY_LEVEL = new Map([
20+
[1, ['D']],
21+
[6, []],
22+
[11, []],
23+
[null, []],
24+
]);
25+
26+
/**
27+
* Return the severity codes that are disabled for a given log level.
28+
* @param {number|null} level - the current log level (1=Ops, 6=Support, 11=Developer, null=Trace)
29+
* If provided a level not in the map, we enable all severities as this will be a custom event
30+
* @returns {string[]} severity codes that should be disabled at the given log level
31+
*/
32+
export const getDisabledSeverities = (level) => DISABLED_SEVERITIES_BY_LEVEL.get(level) ?? [];

InfoLogger/public/log/Log.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export default class Log extends Observable {
3333

3434
this.filter = new LogFilter(model);
3535
this.filter.bubbleTo(this);
36+
this.filter.observe(this.onFilterChange.bind(this));
3637

3738
this.focus = { // show date picker on focus
3839
timestampSince: false,
@@ -400,17 +401,22 @@ export default class Log extends Observable {
400401
}
401402
value = copy.join(' ');
402403
}
403-
if (this.filter.setCriteria(field, operator, value)) {
404-
if (this.isLiveModeRunning()) {
405-
this.model.ws.setFilter(this.model.log.filter.toStringifyFunction());
406-
this.model.notification.show(
407-
'The current live session has been adapted to the new filter configuration.',
408-
'primary',
409-
2000,
410-
);
411-
} else if (this.isActiveModeQuery()) {
412-
this.model.notification.show('Filters have changed. Query again for updated results', 'primary', 2000);
413-
}
404+
this.filter.setCriteria(field, operator, value);
405+
}
406+
407+
/**
408+
* Notify the active mode (live or query) that filters have changed.
409+
*/
410+
onFilterChange() {
411+
if (this.isLiveModeRunning()) {
412+
this.model.ws.setFilter(this.filter.toStringifyFunction());
413+
this.model.notification.show(
414+
'The current live session has been adapted to the new filter configuration.',
415+
'primary',
416+
2000,
417+
);
418+
} else if (this.isActiveModeQuery()) {
419+
this.model.notification.show('Filters have changed. Query again for updated results', 'primary', 2000);
414420
}
415421
}
416422

InfoLogger/public/log/cellContextMenu.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,10 @@ export const cellContextMenu = (model) => {
124124
hideMenu();
125125
},
126126
),
127-
createMenuItem(iconTrash(), 'danger', 'Clear Level Filter', () => {
128-
model.log.setCriteria('level', 'max', null);
127+
createMenuItem(iconTrash(), 'danger', 'Reset Level Filter', () => {
128+
model.log.setCriteria('level', 'max', 1);
129129
hideMenu();
130-
}, model.log.filter.criterias.level.max === null),
130+
}, model.log.filter.criterias.level.max === 1),
131131
];
132132
}
133133
return [

InfoLogger/public/logFilter/LogFilter.js

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import { Observable } from '/js/src/index.js';
1616
import { TEXT_FILTER_OPERATORS } from '../constants/text-filter-operators.const.js';
17+
import { getDisabledSeverities } from '../constants/log-level-filters.const.js';
1718

1819
/**
1920
* @typedef Criteria
@@ -88,6 +89,11 @@ export default class LogFilter extends Observable {
8889
throw new Error('unknown operator');
8990
}
9091

92+
// enforces on both severity and level as fromObject can set them in either order
93+
if (field === 'severity' || field === 'level') {
94+
this.enforceDisabledSeverities();
95+
}
96+
9197
this.notify();
9298
return true;
9399
} else {
@@ -153,6 +159,37 @@ export default class LogFilter extends Observable {
153159
TEXT_FILTER_OPERATORS.some((operator) => criteria[operator]?.trim()));
154160
}
155161

162+
/**
163+
* Check whether a severity is disabled for the current log level.
164+
* @param {string} severityCode - [D, I, W, E, F]
165+
* @returns {boolean} true if the severity is not allowed at the current level
166+
*/
167+
isSeverityDisabled(severityCode) {
168+
return getDisabledSeverities(this.criterias.level.max).includes(severityCode);
169+
}
170+
171+
/**
172+
* Remove any active severity selections that are disallowed by the current level.
173+
*/
174+
enforceDisabledSeverities() {
175+
const disabled = getDisabledSeverities(this.criterias.level.max);
176+
if (disabled.length === 0 || !this.criterias.severity.$in) {
177+
return;
178+
}
179+
180+
const current = this.criterias.severity.$in;
181+
if (!current) {
182+
return;
183+
}
184+
185+
const filteredSeverities = current.filter((s) => !disabled.includes(s));
186+
// Only update if there is a change
187+
if (filteredSeverities.length !== current.length) {
188+
this.criterias.severity.$in = filteredSeverities;
189+
this.criterias.severity.in = filteredSeverities.join(' ');
190+
}
191+
}
192+
156193
/**
157194
* Generates a function to filter a log passed as argument to it
158195
* Output of function is boolean.
@@ -389,11 +426,11 @@ export default class LogFilter extends Observable {
389426
},
390427
severity: {
391428
in: 'I W E F',
392-
$in: ['W', 'I', 'E', 'F'],
429+
$in: ['I', 'W', 'E', 'F'],
393430
},
394431
level: {
395-
max: null, // 0, 1, 6, 11, 21
396-
$max: null, // 0, 1, 6, 11, 21
432+
max: 1,
433+
$max: 1,
397434
},
398435
};
399436
this.notify();

InfoLogger/public/logFilter/commandFilters.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,18 @@ export default (model) => [
5959
* @param {string} value - a char to represent severity: W E F or I, can be many with spaces like 'W E'
6060
* @returns {vnode} - the button to toggle severity
6161
*/
62-
const buttonSeverity = (model, label, title, value) => h('button.btn', {
63-
className: model.log.filter.criterias.severity.in.includes(value) ? 'active' : '',
64-
onclick: (e) => {
65-
model.log.setCriteria('severity', 'in', value);
66-
e.target.blur(); // remove focus so user can 'enter' without actually toggle again the button
67-
},
68-
title: title,
69-
}, label);
62+
const buttonSeverity = (model, label, title, value) => {
63+
const disabled = model.log.filter.isSeverityDisabled(value);
64+
return h('button.btn', {
65+
className: disabled ? 'disabled' : model.log.filter.criterias.severity.in.includes(value) ? 'active' : '',
66+
onclick: disabled ? null : (e) => {
67+
model.log.setCriteria('severity', 'in', value);
68+
e.target.blur();
69+
},
70+
disabled,
71+
title: disabled ? `${label} is not available at the current log level` : title,
72+
}, label);
73+
};
7074

7175
/**
7276
* Makes a button to set filtering level (shifter, debug, etc) with number

InfoLogger/test/lib/mocha-profile-service.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ const DEFAULT_PROFILE = {
9494
errsource: { match: '', exclude: '' },
9595
message: { match: '', exclude: '' },
9696
severity: { in: 'I W E F' },
97-
level: { max: null },
97+
level: { max: 1 },
9898
},
9999
},
100100
};
@@ -135,7 +135,7 @@ const FULL_PROFILE = {
135135
errsource: { match: '', exclude: '' },
136136
message: { match: '', exclude: '' },
137137
severity: { in: 'I W E F' },
138-
level: { max: null },
138+
level: { max: 1 },
139139
},
140140
},
141141
};

InfoLogger/test/mocha-index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ describe('InfoLogger', function() {
9393
}
9494
});
9595

96-
it('should have redirected to default page "/?q={"severity":{"in":"I W E F"}}"', async function() {
96+
it('should have redirected to default page "/?q={"severity":{"in":"I W E F"},"level":{"max":1}}"', async function() {
9797
await page.goto(baseUrl, {waitUntil: 'networkidle0'});
9898
const location = await page.evaluate(() => window.location);
9999
const search = decodeURIComponent(location.search);
100100

101-
assert.deepStrictEqual(search, '?q={"severity":{"in":"I W E F"}}');
101+
assert.deepStrictEqual(search, '?q={"severity":{"in":"I W E F"},"level":{"max":1}}');
102102
});
103103

104104
require('./public/user-actions-mocha');

InfoLogger/test/public/live-mode-mocha.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe('Live Mode test-suite', async () => {
2727
const location = await page.evaluate(() => window.location);
2828
const search = decodeURIComponent(location.search);
2929

30-
assert.deepStrictEqual(search, '?q={"severity":{"in":"I W E F"}}');
30+
assert.deepStrictEqual(search, '?q={"severity":{"in":"I W E F"},"level":{"max":1}}');
3131
});
3232

3333
it('should successfully enable LIVE mode', async () => {
@@ -60,6 +60,7 @@ describe('Live Mode test-suite', async () => {
6060
await page.evaluate(() => window.model.log.liveStop('Paused'));
6161
await page.evaluate(() => {
6262
window.model.log.filter.resetCriteria();
63+
window.model.log.filter.setCriteria('level', 'max', null);
6364
window.model.log.filter.setCriteria('hostname', 'match', 'aldaqecs01-v1');
6465
});
6566
await page.evaluate(() => window.model.log.liveStart());
@@ -76,6 +77,7 @@ describe('Live Mode test-suite', async () => {
7677
await page.evaluate(() => window.model.log.liveStop('Query'));
7778
await page.evaluate(() => {
7879
window.model.log.filter.resetCriteria();
80+
window.model.log.filter.setCriteria('level', 'max', null);
7981
window.model.log.filter.setCriteria('hostname', 'exclude', 'aldaqdip01');
8082
});
8183
await page.evaluate(() => window.model.log.liveStart());
@@ -90,7 +92,10 @@ describe('Live Mode test-suite', async () => {
9092

9193
it('should filter messages based on SQL Wildcards `hostname` excluding `%ldaqdip%` and username matching `a_iceda_`'
9294
+ ' without changing state of live mode', async () => {
93-
await page.evaluate(() => window.model.log.filter.resetCriteria());
95+
await page.evaluate(() => {
96+
window.model.log.filter.resetCriteria();
97+
window.model.log.filter.setCriteria('level', 'max', null);
98+
});
9499
await page.evaluate(() => {
95100
window.model.log.setCriteria('hostname', 'exclude', '%ldaqdip%');
96101
window.model.log.setCriteria('username', 'match', 'a_iceda_');

InfoLogger/test/public/log-context-menu-mocha.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ describe('Cell Context Menu', async () => {
276276
it('should show correct actions for level field', async () => {
277277
await openContextMenu(page, 'level', '3', 100, 120);
278278
const labels = await getMenuActionLabels(page);
279-
assert.deepStrictEqual(labels, ['Set Level To Support', 'Set Level To Ops', 'Clear Level Filter', 'Copy', 'Open Inspector']);
279+
assert.deepStrictEqual(labels, ['Set Level To Support', 'Set Level To Ops', 'Reset Level Filter', 'Copy', 'Open Inspector']);
280280
});
281281
});
282282

@@ -561,7 +561,7 @@ describe('Cell Context Menu', async () => {
561561
});
562562
});
563563

564-
describe('Set/Clear level filter for level field', async () => {
564+
describe('Set/Reset Level Filter for level field', async () => {
565565
it('should set level to nearest threshold above via include', async () => {
566566
await openContextMenu(page, 'level', '3', 100, 120);
567567

@@ -586,34 +586,38 @@ describe('Cell Context Menu', async () => {
586586
assert.strictEqual(level.$max, 1);
587587
});
588588

589-
it('should disable "Clear Level Filter" when no level filter is set', async () => {
589+
it('should disable "Reset Level Filter" when level is already cleared', async () => {
590+
await page.evaluate(() => {
591+
window.model.log.filter.setCriteria('level', 'max', 1);
592+
});
593+
590594
await openContextMenu(page, 'level', '3', 100, 120);
591595

592-
assert.strictEqual(await isMenuItemDisabled(page, 'Clear Level Filter'), true);
596+
assert.strictEqual(await isMenuItemDisabled(page, 'Reset Level Filter'), true);
593597
});
594598

595-
it('should enable "Clear Level Filter" when a level filter is active', async () => {
599+
it('should enable "Reset Level Filter" when a level filter is active', async () => {
596600
await page.evaluate(() => {
597601
window.model.log.filter.setCriteria('level', 'max', 6);
598602
});
599603

600604
await openContextMenu(page, 'level', '3', 100, 120);
601605

602-
assert.strictEqual(await isMenuItemDisabled(page, 'Clear Level Filter'), false);
606+
assert.strictEqual(await isMenuItemDisabled(page, 'Reset Level Filter'), false);
603607
});
604608

605-
it('should clear level filter back to null', async () => {
609+
it('should reset level filter back to default', async () => {
606610
await page.evaluate(() => {
607611
window.model.log.filter.setCriteria('level', 'max', 6);
608612
});
609613

610614
await openContextMenu(page, 'level', '3', 100, 120);
611615

612-
await clickMenuItemByLabel(page, 'Clear Level Filter');
616+
await clickMenuItemByLabel(page, 'Reset Level Filter');
613617

614618
const level = await page.evaluate(() => window.model.log.filter.criterias.level);
615-
assert.strictEqual(level.max, null);
616-
assert.strictEqual(level.$max, null);
619+
assert.strictEqual(level.max, 1);
620+
assert.strictEqual(level.$max, 1);
617621
});
618622
});
619623

0 commit comments

Comments
 (0)