New group logging

This commit is contained in:
Pierre committed 2026-09-27 22:54:08 +02:00
1 parent 400837b41a
commit cded4a0200
14 files changed
+324 -75

No files matched your search

@@ -45,3 +45,18 @@ test('bounds retained history',()=>{
e.poll();e.poll();assert.ok(e.entries.size<=10000);
});
process.on('exit',()=>fs.rmSync(root,{recursive:true,force:true}));
test('groups plain app.log lines between explicit initialization markers',()=>{
const e=explorer();messages=[];
fs.writeFileSync(file,[
'27-09-26 10:12:13 INFO kitchen: Initialization started [group=initialization:0123456789ab]',
'27-09-26 10:12:13 INFO kitchen: Setting up an output through app.log()',
'27-09-26 10:12:14 INFO kitchen: Configured helper [group=initialization:0123456789ab]',
'27-09-26 10:12:14 INFO kitchen: Initialization completed [group=initialization:0123456789ab]'
].join('\n')+'\n');e.poll();
const grouped=latest().filter(entry=>entry.app==='kitchen');
assert.equal(grouped.length,4);
assert.deepEqual(grouped.map(entry=>entry.initialization_id),Array(4).fill('0123456789ab'));
assert.equal(grouped[1].group_inferred,true);
assert.equal(grouped[2].group_inferred,undefined);
});
+6
View File
@@ -27,3 +27,9 @@ test('raw initialization IDs are retained without structured events', () => {
const e=parseLine('27-09-26 10:12:13 INFO app: Setting up [event=e1 trace=t1] [init=init1]','log',0);
assert.equal(e.initialization_id,'init1'); assert.equal(e.phase,'initialization');
});
test('parses readable group tags without changing the log message format', () => {
const e=parseLine('27-09-26 10:12:13 INFO app: Selected value [group=value_selector:0123456789ab]','log',0);
assert.equal(e.group_id,'0123456789ab'); assert.equal(e.group_kind,'value_selector');
assert.equal(e.initialization_id,undefined); assert.match(e.message,/\[group=value_selector:/);
});
+23 -6
View File
@@ -26,18 +26,20 @@ test('English interface, latest timestamps, sorting and separate initialization
d.getElementById('sort').value='oldest';d.getElementById('sort').dispatchEvent(new dom.window.Event('input'));
assert.equal(d.querySelector('[data-app]').dataset.app,'alpha');
const alpha=d.querySelector('[data-app="alpha"]');alpha.open=true;alpha.dispatchEvent(new dom.window.Event('toggle'));
assert.equal(alpha.querySelectorAll('.init-group').length,2);
d.getElementById('group-init').checked=false;d.getElementById('group-init').dispatchEvent(new dom.window.Event('input'));
assert.equal(d.querySelectorAll('.init-group').length,0);
assert.equal(d.querySelector('[data-app="alpha"]').querySelectorAll('.row').length,4);
assert.equal(alpha.querySelectorAll('.rows>.row').length,3);
assert.equal(alpha.querySelectorAll('.event-log-group').length,1);
assert.equal(alpha.querySelector('.event-log-group .row-message').textContent,'Preparing sensors\nReady');
assert.equal(alpha.querySelectorAll('.rows details').length,0);
assert.equal(d.getElementById('group-init'),null);
assert.deepEqual(errors,[]);dom.window.close();
});
test('copies selected logs and entire initialization groups through VS Code transport',()=>{
const {dom,d,sent,errors}=setup();const alpha=d.querySelector('[data-app="alpha"]');alpha.open=true;alpha.dispatchEvent(new dom.window.Event('toggle'));
[...alpha.querySelectorAll('.row')].find(e=>e.textContent.includes('Température déjà disponible')).click();d.getElementById('copy').click();
assert.equal(sent.at(-1).type,'copy');assert.match(sent.at(-1).text,/Température déjà disponible/);
const groups=[...alpha.querySelectorAll('.init-group')];
groups.find(e=>e.textContent.includes('Preparing sensors')).querySelector('.init-rows>button').click();
const group=alpha.querySelector('.event-log-group');
group.click();d.getElementById('copy').click();
assert.match(d.getElementById('detail').textContent,/Preparing sensors\s+Ready/);
assert.match(sent.at(-1).text,/Preparing sensors/);assert.match(sent.at(-1).text,/Ready/);assert.doesNotMatch(sent.at(-1).text,/Restarting/);
const input=d.getElementById('search'),paste=new dom.window.KeyboardEvent('keydown',{key:'v',ctrlKey:true,bubbles:true,cancelable:true});input.dispatchEvent(paste);assert.equal(paste.defaultPrevented,false);
assert.deepEqual(errors,[]);dom.window.close();
@@ -140,3 +142,18 @@ test('shows and refreshes relative time on each log entry while retaining exact
dom.window.close();
});
test('shows consecutive logs from one explicit group as a single visible row',()=>{
const {dom,d,entries,send}=setup();
const group=[
{...entries[3],event_id:'selector-1',time:entries[3].time+1000,message:'Rejected candidate',group_id:'0123456789ab',group_kind:'value_selector'},
{...entries[3],event_id:'selector-2',time:entries[3].time+1000,message:'Selected candidate',group_id:'0123456789ab',group_kind:'value_selector'}
];
send(group);
const app=d.querySelector('[data-app="alpha"]');app.open=true;app.dispatchEvent(new dom.window.Event('toggle'));
const rows=[...app.querySelectorAll('.rows>.row')].filter(row=>row.textContent.includes('Rejected candidate'));
assert.equal(rows.length,1);assert.ok(rows[0].classList.contains('event-log-group'));
assert.match(rows[0].querySelector('.row-message').textContent,/Rejected candidate\nSelected candidate/);
assert.doesNotMatch(rows[0].textContent,/\[group=/);
dom.window.close();
});