mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-21 09:38:01 +02:00
Chore: Allow disabling deletion logging (#10105)
This commit is contained in:
parent
c16ce1c434
commit
49cd17e520
@ -1112,6 +1112,7 @@ packages/lib/themes/solarizedLight.js
|
|||||||
packages/lib/themes/type.js
|
packages/lib/themes/type.js
|
||||||
packages/lib/time.js
|
packages/lib/time.js
|
||||||
packages/lib/types.js
|
packages/lib/types.js
|
||||||
|
packages/lib/utils/ActionLogger.test.js
|
||||||
packages/lib/utils/ActionLogger.js
|
packages/lib/utils/ActionLogger.js
|
||||||
packages/lib/utils/credentialFiles.js
|
packages/lib/utils/credentialFiles.js
|
||||||
packages/lib/utils/ipc/RemoteMessenger.test.js
|
packages/lib/utils/ipc/RemoteMessenger.test.js
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1092,6 +1092,7 @@ packages/lib/themes/solarizedLight.js
|
|||||||
packages/lib/themes/type.js
|
packages/lib/themes/type.js
|
||||||
packages/lib/time.js
|
packages/lib/time.js
|
||||||
packages/lib/types.js
|
packages/lib/types.js
|
||||||
|
packages/lib/utils/ActionLogger.test.js
|
||||||
packages/lib/utils/ActionLogger.js
|
packages/lib/utils/ActionLogger.js
|
||||||
packages/lib/utils/credentialFiles.js
|
packages/lib/utils/credentialFiles.js
|
||||||
packages/lib/utils/ipc/RemoteMessenger.test.js
|
packages/lib/utils/ipc/RemoteMessenger.test.js
|
||||||
|
63
packages/lib/utils/ActionLogger.test.ts
Normal file
63
packages/lib/utils/ActionLogger.test.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import Logger, { LogLevel, TargetType } from '@joplin/utils/Logger';
|
||||||
|
import { setupDatabaseAndSynchronizer, switchClient } from '../testing/test-utils';
|
||||||
|
import Note from '../models/Note';
|
||||||
|
import ActionLogger from './ActionLogger';
|
||||||
|
import Setting from '../models/Setting';
|
||||||
|
import { pathExists, readFile, remove, writeFile } from 'fs-extra';
|
||||||
|
|
||||||
|
const getLogPath = () => `${Setting.value('profileDir')}/log.txt`;
|
||||||
|
|
||||||
|
const logContainsEntryWith = async (...terms: string[]) => {
|
||||||
|
const lines = (await readFile(getLogPath(), 'utf8')).split('\n');
|
||||||
|
for (const line of lines) {
|
||||||
|
if (terms.every(t => line.includes(t))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('ActionLogger', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await setupDatabaseAndSynchronizer(1);
|
||||||
|
await switchClient(1);
|
||||||
|
|
||||||
|
const logPath = getLogPath();
|
||||||
|
if (await pathExists(logPath)) {
|
||||||
|
await remove(logPath);
|
||||||
|
}
|
||||||
|
await writeFile(logPath, '', 'utf8');
|
||||||
|
|
||||||
|
const logger = new Logger();
|
||||||
|
logger.addTarget(TargetType.File, { path: logPath });
|
||||||
|
logger.setLevel(LogLevel.Info);
|
||||||
|
|
||||||
|
Logger.initializeGlobalLogger(logger);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log deletions', async () => {
|
||||||
|
const note = await Note.save({ title: 'MyTestNote' });
|
||||||
|
await Note.delete(note.id, { toTrash: false });
|
||||||
|
await Logger.globalLogger.waitForFileWritesToComplete_();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await logContainsEntryWith('DeleteAction', note.id, note.title),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be possible to disable ActionLogger globally', async () => {
|
||||||
|
const note1 = await Note.save({ title: 'testNote1' });
|
||||||
|
const note2 = await Note.save({ title: 'testNote2' });
|
||||||
|
|
||||||
|
ActionLogger.enabled = true;
|
||||||
|
await Note.delete(note1.id, { toTrash: false });
|
||||||
|
ActionLogger.enabled = false;
|
||||||
|
await Note.delete(note2.id, { toTrash: false });
|
||||||
|
ActionLogger.enabled = true;
|
||||||
|
await Logger.globalLogger.waitForFileWritesToComplete_();
|
||||||
|
|
||||||
|
expect(await logContainsEntryWith('DeleteAction', note1.id)).toBe(true);
|
||||||
|
expect(await logContainsEntryWith('DeleteAction', note2.id)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
@ -9,25 +9,29 @@ const actionTypeToLogger = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default class ActionLogger {
|
export default class ActionLogger {
|
||||||
private descriptions: string[] = [];
|
private descriptions_: string[] = [];
|
||||||
|
|
||||||
private constructor(private source: string) { }
|
private constructor(private source: string) { }
|
||||||
|
|
||||||
public clone() {
|
public clone() {
|
||||||
const clone = new ActionLogger(this.source);
|
const clone = new ActionLogger(this.source);
|
||||||
clone.descriptions = [...this.descriptions];
|
clone.descriptions_ = [...this.descriptions_];
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
// addDescription is used to add labels with information that may not be available
|
// addDescription is used to add labels with information that may not be available
|
||||||
// when .log is called. For example, to include the title of a deleted note.
|
// when .log is called. For example, to include the title of a deleted note.
|
||||||
public addDescription(description: string) {
|
public addDescription(description: string) {
|
||||||
this.descriptions.push(description);
|
this.descriptions_.push(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
public log(action: ItemActionType, itemIds: string|string[]) {
|
public log(action: ItemActionType, itemIds: string|string[]) {
|
||||||
|
if (!ActionLogger.enabled_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const logger = actionTypeToLogger[action];
|
const logger = actionTypeToLogger[action];
|
||||||
logger.info(`${this.source}: ${this.descriptions.join(',')}; Item IDs: ${JSON.stringify(itemIds)}`);
|
logger.info(`${this.source}: ${this.descriptions_.join(',')}; Item IDs: ${JSON.stringify(itemIds)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static from(source: ActionLogger|string|undefined) {
|
public static from(source: ActionLogger|string|undefined) {
|
||||||
@ -41,4 +45,17 @@ export default class ActionLogger {
|
|||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Disabling the action logger globally can be useful on Joplin Server/Cloud
|
||||||
|
// when many deletions are expected (e.g. for email-to-note).
|
||||||
|
private static enabled_ = true;
|
||||||
|
|
||||||
|
public static set enabled(v: boolean) {
|
||||||
|
this.enabled_ = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static get enabled() {
|
||||||
|
return this.enabled_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,6 +328,13 @@ class Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For tests
|
||||||
|
public async waitForFileWritesToComplete_() {
|
||||||
|
const release = await writeToFileMutex_.acquire();
|
||||||
|
release();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
public error(...object: any[]) {
|
public error(...object: any[]) {
|
||||||
return this.log(LogLevel.Error, null, ...object);
|
return this.log(LogLevel.Error, null, ...object);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user