move logging.js to ts

pull/2239/head
Audric Ackermann 3 years ago
parent d37d7af667
commit 175c0e4843

@ -101,7 +101,7 @@
"react-toastify": "^6.0.9", "react-toastify": "^6.0.9",
"react-use": "^17.2.1", "react-use": "^17.2.1",
"react-virtualized": "9.22.3", "react-virtualized": "9.22.3",
"read-last-lines": "1.3.0", "read-last-lines-ts": "^1.2.1",
"redux": "4.0.1", "redux": "4.0.1",
"redux-logger": "3.0.6", "redux-logger": "3.0.6",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
@ -119,6 +119,7 @@
"@types/better-sqlite3": "5.4.1", "@types/better-sqlite3": "5.4.1",
"@types/blueimp-load-image": "5.14.4", "@types/blueimp-load-image": "5.14.4",
"@types/buffer-crc32": "^0.2.0", "@types/buffer-crc32": "^0.2.0",
"@types/bunyan": "^1.8.8",
"@types/bytebuffer": "^5.0.41", "@types/bytebuffer": "^5.0.41",
"@types/chai": "4.2.18", "@types/chai": "4.2.18",
"@types/chai-as-promised": "^7.1.2", "@types/chai-as-promised": "^7.1.2",
@ -129,6 +130,7 @@
"@types/electron-is-dev": "^1.1.1", "@types/electron-is-dev": "^1.1.1",
"@types/emoji-mart": "^2.11.3", "@types/emoji-mart": "^2.11.3",
"@types/filesize": "3.6.0", "@types/filesize": "3.6.0",
"@types/firstline": "^2.0.2",
"@types/fs-extra": "5.0.5", "@types/fs-extra": "5.0.5",
"@types/jquery": "3.3.29", "@types/jquery": "3.3.29",
"@types/libsodium-wrappers-sumo": "^0.7.5", "@types/libsodium-wrappers-sumo": "^0.7.5",

