diff --git a/.eslintignore b/.eslintignore index 24134f65f..207f5fcc7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1638,6 +1638,9 @@ packages/lib/services/synchronizer/migrations/2.js.map packages/lib/services/synchronizer/migrations/3.d.ts packages/lib/services/synchronizer/migrations/3.js packages/lib/services/synchronizer/migrations/3.js.map +packages/lib/services/synchronizer/syncDebugLog.d.ts +packages/lib/services/synchronizer/syncDebugLog.js +packages/lib/services/synchronizer/syncDebugLog.js.map packages/lib/services/synchronizer/syncInfoUtils.d.ts packages/lib/services/synchronizer/syncInfoUtils.js packages/lib/services/synchronizer/syncInfoUtils.js.map diff --git a/.gitignore b/.gitignore index 09a76e105..cd1b1d266 100644 --- a/.gitignore +++ b/.gitignore @@ -1621,6 +1621,9 @@ packages/lib/services/synchronizer/migrations/2.js.map packages/lib/services/synchronizer/migrations/3.d.ts packages/lib/services/synchronizer/migrations/3.js packages/lib/services/synchronizer/migrations/3.js.map +packages/lib/services/synchronizer/syncDebugLog.d.ts +packages/lib/services/synchronizer/syncDebugLog.js +packages/lib/services/synchronizer/syncDebugLog.js.map packages/lib/services/synchronizer/syncInfoUtils.d.ts packages/lib/services/synchronizer/syncInfoUtils.js packages/lib/services/synchronizer/syncInfoUtils.js.map diff --git a/packages/app-desktop/app.ts b/packages/app-desktop/app.ts index f8c9f31d3..b14b9a136 100644 --- a/packages/app-desktop/app.ts +++ b/packages/app-desktop/app.ts @@ -60,6 +60,7 @@ import editorCommandDeclarations from './gui/NoteEditor/editorCommandDeclaration import ShareService from '@joplin/lib/services/share/ShareService'; import checkForUpdates from './checkForUpdates'; import { AppState } from './app.reducer'; +import syncDebugLog from '../lib/services/synchronizer/syncDebugLog'; // import { runIntegrationTests } from '@joplin/lib/services/e2ee/ppkTestUtils'; const pluginClasses = [ @@ -355,7 +356,14 @@ class Application extends BaseApplication { reg.logger().info('app.start: doing regular boot'); - const dir = Setting.value('profileDir'); + const dir: string = Setting.value('profileDir'); + + syncDebugLog.enabled = false; + + if (dir.endsWith('dev-desktop-2')) { + syncDebugLog.enabled = true; + syncDebugLog.info(`Profile dir: ${dir}`); + } // Loads app-wide styles. (Markdown preview-specific styles loaded in app.js) const filename = Setting.custom_css_files.JOPLIN_APP; diff --git a/packages/lib/Logger.ts b/packages/lib/Logger.ts index 7462f0d79..b0f481125 100644 --- a/packages/lib/Logger.ts +++ b/packages/lib/Logger.ts @@ -20,8 +20,7 @@ export enum LogLevel { Debug = 40, } -interface Target { - type: TargetType; +interface TargetOptions { level?: LogLevel; database?: any; console?: any; @@ -36,6 +35,10 @@ interface Target { formatInfo?: string; } +interface Target extends TargetOptions { + type: TargetType; +} + export interface LoggerWrapper { debug: Function; info: Function; @@ -103,11 +106,11 @@ class Logger { return this.targets_; } - addTarget(type: TargetType, options: any = null) { + addTarget(type: TargetType, options: TargetOptions = null) { const target = { type: type }; for (const n in options) { if (!options.hasOwnProperty(n)) continue; - (target as any)[n] = options[n]; + (target as any)[n] = (options as any)[n]; } this.targets_.push(target); diff --git a/packages/lib/Synchronizer.ts b/packages/lib/Synchronizer.ts index a81fb4586..4f92544c0 100644 --- a/packages/lib/Synchronizer.ts +++ b/packages/lib/Synchronizer.ts @@ -25,6 +25,7 @@ import JoplinDatabase from './JoplinDatabase'; import { fetchSyncInfo, getActiveMasterKey, localSyncInfo, mergeSyncInfos, saveLocalSyncInfo, SyncInfo, syncInfoEquals, uploadSyncInfo } from './services/synchronizer/syncInfoUtils'; import { getMasterPassword, setupAndDisableEncryption, setupAndEnableEncryption } from './services/e2ee/utils'; import { generateKeyPair } from './services/e2ee/ppk'; +import syncDebugLog from './services/synchronizer/syncDebugLog'; const { sprintf } = require('sprintf-js'); const { Dirnames } = require('./services/synchronizer/utils/types'); @@ -197,7 +198,7 @@ export default class Synchronizer { return lines; } - logSyncOperation(action: any, local: any = null, remote: RemoteItem = null, message: string = null, actionCount: number = 1) { + logSyncOperation(action: string, local: any = null, remote: RemoteItem = null, message: string = null, actionCount: number = 1) { const line = ['Sync']; line.push(action); if (message) line.push(message); @@ -225,6 +226,8 @@ export default class Synchronizer { logger.debug(line.join(': ')); } + if (!['fetchingProcessed', 'fetchingTotal'].includes(action)) syncDebugLog.info(line.join(': ')); + if (!this.progressReport_[action]) this.progressReport_[action] = 0; this.progressReport_[action] += actionCount; this.progressReport_.state = this.state(); diff --git a/packages/lib/models/Folder.ts b/packages/lib/models/Folder.ts index 2e1b8c34e..c96fa27ef 100644 --- a/packages/lib/models/Folder.ts +++ b/packages/lib/models/Folder.ts @@ -8,6 +8,7 @@ import BaseItem from './BaseItem'; import Resource from './Resource'; import { isRootSharedFolder } from '../services/share/reducer'; import Logger from '../Logger'; +import syncDebugLog from '../services/synchronizer/syncDebugLog'; const { substrWithEllipsis } = require('../string-utils.js'); const logger = Logger.create('models/Folder'); @@ -651,6 +652,8 @@ export default class Folder extends BaseItem { if (o.title == Folder.conflictFolderTitle()) throw new Error(_('Notebooks cannot be named "%s", which is a reserved title.', o.title)); } + syncDebugLog.info('Folder Save:', o); + return super.save(o, options).then((folder: FolderEntity) => { this.dispatch({ type: 'FOLDER_UPDATE_ONE', diff --git a/packages/lib/models/Note.ts b/packages/lib/models/Note.ts index 639be8649..3d2cb1132 100644 --- a/packages/lib/models/Note.ts +++ b/packages/lib/models/Note.ts @@ -10,6 +10,7 @@ import Tag from './Tag'; const { sprintf } = require('sprintf-js'); import Resource from './Resource'; +import syncDebugLog from '../services/synchronizer/syncDebugLog'; const { pregQuote, substrWithEllipsis } = require('../string-utils.js'); const { _ } = require('../locale'); const ArrayUtils = require('../ArrayUtils.js'); @@ -664,6 +665,8 @@ export default class Note extends BaseItem { // Trying to fix: https://github.com/laurent22/joplin/issues/3893 const oldNote = !isNew && o.id ? await Note.load(o.id) : null; + syncDebugLog.info('Save Note: P:', oldNote); + let beforeNoteJson = null; if (oldNote && this.revisionService().isOldNote(o.id)) { beforeNoteJson = JSON.stringify(oldNote); @@ -680,6 +683,8 @@ export default class Note extends BaseItem { } } + syncDebugLog.info('Save Note: N:', o); + const note = await super.save(o, options); const changeSource = options && options.changeSource ? options.changeSource : null; diff --git a/packages/lib/services/synchronizer/syncDebugLog.ts b/packages/lib/services/synchronizer/syncDebugLog.ts new file mode 100644 index 000000000..6784079ee --- /dev/null +++ b/packages/lib/services/synchronizer/syncDebugLog.ts @@ -0,0 +1,13 @@ +// The sync debug log can be used to view from a single file a sequence of sync +// related events. In particular, it logs notes and folders being saved, and the +// relevant sync operations. + +import Logger, { TargetType } from '../../Logger'; +import { homedir } from 'os'; + +const syncDebugLog = new Logger(); +syncDebugLog.addTarget(TargetType.File, { + path: `${homedir()}/synclog.txt`, +}); + +export default syncDebugLog;