feat(logs): session log filename → DD-MM-YYYY-mdu-session-HH-MM (v3.3.107)
Per user request, the per-session log file is renamed from
fileuploader-session-YYYY-MM-DD_HH-MM-SS-<pid>.log to
DD-MM-YYYY-mdu-session-HH-MM.log (hour and minute only, no seconds or pid).
lib/log-mode.js:
- formatSessionStamp(date) returns `${DD}-${MM}-${YYYY}-mdu-session-${HH}-${MM}`
(the pid argument is dropped; main.js still passes process.pid, harmlessly
ignored). Same-minute restarts now share a session file, which is the intended
human-readable trade.
- the session branch of resolveLogFileName returns `${sessionId}${ext}` — the stamp
is the full app-defined stem and baseName is intentionally ignored for session
mode (single/daily still use the 'fileuploader' base).
- stripModeStampFromFileName recognizes the new format and resets to the default
'fileuploader' base (the new stem embeds no base, so the configured base is not
recoverable from it); the existing daily and old-session strip regexes are kept
for backward-compat with any persisted old paths, and the persist/re-resolve
round-trip stays idempotent (no compounding stamps).
Tests updated for the new format (formatSessionStamp, session resolveLogFileName,
the new-format strip, and the idempotency regression). 410 tests pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8fed8669f3
commit
66ae240794
@ -1,7 +1,7 @@
|
||||
// Log-file mode resolution for fileuploader.log:
|
||||
// - "single" → one file: fileuploader.log
|
||||
// - "daily" → per-day: fileuploader-YYYY-MM-DD.log
|
||||
// - "session" → per-launch: fileuploader-session-YYYY-MM-DD_HH-MM-SS-<pid>.log
|
||||
// - "session" → per-launch: DD-MM-YYYY-mdu-session-HH-MM.log
|
||||
//
|
||||
// Pure functions only — no fs, no Date.now() at call time — so they unit-test
|
||||
// cleanly and the main.js call sites pass in `new Date()` + the session stamp.
|
||||
@ -38,13 +38,10 @@
|
||||
return `${date.getFullYear()}-${_two(date.getMonth() + 1)}-${_two(date.getDate())}`;
|
||||
}
|
||||
|
||||
function formatSessionStamp(date, pid) {
|
||||
const d = `${date.getFullYear()}-${_two(date.getMonth() + 1)}-${_two(date.getDate())}`;
|
||||
const t = `${_two(date.getHours())}-${_two(date.getMinutes())}-${_two(date.getSeconds())}`;
|
||||
// PID disambiguates a same-second close→reopen — a human can't but two
|
||||
// automated runs might. Cheap belt to a suspenders-not-required problem.
|
||||
const pidStr = pid !== undefined && pid !== null ? `-${pid}` : '';
|
||||
return `${d}_${t}${pidStr}`;
|
||||
function formatSessionStamp(date) {
|
||||
const d = `${_two(date.getDate())}-${_two(date.getMonth() + 1)}-${date.getFullYear()}`;
|
||||
const t = `${_two(date.getHours())}-${_two(date.getMinutes())}`;
|
||||
return `${d}-mdu-session-${t}`;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,9 +64,10 @@
|
||||
const date = a.date instanceof Date ? a.date : new Date();
|
||||
return `${base}-${formatDateStamp(date)}${ext}`;
|
||||
}
|
||||
// session
|
||||
// session — the stamp is the full app-defined stem (DD-MM-YYYY-mdu-session-HH-MM),
|
||||
// independent of baseName.
|
||||
const sid = a.sessionId && String(a.sessionId).trim();
|
||||
if (sid) return `${base}-session-${sid}${ext}`;
|
||||
if (sid) return `${sid}${ext}`;
|
||||
// Defensive: if a session-id wasn't passed, fall back to single rather
|
||||
// than emit a malformed name. main.js always supplies one.
|
||||
return `${base}${ext}`;
|
||||
@ -85,6 +83,9 @@
|
||||
*/
|
||||
function stripModeStampFromFileName(fileName) {
|
||||
if (!fileName || typeof fileName !== 'string') return fileName;
|
||||
const newSessionRe = /^\d{2}-\d{2}-\d{4}-mdu-session-\d{2}-\d{2}(\.[^.]+)?$/;
|
||||
const mNew = fileName.match(newSessionRe);
|
||||
if (mNew) return `fileuploader${mNew[1] || ''}`;
|
||||
// Order matters: session first (longer, more specific) before daily.
|
||||
// Both regexes are anchored to $ with no nested/ambiguous quantifiers, so
|
||||
// matching is linear — the eslint security warning is precautionary.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "multi-hoster-uploader",
|
||||
"version": "3.3.106",
|
||||
"version": "3.3.107",
|
||||
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
||||
@ -1,3 +1,18 @@
|
||||
# v3.3.107 — session log filename template → DD-MM-YYYY-mdu-session-HH-MM
|
||||
|
||||
User: change the session log filename from fileuploader-session-YYYY-MM-DD_HH-MM-SS-<pid>.log to
|
||||
DD-MM-YYYY-mdu-session-HH-MM.log (hour-minute, no seconds/pid). lib/log-mode.js:
|
||||
- formatSessionStamp(date) now returns `${DD}-${MM}-${YYYY}-mdu-session-${HH}-${MM}` (pid arg dropped; main.js
|
||||
still passes process.pid, harmlessly ignored).
|
||||
- resolveLogFileName session branch returns `${sid}${ext}` (the stamp is the full app-defined stem, baseName
|
||||
ignored — single/daily still use baseName 'fileuploader').
|
||||
- stripModeStampFromFileName recognizes the new format (^DD-MM-YYYY-mdu-session-HH-MM(.ext)$) and resets to the
|
||||
default 'fileuploader' base (the new format embeds no base); the old daily + old-session strip regexes stay
|
||||
for backward-compat with any persisted old paths. The compounding round-trip stays idempotent.
|
||||
Tests updated (formatSessionStamp, resolveLogFileName session, strip new-format, idempotency). 410 pass.
|
||||
|
||||
---
|
||||
|
||||
# v3.3.106 — intermittent white-screen on startup (RDP/VM GPU) + export filename
|
||||
|
||||
Two asks. (A) White screen: user sometimes gets a PURE-WHITE window on start (no error banner, NOT even the
|
||||
|
||||
@ -57,13 +57,18 @@ test('resolveLogFileName: daily mode → fileuploader-YYYY-MM-DD.log', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('resolveLogFileName: session mode → fileuploader-session-<id>.log', () => {
|
||||
test('resolveLogFileName: session mode → <sessionId>.log (baseName ignored)', () => {
|
||||
assert.equal(
|
||||
resolveLogFileName({ baseName: 'fileuploader', ext: '.log', mode: 'session', sessionId: '2026-05-28_22-44-52-12345' }),
|
||||
'fileuploader-session-2026-05-28_22-44-52-12345.log'
|
||||
resolveLogFileName({ baseName: 'fileuploader', ext: '.log', mode: 'session', sessionId: '26-05-2026-mdu-session-22-44' }),
|
||||
'26-05-2026-mdu-session-22-44.log'
|
||||
);
|
||||
});
|
||||
|
||||
test('formatSessionStamp: DD-MM-YYYY-mdu-session-HH-MM', () => {
|
||||
const { formatSessionStamp } = require('../lib/log-mode');
|
||||
assert.equal(formatSessionStamp(new Date(2026, 5, 26, 6, 2, 36)), '26-06-2026-mdu-session-06-02');
|
||||
});
|
||||
|
||||
test('resolveLogFileName: session mode with missing sessionId falls back to single (never emits malformed name)', () => {
|
||||
assert.equal(
|
||||
resolveLogFileName({ baseName: 'fileuploader', ext: '.log', mode: 'session' }),
|
||||
@ -102,12 +107,16 @@ test('stripModeStampFromFileName: strips a session-stamp suffix (with and withou
|
||||
);
|
||||
});
|
||||
|
||||
test('stripModeStampFromFileName: new DD-MM-YYYY-mdu-session-HH-MM resets to the default base', () => {
|
||||
assert.equal(stripModeStampFromFileName('26-06-2026-mdu-session-06-02.log'), 'fileuploader.log');
|
||||
});
|
||||
|
||||
test('regression: resolveLogFileName(stripModeStampFromFileName(...)) is idempotent — persisting then re-resolving never compounds stamps', () => {
|
||||
// This is the exact bug shape: persist the resolved path, then on next call
|
||||
// re-resolve from the saved base — must produce the same file, not a doubled
|
||||
// session-stamped one. The fix is the strip; this test guards against
|
||||
// regressing _persistFallbackLogPath into the 3.3.35 bug.
|
||||
const sessionId = '2026-06-03_18-16-20-8132';
|
||||
const sessionId = '03-06-2026-mdu-session-18-16';
|
||||
const dailyDate = new Date(2026, 5, 3);
|
||||
for (const mode of ['daily', 'session']) {
|
||||
const date = mode === 'daily' ? dailyDate : new Date();
|
||||
@ -129,12 +138,7 @@ test('formatDateStamp: zero-pads month and day', () => {
|
||||
assert.equal(formatDateStamp(new Date(2026, 11, 31)), '2026-12-31');
|
||||
});
|
||||
|
||||
test('formatSessionStamp: produces YYYY-MM-DD_HH-MM-SS-pid', () => {
|
||||
const d = new Date(2026, 4, 28, 7, 9, 5);
|
||||
assert.equal(formatSessionStamp(d, 12345), '2026-05-28_07-09-05-12345');
|
||||
});
|
||||
|
||||
test('formatSessionStamp: omits the pid suffix when none provided', () => {
|
||||
const d = new Date(2026, 4, 28, 22, 44, 52);
|
||||
assert.equal(formatSessionStamp(d), '2026-05-28_22-44-52');
|
||||
test('formatSessionStamp: DD-MM-YYYY-mdu-session-HH-MM (no seconds/pid)', () => {
|
||||
assert.equal(formatSessionStamp(new Date(2026, 4, 28, 7, 9, 5)), '28-05-2026-mdu-session-07-09');
|
||||
assert.equal(formatSessionStamp(new Date(2026, 4, 28, 22, 44, 52)), '28-05-2026-mdu-session-22-44');
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user