@ -1,29 +1,30 @@
// NOTE: Temporarily allow `then` until we convert the entire file to `async` / `await`: // NOTE: Temporarily allow `then` until we convert the entire file to `async` / `await`:
/* eslint-disable more/no-then */ /* eslint-disable more/no-then */
const path = require('path'); import path from 'path';
const fs = require('fs'); import fs from 'fs';
const electron = require('electron'); import { app, ipcMain as ipc } from 'electron';
const bunyan = require('bunyan'); import Logger from 'bunyan';
const _ = require('lodash'); import _ from 'lodash';
const readFirstLine = require('firstline'); import firstline from 'firstline';
const readLastLines = require('read-last-lines').read; import { readLastLinesEnc } from 'read-last-lines-ts';
const rimraf = require('rimraf'); import rimraf from 'rimraf';
const { redactAll } = require('../ts/util/privacy'); import { redactAll } from '../util/privacy';
const { app, ipcMain: ipc } = electron;
const LEVELS = ['fatal', 'error', 'warn', 'info', 'debug', 'trace']; const LEVELS = ['fatal', 'error', 'warn', 'info', 'debug', 'trace'];
let logger; let logger: Logger | undefined;
// tslint:disable: non-literal-fs-path
module.exports = { // tslint:disable: no-console
initialize,
getLogger, type ConsoleCustom = typeof console & {
fetch, _log: (...args: any) => void;
_warn: (...args: any) => void;
_error: (...args: any) => void;
}; };
function initialize() { export async function initialize() {
if (logger) { if (logger) {
throw new Error('Already called initialize!'); throw new Error('Already called initialize!');
} }
@ -39,7 +40,7 @@ function initialize() {
const logFile = path.join(logPath, 'log.log'); const logFile = path.join(logPath, 'log.log');
logger = bunyan.createLogger({ logger = Logger.createLogger({
name: 'log', name: 'log',
streams: [ streams: [
{ {
@ -56,8 +57,8 @@ function initialize() {
}); });
LEVELS.forEach(level => { LEVELS.forEach(level => {
ipc.on(`log-${level}`, (first, ...rest) => { ipc.on(`log-${level}`, (_first, ...rest) => {
logger[level](...rest); (logger as any)[level](...rest);
}); });
}); });
@ -69,7 +70,7 @@ function initialize() {
event.sender.send('fetched-log', data); event.sender.send('fetched-log', data);
}, },
error => { error => {
logger.error(`Problem loading log from disk: ${error.stack}`); logger?.error(`Problem loading log from disk: ${error.stack}`);
} }
); );
}); });
@ -78,7 +79,7 @@ function initialize() {
try { try {
await deleteAllLogs(logPath); await deleteAllLogs(logPath);
} catch (error) { } catch (error) {
logger.error(`Problem deleting all logs: ${error.stack}`); logger?.error(`Problem deleting all logs: ${error.stack}`);
} }
event.sender.send('delete-all-logs-complete'); event.sender.send('delete-all-logs-complete');
@ -86,7 +87,7 @@ function initialize() {
}); });
} }
async function deleteAllLogs(logPath) { async function deleteAllLogs(logPath: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
rimraf( rimraf(
logPath, logPath,
@ -95,16 +96,18 @@ async function deleteAllLogs(logPath) {
}, },
error => { error => {
if (error) { if (error) {
return reject(error); reject(error);
return;
} }
return resolve(); resolve(undefined);
return;
} }
); );
}); });
} }
async function cleanupLogs(logPath) { async function cleanupLogs(logPath: string) {
const now = new Date(); const now = new Date();
const earliestDate = new Date( const earliestDate = new Date(
Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 6) Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 6)
@ -128,7 +131,7 @@ async function cleanupLogs(logPath) {
} }
} }
function isLineAfterDate(line, date) { function isLineAfterDate(line: string, date: Date) {
if (!line) { if (!line) {
return false; return false;
} }
@ -142,13 +145,13 @@ function isLineAfterDate(line, date) {
} }
} }
function eliminateOutOfDateFiles(logPath, date) { async function eliminateOutOfDateFiles(logPath: string, date: Date) {
const files = fs.readdirSync(logPath); const files = fs.readdirSync(logPath);
const paths = files.map(file => path.join(logPath, file)); const paths = files.map(file => path.join(logPath, file));
return Promise.all( return Promise.all(
_.map(paths, target => _.map(paths, target =>
Promise.all([readFirstLine(target), readLastLines(target, 2)]).then(results => { Promise.all([firstline(target), readLastLinesEnc('utf8')(target, 2)]).then(results => {
const start = results[0]; const start = results[0];
const end = results[1].split('\n'); const end = results[1].split('\n');
@ -170,22 +173,22 @@ function eliminateOutOfDateFiles(logPath, date) {
); );
} }
function eliminateOldEntries(files, date) { async function eliminateOldEntries(files: any, date: Date) {
const earliest = date.getTime(); const earliest = date.getTime();
return Promise.all( return Promise.all(
_.map(files, file => _.map(files, file =>
fetchLog(file.path).then(lines => { fetchLog(file.path).then((lines: any) => {
const recent = _.filter(lines, line => new Date(line.time).getTime() >= earliest); const recent = _.filter(lines, line => new Date(line.time).getTime() >= earliest);
const text = _.map(recent, line => JSON.stringify(line)).join('\n'); const text = _.map(recent, line => JSON.stringify(line)).join('\n');
return fs.writeFileSync(file.path, `${text}\n`); fs.writeFileSync(file.path, `${text}\n`);
}) })
) )
); );
} }
function getLogger() { export function getLogger() {
if (!logger) { if (!logger) {
throw new Error("Logger hasn't been initialized yet!"); throw new Error("Logger hasn't been initialized yet!");
} }
@ -193,11 +196,12 @@ function getLogger() {
return logger; return logger;
} }
function fetchLog(logFile) { async function fetchLog(logFile: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fs.readFile(logFile, { encoding: 'utf8' }, (err, text) => { fs.readFile(logFile, { encoding: 'utf8' }, (err, text) => {
if (err) { if (err) {
return reject(err); reject(err);
return;
} }
const lines = _.compact(text.split('\n')); const lines = _.compact(text.split('\n'));
@ -211,15 +215,18 @@ function fetchLog(logFile) {
}) })
); );
return resolve(data); resolve(data);
return;
}); });
}); });
} }
function fetch(logPath) { export async function fetch(logPath: string) {
// Check that the file exists locally // Check that the file exists locally
if (!fs.existsSync(logPath)) { if (!fs.existsSync(logPath)) {
console._log('Log folder not found while fetching its content. Quick! Creating it.'); (console as ConsoleCustom)._log(
'Log folder not found while fetching its content. Quick! Creating it.'
);
fs.mkdirSync(logPath, { recursive: true }); fs.mkdirSync(logPath, { recursive: true });
} }
const files = fs.readdirSync(logPath); const files = fs.readdirSync(logPath);
@ -242,10 +249,10 @@ function fetch(logPath) {
}); });
} }
function logAtLevel(level, ...args) { function logAtLevel(level: string, ...args: any) {
if (logger) { if (logger) {
// To avoid [Object object] in our log since console.log handles non-strings smoothly // To avoid [Object object] in our log since console.log handles non-strings smoothly
const str = args.map(item => { const str = args.map((item: any) => {
if (typeof item !== 'string') { if (typeof item !== 'string') {
try { try {
return JSON.stringify(item); return JSON.stringify(item);
@ -256,18 +263,18 @@ function logAtLevel(level, ...args) {
return item; return item;
}); });
logger[level](redactAll(str.join(' '))); (logger as any)[level](redactAll(str.join(' ')));
} else { } else {
console._log(...args); (console as ConsoleCustom)._log(...args);
} }
} }
// This blows up using mocha --watch, so we ensure it is run just once // This blows up using mocha --watch, so we ensure it is run just once
if (!console._log) { if (!(console as ConsoleCustom)._log) {
console._log = console.log; (console as ConsoleCustom)._log = console.log;
console.log = _.partial(logAtLevel, 'info'); console.log = _.partial(logAtLevel, 'info');
console._error = console.error; (console as ConsoleCustom)._error = console.error;
console.error = _.partial(logAtLevel, 'error'); console.error = _.partial(logAtLevel, 'error');
console._warn = console.warn; (console as ConsoleCustom)._warn = console.warn;
console.warn = _.partial(logAtLevel, 'warn'); console.warn = _.partial(logAtLevel, 'warn');
} }

@ -848,6 +848,13 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/bunyan@^1.8.8":
version "1.8.8"
resolved "https://registry.yarnpkg.com/@types/bunyan/-/bunyan-1.8.8.tgz#8d6d33f090f37c07e2a80af30ae728450a101008"
integrity sha512-Cblq+Yydg3u+sGiz2mjHjC5MPmdjY+No4qvHrF+BUhblsmSfMvsHLbOG62tPbonsqBj6sbWv1LHcsoe5Jw+/Ow==
dependencies:
"@types/node" "*"
"@types/bytebuffer@^5.0.41": "@types/bytebuffer@^5.0.41":
version "5.0.41" version "5.0.41"
resolved "https://registry.yarnpkg.com/@types/bytebuffer/-/bytebuffer-5.0.41.tgz#6850dba4d4cd2846596b4842874d5bfc01cd3db1" resolved "https://registry.yarnpkg.com/@types/bytebuffer/-/bytebuffer-5.0.41.tgz#6850dba4d4cd2846596b4842874d5bfc01cd3db1"
@ -959,6 +966,13 @@
resolved "https://registry.yarnpkg.com/@types/filesize/-/filesize-3.6.0.tgz#5f1a25c7b4e3d5ee2bc63133d374d096b7008c8d" resolved "https://registry.yarnpkg.com/@types/filesize/-/filesize-3.6.0.tgz#5f1a25c7b4e3d5ee2bc63133d374d096b7008c8d"
integrity sha512-rOWxCKMjt2DBuwddUnl5GOpf/jAkkqteB+XldncpVxVX+HPTmK2c5ACMOVEbp9gaH81IlhTdC3TwvRa5nopasw== integrity sha512-rOWxCKMjt2DBuwddUnl5GOpf/jAkkqteB+XldncpVxVX+HPTmK2c5ACMOVEbp9gaH81IlhTdC3TwvRa5nopasw==
"@types/firstline@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@types/firstline/-/firstline-2.0.2.tgz#b7b051c235a667f25f205eaedbfaeeb6c92b8488"
integrity sha512-/Qjs+MO7PwS7EI2k6Iwcc7jHLqf7AlIMDyEmPGB7LrIUFqQWZtbk6UsQxqlPMpOM10f0XiSc6RMsEIKbEGOrGw==
dependencies:
"@types/node" "*"
"@types/fs-extra@5.0.5": "@types/fs-extra@5.0.5":
version "5.0.5" version "5.0.5"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.5.tgz#080d90a792f3fa2c5559eb44bd8ef840aae9104b" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.5.tgz#080d90a792f3fa2c5559eb44bd8ef840aae9104b"
@ -1633,11 +1647,6 @@ ansi-styles@^5.0.0:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
app-builder-bin@3.5.9: app-builder-bin@3.5.9:
version "3.5.9" version "3.5.9"
resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.9.tgz#a3ac0c25286bac68357321cb2eaf7128b0bc0a4f" resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.9.tgz#a3ac0c25286bac68357321cb2eaf7128b0bc0a4f"
@ -3645,7 +3654,7 @@ form-data@~2.3.2:
combined-stream "^1.0.6" combined-stream "^1.0.6"
mime-types "^2.1.12" mime-types "^2.1.12"
fs-extra@0.26.7, fs-extra@^0.26.5: fs-extra@0.26.7:
version "0.26.7" version "0.26.7"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9"
integrity sha1-muH92UiXeY7at20JGM9C0MMYT6k= integrity sha1-muH92UiXeY7at20JGM9C0MMYT6k=
@ -3692,16 +3701,6 @@ fs-minipass@^2.0.0:
dependencies: dependencies:
minipass "^3.0.0" minipass "^3.0.0"
fs-promise@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-0.5.0.tgz#4347d6bf624655a7061a4319213c393276ad3ef3"
integrity sha1-Q0fWv2JGVacGGkMZITw5MnatPvM=
dependencies:
any-promise "^1.0.0"
fs-extra "^0.26.5"
mz "^2.3.1"
thenify-all "^1.6.0"
fs.realpath@^1.0.0: fs.realpath@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@ -5353,15 +5352,6 @@ mv@~2:
ncp "~2.0.0" ncp "~2.0.0"
rimraf "~2.4.0" rimraf "~2.4.0"
mz@^2.3.1:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
nan@2.14.2, nan@^2.13.2: nan@2.14.2, nan@^2.13.2:
version "2.14.2" version "2.14.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
@ -6424,12 +6414,10 @@ read-config-file@6.0.0:
json5 "^2.1.2" json5 "^2.1.2"
lazy-val "^1.0.4" lazy-val "^1.0.4"
read-last-lines@1.3.0: read-last-lines-ts@^1.2.1:
version "1.3.0" version "1.2.1"
resolved "https://registry.yarnpkg.com/read-last-lines/-/read-last-lines-1.3.0.tgz#0dd170188d46124a23eb1a87156baf46b315ac4b" resolved "https://registry.yarnpkg.com/read-last-lines-ts/-/read-last-lines-ts-1.2.1.tgz#99e46288c5373c06e16e90e666a46b595dad80a1"
integrity sha1-DdFwGI1GEkoj6xqHFWuvRrMVrEs= integrity sha512-1VcCrAU38DILYiF4sbNY13zdrMGwrFqjGQnXJy28G1zLJItvnWtgCbqoAJlnZZSiEICMKdM4Ol7LYvVMEoKrAg==
dependencies:
fs-promise "^0.5.0"
read-pkg-up@^1.0.1: read-pkg-up@^1.0.1:
version "1.0.1" version "1.0.1"
@ -7526,20 +7514,6 @@ text-table@~0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
thenify-all@^1.0.0, thenify-all@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.0"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=
dependencies:
any-promise "^1.0.0"
throttle-debounce@^3.0.1: throttle-debounce@^3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb" resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb"

Loading…
Cancel
Save