Scope pino lines with filename

This commit is contained in:
Fedor Indutny 2025-06-16 11:59:31 -07:00 committed by GitHub
commit 4347964030
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
338 changed files with 1524 additions and 1111 deletions

View file

@ -14,11 +14,13 @@ import type {
OptionalResourcesDictType, OptionalResourcesDictType,
} from '../ts/types/OptionalResource'; } from '../ts/types/OptionalResource';
import { OptionalResourcesDictSchema } from '../ts/types/OptionalResource'; import { OptionalResourcesDictSchema } from '../ts/types/OptionalResource';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import { getGotOptions } from '../ts/updater/got'; import { getGotOptions } from '../ts/updater/got';
import { drop } from '../ts/util/drop'; import { drop } from '../ts/util/drop';
import { parseUnknown } from '../ts/util/schemas'; import { parseUnknown } from '../ts/util/schemas';
const log = createLogger('OptionalResourceService');
const RESOURCES_DICT_PATH = join( const RESOURCES_DICT_PATH = join(
__dirname, __dirname,
'..', '..',
@ -75,12 +77,12 @@ export class OptionalResourceService {
timingSafeEqual(digest, Buffer.from(decl.digest, 'base64')) && timingSafeEqual(digest, Buffer.from(decl.digest, 'base64')) &&
onDisk.length === decl.size onDisk.length === decl.size
) { ) {
log.warn(`OptionalResourceService: loaded ${name} from disk`); log.warn(`loaded ${name} from disk`);
this.#cache.set(name, onDisk); this.#cache.set(name, onDisk);
return onDisk; return onDisk;
} }
log.warn(`OptionalResourceService: ${name} is no longer valid on disk`); log.warn(`${name} is no longer valid on disk`);
} catch (error) { } catch (error) {
if (error.code !== 'ENOENT') { if (error.code !== 'ENOENT') {
throw error; throw error;
@ -135,10 +137,7 @@ export class OptionalResourceService {
try { try {
await unlink(fullPath); await unlink(fullPath);
} catch (error) { } catch (error) {
log.error( log.error(`failed to cleanup ${subPath}`, error);
`OptionalResourceService: failed to cleanup ${subPath}`,
error
);
} }
}) })
); );
@ -182,7 +181,7 @@ export class OptionalResourceService {
await mkdir(dirname(destPath), { recursive: true }); await mkdir(dirname(destPath), { recursive: true });
await writeFile(destPath, result); await writeFile(destPath, result);
} catch (error) { } catch (error) {
log.error('OptionalResourceService: failed to save file', error); log.error('failed to save file', error);
// Still return the data that we just fetched // Still return the data that we just fetched
} }

View file

@ -2,7 +2,9 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { PowerSaveBlocker } from 'electron'; import type { PowerSaveBlocker } from 'electron';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
const log = createLogger('PreventDisplaySleepService');
export class PreventDisplaySleepService { export class PreventDisplaySleepService {
private blockerId: undefined | number; private blockerId: undefined | number;

View file

@ -6,9 +6,11 @@ import { Menu, Tray, app, nativeImage, nativeTheme, screen } from 'electron';
import os from 'node:os'; import os from 'node:os';
import { join } from 'node:path'; import { join } from 'node:path';
import { readFileSync } from 'node:fs'; import { readFileSync } from 'node:fs';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import type { LocalizerType } from '../ts/types/I18N'; import type { LocalizerType } from '../ts/types/I18N';
const log = createLogger('SystemTrayService');
export type SystemTrayServiceOptionsType = Readonly<{ export type SystemTrayServiceOptionsType = Readonly<{
i18n: LocalizerType; i18n: LocalizerType;

View file

@ -1,7 +1,7 @@
// Copyright 2017 Signal Messenger, LLC // Copyright 2017 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import OS from '../ts/util/os/osMain'; import OS from '../ts/util/os/osMain';
import { import {
parseSystemTraySetting, parseSystemTraySetting,
@ -10,6 +10,8 @@ import {
import { isSystemTraySupported } from '../ts/types/Settings'; import { isSystemTraySupported } from '../ts/types/Settings';
import type { ConfigType } from './base_config'; import type { ConfigType } from './base_config';
const log = createLogger('SystemTraySettingCache');
/** /**
* A small helper class to get and cache the `system-tray-setting` preference in the main * A small helper class to get and cache the `system-tray-setting` preference in the main
* process. * process.

View file

@ -9,11 +9,13 @@ import {
sendDummyKeystroke, sendDummyKeystroke,
} from '@indutny/simple-windows-notifications'; } from '@indutny/simple-windows-notifications';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import { AUMID } from './startup_config'; import { AUMID } from './startup_config';
import type { WindowsNotificationData } from '../ts/services/notifications'; import type { WindowsNotificationData } from '../ts/services/notifications';
import { renderWindowsToast } from './renderWindowsToast'; import { renderWindowsToast } from './renderWindowsToast';
const log = createLogger('WindowsNotifications');
export { sendDummyKeystroke }; export { sendDummyKeystroke };
const notifier = new Notifier(AUMID); const notifier = new Notifier(AUMID);

View file

@ -42,7 +42,7 @@ import { safeParseInteger } from '../ts/util/numbers';
import { parseLoose } from '../ts/util/schemas'; import { parseLoose } from '../ts/util/schemas';
import { sleep } from '../ts/util/sleep'; import { sleep } from '../ts/util/sleep';
import { toWebStream } from '../ts/util/toWebStream'; import { toWebStream } from '../ts/util/toWebStream';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import { import {
deleteAll as deleteAllAttachments, deleteAll as deleteAllAttachments,
deleteAllBadges, deleteAllBadges,
@ -62,6 +62,8 @@ import {
getTempPath, getTempPath,
} from './attachments'; } from './attachments';
const log = createLogger('attachment_channel');
let initialized = false; let initialized = false;
const ERASE_ATTACHMENTS_KEY = 'erase-attachments'; const ERASE_ATTACHMENTS_KEY = 'erase-attachments';
@ -731,13 +733,13 @@ function handleRangeRequest({
// Chromium only sends open-ended ranges: "start-" // Chromium only sends open-ended ranges: "start-"
const match = range.match(/^bytes=(\d+)-$/); const match = range.match(/^bytes=(\d+)-$/);
if (match == null) { if (match == null) {
log.error(`attachment_channel: invalid range header: ${range}`); log.error(`invalid range header: ${range}`);
return create200Response(); return create200Response();
} }
const startParam = safeParseInteger(match[1]); const startParam = safeParseInteger(match[1]);
if (startParam == null) { if (startParam == null) {
log.error(`attachment_channel: invalid range header: ${range}`); log.error(`invalid range header: ${range}`);
return create200Response(); return create200Response();
} }

View file

@ -20,7 +20,9 @@ import {
} from '../ts/AttachmentCrypto'; } from '../ts/AttachmentCrypto';
import type { LocalAttachmentV2Type } from '../ts/types/Attachment'; import type { LocalAttachmentV2Type } from '../ts/types/Attachment';
import * as Errors from '../ts/types/errors'; import * as Errors from '../ts/types/errors';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
const log = createLogger('attachments');
const PATH = 'attachments.noindex'; const PATH = 'attachments.noindex';
const AVATAR_PATH = 'avatars.noindex'; const AVATAR_PATH = 'avatars.noindex';

View file

@ -7,7 +7,9 @@ import { sync as writeFileSync } from 'write-file-atomic';
import { get } from 'lodash'; import { get } from 'lodash';
import { set } from 'lodash/fp'; import { set } from 'lodash/fp';
import { strictAssert } from '../ts/util/assert'; import { strictAssert } from '../ts/util/assert';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
const log = createLogger('base_config');
const ENCODING = 'utf8'; const ENCODING = 'utf8';

View file

@ -12,7 +12,9 @@ import {
setEnvironment, setEnvironment,
parseEnvironment, parseEnvironment,
} from '../ts/environment'; } from '../ts/environment';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
const log = createLogger('config');
// In production mode, NODE_ENV cannot be customized by the user // In production mode, NODE_ENV cannot be customized by the user
if (app.isPackaged) { if (app.isPackaged) {
@ -52,7 +54,7 @@ const config: IConfig = require('config');
if (getEnvironment() !== Environment.PackagedApp) { if (getEnvironment() !== Environment.PackagedApp) {
config.util.getConfigSources().forEach(source => { config.util.getConfigSources().forEach(source => {
log.info(`config: Using config source ${basename(source.name)}`); log.info(`Using config source ${basename(source.name)}`);
}); });
} }

View file

@ -6,7 +6,9 @@ import { readFile } from 'fs/promises';
import { DNSFallbackSchema } from '../ts/types/DNSFallback'; import { DNSFallbackSchema } from '../ts/types/DNSFallback';
import type { DNSFallbackType } from '../ts/types/DNSFallback'; import type { DNSFallbackType } from '../ts/types/DNSFallback';
import { parseUnknown } from '../ts/util/schemas'; import { parseUnknown } from '../ts/util/schemas';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
const log = createLogger('dns-fallback');
let cached: DNSFallbackType | undefined; let cached: DNSFallbackType | undefined;

View file

@ -6,10 +6,12 @@ import os from 'node:os';
import * as Errors from '../ts/types/errors'; import * as Errors from '../ts/types/errors';
import { redactAll } from '../ts/util/privacy'; import { redactAll } from '../ts/util/privacy';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import { reallyJsonStringify } from '../ts/util/reallyJsonStringify'; import { reallyJsonStringify } from '../ts/util/reallyJsonStringify';
import type { LocaleType } from './locale'; import type { LocaleType } from './locale';
const log = createLogger('global_errors');
// We use hard-coded strings until we're able to update these strings from the locale. // We use hard-coded strings until we're able to update these strings from the locale.
let quitText = 'Quit'; let quitText = 'Quit';
let copyErrorAndQuitText = 'Copy error and quit'; let copyErrorAndQuitText = 'Copy error and quit';

View file

@ -46,7 +46,7 @@ import type { ThemeSettingType } from '../ts/types/StorageUIKeys';
import { ThemeType } from '../ts/types/Util'; import { ThemeType } from '../ts/types/Util';
import * as Errors from '../ts/types/errors'; import * as Errors from '../ts/types/errors';
import { resolveCanonicalLocales } from '../ts/util/resolveCanonicalLocales'; import { resolveCanonicalLocales } from '../ts/util/resolveCanonicalLocales';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import * as debugLog from '../ts/logging/debuglogs'; import * as debugLog from '../ts/logging/debuglogs';
import * as uploadDebugLog from '../ts/logging/uploadDebugLog'; import * as uploadDebugLog from '../ts/logging/uploadDebugLog';
import { explodePromise } from '../ts/util/explodePromise'; import { explodePromise } from '../ts/util/explodePromise';
@ -125,6 +125,8 @@ import { getOwn } from '../ts/util/getOwn';
import { safeParseLoose, safeParseUnknown } from '../ts/util/schemas'; import { safeParseLoose, safeParseUnknown } from '../ts/util/schemas';
import { getAppErrorIcon } from '../ts/util/getAppErrorIcon'; import { getAppErrorIcon } from '../ts/util/getAppErrorIcon';
const log = createLogger('app/main');
const animationSettings = systemPreferences.getAnimationSettings(); const animationSettings = systemPreferences.getAnimationSettings();
if (OS.isMacOS()) { if (OS.isMacOS()) {

View file

@ -7,7 +7,9 @@
import type { session as ElectronSession, Session } from 'electron'; import type { session as ElectronSession, Session } from 'electron';
import type { ConfigType } from './base_config'; import type { ConfigType } from './base_config';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
const log = createLogger('permissions');
const PERMISSIONS: Record<string, boolean> = { const PERMISSIONS: Record<string, boolean> = {
// Allowed // Allowed

View file

@ -15,7 +15,9 @@ import {
getTempPath, getTempPath,
getUpdateCachePath, getUpdateCachePath,
} from './attachments'; } from './attachments';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
const log = createLogger('protocol_filter');
type CallbackType = (response: string | ProtocolResponse) => void; type CallbackType = (response: string | ProtocolResponse) => void;

View file

@ -11,9 +11,11 @@ import type { MenuListType } from '../ts/types/menu';
import type { LocalizerType } from '../ts/types/Util'; import type { LocalizerType } from '../ts/types/Util';
import { strictAssert } from '../ts/util/assert'; import { strictAssert } from '../ts/util/assert';
import type { LoggerType } from '../ts/types/Logging'; import type { LoggerType } from '../ts/types/Logging';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import { handleAttachmentRequest } from './attachment_channel'; import { handleAttachmentRequest } from './attachment_channel';
const log = createLogger('spell_check');
export const FAKE_DEFAULT_LOCALE = 'und'; // 'und' is the BCP 47 subtag for "undetermined" export const FAKE_DEFAULT_LOCALE = 'und'; // 'und' is the BCP 47 subtag for "undetermined"
strictAssert( strictAssert(

View file

@ -4,9 +4,11 @@
import { app } from 'electron'; import { app } from 'electron';
import packageJson from '../package.json'; import packageJson from '../package.json';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import * as GlobalErrors from './global_errors'; import * as GlobalErrors from './global_errors';
const log = createLogger('startup_config');
GlobalErrors.addHandler(); GlobalErrors.addHandler();
// Set umask early on in the process lifecycle to ensure file permissions are // Set umask early on in the process lifecycle to ensure file permissions are

View file

@ -7,9 +7,11 @@ import { app } from 'electron';
import { start } from './base_config'; import { start } from './base_config';
import config from './config'; import config from './config';
import * as log from '../ts/logging/log'; import { createLogger } from '../ts/logging/log';
import * as Errors from '../ts/types/errors'; import * as Errors from '../ts/types/errors';
const log = createLogger('user_config');
let userData: string | undefined; let userData: string | undefined;
// Use separate data directory for benchmarks & development // Use separate data directory for benchmarks & development
if (config.has('storagePath')) { if (config.has('storagePath')) {

View file

@ -21,7 +21,7 @@ import {
import type { ChunkSizeChoice } from '@signalapp/libsignal-client/dist/incremental_mac'; import type { ChunkSizeChoice } from '@signalapp/libsignal-client/dist/incremental_mac';
import { isAbsolute } from 'path'; import { isAbsolute } from 'path';
import * as log from './logging/log'; import { createLogger } from './logging/log';
import { import {
HashType, HashType,
CipherType, CipherType,
@ -45,6 +45,8 @@ import { missingCaseError } from './util/missingCaseError';
import { getEnvironment, Environment } from './environment'; import { getEnvironment, Environment } from './environment';
import { toBase64 } from './Bytes'; import { toBase64 } from './Bytes';
const log = createLogger('AttachmentCrypto');
// This file was split from ts/Crypto.ts because it pulls things in from node, and // This file was split from ts/Crypto.ts because it pulls things in from node, and
// too many things pull in Crypto.ts, so it broke storybook. // too many things pull in Crypto.ts, so it broke storybook.

View file

@ -6,7 +6,7 @@ import { ipcRenderer } from 'electron';
import type { IPCResponse as ChallengeResponseType } from './challenge'; import type { IPCResponse as ChallengeResponseType } from './challenge';
import type { MessageAttributesType } from './model-types.d'; import type { MessageAttributesType } from './model-types.d';
import * as log from './logging/log'; import { createLogger } from './logging/log';
import { explodePromise } from './util/explodePromise'; import { explodePromise } from './util/explodePromise';
import { AccessType, ipcInvoke } from './sql/channels'; import { AccessType, ipcInvoke } from './sql/channels';
import { backupsService } from './services/backups'; import { backupsService } from './services/backups';
@ -19,6 +19,8 @@ import { strictAssert } from './util/assert';
import { MessageModel } from './models/messages'; import { MessageModel } from './models/messages';
import type { SocketStatuses } from './textsecure/SocketManager'; import type { SocketStatuses } from './textsecure/SocketManager';
const log = createLogger('CI');
type ResolveType = (data: unknown) => void; type ResolveType = (data: unknown) => void;
export type CIType = { export type CIType = {
@ -81,7 +83,7 @@ export function getCI({
const pendingCompleted = completedEvents.get(event) || []; const pendingCompleted = completedEvents.get(event) || [];
if (pendingCompleted.length) { if (pendingCompleted.length) {
const pending = pendingCompleted.shift(); const pending = pendingCompleted.shift();
log.info(`CI: resolving pending result for ${event}`, pending); log.info(`resolving pending result for ${event}`, pending);
if (pendingCompleted.length === 0) { if (pendingCompleted.length === 0) {
completedEvents.delete(event); completedEvents.delete(event);
@ -91,7 +93,7 @@ export function getCI({
} }
} }
log.info(`CI: waiting for event ${event}`); log.info(`waiting for event ${event}`);
const { resolve, reject, promise } = explodePromise(); const { resolve, reject, promise } = explodePromise();
const timer = setTimeout(() => { const timer = setTimeout(() => {
@ -134,12 +136,12 @@ export function getCI({
eventListeners.delete(event); eventListeners.delete(event);
} }
log.info(`CI: got event ${event} with data`, data); log.info(`got event ${event} with data`, data);
resolve(data); resolve(data);
return; return;
} }
log.info(`CI: postponing event ${event}`); log.info(`postponing event ${event}`);
let resultList = completedEvents.get(event); let resultList = completedEvents.get(event);
if (!resultList) { if (!resultList) {

View file

@ -15,9 +15,11 @@ import { sleep } from '../util/sleep';
import { stats } from '../util/benchmark/stats'; import { stats } from '../util/benchmark/stats';
import type { StatsType } from '../util/benchmark/stats'; import type { StatsType } from '../util/benchmark/stats';
import type { MessageAttributesType } from '../model-types.d'; import type { MessageAttributesType } from '../model-types.d';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { postSaveUpdates } from '../util/cleanup'; import { postSaveUpdates } from '../util/cleanup';
const log = createLogger('benchmarkConversationOpen');
const BUFFER_DELAY_MS = 50; const BUFFER_DELAY_MS = 50;
type PopulateConversationArgsType = { type PopulateConversationArgsType = {

View file

@ -15,7 +15,7 @@ import type {
import type { ConversationModel } from './models/conversations'; import type { ConversationModel } from './models/conversations';
import { DataReader, DataWriter } from './sql/Client'; import { DataReader, DataWriter } from './sql/Client';
import * as log from './logging/log'; import { createLogger } from './logging/log';
import * as Errors from './types/errors'; import * as Errors from './types/errors';
import { getAuthorId } from './messages/helpers'; import { getAuthorId } from './messages/helpers';
import { maybeDeriveGroupV2Id } from './groups'; import { maybeDeriveGroupV2Id } from './groups';
@ -43,6 +43,8 @@ import { isConversationAccepted } from './util/isConversationAccepted';
import { areWePending } from './util/groupMembershipUtils'; import { areWePending } from './util/groupMembershipUtils';
import { conversationJobQueue } from './jobs/conversationJobQueue'; import { conversationJobQueue } from './jobs/conversationJobQueue';
const log = createLogger('ConversationController');
type ConvoMatchType = type ConvoMatchType =
| { | {
key: 'serviceId' | 'pni'; key: 'serviceId' | 'pni';
@ -854,7 +856,7 @@ export class ConversationController {
// Note: `doCombineConversations` is directly used within this function since both // Note: `doCombineConversations` is directly used within this function since both
// run on `_combineConversationsQueue` queue and we don't want deadlocks. // run on `_combineConversationsQueue` queue and we don't want deadlocks.
async #doCheckForConflicts(): Promise<void> { async #doCheckForConflicts(): Promise<void> {
log.info('ConversationController.checkForConflicts: starting...'); log.info('checkForConflicts: starting...');
const byServiceId = Object.create(null); const byServiceId = Object.create(null);
const byE164 = Object.create(null); const byE164 = Object.create(null);
const byGroupV2Id = Object.create(null); const byGroupV2Id = Object.create(null);
@ -1309,11 +1311,11 @@ export class ConversationController {
setReadOnly(value: boolean): void { setReadOnly(value: boolean): void {
if (this.#isReadOnly === value) { if (this.#isReadOnly === value) {
log.warn(`ConversationController: already at readOnly=${value}`); log.warn(`already at readOnly=${value}`);
return; return;
} }
log.info(`ConversationController: readOnly=${value}`); log.info(`readOnly=${value}`);
this.#isReadOnly = value; this.#isReadOnly = value;
} }
@ -1415,7 +1417,7 @@ export class ConversationController {
} }
} }
log.info( log.info(
`ConversationController: unset avatars for ${numberOfConversationsMigrated} unaccepted conversations` `unset avatars for ${numberOfConversationsMigrated} unaccepted conversations`
); );
drop(window.storage.put('avatarsHaveBeenMigrated', true)); drop(window.storage.put('avatarsHaveBeenMigrated', true));
} }
@ -1430,9 +1432,7 @@ export class ConversationController {
continue; continue;
} }
log.warn( log.warn(`Repairing ${convo.idForLogging()}'s isPinned`);
`ConversationController: Repairing ${convo.idForLogging()}'s isPinned`
);
convo.set('isPinned', true); convo.set('isPinned', true);
drop(updateConversation(convo.attributes)); drop(updateConversation(convo.attributes));
@ -1447,7 +1447,7 @@ export class ConversationController {
} }
log.info( log.info(
'ConversationController.clearShareMyPhoneNumber: ' + 'clearShareMyPhoneNumber: ' +
`updating ${sharedWith.length} conversations` `updating ${sharedWith.length} conversations`
); );
@ -1469,7 +1469,7 @@ export class ConversationController {
const e164ToUse = transformedE164s.get(e164) ?? e164; const e164ToUse = transformedE164s.get(e164) ?? e164;
const pni = serviceIdMap.get(e164ToUse)?.pni; const pni = serviceIdMap.get(e164ToUse)?.pni;
log.info(`ConversationController: forgetting e164=${e164ToUse} pni=${pni}`); log.info(`forgetting e164=${e164ToUse} pni=${pni}`);
const convos = [this.get(e164ToUse), this.get(pni)]; const convos = [this.get(e164ToUse), this.get(pni)];
@ -1486,7 +1486,7 @@ export class ConversationController {
} }
async #doLoad(): Promise<void> { async #doLoad(): Promise<void> {
log.info('ConversationController: starting initial fetch'); log.info('starting initial fetch');
if (this._conversations.length) { if (this._conversations.length) {
throw new Error('ConversationController: Already loaded!'); throw new Error('ConversationController: Already loaded!');
@ -1502,7 +1502,7 @@ export class ConversationController {
if (temporaryConversations.length) { if (temporaryConversations.length) {
log.warn( log.warn(
`ConversationController: Removing ${temporaryConversations.length} temporary conversations` `Removing ${temporaryConversations.length} temporary conversations`
); );
} }
const queue = new PQueue({ const queue = new PQueue({
@ -1563,21 +1563,18 @@ export class ConversationController {
} }
} catch (error) { } catch (error) {
log.error( log.error(
'ConversationController.load/map: Failed to prepare a conversation', 'load/map: Failed to prepare a conversation',
Errors.toLogFormat(error) Errors.toLogFormat(error)
); );
} }
}) })
); );
log.info( log.info(
'ConversationController: done with initial fetch, ' + 'done with initial fetch, ' +
`got ${this._conversations.length} conversations` `got ${this._conversations.length} conversations`
); );
} catch (error) { } catch (error) {
log.error( log.error('initial fetch failed', Errors.toLogFormat(error));
'ConversationController: initial fetch failed',
Errors.toLogFormat(error)
);
throw error; throw error;
} }
} }

View file

@ -11,7 +11,9 @@ import type {
CompatPreKeyType, CompatPreKeyType,
CompatSignedPreKeyType, CompatSignedPreKeyType,
} from './textsecure/Types.d'; } from './textsecure/Types.d';
import * as log from './logging/log'; import { createLogger } from './logging/log';
const log = createLogger('Curve');
export function isNonNegativeInteger(n: unknown): n is number { export function isNonNegativeInteger(n: unknown): n is number {
return typeof n === 'number' && n % 1 === 0 && n >= 0; return typeof n === 'number' && n % 1 === 0 && n >= 0;

View file

@ -2,9 +2,11 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import EventEmitter from 'events'; import EventEmitter from 'events';
import * as log from './logging/log'; import { createLogger } from './logging/log';
import { clearTimeoutIfNecessary } from './util/clearTimeoutIfNecessary'; import { clearTimeoutIfNecessary } from './util/clearTimeoutIfNecessary';
const log = createLogger('IdleDetector');
const POLL_INTERVAL_MS = 5 * 1000; const POLL_INTERVAL_MS = 5 * 1000;
const IDLE_THRESHOLD_MS = 20; const IDLE_THRESHOLD_MS = 20;

View file

@ -4,7 +4,7 @@
import { get, throttle } from 'lodash'; import { get, throttle } from 'lodash';
import type { WebAPIType } from './textsecure/WebAPI'; import type { WebAPIType } from './textsecure/WebAPI';
import * as log from './logging/log'; import { createLogger } from './logging/log';
import type { AciString } from './types/ServiceId'; import type { AciString } from './types/ServiceId';
import { parseIntOrThrow } from './util/parseIntOrThrow'; import { parseIntOrThrow } from './util/parseIntOrThrow';
import { HOUR } from './util/durations'; import { HOUR } from './util/durations';
@ -15,6 +15,8 @@ import { HashType } from './types/Crypto';
import { getCountryCode } from './types/PhoneNumber'; import { getCountryCode } from './types/PhoneNumber';
import { parseRemoteClientExpiration } from './util/parseRemoteClientExpiration'; import { parseRemoteClientExpiration } from './util/parseRemoteClientExpiration';
const log = createLogger('RemoteConfig');
export type ConfigKeyType = export type ConfigKeyType =
| 'desktop.calling.ringrtcAdmFull.3' | 'desktop.calling.ringrtcAdmFull.3'
| 'desktop.calling.ringrtcAdmInternal' | 'desktop.calling.ringrtcAdmInternal'

View file

@ -54,7 +54,7 @@ import { isServiceIdString, ServiceIdKind } from './types/ServiceId';
import type { Address } from './types/Address'; import type { Address } from './types/Address';
import type { QualifiedAddressStringType } from './types/QualifiedAddress'; import type { QualifiedAddressStringType } from './types/QualifiedAddress';
import { QualifiedAddress } from './types/QualifiedAddress'; import { QualifiedAddress } from './types/QualifiedAddress';
import * as log from './logging/log'; import { createLogger } from './logging/log';
import * as Errors from './types/errors'; import * as Errors from './types/errors';
import { MINUTE } from './util/durations'; import { MINUTE } from './util/durations';
import { conversationJobQueue } from './jobs/conversationJobQueue'; import { conversationJobQueue } from './jobs/conversationJobQueue';
@ -65,6 +65,8 @@ import {
import { formatGroups, groupWhile } from './util/groupWhile'; import { formatGroups, groupWhile } from './util/groupWhile';
import { parseUnknown } from './util/schemas'; import { parseUnknown } from './util/schemas';
const log = createLogger('SignalProtocolStore');
const TIMESTAMP_THRESHOLD = 5 * 1000; // 5 seconds const TIMESTAMP_THRESHOLD = 5 * 1000; // 5 seconds
const LOW_KEYS_THRESHOLD = 25; const LOW_KEYS_THRESHOLD = 25;
@ -172,7 +174,7 @@ async function _fillCaches<ID, T extends HasIdType<ID>, HydratedType>(
}); });
} }
log.info(`SignalProtocolStore: Finished caching ${field} data`); log.info(`Finished caching ${field} data`);
// eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any
object[field] = cache as any; object[field] = cache as any;
} }
@ -1203,7 +1205,7 @@ export class SignalProtocolStore extends EventEmitter {
this.#currentZone = zone; this.#currentZone = zone;
if (zone !== GLOBAL_ZONE) { if (zone !== GLOBAL_ZONE) {
log.info(`SignalProtocolStore.enterZone(${zone.name}:${name})`); log.info(`enterZone(${zone.name}:${name})`);
} }
} }
} }
@ -1225,7 +1227,7 @@ export class SignalProtocolStore extends EventEmitter {
} }
if (zone !== GLOBAL_ZONE) { if (zone !== GLOBAL_ZONE) {
log.info(`SignalProtocolStore.leaveZone(${zone.name})`); log.info(`leaveZone(${zone.name})`);
} }
this.#currentZone = undefined; this.#currentZone = undefined;
@ -1245,8 +1247,7 @@ export class SignalProtocolStore extends EventEmitter {
} }
log.info( log.info(
`SignalProtocolStore: running blocked ${toEnter.length} jobs in ` + `running blocked ${toEnter.length} jobs in zone ${next.zone.name}`
`zone ${next.zone.name}`
); );
for (const { callback } of toEnter) { for (const { callback } of toEnter) {
callback(); callback();
@ -1781,8 +1782,7 @@ export class SignalProtocolStore extends EventEmitter {
}; };
log.info( log.info(
`SignalProtocolStore: migrating identity key from ${record.fromDB.id} ` + `migrating identity key from ${record.fromDB.id} to ${newRecord.id}`
`to ${newRecord.id}`
); );
await this.#_saveIdentityKey(newRecord); await this.#_saveIdentityKey(newRecord);
@ -2428,7 +2428,7 @@ export class SignalProtocolStore extends EventEmitter {
async removeOurOldPni(oldPni: PniString): Promise<void> { async removeOurOldPni(oldPni: PniString): Promise<void> {
const { storage } = window; const { storage } = window;
log.info(`SignalProtocolStore.removeOurOldPni(${oldPni})`); log.info(`removeOurOldPni(${oldPni})`);
// Update caches // Update caches
this.#ourIdentityKeys.delete(oldPni); this.#ourIdentityKeys.delete(oldPni);

View file

@ -2,7 +2,9 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type * as Backbone from 'backbone'; import type * as Backbone from 'backbone';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('reliable_trigger');
type InternalBackboneEvent = { type InternalBackboneEvent = {
callback: (...args: Array<unknown>) => unknown; callback: (...args: Array<unknown>) => unknown;

View file

@ -148,7 +148,7 @@ import {
} from './types/ServiceId'; } from './types/ServiceId';
import { isAciString } from './util/isAciString'; import { isAciString } from './util/isAciString';
import { normalizeAci } from './util/normalizeAci'; import { normalizeAci } from './util/normalizeAci';
import * as log from './logging/log'; import { createLogger } from './logging/log';
import { deleteAllLogs } from './util/deleteAllLogs'; import { deleteAllLogs } from './util/deleteAllLogs';
import { startInteractionMode } from './services/InteractionMode'; import { startInteractionMode } from './services/InteractionMode';
import { ReactionSource } from './reactions/ReactionSource'; import { ReactionSource } from './reactions/ReactionSource';
@ -220,6 +220,8 @@ import { NavTab } from './state/ducks/nav';
import { Page } from './components/Preferences'; import { Page } from './components/Preferences';
import { EditState } from './components/ProfileEditor'; import { EditState } from './components/ProfileEditor';
const log = createLogger('background');
export function isOverHourIntoPast(timestamp: number): boolean { export function isOverHourIntoPast(timestamp: number): boolean {
return isNumber(timestamp) && isOlderThan(timestamp, HOUR); return isNumber(timestamp) && isOlderThan(timestamp, HOUR);
} }
@ -371,7 +373,7 @@ export async function startApp(): Promise<void> {
const { Message } = window.Signal.Types; const { Message } = window.Signal.Types;
log.info('background page reloaded'); log.info('page reloaded');
log.info('environment:', getEnvironment()); log.info('environment:', getEnvironment());
let newVersion = false; let newVersion = false;
@ -756,7 +758,7 @@ export async function startApp(): Promise<void> {
// These make key operations available to IPC handlers created in preload.js // These make key operations available to IPC handlers created in preload.js
window.Events = createIPCEvents({ window.Events = createIPCEvents({
shutdown: async () => { shutdown: async () => {
log.info('background/shutdown'); log.info('shutdown');
flushMessageCounter(); flushMessageCounter();
@ -780,12 +782,12 @@ export async function startApp(): Promise<void> {
server !== undefined, server !== undefined,
'WebAPI should be initialized together with MessageReceiver' 'WebAPI should be initialized together with MessageReceiver'
); );
log.info('background/shutdown: shutting down messageReceiver'); log.info('shutdown: shutting down messageReceiver');
pauseProcessing('shutdown'); pauseProcessing('shutdown');
await window.waitForAllBatchers(); await window.waitForAllBatchers();
} }
log.info('background/shutdown: flushing conversations'); log.info('shutdown: flushing conversations');
// Flush debounced updates for conversations // Flush debounced updates for conversations
await Promise.all( await Promise.all(
@ -797,27 +799,27 @@ export async function startApp(): Promise<void> {
sleeper.shutdown(); sleeper.shutdown();
const shutdownQueues = async () => { const shutdownQueues = async () => {
log.info('background/shutdown: shutting down queues'); log.info('shutdown: shutting down queues');
await Promise.allSettled([ await Promise.allSettled([
StartupQueue.shutdown(), StartupQueue.shutdown(),
shutdownAllJobQueues(), shutdownAllJobQueues(),
]); ]);
log.info('background/shutdown: shutting down conversation queues'); log.info('shutdown: shutting down conversation queues');
await Promise.allSettled( await Promise.allSettled(
window.ConversationController.getAll().map(async convo => { window.ConversationController.getAll().map(async convo => {
try { try {
await convo.shutdownJobQueue(); await convo.shutdownJobQueue();
} catch (err) { } catch (err) {
log.error( log.error(
`background/shutdown: error waiting for conversation ${convo.idForLogging} job queue shutdown`, `shutdown: error waiting for conversation ${convo.idForLogging} job queue shutdown`,
Errors.toLogFormat(err) Errors.toLogFormat(err)
); );
} }
}) })
); );
log.info('background/shutdown: all queues shutdown'); log.info('shutdown: all queues shutdown');
}; };
// wait for at most 1 minutes for startup queue and job queues to drain // wait for at most 1 minutes for startup queue and job queues to drain
@ -827,7 +829,7 @@ export async function startApp(): Promise<void> {
new Promise<void>((resolve, _) => { new Promise<void>((resolve, _) => {
timeout = setTimeout(() => { timeout = setTimeout(() => {
log.warn( log.warn(
'background/shutdown - timed out waiting for StartupQueue/JobQueues, continuing with shutdown' 'shutdown - timed out waiting for StartupQueue/JobQueues, continuing with shutdown'
); );
timeout = undefined; timeout = undefined;
resolve(); resolve();
@ -838,7 +840,7 @@ export async function startApp(): Promise<void> {
clearTimeout(timeout); clearTimeout(timeout);
} }
log.info('background/shutdown: waiting for all batchers'); log.info('shutdown: waiting for all batchers');
// A number of still-to-queue database queries might be waiting inside batchers. // A number of still-to-queue database queries might be waiting inside batchers.
// We wait for these to empty first, and then shut down the data interface. // We wait for these to empty first, and then shut down the data interface.
@ -848,14 +850,14 @@ export async function startApp(): Promise<void> {
]); ]);
log.info( log.info(
'background/shutdown: waiting for all attachment backups & downloads to finish' 'shutdown: waiting for all attachment backups & downloads to finish'
); );
// Since we canceled the inflight requests earlier in shutdown, these should // Since we canceled the inflight requests earlier in shutdown, these should
// resolve quickly // resolve quickly
await attachmentDownloadStopPromise; await attachmentDownloadStopPromise;
await attachmentBackupStopPromise; await attachmentBackupStopPromise;
log.info('background/shutdown: closing the database'); log.info('shutdown: closing the database');
// Shut down the data interface cleanly // Shut down the data interface cleanly
await DataWriter.shutdown(); await DataWriter.shutdown();
@ -1095,7 +1097,7 @@ export async function startApp(): Promise<void> {
); );
} catch (error) { } catch (error) {
log.warn( log.warn(
'background/setInterval: Failed to parse integer from desktop.retryRespondMaxAge feature flag', 'setInterval: Failed to parse integer from desktop.retryRespondMaxAge feature flag',
Errors.toLogFormat(error) Errors.toLogFormat(error)
); );
} }
@ -1104,7 +1106,7 @@ export async function startApp(): Promise<void> {
await DataWriter.deleteSentProtosOlderThan(now - sentProtoMaxAge); await DataWriter.deleteSentProtosOlderThan(now - sentProtoMaxAge);
} catch (error) { } catch (error) {
log.error( log.error(
'background/onready/setInterval: Error deleting sent protos: ', 'onready/setInterval: Error deleting sent protos: ',
Errors.toLogFormat(error) Errors.toLogFormat(error)
); );
} }
@ -1135,7 +1137,7 @@ export async function startApp(): Promise<void> {
}); });
} catch (error) { } catch (error) {
log.error( log.error(
'background/onready/setInterval: Error getting expired retry placeholders: ', 'onready/setInterval: Error getting expired retry placeholders: ',
Errors.toLogFormat(error) Errors.toLogFormat(error)
); );
} }
@ -1162,7 +1164,7 @@ export async function startApp(): Promise<void> {
await window.ConversationController.checkForConflicts(); await window.ConversationController.checkForConflicts();
} catch (error) { } catch (error) {
log.error( log.error(
'background.js: ConversationController failed to load:', 'js: ConversationController failed to load:',
Errors.toLogFormat(error) Errors.toLogFormat(error)
); );
} finally { } finally {
@ -1344,7 +1346,7 @@ export async function startApp(): Promise<void> {
}); });
if (reconnect) { if (reconnect) {
log.info('background: reconnecting websocket on user change'); log.info('reconnecting websocket on user change');
enqueueReconnectToWebSocket(); enqueueReconnectToWebSocket();
} }
}); });
@ -1434,7 +1436,7 @@ export async function startApp(): Promise<void> {
return; return;
} }
log.error('background: remote expiration detected, disabling reconnects'); log.error('remote expiration detected, disabling reconnects');
drop(window.storage.put('remoteBuildExpiration', Date.now())); drop(window.storage.put('remoteBuildExpiration', Date.now()));
drop(server?.onExpiration('remote')); drop(server?.onExpiration('remote'));
remotelyExpired = true; remotelyExpired = true;
@ -1646,7 +1648,7 @@ export async function startApp(): Promise<void> {
strictAssert(server, 'server must be initialized'); strictAssert(server, 'server must be initialized');
const onOnline = () => { const onOnline = () => {
log.info('background: online'); log.info('online');
drop(afterAuthSocketConnect()); drop(afterAuthSocketConnect());
}; };
@ -1658,7 +1660,7 @@ export async function startApp(): Promise<void> {
const hasAppEverBeenRegistered = Registration.everDone(); const hasAppEverBeenRegistered = Registration.everDone();
log.info('background: offline', { log.info('offline', {
authSocketConnectCount, authSocketConnectCount,
hasInitialLoadCompleted, hasInitialLoadCompleted,
appView, appView,
@ -1679,19 +1681,17 @@ export async function startApp(): Promise<void> {
if (state.app.appView === AppViewType.Installer) { if (state.app.appView === AppViewType.Installer) {
if (state.installer.step === InstallScreenStep.LinkInProgress) { if (state.installer.step === InstallScreenStep.LinkInProgress) {
log.info( log.info(
'background: offline, but app has been registered before; opening inbox' 'offline, but app has been registered before; opening inbox'
); );
window.reduxActions.app.openInbox(); window.reduxActions.app.openInbox();
} else if (state.installer.step === InstallScreenStep.BackupImport) { } else if (state.installer.step === InstallScreenStep.BackupImport) {
log.warn('background: offline, but app has needs to import backup'); log.warn('offline, but app has needs to import backup');
// TODO: DESKTOP-7584 // TODO: DESKTOP-7584
} }
} }
if (!hasInitialLoadCompleted) { if (!hasInitialLoadCompleted) {
log.info( log.info('offline; initial load not completed; triggering onEmpty');
'background: offline; initial load not completed; triggering onEmpty'
);
drop(onEmpty({ isFromMessageReceiver: false })); // this ensures that the inbox loading progress bar is dismissed drop(onEmpty({ isFromMessageReceiver: false })); // this ensures that the inbox loading progress bar is dismissed
} }
} }
@ -2019,13 +2019,13 @@ export async function startApp(): Promise<void> {
} }
function onNavigatorOffline() { function onNavigatorOffline() {
log.info('background: navigator offline'); log.info('navigator offline');
drop(server?.onNavigatorOffline()); drop(server?.onNavigatorOffline());
} }
function onNavigatorOnline() { function onNavigatorOnline() {
log.info('background: navigator online'); log.info('navigator online');
drop(server?.onNavigatorOnline()); drop(server?.onNavigatorOnline());
} }
@ -3247,7 +3247,7 @@ export async function startApp(): Promise<void> {
function onError(ev: ErrorEvent): void { function onError(ev: ErrorEvent): void {
const { error } = ev; const { error } = ev;
log.error('background onError:', Errors.toLogFormat(error)); log.error('onError:', Errors.toLogFormat(error));
if ( if (
error instanceof HTTPError && error instanceof HTTPError &&
@ -3257,7 +3257,7 @@ export async function startApp(): Promise<void> {
return; return;
} }
log.warn('background onError: Doing nothing with incoming error'); log.warn('onError: Doing nothing with incoming error');
} }
function onViewOnceOpenSync(ev: ViewOnceOpenSyncEvent): void { function onViewOnceOpenSync(ev: ViewOnceOpenSyncEvent): void {

View file

@ -3,11 +3,13 @@
import PQueue from 'p-queue'; import PQueue from 'p-queue';
import { DataWriter } from '../sql/Client'; import { DataWriter } from '../sql/Client';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { MINUTE } from '../util/durations'; import { MINUTE } from '../util/durations';
import { missingCaseError } from '../util/missingCaseError'; import { missingCaseError } from '../util/missingCaseError';
import { waitForOnline } from '../util/waitForOnline'; import { waitForOnline } from '../util/waitForOnline';
const log = createLogger('badgeImageFileDownloader');
enum BadgeDownloaderState { enum BadgeDownloaderState {
Idle, Idle,
Checking, Checking,

View file

@ -5,12 +5,14 @@ import * as z from 'zod';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import { isRecord } from '../util/isRecord'; import { isRecord } from '../util/isRecord';
import { isNormalNumber } from '../util/isNormalNumber'; import { isNormalNumber } from '../util/isNormalNumber';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import type { BadgeType, BadgeImageType } from './types'; import type { BadgeType, BadgeImageType } from './types';
import { parseBadgeCategory } from './BadgeCategory'; import { parseBadgeCategory } from './BadgeCategory';
import { BadgeImageTheme, parseBadgeImageTheme } from './BadgeImageTheme'; import { BadgeImageTheme, parseBadgeImageTheme } from './BadgeImageTheme';
import { safeParseUnknown } from '../util/schemas'; import { safeParseUnknown } from '../util/schemas';
const log = createLogger('parseBadgesFromServer');
const MAX_BADGES = 1000; const MAX_BADGES = 1000;
const badgeFromServerSchema = z.object({ const badgeFromServerSchema = z.object({

View file

@ -9,7 +9,9 @@
import { videoPixelFormatToEnum } from '@signalapp/ringrtc'; import { videoPixelFormatToEnum } from '@signalapp/ringrtc';
import type { VideoFrameSender, VideoFrameSource } from '@signalapp/ringrtc'; import type { VideoFrameSender, VideoFrameSource } from '@signalapp/ringrtc';
import type { RefObject } from 'react'; import type { RefObject } from 'react';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('VideoSupport');
export class GumVideoCaptureOptions { export class GumVideoCaptureOptions {
maxWidth = 640; maxWidth = 640;

View file

@ -19,11 +19,13 @@ import { missingCaseError } from './util/missingCaseError';
import type { StorageInterface } from './types/Storage.d'; import type { StorageInterface } from './types/Storage.d';
import * as Errors from './types/errors'; import * as Errors from './types/errors';
import { HTTPError, type SendMessageChallengeData } from './textsecure/Errors'; import { HTTPError, type SendMessageChallengeData } from './textsecure/Errors';
import * as log from './logging/log'; import { createLogger } from './logging/log';
import { drop } from './util/drop'; import { drop } from './util/drop';
import { findRetryAfterTimeFromError } from './jobs/helpers/findRetryAfterTimeFromError'; import { findRetryAfterTimeFromError } from './jobs/helpers/findRetryAfterTimeFromError';
import { MINUTE } from './util/durations'; import { MINUTE } from './util/durations';
const log = createLogger('challenge');
export type ChallengeResponse = Readonly<{ export type ChallengeResponse = Readonly<{
captcha: string; captcha: string;
}>; }>;
@ -150,14 +152,14 @@ export class ChallengeHandler {
const challenges: ReadonlyArray<RegisteredChallengeType> = const challenges: ReadonlyArray<RegisteredChallengeType> =
this.options.storage.get(STORAGE_KEY) || []; this.options.storage.get(STORAGE_KEY) || [];
log.info(`challenge: loading ${challenges.length} challenges`); log.info(`loading ${challenges.length} challenges`);
await Promise.all( await Promise.all(
challenges.map(async challenge => { challenges.map(async challenge => {
const expireAfter = this.options.expireAfter || DEFAULT_EXPIRE_AFTER; const expireAfter = this.options.expireAfter || DEFAULT_EXPIRE_AFTER;
if (isOlderThan(challenge.createdAt, expireAfter)) { if (isOlderThan(challenge.createdAt, expireAfter)) {
log.info( log.info(
`challenge: expired challenge for conversation ${challenge.conversationId}` `expired challenge for conversation ${challenge.conversationId}`
); );
return; return;
} }
@ -177,7 +179,7 @@ export class ChallengeHandler {
public async onOffline(): Promise<void> { public async onOffline(): Promise<void> {
this.#isOnline = false; this.#isOnline = false;
log.info('challenge: offline'); log.info('offline');
} }
public async onOnline(): Promise<void> { public async onOnline(): Promise<void> {
@ -186,7 +188,7 @@ export class ChallengeHandler {
const pending = Array.from(this.#pendingStarts.values()); const pending = Array.from(this.#pendingStarts.values());
this.#pendingStarts.clear(); this.#pendingStarts.clear();
log.info(`challenge: online, starting ${pending.length} queues`); log.info(`online, starting ${pending.length} queues`);
// Start queues for challenges that matured while we were offline // Start queues for challenges that matured while we were offline
await this.#startAllQueues(); await this.#startAllQueues();
@ -321,9 +323,7 @@ export class ChallengeHandler {
conversationId: string, conversationId: string,
source: string source: string
): Promise<void> { ): Promise<void> {
log.info( log.info(`unregistered conversation ${conversationId} via ${source}`);
`challenge: unregistered conversation ${conversationId} via ${source}`
);
this.#registeredConversations.delete(conversationId); this.#registeredConversations.delete(conversationId);
this.#pendingStarts.delete(conversationId); this.#pendingStarts.delete(conversationId);
@ -374,7 +374,7 @@ export class ChallengeHandler {
}: { }: {
force?: boolean; force?: boolean;
} = {}): void { } = {}): void {
log.info(`challenge: startAllQueues force=${force}`); log.info(`startAllQueues force=${force}`);
Array.from(this.#registeredConversations.values()) Array.from(this.#registeredConversations.values())
.filter(challenge => force || shouldStartQueue(challenge)) .filter(challenge => force || shouldStartQueue(challenge))

View file

@ -16,7 +16,7 @@ import { filterDOMProps } from '@react-aria/utils';
import type { AvatarColorType } from '../types/Colors'; import type { AvatarColorType } from '../types/Colors';
import type { BadgeType } from '../badges/types'; import type { BadgeType } from '../badges/types';
import type { LocalizerType } from '../types/Util'; import type { LocalizerType } from '../types/Util';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { BadgeImageTheme } from '../badges/BadgeImageTheme'; import { BadgeImageTheme } from '../badges/BadgeImageTheme';
import { HasStories } from '../types/Stories'; import { HasStories } from '../types/Stories';
import { Spinner } from './Spinner'; import { Spinner } from './Spinner';
@ -28,6 +28,8 @@ import { isBadgeVisible } from '../badges/isBadgeVisible';
import { SIGNAL_AVATAR_PATH } from '../types/SignalConversation'; import { SIGNAL_AVATAR_PATH } from '../types/SignalConversation';
import { getAvatarPlaceholderGradient } from '../utils/getAvatarPlaceholderGradient'; import { getAvatarPlaceholderGradient } from '../utils/getAvatarPlaceholderGradient';
const log = createLogger('Avatar');
export enum AvatarBlur { export enum AvatarBlur {
NoBlur, NoBlur,
BlurPicture, BlurPicture,
@ -134,7 +136,7 @@ export function Avatar({
const image = new Image(); const image = new Image();
image.src = avatarUrl; image.src = avatarUrl;
image.onerror = () => { image.onerror = () => {
log.warn('Avatar: Image failed to load; failing over to placeholder'); log.warn('Image failed to load; failing over to placeholder');
setImageBroken(true); setImageBroken(true);
}; };

View file

@ -5,7 +5,7 @@ import type { CSSProperties } from 'react';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { noop } from 'lodash'; import { noop } from 'lodash';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import type { LocalizerType } from '../types/Util'; import type { LocalizerType } from '../types/Util';
import { Spinner } from './Spinner'; import { Spinner } from './Spinner';
import type { AvatarColorType } from '../types/Colors'; import type { AvatarColorType } from '../types/Colors';
@ -14,6 +14,8 @@ import { getInitials } from '../util/getInitials';
import { imagePathToBytes } from '../util/imagePathToBytes'; import { imagePathToBytes } from '../util/imagePathToBytes';
import { type ConversationType } from '../state/ducks/conversations'; import { type ConversationType } from '../state/ducks/conversations';
const log = createLogger('AvatarPreview');
export type PropsType = { export type PropsType = {
avatarColor?: AvatarColorType; avatarColor?: AvatarColorType;
avatarUrl?: string; avatarUrl?: string;

View file

@ -48,7 +48,7 @@ import { missingCaseError } from '../util/missingCaseError';
import { CallingToastProvider } from './CallingToast'; import { CallingToastProvider } from './CallingToast';
import type { SmartReactionPicker } from '../state/smart/ReactionPicker'; import type { SmartReactionPicker } from '../state/smart/ReactionPicker';
import type { Props as ReactionPickerProps } from './conversation/ReactionPicker'; import type { Props as ReactionPickerProps } from './conversation/ReactionPicker';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { isGroupOrAdhocActiveCall } from '../util/isGroupOrAdhocCall'; import { isGroupOrAdhocActiveCall } from '../util/isGroupOrAdhocCall';
import { CallingAdhocCallInfo } from './CallingAdhocCallInfo'; import { CallingAdhocCallInfo } from './CallingAdhocCallInfo';
import { callLinkRootKeyToUrl } from '../util/callLinkRootKeyToUrl'; import { callLinkRootKeyToUrl } from '../util/callLinkRootKeyToUrl';
@ -60,6 +60,8 @@ import {
} from '../types/NotificationProfile'; } from '../types/NotificationProfile';
import type { NotificationProfileType } from '../types/NotificationProfile'; import type { NotificationProfileType } from '../types/NotificationProfile';
const log = createLogger('CallManager');
const GROUP_CALL_RING_DURATION = 60 * 1000; const GROUP_CALL_RING_DURATION = 60 * 1000;
export type DirectIncomingCall = Readonly<{ export type DirectIncomingCall = Readonly<{
@ -618,16 +620,16 @@ export function CallManager({
activeNotificationProfile?.id ?? '' activeNotificationProfile?.id ?? ''
); );
log.info( log.info(
`CallManager: Would play ringtone, but notification profile ${redactedId} prevented it` `Would play ringtone, but notification profile ${redactedId} prevented it`
); );
return; return;
} }
log.info('CallManager: Playing ringtone'); log.info('Playing ringtone');
playRingtone(); playRingtone();
return () => { return () => {
log.info('CallManager: Stopping ringtone'); log.info('Stopping ringtone');
stopRingtone(); stopRingtone();
}; };
} }
@ -734,7 +736,7 @@ export function CallManager({
activeNotificationProfile?.id ?? '' activeNotificationProfile?.id ?? ''
); );
log.info( log.info(
`CallManager: Would show incoming call bar, but notification profile ${redactedId} prevented it` `Would show incoming call bar, but notification profile ${redactedId} prevented it`
); );
return null; return null;
} }

View file

@ -12,10 +12,12 @@ import type { LocalizerType } from '../types/Util';
import type { ConversationType } from '../state/ducks/conversations'; import type { ConversationType } from '../state/ducks/conversations';
import { ModalHost } from './ModalHost'; import { ModalHost } from './ModalHost';
import { drop } from '../util/drop'; import { drop } from '../util/drop';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { usePrevious } from '../hooks/usePrevious'; import { usePrevious } from '../hooks/usePrevious';
import { useReducedMotion } from '../hooks/useReducedMotion'; import { useReducedMotion } from '../hooks/useReducedMotion';
const log = createLogger('CallingRaisedHandsList');
export type PropsType = { export type PropsType = {
readonly i18n: LocalizerType; readonly i18n: LocalizerType;
readonly onClose: () => void; readonly onClose: () => void;
@ -45,10 +47,9 @@ export function CallingRaisedHandsList({
raisedHands.forEach(demuxId => { raisedHands.forEach(demuxId => {
const conversation = conversationsByDemuxId.get(demuxId); const conversation = conversationsByDemuxId.get(demuxId);
if (!conversation) { if (!conversation) {
log.warn( log.warn('Failed to get conversationsByDemuxId for demuxId', {
'CallingRaisedHandsList: Failed to get conversationsByDemuxId for demuxId', demuxId,
{ demuxId } });
);
return; return;
} }

View file

@ -36,7 +36,7 @@ import {
toBoundedDate, toBoundedDate,
} from '../util/timestamp'; } from '../util/timestamp';
import type { ConversationType } from '../state/ducks/conversations'; import type { ConversationType } from '../state/ducks/conversations';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { refMerger } from '../util/refMerger'; import { refMerger } from '../util/refMerger';
import { drop } from '../util/drop'; import { drop } from '../util/drop';
import { strictAssert } from '../util/assert'; import { strictAssert } from '../util/assert';
@ -73,6 +73,8 @@ import type { StartCallData } from './ConfirmLeaveCallModal';
import { Button, ButtonVariant } from './Button'; import { Button, ButtonVariant } from './Button';
import type { ICUJSXMessageParamsByKeyType } from '../types/Util'; import type { ICUJSXMessageParamsByKeyType } from '../types/Util';
const log = createLogger('CallsList');
function Timestamp({ function Timestamp({
i18n, i18n,
timestamp, timestamp,
@ -576,7 +578,7 @@ export function CallsList({
]); ]);
results = { count, items }; results = { count, items };
} catch (error) { } catch (error) {
log.error('CallsList#fetchTotal error fetching', error); log.error('fetchTotal error fetching', error);
} }
// Clear the loading indicator timeout // Clear the loading indicator timeout
@ -671,7 +673,7 @@ export function CallsList({
}; };
}); });
} catch (error) { } catch (error) {
log.error('CallsList#loadMoreRows error fetching', error); log.error('loadMoreRows error fetching', error);
} }
}, },
[enqueueCallPeeks, searchState] [enqueueCallPeeks, searchState]

View file

@ -59,7 +59,7 @@ import { SignalClipboard } from '../quill/signal-clipboard';
import { DirectionalBlot } from '../quill/block/blot'; import { DirectionalBlot } from '../quill/block/blot';
import { getClassNamesFor } from '../util/getClassNamesFor'; import { getClassNamesFor } from '../util/getClassNamesFor';
import { isNotNil } from '../util/isNotNil'; import { isNotNil } from '../util/isNotNil';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import type { LinkPreviewForUIType } from '../types/message/LinkPreviews'; import type { LinkPreviewForUIType } from '../types/message/LinkPreviews';
import { StagedLinkPreview } from './conversation/StagedLinkPreview'; import { StagedLinkPreview } from './conversation/StagedLinkPreview';
@ -83,6 +83,8 @@ import { useFunEmojiSearch } from './fun/useFunEmojiSearch';
import type { EmojiCompletionOptions } from '../quill/emoji/completion'; import type { EmojiCompletionOptions } from '../quill/emoji/completion';
import { useFunEmojiLocalizer } from './fun/useFunEmojiLocalizer'; import { useFunEmojiLocalizer } from './fun/useFunEmojiLocalizer';
const log = createLogger('CompositionInput');
Quill.register( Quill.register(
{ {
'formats/emoji': EmojiBlot, 'formats/emoji': EmojiBlot,
@ -348,16 +350,14 @@ export function CompositionInput(props: Props): React.ReactElement {
} }
if (!canSendRef.current) { if (!canSendRef.current) {
log.warn( log.warn('Not submitting message - cannot send right now');
'CompositionInput: Not submitting message - cannot send right now'
);
return; return;
} }
const { text, bodyRanges } = getTextAndRanges(); const { text, bodyRanges } = getTextAndRanges();
log.info( log.info(
`CompositionInput: Submitting message ${timestamp} with ${bodyRanges.length} ranges` `Submitting message ${timestamp} with ${bodyRanges.length} ranges`
); );
canSendRef.current = false; canSendRef.current = false;
const didSend = onSubmit(text, bodyRanges, timestamp); const didSend = onSubmit(text, bodyRanges, timestamp);
@ -967,7 +967,7 @@ export function CompositionInput(props: Props): React.ReactElement {
window.addEventListener('mouseup', onMouseUp); window.addEventListener('mouseup', onMouseUp);
} catch (error) { } catch (error) {
log.error( log.error(
'CompositionInput.onMouseDown: Failed to check event target', 'onMouseDown: Failed to check event target',
Errors.toLogFormat(error) Errors.toLogFormat(error)
); );
} }

View file

@ -7,10 +7,12 @@ import type { LocalizerType } from '../types/Util';
import { WaveformScrubber } from './conversation/WaveformScrubber'; import { WaveformScrubber } from './conversation/WaveformScrubber';
import { PlaybackButton } from './PlaybackButton'; import { PlaybackButton } from './PlaybackButton';
import { RecordingComposer } from './RecordingComposer'; import { RecordingComposer } from './RecordingComposer';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import type { Size } from '../hooks/useSizeObserver'; import type { Size } from '../hooks/useSizeObserver';
import { SizeObserver } from '../hooks/useSizeObserver'; import { SizeObserver } from '../hooks/useSizeObserver';
const log = createLogger('CompositionRecordingDraft');
export type Props = { export type Props = {
i18n: LocalizerType; i18n: LocalizerType;
audioUrl: string | undefined; audioUrl: string | undefined;

View file

@ -8,7 +8,7 @@ import type { LocalizerType } from '../types/Util';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import type { AnyToast } from '../types/Toast'; import type { AnyToast } from '../types/Toast';
import { ToastType } from '../types/Toast'; import { ToastType } from '../types/Toast';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { Button, ButtonVariant } from './Button'; import { Button, ButtonVariant } from './Button';
import { Spinner } from './Spinner'; import { Spinner } from './Spinner';
import { ToastManager } from './ToastManager'; import { ToastManager } from './ToastManager';
@ -17,6 +17,8 @@ import { shouldNeverBeCalled } from '../util/shouldNeverBeCalled';
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser'; import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser';
import { useEscapeHandling } from '../hooks/useEscapeHandling'; import { useEscapeHandling } from '../hooks/useEscapeHandling';
const log = createLogger('DebugLogWindow');
enum LoadState { enum LoadState {
NotStarted, NotStarted,
Started, Started,
@ -96,7 +98,7 @@ export function DebugLogWindow({
const publishedLogURL = await uploadLogs(text); const publishedLogURL = await uploadLogs(text);
setPublicLogURL(publishedLogURL); setPublicLogURL(publishedLogURL);
} catch (error) { } catch (error) {
log.error('DebugLogWindow error:', Errors.toLogFormat(error)); log.error('error:', Errors.toLogFormat(error));
setLoadState(LoadState.Loaded); setLoadState(LoadState.Loaded);
setToast({ toastType: ToastType.DebugLogError }); setToast({ toastType: ToastType.DebugLogError });
} }

View file

@ -5,9 +5,11 @@ import type { ReactNode, ErrorInfo } from 'react';
import React from 'react'; import React from 'react';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { ToastType } from '../types/Toast'; import { ToastType } from '../types/Toast';
const log = createLogger('ErrorBoundary');
export type Props = { export type Props = {
children: ReactNode; children: ReactNode;
name: string; name: string;
@ -33,7 +35,7 @@ export class ErrorBoundary extends React.PureComponent<Props, State> {
const { closeView, name } = this.props; const { closeView, name } = this.props;
log.error( log.error(
`ErrorBoundary/${name}: ` + `${name}: ` +
`captured rendering error ${Errors.toLogFormat(error)}` + `captured rendering error ${Errors.toLogFormat(error)}` +
`\nerrorInfo: ${errorInfo.componentStack}` `\nerrorInfo: ${errorInfo.componentStack}`
); );

View file

@ -24,12 +24,14 @@ import { missingCaseError } from '../util/missingCaseError';
import { SECOND } from '../util/durations'; import { SECOND } from '../util/durations';
import { filter, join } from '../util/iterables'; import { filter, join } from '../util/iterables';
import * as setUtil from '../util/setUtil'; import * as setUtil from '../util/setUtil';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { MAX_FRAME_HEIGHT, MAX_FRAME_WIDTH } from '../calling/constants'; import { MAX_FRAME_HEIGHT, MAX_FRAME_WIDTH } from '../calling/constants';
import { SizeObserver } from '../hooks/useSizeObserver'; import { SizeObserver } from '../hooks/useSizeObserver';
import { strictAssert } from '../util/assert'; import { strictAssert } from '../util/assert';
import type { CallingImageDataCache } from './CallManager'; import type { CallingImageDataCache } from './CallManager';
const log = createLogger('GroupCallRemoteParticipants');
const SMALL_TILES_MIN_HEIGHT = 80; const SMALL_TILES_MIN_HEIGHT = 80;
const LARGE_TILES_MIN_HEIGHT = 200; const LARGE_TILES_MIN_HEIGHT = 200;
const PARTICIPANT_MARGIN = 12; const PARTICIPANT_MARGIN = 12;
@ -774,7 +776,7 @@ function getGridParticipantsByPage({
if (!nextPage) { if (!nextPage) {
log.warn( log.warn(
`GroupCallRemoteParticipants: failed after ${attemptNumber} attempts to layout `failed after ${attemptNumber} attempts to layout
the page; pageIndex: ${pages.length}, \ the page; pageIndex: ${pages.length}, \
# fit in priority order: ${nextPageInPriorityOrder.numParticipants}, \ # fit in priority order: ${nextPageInPriorityOrder.numParticipants}, \
# fit in sorted order: ${nextPageInSortedOrder.numParticipants}` # fit in sorted order: ${nextPageInSortedOrder.numParticipants}`

View file

@ -7,7 +7,9 @@ import type {
LocalizerType, LocalizerType,
ICUJSXMessageParamsByKeyType, ICUJSXMessageParamsByKeyType,
} from '../types/Util'; } from '../types/Util';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('I18n');
export type Props<Key extends keyof ICUJSXMessageParamsByKeyType> = { export type Props<Key extends keyof ICUJSXMessageParamsByKeyType> = {
/** The translation string id */ /** The translation string id */

View file

@ -5,10 +5,12 @@ import type { ReactNode } from 'react';
import React, { useEffect, useState, useMemo } from 'react'; import React, { useEffect, useState, useMemo } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import type { LocalizerType } from '../types/Util'; import type { LocalizerType } from '../types/Util';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { SECOND, DAY } from '../util/durations'; import { SECOND, DAY } from '../util/durations';
import type { SmartNavTabsProps } from '../state/smart/NavTabs'; import type { SmartNavTabsProps } from '../state/smart/NavTabs';
const log = createLogger('Inbox');
export type PropsType = { export type PropsType = {
firstEnvelopeTimestamp: number | undefined; firstEnvelopeTimestamp: number | undefined;
envelopeTimestamp: number | undefined; envelopeTimestamp: number | undefined;

View file

@ -16,7 +16,7 @@ import type {
import type { LocalizerType } from '../types/Util'; import type { LocalizerType } from '../types/Util';
import type { MediaItemType } from '../types/MediaItem'; import type { MediaItemType } from '../types/MediaItem';
import * as GoogleChrome from '../util/GoogleChrome'; import * as GoogleChrome from '../util/GoogleChrome';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import { Avatar, AvatarSize } from './Avatar'; import { Avatar, AvatarSize } from './Avatar';
import { IMAGE_PNG, isImage, isVideo } from '../types/MIME'; import { IMAGE_PNG, isImage, isVideo } from '../types/MIME';
@ -35,6 +35,8 @@ import { formatFileSize } from '../util/formatFileSize';
import { SECOND } from '../util/durations'; import { SECOND } from '../util/durations';
import { Toast } from './Toast'; import { Toast } from './Toast';
const log = createLogger('Lightbox');
export type PropsType = { export type PropsType = {
children?: ReactNode; children?: ReactNode;
closeLightbox: () => unknown; closeLightbox: () => unknown;
@ -308,7 +310,7 @@ export function Lightbox({
if (videoElement.paused) { if (videoElement.paused) {
onMediaPlaybackStart(); onMediaPlaybackStart();
void videoElement.play().catch(error => { void videoElement.play().catch(error => {
log.error('Lightbox: Failed to play video', Errors.toLogFormat(error)); log.error('Failed to play video', Errors.toLogFormat(error));
}); });
} else { } else {
videoElement.pause(); videoElement.pause();
@ -667,7 +669,7 @@ export function Lightbox({
/> />
); );
} else { } else {
log.info('Lightbox: Unexpected content type', { contentType }); log.info('Unexpected content type', { contentType });
content = ( content = (
<button <button

View file

@ -40,7 +40,7 @@ import {
getTextStyleAttributes, getTextStyleAttributes,
TextStyle, TextStyle,
} from '../mediaEditor/util/getTextStyleAttributes'; } from '../mediaEditor/util/getTextStyleAttributes';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { Button, ButtonVariant } from './Button'; import { Button, ButtonVariant } from './Button';
import { CompositionInput } from './CompositionInput'; import { CompositionInput } from './CompositionInput';
import { ContextMenu } from './ContextMenu'; import { ContextMenu } from './ContextMenu';
@ -69,6 +69,8 @@ import type { FunStickerSelection } from './fun/panels/FunPanelStickers';
import { drop } from '../util/drop'; import { drop } from '../util/drop';
import type { FunTimeStickerStyle } from './fun/constants'; import type { FunTimeStickerStyle } from './fun/constants';
const log = createLogger('MediaEditor');
export type MediaEditorResultType = Readonly<{ export type MediaEditorResultType = Readonly<{
data: Uint8Array; data: Uint8Array;
contentType: MIMEType; contentType: MIMEType;

View file

@ -15,7 +15,7 @@ import { assertDev } from '../util/assert';
import { getClassNamesFor } from '../util/getClassNamesFor'; import { getClassNamesFor } from '../util/getClassNamesFor';
import { useAnimated } from '../hooks/useAnimated'; import { useAnimated } from '../hooks/useAnimated';
import { useHasWrapped } from '../hooks/useHasWrapped'; import { useHasWrapped } from '../hooks/useHasWrapped';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { import {
isScrollOverflowVertical, isScrollOverflowVertical,
isScrollAtTop, isScrollAtTop,
@ -23,6 +23,8 @@ import {
useScrollObserver, useScrollObserver,
} from '../hooks/useSizeObserver'; } from '../hooks/useSizeObserver';
const log = createLogger('Modal');
type PropsType = { type PropsType = {
children: ReactNode; children: ReactNode;
modalName: string; modalName: string;
@ -98,7 +100,7 @@ export function Modal({
} }
const timer = setTimeout(() => { const timer = setTimeout(() => {
log.error(`Modal ${modalName} is closed, but still visible`); log.error(`${modalName} is closed, but still visible`);
assertDev(false, `Invisible modal ${modalName}`); assertDev(false, `Invisible modal ${modalName}`);
}, 0); }, 0);
return () => { return () => {

View file

@ -16,7 +16,9 @@ import { themeClassName } from '../util/theme';
import { useEscapeHandling } from '../hooks/useEscapeHandling'; import { useEscapeHandling } from '../hooks/useEscapeHandling';
import { usePrevious } from '../hooks/usePrevious'; import { usePrevious } from '../hooks/usePrevious';
import { handleOutsideClick } from '../util/handleOutsideClick'; import { handleOutsideClick } from '../util/handleOutsideClick';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('ModalHost');
export const ModalContainerContext = React.createContext<HTMLElement | null>( export const ModalContainerContext = React.createContext<HTMLElement | null>(
null null
@ -53,7 +55,7 @@ export const ModalHost = React.memo(function ModalHostInner({
if (previousModalName !== modalName) { if (previousModalName !== modalName) {
log.error( log.error(
`ModalHost detected conflict between ${previousModalName} ` + `detected conflict between ${previousModalName} ` +
`and ${modalName}. Consider using "key" attributes on both modals.` `and ${modalName}. Consider using "key" attributes on both modals.`
); );
assertDev(false, 'Modal conflict'); assertDev(false, 'Modal conflict');

View file

@ -3,7 +3,9 @@
import type { ProfilerOnRenderCallback, ReactNode } from 'react'; import type { ProfilerOnRenderCallback, ReactNode } from 'react';
import React from 'react'; import React from 'react';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('Profiler');
export type PropsType = Readonly<{ export type PropsType = Readonly<{
id: string; id: string;
@ -19,7 +21,7 @@ const onRender: ProfilerOnRenderCallback = (
commit commit
) => { ) => {
log.info( log.info(
`Profiler.tsx(${id}): actual=${actual.toFixed(1)}ms phase=${phase} ` + `tsx(${id}): actual=${actual.toFixed(1)}ms phase=${phase} ` +
`base=${base.toFixed(1)}ms start=${start.toFixed(1)}ms ` + `base=${base.toFixed(1)}ms start=${start.toFixed(1)}ms ` +
`commit=${commit.toFixed(1)}ms` `commit=${commit.toFixed(1)}ms`
); );

View file

@ -21,9 +21,11 @@ import {
} from '../types/Attachment'; } from '../types/Attachment';
import { getClassNamesFor } from '../util/getClassNamesFor'; import { getClassNamesFor } from '../util/getClassNamesFor';
import { isVideoTypeSupported } from '../util/GoogleChrome'; import { isVideoTypeSupported } from '../util/GoogleChrome';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
const log = createLogger('StoryImage');
export type PropsType = { export type PropsType = {
readonly attachment?: AttachmentType; readonly attachment?: AttachmentType;
readonly children?: ReactNode; readonly children?: ReactNode;
@ -78,10 +80,7 @@ export function StoryImage({
} else { } else {
onMediaPlaybackStart(); onMediaPlaybackStart();
void videoRef.current.play().catch(error => { void videoRef.current.play().catch(error => {
log.error( log.error('Failed to play video', Errors.toLogFormat(error));
'StoryImage: Failed to play video',
Errors.toLogFormat(error)
);
}); });
} }
}, [isPaused, onMediaPlaybackStart]); }, [isPaused, onMediaPlaybackStart]);

View file

@ -19,7 +19,7 @@ import type { ReplyStateType, StoryViewType } from '../types/Stories';
import type { StoryDistributionIdString } from '../types/StoryDistributionId'; import type { StoryDistributionIdString } from '../types/StoryDistributionId';
import type { ShowToastAction } from '../state/ducks/toast'; import type { ShowToastAction } from '../state/ducks/toast';
import type { ViewStoryActionCreatorType } from '../state/ducks/stories'; import type { ViewStoryActionCreatorType } from '../state/ducks/stories';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { AnimatedEmojiGalore } from './AnimatedEmojiGalore'; import { AnimatedEmojiGalore } from './AnimatedEmojiGalore';
import { Avatar, AvatarSize } from './Avatar'; import { Avatar, AvatarSize } from './Avatar';
import { ConfirmationDialog } from './ConfirmationDialog'; import { ConfirmationDialog } from './ConfirmationDialog';
@ -55,6 +55,8 @@ import { arrow } from '../util/keyboard';
import { StoryProgressSegment } from './StoryProgressSegment'; import { StoryProgressSegment } from './StoryProgressSegment';
import type { EmojiSkinTone } from './fun/data/emojis'; import type { EmojiSkinTone } from './fun/data/emojis';
const log = createLogger('StoryViewer');
function renderStrong(parts: Array<JSX.Element | string>) { function renderStrong(parts: Array<JSX.Element | string>) {
return <strong>{parts}</strong>; return <strong>{parts}</strong>;
} }

View file

@ -6,9 +6,11 @@ import PQueue from 'p-queue';
import { LRUCache } from 'lru-cache'; import { LRUCache } from 'lru-cache';
import type { WaveformCache } from '../types/Audio'; import type { WaveformCache } from '../types/Audio';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { redactAttachmentUrl } from '../util/privacy'; import { redactAttachmentUrl } from '../util/privacy';
const log = createLogger('VoiceNotesPlaybackContext');
const MAX_WAVEFORM_COUNT = 1000; const MAX_WAVEFORM_COUNT = 1000;
const MAX_PARALLEL_COMPUTE = 8; const MAX_PARALLEL_COMPUTE = 8;
const MAX_AUDIO_DURATION = 15 * 60; // 15 minutes const MAX_AUDIO_DURATION = 15 * 60; // 15 minutes

View file

@ -25,7 +25,7 @@ import {
} from '../../util/callingNotification'; } from '../../util/callingNotification';
import { missingCaseError } from '../../util/missingCaseError'; import { missingCaseError } from '../../util/missingCaseError';
import { Tooltip, TooltipPlacement } from '../Tooltip'; import { Tooltip, TooltipPlacement } from '../Tooltip';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import { import {
type ContextMenuTriggerType, type ContextMenuTriggerType,
MessageContextMenu, MessageContextMenu,
@ -41,6 +41,8 @@ import { isMoreRecentThan } from '../../util/timestamp';
import { InAnotherCallTooltip } from './InAnotherCallTooltip'; import { InAnotherCallTooltip } from './InAnotherCallTooltip';
import type { InteractionModeType } from '../../state/ducks/conversations'; import type { InteractionModeType } from '../../state/ducks/conversations';
const log = createLogger('CallingNotification');
export type PropsActionsType = { export type PropsActionsType = {
onOutgoingAudioCallInConversation: (conversationId: string) => void; onOutgoingAudioCallInConversation: (conversationId: string) => void;
onOutgoingVideoCallInConversation: (conversationId: string) => void; onOutgoingVideoCallInConversation: (conversationId: string) => void;
@ -239,7 +241,7 @@ function renderCallingNotificationButton(
break; break;
} }
case CallMode.Adhoc: case CallMode.Adhoc:
log.warn('CallingNotification for adhoc call, should never happen'); log.warn('for adhoc call, should never happen');
return null; return null;
default: default:
log.error(toLogFormat(missingCaseError(props.callHistory.mode))); log.error(toLogFormat(missingCaseError(props.callHistory.mode)));

View file

@ -13,7 +13,7 @@ import type { HasStories } from '../../types/Stories';
import type { LocalizerType, ThemeType } from '../../types/Util'; import type { LocalizerType, ThemeType } from '../../types/Util';
import type { ViewUserStoriesActionCreatorType } from '../../state/ducks/stories'; import type { ViewUserStoriesActionCreatorType } from '../../state/ducks/stories';
import { StoryViewModeType } from '../../types/Stories'; import { StoryViewModeType } from '../../types/Stories';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import { Avatar, AvatarBlur, AvatarSize } from '../Avatar'; import { Avatar, AvatarBlur, AvatarSize } from '../Avatar';
import { AvatarLightbox } from '../AvatarLightbox'; import { AvatarLightbox } from '../AvatarLightbox';
import { BadgeDialog } from '../BadgeDialog'; import { BadgeDialog } from '../BadgeDialog';
@ -32,6 +32,8 @@ import {
getTooltipContent, getTooltipContent,
} from './InAnotherCallTooltip'; } from './InAnotherCallTooltip';
const log = createLogger('ContactModal');
export type PropsDataType = { export type PropsDataType = {
areWeASubscriber: boolean; areWeASubscriber: boolean;
areWeAdmin: boolean; areWeAdmin: boolean;
@ -216,7 +218,7 @@ export function ContactModal({
break; break;
case SubModalState.ToggleAdmin: case SubModalState.ToggleAdmin:
if (!conversation?.id) { if (!conversation?.id) {
log.warn('ContactModal: ToggleAdmin state - missing conversationId'); log.warn('ToggleAdmin state - missing conversationId');
modalNode = undefined; modalNode = undefined;
break; break;
} }
@ -247,9 +249,7 @@ export function ContactModal({
break; break;
case SubModalState.MemberRemove: case SubModalState.MemberRemove:
if (!contact || !conversation?.id) { if (!contact || !conversation?.id) {
log.warn( log.warn('MemberRemove state - missing contact or conversationId');
'ContactModal: MemberRemove state - missing contact or conversationId'
);
modalNode = undefined; modalNode = undefined;
break; break;
} }
@ -291,7 +291,7 @@ export function ContactModal({
break; break;
default: { default: {
const state: never = subModalState; const state: never = subModalState;
log.warn(`ContactModal: unexpected ${state}!`); log.warn(`unexpected ${state}!`);
modalNode = undefined; modalNode = undefined;
break; break;
} }

View file

@ -11,9 +11,11 @@ import {
isEmojiVariantValue, isEmojiVariantValue,
isEmojiVariantValueNonQualified, isEmojiVariantValueNonQualified,
} from '../fun/data/emojis'; } from '../fun/data/emojis';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import { useFunEmojiLocalizer } from '../fun/useFunEmojiLocalizer'; import { useFunEmojiLocalizer } from '../fun/useFunEmojiLocalizer';
const log = createLogger('Emojify');
export type Props = { export type Props = {
fontSizeOverride?: number | null; fontSizeOverride?: number | null;
text: string; text: string;

View file

@ -6,7 +6,9 @@ import React from 'react';
import type { LocalizerType } from '../../types/Util'; import type { LocalizerType } from '../../types/Util';
import * as Errors from '../../types/errors'; import * as Errors from '../../types/errors';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
const log = createLogger('ErrorBoundary');
export type Props = { export type Props = {
i18n: LocalizerType; i18n: LocalizerType;
@ -29,10 +31,7 @@ export class ErrorBoundary extends React.PureComponent<Props, State> {
} }
public static getDerivedStateFromError(error: Error): State { public static getDerivedStateFromError(error: Error): State {
log.error( log.error('captured rendering error', Errors.toLogFormat(error));
'ErrorBoundary: captured rendering error',
Errors.toLogFormat(error)
);
return { error }; return { error };
} }

View file

@ -15,12 +15,14 @@ import {
isDownloadable, isDownloadable,
} from '../../types/Attachment'; } from '../../types/Attachment';
import * as Errors from '../../types/errors'; import * as Errors from '../../types/errors';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import { useReducedMotion } from '../../hooks/useReducedMotion'; import { useReducedMotion } from '../../hooks/useReducedMotion';
import { AttachmentDetailPill } from './AttachmentDetailPill'; import { AttachmentDetailPill } from './AttachmentDetailPill';
import { getSpinner } from './Image'; import { getSpinner } from './Image';
import { useUndownloadableMediaHandler } from '../../hooks/useUndownloadableMediaHandler'; import { useUndownloadableMediaHandler } from '../../hooks/useUndownloadableMediaHandler';
const log = createLogger('GIF');
const MAX_GIF_REPEAT = 4; const MAX_GIF_REPEAT = 4;
const MAX_GIF_TIME = 8; const MAX_GIF_TIME = 8;

View file

@ -11,7 +11,9 @@ import type { PreferredBadgeSelectorType } from '../../state/selectors/badges';
import { I18n } from '../I18n'; import { I18n } from '../I18n';
import { ContactName } from './ContactName'; import { ContactName } from './ContactName';
import { GroupV1MigrationDialog } from '../GroupV1MigrationDialog'; import { GroupV1MigrationDialog } from '../GroupV1MigrationDialog';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
const log = createLogger('GroupV1Migration');
export type PropsDataType = { export type PropsDataType = {
areWeInvited: boolean; areWeInvited: boolean;
@ -101,7 +103,7 @@ export function GroupV1Migration(props: PropsType): React.ReactElement {
i18n={i18n} i18n={i18n}
invitedMembers={invitedMembers} invitedMembers={invitedMembers}
invitedMemberCount={invitedMemberCount} invitedMemberCount={invitedMemberCount}
onMigrate={() => log.warn('GroupV1Migration: Modal called migrate()')} onMigrate={() => log.warn('Modal called migrate()')}
onClose={dismissDialog} onClose={dismissDialog}
theme={theme} theme={theme}
/> />

View file

@ -6,7 +6,7 @@ import React, { useState } from 'react';
import { get } from 'lodash'; import { get } from 'lodash';
import type { ReadonlyDeep } from 'type-fest'; import type { ReadonlyDeep } from 'type-fest';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import { I18n } from '../I18n'; import { I18n } from '../I18n';
import type { import type {
LocalizerType, LocalizerType,
@ -28,6 +28,8 @@ import { renderChange } from '../../groupChange';
import { Modal } from '../Modal'; import { Modal } from '../Modal';
import { ConfirmationDialog } from '../ConfirmationDialog'; import { ConfirmationDialog } from '../ConfirmationDialog';
const log = createLogger('GroupV2Change');
export type PropsDataType = ReadonlyDeep<{ export type PropsDataType = ReadonlyDeep<{
areWeAdmin: boolean; areWeAdmin: boolean;
change: GroupV2ChangeType; change: GroupV2ChangeType;

View file

@ -51,7 +51,7 @@ import { toLogFormat } from '../../types/errors';
import { shouldUseFullSizeLinkPreviewImage } from '../../linkPreviews/shouldUseFullSizeLinkPreviewImage'; import { shouldUseFullSizeLinkPreviewImage } from '../../linkPreviews/shouldUseFullSizeLinkPreviewImage';
import type { WidthBreakpoint } from '../_util'; import type { WidthBreakpoint } from '../_util';
import { OutgoingGiftBadgeModal } from '../OutgoingGiftBadgeModal'; import { OutgoingGiftBadgeModal } from '../OutgoingGiftBadgeModal';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import { StoryViewModeType } from '../../types/Stories'; import { StoryViewModeType } from '../../types/Stories';
import type { import type {
AttachmentForUIType, AttachmentForUIType,
@ -123,6 +123,8 @@ import {
} from '../fun/data/emojis'; } from '../fun/data/emojis';
import { useGroupedAndOrderedReactions } from '../../util/groupAndOrderReactions'; import { useGroupedAndOrderedReactions } from '../../util/groupAndOrderReactions';
const log = createLogger('Message');
const GUESS_METADATA_WIDTH_TIMESTAMP_SIZE = 16; const GUESS_METADATA_WIDTH_TIMESTAMP_SIZE = 16;
const GUESS_METADATA_WIDTH_EXPIRE_TIMER_SIZE = 18; const GUESS_METADATA_WIDTH_EXPIRE_TIMER_SIZE = 18;
const GUESS_METADATA_WIDTH_SMS_SIZE = 18; const GUESS_METADATA_WIDTH_SMS_SIZE = 18;
@ -718,9 +720,7 @@ export class Message extends React.PureComponent<Props, State> {
public handleImageError = (): void => { public handleImageError = (): void => {
const { id } = this.props; const { id } = this.props;
log.info( log.info(`${id}: Image failed to load; failing over to placeholder`);
`Message ${id}: Image failed to load; failing over to placeholder`
);
this.setState({ this.setState({
imageBroken: true, imageBroken: true,
}); });
@ -813,7 +813,7 @@ export class Message extends React.PureComponent<Props, State> {
delta, delta,
}); });
log.info( log.info(
`Message.tsx: Rendered 'send complete' for message ${timestamp}; took ${delta}ms` `tsx: Rendered 'send complete' for message ${timestamp}; took ${delta}ms`
); );
} }
} }

View file

@ -15,7 +15,7 @@ import type { DirectionType, MessageStatusType } from './Message';
import type { ComputePeaksResult } from '../VoiceNotesPlaybackContext'; import type { ComputePeaksResult } from '../VoiceNotesPlaybackContext';
import { MessageMetadata } from './MessageMetadata'; import { MessageMetadata } from './MessageMetadata';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import type { ActiveAudioPlayerStateType } from '../../state/ducks/audioPlayer'; import type { ActiveAudioPlayerStateType } from '../../state/ducks/audioPlayer';
import { PlaybackRateButton } from '../PlaybackRateButton'; import { PlaybackRateButton } from '../PlaybackRateButton';
import { PlaybackButton } from '../PlaybackButton'; import { PlaybackButton } from '../PlaybackButton';
@ -26,6 +26,8 @@ import { shouldNeverBeCalled } from '../../util/shouldNeverBeCalled';
import { formatFileSize } from '../../util/formatFileSize'; import { formatFileSize } from '../../util/formatFileSize';
import { roundFractionForProgressBar } from '../../util/numbers'; import { roundFractionForProgressBar } from '../../util/numbers';
const log = createLogger('MessageAudio');
export type OwnProps = Readonly<{ export type OwnProps = Readonly<{
active: active:
| Pick< | Pick<

View file

@ -25,7 +25,7 @@ import {
type VisibleSendStatus, type VisibleSendStatus,
} from '../../messages/MessageSendState'; } from '../../messages/MessageSendState';
import { WidthBreakpoint } from '../_util'; import { WidthBreakpoint } from '../_util';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import { formatDateTimeLong } from '../../util/timestamp'; import { formatDateTimeLong } from '../../util/timestamp';
import { DurationInSeconds } from '../../util/durations'; import { DurationInSeconds } from '../../util/durations';
import { format as formatRelativeTime } from '../../util/expirationTimer'; import { format as formatRelativeTime } from '../../util/expirationTimer';
@ -37,6 +37,8 @@ import {
IconType, IconType,
} from './conversation-details/ConversationDetailsIcon'; } from './conversation-details/ConversationDetailsIcon';
const log = createLogger('MessageDetail');
export type Contact = Pick< export type Contact = Pick<
ConversationType, ConversationType,
| 'acceptedMessageRequest' | 'acceptedMessageRequest'
@ -361,7 +363,7 @@ export function MessageDetail({
showConversation={showConversation} showConversation={showConversation}
showSpoiler={showSpoiler} showSpoiler={showSpoiler}
scrollToQuotedMessage={() => { scrollToQuotedMessage={() => {
log.warn('MessageDetail: scrollToQuotedMessage called!'); log.warn('scrollToQuotedMessage called!');
}} }}
showContactModal={showContactModal} showContactModal={showContactModal}
showAttachmentDownloadStillInProgressToast={ showAttachmentDownloadStillInProgressToast={

View file

@ -10,7 +10,9 @@ import { I18n } from '../I18n';
import type { LocalizerType } from '../../types/Util'; import type { LocalizerType } from '../../types/Util';
import * as expirationTimer from '../../util/expirationTimer'; import * as expirationTimer from '../../util/expirationTimer';
import type { DurationInSeconds } from '../../util/durations'; import type { DurationInSeconds } from '../../util/durations';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
const log = createLogger('TimerNotification');
export type TimerNotificationType = export type TimerNotificationType =
| 'fromOther' | 'fromOther'
@ -83,7 +85,7 @@ export function TimerNotification(props: Props): JSX.Element {
: i18n('icu:timerSetByMember', { time: timespan }); : i18n('icu:timerSetByMember', { time: timespan });
break; break;
default: default:
log.warn('TimerNotification: unsupported type provided:', type); log.warn('unsupported type provided:', type);
break; break;
} }

View file

@ -11,7 +11,9 @@ import {
} from '../../../util/GoogleChrome'; } from '../../../util/GoogleChrome';
import type { LocalizerType } from '../../../types/Util'; import type { LocalizerType } from '../../../types/Util';
import type { MediaItemType } from '../../../types/MediaItem'; import type { MediaItemType } from '../../../types/MediaItem';
import * as log from '../../../logging/log'; import { createLogger } from '../../../logging/log';
const log = createLogger('MediaGridItem');
export type Props = { export type Props = {
mediaItem: ReadonlyDeep<MediaItemType>; mediaItem: ReadonlyDeep<MediaItemType>;
@ -26,9 +28,7 @@ function MediaGridItemContent(props: Props) {
const [imageBroken, setImageBroken] = useState(false); const [imageBroken, setImageBroken] = useState(false);
const handleImageError = useCallback(() => { const handleImageError = useCallback(() => {
log.info( log.info('Image failed to load; failing over to placeholder');
'MediaGridItem: Image failed to load; failing over to placeholder'
);
setImageBroken(true); setImageBroken(true);
}, []); }, []);

View file

@ -4,12 +4,14 @@
import moment from 'moment'; import moment from 'moment';
import { compact, groupBy, sortBy } from 'lodash'; import { compact, groupBy, sortBy } from 'lodash';
import * as log from '../../../logging/log'; import { createLogger } from '../../../logging/log';
import type { MediaItemType } from '../../../types/MediaItem'; import type { MediaItemType } from '../../../types/MediaItem';
import { missingCaseError } from '../../../util/missingCaseError'; import { missingCaseError } from '../../../util/missingCaseError';
import { toLogFormat } from '../../../types/errors'; import { toLogFormat } from '../../../types/errors';
const log = createLogger('groupMediaItemsByDate');
type StaticSectionType = 'today' | 'yesterday' | 'thisWeek' | 'thisMonth'; type StaticSectionType = 'today' | 'yesterday' | 'thisWeek' | 'thisMonth';
type YearMonthSectionType = 'yearMonth'; type YearMonthSectionType = 'yearMonth';

View file

@ -10,7 +10,7 @@ import React, {
useState, useState,
} from 'react'; } from 'react';
import type { LocaleEmojiListType } from '../../types/emoji'; import type { LocaleEmojiListType } from '../../types/emoji';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import * as Errors from '../../types/errors'; import * as Errors from '../../types/errors';
import { drop } from '../../util/drop'; import { drop } from '../../util/drop';
import { import {
@ -28,6 +28,8 @@ import {
import type { LocalizerType } from '../../types/I18N'; import type { LocalizerType } from '../../types/I18N';
import { strictAssert } from '../../util/assert'; import { strictAssert } from '../../util/assert';
const log = createLogger('FunEmojiLocalizationProvider');
export type FunEmojiLocalizationContextType = Readonly<{ export type FunEmojiLocalizationContextType = Readonly<{
emojiSearchIndex: FunEmojiSearchIndex; emojiSearchIndex: FunEmojiSearchIndex;
emojiLocalizerIndex: FunEmojiLocalizerIndex; emojiLocalizerIndex: FunEmojiLocalizerIndex;

View file

@ -8,10 +8,12 @@ import { strictAssert } from '../../util/assert';
import type { Loadable } from '../../util/loadable'; import type { Loadable } from '../../util/loadable';
import { LoadingState } from '../../util/loadable'; import { LoadingState } from '../../util/loadable';
import { useIntent } from './base/FunImage'; import { useIntent } from './base/FunImage';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import * as Errors from '../../types/errors'; import * as Errors from '../../types/errors';
import { isAbortError } from '../../util/isAbortError'; import { isAbortError } from '../../util/isAbortError';
const log = createLogger('FunGif');
export type FunGifProps = Readonly<{ export type FunGifProps = Readonly<{
src: string; src: string;
width: number; width: number;
@ -66,7 +68,7 @@ function FunGifReducedMotion(props: FunGifProps) {
video.play().catch(error => { video.play().catch(error => {
// ignore errors where `play()` was interrupted by `pause()` // ignore errors where `play()` was interrupted by `pause()`
if (!isAbortError(error)) { if (!isAbortError(error)) {
log.error('FunGif: Playback error', Errors.toLogFormat(error)); log.error('Playback error', Errors.toLogFormat(error));
} }
}); });
} else { } else {

View file

@ -2,10 +2,12 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { ReactNode, ErrorInfo } from 'react'; import type { ReactNode, ErrorInfo } from 'react';
import React, { Component, useCallback } from 'react'; import React, { Component, useCallback } from 'react';
import * as log from '../../../logging/log'; import { createLogger } from '../../../logging/log';
import * as Errors from '../../../types/errors'; import * as Errors from '../../../types/errors';
import { ToastType } from '../../../types/Toast'; import { ToastType } from '../../../types/Toast';
const log = createLogger('FunErrorBoundary');
type ErrorBoundaryProps = Readonly<{ type ErrorBoundaryProps = Readonly<{
onError: (error: unknown, info: ErrorInfo) => void; onError: (error: unknown, info: ErrorInfo) => void;
fallback: (error: unknown) => ReactNode; fallback: (error: unknown) => ReactNode;

View file

@ -22,12 +22,14 @@ import {
getScrollRightDistance, getScrollRightDistance,
useScrollObserver, useScrollObserver,
} from '../../../hooks/useSizeObserver'; } from '../../../hooks/useSizeObserver';
import * as log from '../../../logging/log'; import { createLogger } from '../../../logging/log';
import * as Errors from '../../../types/errors'; import * as Errors from '../../../types/errors';
import { strictAssert } from '../../../util/assert'; import { strictAssert } from '../../../util/assert';
import { FunImage } from './FunImage'; import { FunImage } from './FunImage';
import { FunTooltip } from './FunTooltip'; import { FunTooltip } from './FunTooltip';
const log = createLogger('FunSubNav');
/** /**
* Sub Nav * Sub Nav
*/ */

View file

@ -2,10 +2,12 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { useCallback, useEffect, useRef, useState } from 'react'; import { useCallback, useEffect, useRef, useState } from 'react';
import { drop } from '../../../util/drop'; import { drop } from '../../../util/drop';
import * as log from '../../../logging/log'; import { createLogger } from '../../../logging/log';
import * as Errors from '../../../types/errors'; import * as Errors from '../../../types/errors';
import { strictAssert } from '../../../util/assert'; import { strictAssert } from '../../../util/assert';
const log = createLogger('infinite');
export type InfiniteQueryLoader<Query, Page> = ( export type InfiniteQueryLoader<Query, Page> = (
query: Query, query: Query,
previousPage: Page | null, previousPage: Page | null,

View file

@ -61,9 +61,11 @@ import type { tenorDownload } from '../data/tenor';
import { FunGif } from '../FunGif'; import { FunGif } from '../FunGif';
import type { LocalizerType } from '../../../types/I18N'; import type { LocalizerType } from '../../../types/I18N';
import { isAbortError } from '../../../util/isAbortError'; import { isAbortError } from '../../../util/isAbortError';
import * as log from '../../../logging/log'; import { createLogger } from '../../../logging/log';
import * as Errors from '../../../types/errors'; import * as Errors from '../../../types/errors';
const log = createLogger('FunPanelGifs');
const MAX_CACHE_SIZE = 50 * 1024 * 1024; // 50 MB const MAX_CACHE_SIZE = 50 * 1024 * 1024; // 50 MB
const FunGifBlobCache = new LRUCache<string, Blob>({ const FunGifBlobCache = new LRUCache<string, Blob>({
maxSize: MAX_CACHE_SIZE, maxSize: MAX_CACHE_SIZE,

View file

@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { makeEnumParser } from './util/enum'; import { makeEnumParser } from './util/enum';
import * as log from './logging/log'; import { log } from './logging/log';
// Many places rely on this enum being a string. // Many places rely on this enum being a string.
export enum Environment { export enum Environment {

View file

@ -12,7 +12,9 @@ import { missingCaseError } from './util/missingCaseError';
import type { GroupV2ChangeDetailType, GroupV2ChangeType } from './groups'; import type { GroupV2ChangeDetailType, GroupV2ChangeType } from './groups';
import { SignalService as Proto } from './protobuf'; import { SignalService as Proto } from './protobuf';
import * as log from './logging/log'; import { createLogger } from './logging/log';
const log = createLogger('groupChange');
type SelectParamsByKeyType<T extends string | JSX.Element> = T extends string type SelectParamsByKeyType<T extends string | JSX.Element> = T extends string
? ICUStringMessageParamsByKeyType ? ICUStringMessageParamsByKeyType

View file

@ -13,7 +13,7 @@ import {
import Long from 'long'; import Long from 'long';
import type { ClientZkGroupCipher } from '@signalapp/libsignal-client/zkgroup'; import type { ClientZkGroupCipher } from '@signalapp/libsignal-client/zkgroup';
import { LRUCache } from 'lru-cache'; import { LRUCache } from 'lru-cache';
import * as log from './logging/log'; import { createLogger } from './logging/log';
import { import {
getCheckedGroupCredentialsForToday, getCheckedGroupCredentialsForToday,
maybeFetchNewCredentials, maybeFetchNewCredentials,
@ -107,6 +107,8 @@ import { MessageModel } from './models/messages';
import { areWePending } from './util/groupMembershipUtils'; import { areWePending } from './util/groupMembershipUtils';
import { isConversationAccepted } from './util/isConversationAccepted'; import { isConversationAccepted } from './util/isConversationAccepted';
const log = createLogger('groups');
type AccessRequiredEnum = Proto.AccessControl.AccessRequired; type AccessRequiredEnum = Proto.AccessControl.AccessRequired;
export { joinViaLink } from './groups/joinViaLink'; export { joinViaLink } from './groups/joinViaLink';

View file

@ -10,7 +10,7 @@ import type { PreJoinConversationType } from '../state/ducks/conversations';
import { DataWriter } from '../sql/Client'; import { DataWriter } from '../sql/Client';
import * as Bytes from '../Bytes'; import * as Bytes from '../Bytes';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { HTTPError } from '../textsecure/Errors'; import { HTTPError } from '../textsecure/Errors';
import { SignalService as Proto } from '../protobuf'; import { SignalService as Proto } from '../protobuf';
import type { ContactAvatarType } from '../types/Avatar'; import type { ContactAvatarType } from '../types/Avatar';
@ -36,6 +36,8 @@ import { getLocalAttachmentUrl } from '../util/getLocalAttachmentUrl';
import { type Loadable, LoadingState } from '../util/loadable'; import { type Loadable, LoadingState } from '../util/loadable';
import { missingCaseError } from '../util/missingCaseError'; import { missingCaseError } from '../util/missingCaseError';
const log = createLogger('joinViaLink');
export async function joinViaLink(value: string): Promise<void> { export async function joinViaLink(value: string): Promise<void> {
let inviteLinkPassword: string; let inviteLinkPassword: string;
let masterKey: string; let masterKey: string;
@ -43,7 +45,7 @@ export async function joinViaLink(value: string): Promise<void> {
({ inviteLinkPassword, masterKey } = parseGroupLink(value)); ({ inviteLinkPassword, masterKey } = parseGroupLink(value));
} catch (error: unknown) { } catch (error: unknown) {
const errorString = Errors.toLogFormat(error); const errorString = Errors.toLogFormat(error);
log.error(`joinViaLink: Failed to parse group link ${errorString}`); log.error(`Failed to parse group link ${errorString}`);
if (error instanceof Error && error.name === LINK_VERSION_ERROR) { if (error instanceof Error && error.name === LINK_VERSION_ERROR) {
window.reduxActions.globalModals.showErrorModal({ window.reduxActions.globalModals.showErrorModal({
@ -71,9 +73,7 @@ export async function joinViaLink(value: string): Promise<void> {
const ourAci = window.textsecure.storage.user.getCheckedAci(); const ourAci = window.textsecure.storage.user.getCheckedAci();
if (existingConversation && existingConversation.hasMember(ourAci)) { if (existingConversation && existingConversation.hasMember(ourAci)) {
log.warn( log.warn(`${logId}: Already a member of group, opening conversation`);
`joinViaLink/${logId}: Already a member of group, opening conversation`
);
window.reduxActions.conversations.showConversation({ window.reduxActions.conversations.showConversation({
conversationId: existingConversation.id, conversationId: existingConversation.id,
}); });
@ -96,9 +96,7 @@ export async function joinViaLink(value: string): Promise<void> {
}); });
} catch (error: unknown) { } catch (error: unknown) {
const errorString = Errors.toLogFormat(error); const errorString = Errors.toLogFormat(error);
log.error( log.error(`${logId}: Failed to fetch group info - ${errorString}`);
`joinViaLink/${logId}: Failed to fetch group info - ${errorString}`
);
if ( if (
error instanceof HTTPError && error instanceof HTTPError &&
@ -124,7 +122,7 @@ export async function joinViaLink(value: string): Promise<void> {
if (!isAccessControlEnabled(dropNull(result.addFromInviteLink))) { if (!isAccessControlEnabled(dropNull(result.addFromInviteLink))) {
log.error( log.error(
`joinViaLink/${logId}: addFromInviteLink value of ${result.addFromInviteLink} is invalid` `${logId}: addFromInviteLink value of ${result.addFromInviteLink} is invalid`
); );
window.reduxActions.globalModals.showErrorModal({ window.reduxActions.globalModals.showErrorModal({
description: window.i18n('icu:GroupV2--join--link-revoked'), description: window.i18n('icu:GroupV2--join--link-revoked'),
@ -158,9 +156,7 @@ export async function joinViaLink(value: string): Promise<void> {
existingConversation && existingConversation &&
existingConversation.isMemberAwaitingApproval(ourAci) existingConversation.isMemberAwaitingApproval(ourAci)
) { ) {
log.warn( log.warn(`${logId}: Already awaiting approval, opening conversation`);
`joinViaLink/${logId}: Already awaiting approval, opening conversation`
);
const timestamp = existingConversation.get('timestamp') || Date.now(); const timestamp = existingConversation.get('timestamp') || Date.now();
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
const active_at = existingConversation.get('active_at') || Date.now(); const active_at = existingConversation.get('active_at') || Date.now();
@ -266,7 +262,7 @@ export async function joinViaLink(value: string): Promise<void> {
targetConversation.isMemberAwaitingApproval(ourAci))) targetConversation.isMemberAwaitingApproval(ourAci)))
) { ) {
log.warn( log.warn(
`joinViaLink/${logId}: User is part of group on second check, opening conversation` `${logId}: User is part of group on second check, opening conversation`
); );
window.reduxActions.conversations.showConversation({ window.reduxActions.conversations.showConversation({
conversationId: targetConversation.id, conversationId: targetConversation.id,
@ -388,7 +384,7 @@ export async function joinViaLink(value: string): Promise<void> {
getPreJoinConversation() getPreJoinConversation()
); );
log.info(`joinViaLink/${logId}: Showing modal`); log.info(`${logId}: Showing modal`);
let groupV2InfoNode: HTMLDivElement | undefined = let groupV2InfoNode: HTMLDivElement | undefined =
document.createElement('div'); document.createElement('div');

View file

@ -4,7 +4,9 @@
import { noop } from 'lodash'; import { noop } from 'lodash';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { computePeaks } from '../components/VoiceNotesPlaybackContext'; import { computePeaks } from '../components/VoiceNotesPlaybackContext';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('useComputePeaks');
type WaveformData = { type WaveformData = {
peaks: ReadonlyArray<number>; peaks: ReadonlyArray<number>;

View file

@ -2,7 +2,9 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { useCallback, useRef, useState } from 'react'; import { useCallback, useRef, useState } from 'react';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('useIntersectionObserver');
/** /**
* A light hook wrapper around `IntersectionObserver`. * A light hook wrapper around `IntersectionObserver`.

View file

@ -2,7 +2,9 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { useContext, createContext, useEffect, useRef } from 'react'; import { useContext, createContext, useEffect, useRef } from 'react';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('useScrollLock');
export type ScrollerLock = Readonly<{ export type ScrollerLock = Readonly<{
isLocked(): boolean; isLocked(): boolean;

View file

@ -1,7 +1,9 @@
// Copyright 2018 Signal Messenger, LLC // Copyright 2018 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import * as log from './logging/log'; import { createLogger } from './logging/log';
const log = createLogger('indexeddb');
const LEGACY_DATABASE_ID = 'signal'; const LEGACY_DATABASE_ID = 'signal';

View file

@ -6,7 +6,7 @@ import { existsSync } from 'node:fs';
import { PassThrough } from 'node:stream'; import { PassThrough } from 'node:stream';
import * as durations from '../util/durations'; import * as durations from '../util/durations';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { DataWriter } from '../sql/Client'; import { DataWriter } from '../sql/Client';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
@ -65,6 +65,8 @@ import { BackupCredentialType } from '../types/backups';
import { supportsIncrementalMac } from '../types/MIME'; import { supportsIncrementalMac } from '../types/MIME';
import type { MIMEType } from '../types/MIME'; import type { MIMEType } from '../types/MIME';
const log = createLogger('AttachmentBackupManager');
const MAX_CONCURRENT_JOBS = 3; const MAX_CONCURRENT_JOBS = 3;
const RETRY_CONFIG = { const RETRY_CONFIG = {
// As long as we have the file locally, we're always going to keep trying // As long as we have the file locally, we're always going to keep trying
@ -148,12 +150,12 @@ export class AttachmentBackupManager extends JobManager<CoreAttachmentBackupJobT
} }
static async start(): Promise<void> { static async start(): Promise<void> {
log.info('AttachmentBackupManager/starting'); log.info('starting');
await AttachmentBackupManager.instance.start(); await AttachmentBackupManager.instance.start();
} }
static async stop(): Promise<void> { static async stop(): Promise<void> {
log.info('AttachmentBackupManager/stopping'); log.info('stopping');
return AttachmentBackupManager._instance?.stop(); return AttachmentBackupManager._instance?.stop();
} }

View file

@ -4,7 +4,7 @@ import { noop, omit, throttle } from 'lodash';
import { statfs } from 'node:fs/promises'; import { statfs } from 'node:fs/promises';
import * as durations from '../util/durations'; import * as durations from '../util/durations';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import type { AttachmentBackfillResponseSyncEvent } from '../textsecure/messageReceiverEvents'; import type { AttachmentBackfillResponseSyncEvent } from '../textsecure/messageReceiverEvents';
import { import {
type AttachmentDownloadJobTypeType, type AttachmentDownloadJobTypeType,
@ -66,6 +66,8 @@ import {
import { formatCountForLogging } from '../logging/formatCountForLogging'; import { formatCountForLogging } from '../logging/formatCountForLogging';
import { strictAssert } from '../util/assert'; import { strictAssert } from '../util/assert';
const log = createLogger('AttachmentDownloadManager');
export { isPermanentlyUndownloadable }; export { isPermanentlyUndownloadable };
// Type for adding a new job // Type for adding a new job
@ -340,7 +342,7 @@ export class AttachmentDownloadManager extends JobManager<CoreAttachmentDownload
window.storage.get('backupMediaDownloadCompletedBytes', 0); window.storage.get('backupMediaDownloadCompletedBytes', 0);
log.info( log.info(
'AttachmentDownloadManager.checkFreeDiskSpaceForBackupImport: insufficient disk space. ' + 'checkFreeDiskSpaceForBackupImport: insufficient disk space. ' +
`Available: ${formatCountForLogging(freeDiskSpace)}, ` + `Available: ${formatCountForLogging(freeDiskSpace)}, ` +
`Needed: ${formatCountForLogging(remainingBackupBytesToDownload)} ` + `Needed: ${formatCountForLogging(remainingBackupBytesToDownload)} ` +
`Minimum threshold: ${this.#minimumFreeDiskSpace}` `Minimum threshold: ${this.#minimumFreeDiskSpace}`

View file

@ -7,7 +7,7 @@ import { PassThrough } from 'node:stream';
import { constants as FS_CONSTANTS, copyFile, mkdir } from 'fs/promises'; import { constants as FS_CONSTANTS, copyFile, mkdir } from 'fs/promises';
import * as durations from '../util/durations'; import * as durations from '../util/durations';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import { redactGenericText } from '../util/privacy'; import { redactGenericText } from '../util/privacy';
@ -30,6 +30,8 @@ import {
getLocalBackupPathForMediaName, getLocalBackupPathForMediaName,
} from '../services/backups/util/localBackup'; } from '../services/backups/util/localBackup';
const log = createLogger('AttachmentLocalBackupManager');
const MAX_CONCURRENT_JOBS = 3; const MAX_CONCURRENT_JOBS = 3;
const RETRY_CONFIG = { const RETRY_CONFIG = {
maxAttempts: 3, maxAttempts: 3,
@ -81,12 +83,12 @@ export class AttachmentLocalBackupManager extends JobManager<CoreAttachmentLocal
} }
static async start(): Promise<void> { static async start(): Promise<void> {
log.info('AttachmentLocalBackupManager/starting'); log.info('starting');
await AttachmentLocalBackupManager.instance.start(); await AttachmentLocalBackupManager.instance.start();
} }
static async stop(): Promise<void> { static async stop(): Promise<void> {
log.info('AttachmentLocalBackupManager/stopping'); log.info('stopping');
return AttachmentLocalBackupManager.#instance?.stop(); return AttachmentLocalBackupManager.#instance?.stop();
} }

View file

@ -1,7 +1,7 @@
// Copyright 2024 Signal Messenger, LLC // Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import * as durations from '../util/durations'; import * as durations from '../util/durations';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { DataReader, DataWriter } from '../sql/Client'; import { DataReader, DataWriter } from '../sql/Client';
import { import {
JobManager, JobManager,
@ -10,6 +10,8 @@ import {
type JobManagerJobType, type JobManagerJobType,
} from './JobManager'; } from './JobManager';
const log = createLogger('CallLinkFinalizeDeleteManager');
// Type for adding a new job // Type for adding a new job
export type NewCallLinkDeleteJobType = { export type NewCallLinkDeleteJobType = {
roomId: string; roomId: string;

View file

@ -8,7 +8,7 @@ import {
} from '../util/explodePromise'; } from '../util/explodePromise';
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary'; import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
import { drop } from '../util/drop'; import { drop } from '../util/drop';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { missingCaseError } from '../util/missingCaseError'; import { missingCaseError } from '../util/missingCaseError';
import { import {
type ExponentialBackoffOptionsType, type ExponentialBackoffOptionsType,
@ -17,6 +17,8 @@ import {
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import { sleep } from '../util/sleep'; import { sleep } from '../util/sleep';
const log = createLogger('JobManager');
export type JobManagerJobType = { export type JobManagerJobType = {
active: boolean; active: boolean;
attempts: number; attempts: number;

View file

@ -9,7 +9,7 @@ import { Job } from './Job';
import { JobError } from './JobError'; import { JobError } from './JobError';
import type { ParsedJob, StoredJob, JobQueueStore } from './types'; import type { ParsedJob, StoredJob, JobQueueStore } from './types';
import { assertDev } from '../util/assert'; import { assertDev } from '../util/assert';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { JobLogger } from './JobLogger'; import { JobLogger } from './JobLogger';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import type { LoggerType } from '../types/Logging'; import type { LoggerType } from '../types/Logging';
@ -17,6 +17,8 @@ import { drop } from '../util/drop';
import { sleep } from '../util/sleep'; import { sleep } from '../util/sleep';
import { SECOND } from '../util/durations'; import { SECOND } from '../util/durations';
const log = createLogger('JobQueue');
const noopOnCompleteCallbacks = { const noopOnCompleteCallbacks = {
resolve: noop, resolve: noop,
reject: noop, reject: noop,

View file

@ -7,7 +7,9 @@ import { concat, wrapPromise } from '../util/asyncIterables';
import type { JobQueueStore, StoredJob } from './types'; import type { JobQueueStore, StoredJob } from './types';
import { formatJobForInsert } from './formatJobForInsert'; import { formatJobForInsert } from './formatJobForInsert';
import { DataReader, DataWriter } from '../sql/Client'; import { DataReader, DataWriter } from '../sql/Client';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('JobQueueDatabaseStore');
type Database = { type Database = {
getJobsInQueue(queueType: string): Promise<Array<StoredJob>>; getJobsInQueue(queueType: string): Promise<Array<StoredJob>>;
@ -26,18 +28,14 @@ export class JobQueueDatabaseStore implements JobQueueStore {
job: Readonly<StoredJob>, job: Readonly<StoredJob>,
{ shouldPersist = true }: Readonly<{ shouldPersist?: boolean }> = {} { shouldPersist = true }: Readonly<{ shouldPersist?: boolean }> = {}
): Promise<void> { ): Promise<void> {
log.info( log.info(`adding job ${job.id} to queue ${JSON.stringify(job.queueType)}`);
`JobQueueDatabaseStore adding job ${job.id} to queue ${JSON.stringify(
job.queueType
)}`
);
const initialFetchPromise = this.#initialFetchPromises.get(job.queueType); const initialFetchPromise = this.#initialFetchPromises.get(job.queueType);
if (initialFetchPromise) { if (initialFetchPromise) {
await initialFetchPromise; await initialFetchPromise;
} else { } else {
log.warn( log.warn(
`JobQueueDatabaseStore: added job for queue "${job.queueType}" but streaming has not yet started (shouldPersist=${shouldPersist})` `added job for queue "${job.queueType}" but streaming has not yet started (shouldPersist=${shouldPersist})`
); );
} }
@ -80,11 +78,7 @@ export class JobQueueDatabaseStore implements JobQueueStore {
} }
async #fetchJobsAtStart(queueType: string): Promise<Array<StoredJob>> { async #fetchJobsAtStart(queueType: string): Promise<Array<StoredJob>> {
log.info( log.info(`fetching existing jobs for queue ${JSON.stringify(queueType)}`);
`JobQueueDatabaseStore fetching existing jobs for queue ${JSON.stringify(
queueType
)}`
);
// This is initialized to `noop` because TypeScript doesn't know that `Promise` calls // This is initialized to `noop` because TypeScript doesn't know that `Promise` calls
// its callback synchronously, making sure `onFinished` is defined. // its callback synchronously, making sure `onFinished` is defined.
@ -96,7 +90,7 @@ export class JobQueueDatabaseStore implements JobQueueStore {
const result = await this.db.getJobsInQueue(queueType); const result = await this.db.getJobsInQueue(queueType);
log.info( log.info(
`JobQueueDatabaseStore finished fetching existing ${ `finished fetching existing ${
result.length result.length
} jobs for queue ${JSON.stringify(queueType)}` } jobs for queue ${JSON.stringify(queueType)}`
); );

View file

@ -4,7 +4,7 @@
import * as z from 'zod'; import * as z from 'zod';
import PQueue from 'p-queue'; import PQueue from 'p-queue';
import { CallLinkRootKey } from '@signalapp/ringrtc'; import { CallLinkRootKey } from '@signalapp/ringrtc';
import * as globalLogger from '../logging/log'; import { createLogger } from '../logging/log';
import type { LoggerType } from '../types/Logging'; import type { LoggerType } from '../types/Logging';
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff'; import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
import type { ParsedJob, StoredJob } from './types'; import type { ParsedJob, StoredJob } from './types';
@ -22,6 +22,8 @@ import { getRoomIdFromRootKey } from '../util/callLinksRingrtc';
import { toCallHistoryFromUnusedCallLink } from '../util/callLinks'; import { toCallHistoryFromUnusedCallLink } from '../util/callLinks';
import type { StorageServiceFieldsType } from '../sql/Interface'; import type { StorageServiceFieldsType } from '../sql/Interface';
const globalLogger = createLogger('callLinkRefreshJobQueue');
const MAX_RETRY_TIME = DAY; const MAX_RETRY_TIME = DAY;
const MAX_PARALLEL_JOBS = 10; const MAX_PARALLEL_JOBS = 10;
const MAX_ATTEMPTS = exponentialBackoffMaxAttempts(MAX_RETRY_TIME); const MAX_ATTEMPTS = exponentialBackoffMaxAttempts(MAX_RETRY_TIME);

View file

@ -3,7 +3,7 @@
import { z } from 'zod'; import { z } from 'zod';
import type PQueue from 'p-queue'; import type PQueue from 'p-queue';
import * as globalLogger from '../logging/log'; import { createLogger } from '../logging/log';
import * as durations from '../util/durations'; import * as durations from '../util/durations';
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff'; import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
@ -52,6 +52,8 @@ import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
import { FIBONACCI } from '../util/BackOff'; import { FIBONACCI } from '../util/BackOff';
import { parseUnknown } from '../util/schemas'; import { parseUnknown } from '../util/schemas';
const globalLogger = createLogger('conversationJobQueue');
// Note: generally, we only want to add to this list. If you do need to change one of // Note: generally, we only want to add to this list. If you do need to change one of
// these values, you'll likely need to write a database migration. // these values, you'll likely need to write a database migration.
export const conversationQueueJobEnum = z.enum([ export const conversationQueueJobEnum = z.enum([
@ -982,9 +984,7 @@ export class ConversationJobQueue extends JobQueue<ConversationQueueJobData> {
// Note: This should never happen, because the zod call in parseData wouldn't // Note: This should never happen, because the zod call in parseData wouldn't
// accept data that doesn't look like our type specification. // accept data that doesn't look like our type specification.
const problem: never = type; const problem: never = type;
log.error( log.error(`Got job with type ${problem}; Cancelling job.`);
`conversationJobQueue: Got job with type ${problem}; Cancelling job.`
);
} }
} }

View file

@ -3,11 +3,13 @@
import { assertDev } from '../../util/assert'; import { assertDev } from '../../util/assert';
import { isDirectConversation } from '../../util/whatTypeOfConversation'; import { isDirectConversation } from '../../util/whatTypeOfConversation';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import { isAciString } from '../../util/isAciString'; import { isAciString } from '../../util/isAciString';
import type { reportSpamJobQueue } from '../reportSpamJobQueue'; import type { reportSpamJobQueue } from '../reportSpamJobQueue';
import type { ConversationType } from '../../state/ducks/conversations'; import type { ConversationType } from '../../state/ducks/conversations';
const log = createLogger('addReportSpamJob');
export async function addReportSpamJob({ export async function addReportSpamJob({
conversation, conversation,
getMessageServerGuidsForSpam, getMessageServerGuidsForSpam,
@ -29,7 +31,7 @@ export async function addReportSpamJob({
const { serviceId: aci } = conversation; const { serviceId: aci } = conversation;
if (!aci || !isAciString(aci)) { if (!aci || !isAciString(aci)) {
log.info( log.info(
'addReportSpamJob got a conversation with no aci, which the server does not support. Doing nothing' 'got a conversation with no aci, which the server does not support. Doing nothing'
); );
return; return;
} }
@ -39,9 +41,7 @@ export async function addReportSpamJob({
// This can happen under normal conditions. We haven't always stored server GUIDs, so // This can happen under normal conditions. We haven't always stored server GUIDs, so
// a user might try to report spam for a conversation that doesn't have them. (It // a user might try to report spam for a conversation that doesn't have them. (It
// may also indicate developer error, but that's not necessarily the case.) // may also indicate developer error, but that's not necessarily the case.)
log.info( log.info('got no server GUIDs from the database. Doing nothing');
'addReportSpamJob got no server GUIDs from the database. Doing nothing'
);
return; return;
} }

View file

@ -3,7 +3,7 @@
import type { AttachmentBackfillResponseSyncEvent } from '../../textsecure/messageReceiverEvents'; import type { AttachmentBackfillResponseSyncEvent } from '../../textsecure/messageReceiverEvents';
import MessageSender from '../../textsecure/SendMessage'; import MessageSender from '../../textsecure/SendMessage';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import type { ReadonlyMessageAttributesType } from '../../model-types.d'; import type { ReadonlyMessageAttributesType } from '../../model-types.d';
import { import {
type AttachmentType, type AttachmentType,
@ -44,6 +44,8 @@ import * as RemoteConfig from '../../RemoteConfig';
import { isTestOrMockEnvironment } from '../../environment'; import { isTestOrMockEnvironment } from '../../environment';
import { BackfillFailureKind } from '../../components/BackfillFailureModal'; import { BackfillFailureKind } from '../../components/BackfillFailureModal';
const log = createLogger('attachmentBackfill');
const REQUEST_TIMEOUT = isTestOrMockEnvironment() ? 5 * SECOND : 10 * SECOND; const REQUEST_TIMEOUT = isTestOrMockEnvironment() ? 5 * SECOND : 10 * SECOND;
const PLACEHOLDER_ATTACHMENT: AttachmentType = { const PLACEHOLDER_ATTACHMENT: AttachmentType = {

View file

@ -2,9 +2,11 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { isNotNil } from '../../util/isNotNil'; import { isNotNil } from '../../util/isNotNil';
import * as log from '../../logging/log'; import { createLogger } from '../../logging/log';
import type { ServiceIdString } from '../../types/ServiceId'; import type { ServiceIdString } from '../../types/ServiceId';
const log = createLogger('getUntrustedConversationServiceIds');
export function getUntrustedConversationServiceIds( export function getUntrustedConversationServiceIds(
recipients: ReadonlyArray<string> recipients: ReadonlyArray<string>
): Array<ServiceIdString> { ): Array<ServiceIdString> {
@ -22,7 +24,7 @@ export function getUntrustedConversationServiceIds(
const serviceId = recipientConversation.getServiceId(); const serviceId = recipientConversation.getServiceId();
if (!serviceId) { if (!serviceId) {
log.warn( log.warn(
`getUntrustedConversationServiceIds: Conversation ${recipientConversation.idForLogging()} had no serviceId` `Conversation ${recipientConversation.idForLogging()} had no serviceId`
); );
return null; return null;
} }

View file

@ -530,7 +530,7 @@ function getMessageRecipients({
const serviceId = recipient.getServiceId(); const serviceId = recipient.getServiceId();
if (!serviceId) { if (!serviceId) {
log.error( log.error(
`sendNormalMessage/getMessageRecipients: Untrusted conversation ${recipient.idForLogging()} missing serviceId.` `getMessageRecipients: Untrusted conversation ${recipient.idForLogging()} missing serviceId.`
); );
return; return;
} }

View file

@ -426,7 +426,7 @@ function getRecipients(
const serviceId = recipient.getServiceId(); const serviceId = recipient.getServiceId();
if (!serviceId) { if (!serviceId) {
log.error( log.error(
`sendReaction/getRecipients: Untrusted conversation ${recipient.idForLogging()} missing serviceId.` `getRecipients: Untrusted conversation ${recipient.idForLogging()} missing serviceId.`
); );
continue; continue;
} }

View file

@ -59,7 +59,7 @@ export class ReportSpamJobQueue extends JobQueue<ReportSpamJobData> {
}); });
if (!isDeviceLinked()) { if (!isDeviceLinked()) {
log.info("reportSpamJobQueue: skipping this job because we're unlinked"); log.info("skipping this job because we're unlinked");
return undefined; return undefined;
} }
@ -89,15 +89,13 @@ export class ReportSpamJobQueue extends JobQueue<ReportSpamJobData> {
} }
if (code === 508) { if (code === 508) {
log.info( log.info('server responded with 508. Giving up on this job');
'reportSpamJobQueue: server responded with 508. Giving up on this job'
);
return undefined; return undefined;
} }
if (isRetriable4xxStatus(code) || is5xxStatus(code)) { if (isRetriable4xxStatus(code) || is5xxStatus(code)) {
log.info( log.info(
`reportSpamJobQueue: server responded with ${code} status code. Sleeping before our next attempt` `server responded with ${code} status code. Sleeping before our next attempt`
); );
await sleeper.sleep( await sleeper.sleep(
RETRY_WAIT_TIME, RETRY_WAIT_TIME,
@ -108,7 +106,7 @@ export class ReportSpamJobQueue extends JobQueue<ReportSpamJobData> {
if (is4xxStatus(code)) { if (is4xxStatus(code)) {
log.error( log.error(
`reportSpamJobQueue: server responded with ${code} status code. Giving up on this job` `server responded with ${code} status code. Giving up on this job`
); );
return undefined; return undefined;
} }

View file

@ -15,7 +15,9 @@ import {
} from '../types/MIME'; } from '../types/MIME';
import type { LoggerType } from '../types/Logging'; import type { LoggerType } from '../types/Logging';
import { scaleImageToLevel } from '../util/scaleImageToLevel'; import { scaleImageToLevel } from '../util/scaleImageToLevel';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
const log = createLogger('linkPreviewFetch');
const USER_AGENT = 'WhatsApp/2'; const USER_AGENT = 'WhatsApp/2';

View file

@ -3,7 +3,7 @@
import pino from 'pino'; import pino from 'pino';
import type { LoggerType, LoggingFn } from '../types/Logging'; import type { LoggerType } from '../types/Logging';
import { Environment, getEnvironment } from '../environment'; import { Environment, getEnvironment } from '../environment';
import { reallyJsonStringify } from '../util/reallyJsonStringify'; import { reallyJsonStringify } from '../util/reallyJsonStringify';
import { getLogLevelString } from './shared'; import { getLogLevelString } from './shared';
@ -72,15 +72,17 @@ const pinoInstance = pino(
} }
); );
export const fatal: LoggingFn = pinoInstance.fatal.bind(pinoInstance); export const log: LoggerType = {
export const error: LoggingFn = pinoInstance.error.bind(pinoInstance); fatal: pinoInstance.fatal.bind(pinoInstance),
export const warn: LoggingFn = pinoInstance.error.bind(pinoInstance); error: pinoInstance.error.bind(pinoInstance),
export const info: LoggingFn = pinoInstance.info.bind(pinoInstance); warn: pinoInstance.error.bind(pinoInstance),
export const debug: LoggingFn = pinoInstance.debug.bind(pinoInstance); info: pinoInstance.info.bind(pinoInstance),
export const trace: LoggingFn = pinoInstance.trace.bind(pinoInstance); debug: pinoInstance.debug.bind(pinoInstance),
export const child = createChild.bind(pinoInstance); trace: pinoInstance.trace.bind(pinoInstance),
child: createLogger.bind(pinoInstance),
};
function createChild(name: string): LoggerType { export function createLogger(name: string): LoggerType {
const instance = pinoInstance.child({}, { msgPrefix: `[${name}] ` }); const instance = pinoInstance.child({}, { msgPrefix: `[${name}] ` });
return { return {
@ -90,7 +92,7 @@ function createChild(name: string): LoggerType {
info: instance.info.bind(instance), info: instance.info.bind(instance),
debug: instance.debug.bind(instance), debug: instance.debug.bind(instance),
trace: instance.trace.bind(instance), trace: instance.trace.bind(instance),
child: createChild.bind(instance), child: createLogger.bind(instance),
}; };
} }

View file

@ -27,7 +27,7 @@ import * as Errors from '../types/errors';
import { createRotatingPinoDest } from '../util/rotatingPinoDest'; import { createRotatingPinoDest } from '../util/rotatingPinoDest';
import { redactAll } from '../util/privacy'; import { redactAll } from '../util/privacy';
import * as log from './log'; import { setPinoDestination, log } from './log';
import type { FetchLogIpcData, LogEntryType } from './shared'; import type { FetchLogIpcData, LogEntryType } from './shared';
import { LogLevel, isLogEntry } from './shared'; import { LogLevel, isLogEntry } from './shared';
@ -82,7 +82,7 @@ export async function initialize(
rotatingStream.on('close', onClose); rotatingStream.on('close', onClose);
rotatingStream.on('error', onClose); rotatingStream.on('error', onClose);
log.setPinoDestination(rotatingStream, redactAll); setPinoDestination(rotatingStream, redactAll);
ipc.removeHandler('fetch-log'); ipc.removeHandler('fetch-log');
ipc.handle('fetch-log', async () => { ipc.handle('fetch-log', async () => {

View file

@ -11,7 +11,7 @@ import {
LogLevel as SignalClientLogLevel, LogLevel as SignalClientLogLevel,
} from '@signalapp/libsignal-client'; } from '@signalapp/libsignal-client';
import * as log from './log'; import { setPinoDestination, log } from './log';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
import { createRotatingPinoDest } from '../util/rotatingPinoDest'; import { createRotatingPinoDest } from '../util/rotatingPinoDest';
import { redactAll } from '../util/privacy'; import { redactAll } from '../util/privacy';
@ -45,7 +45,7 @@ export function initialize(): void {
stream.on('close', onClose); stream.on('close', onClose);
stream.on('error', onClose); stream.on('error', onClose);
log.setPinoDestination(stream, redactAll); setPinoDestination(stream, redactAll);
} }
function toLocation(source?: string, line?: number, column?: number) { function toLocation(source?: string, line?: number, column?: number) {
@ -75,6 +75,8 @@ window.addEventListener('unhandledrejection', rejectionEvent => {
log.error(`Top-level unhandled promise rejection: ${errorString}`); log.error(`Top-level unhandled promise rejection: ${errorString}`);
}); });
const libSignalLog = log.child('@signalapp/libsignal-client');
initLogger( initLogger(
SignalClientLogLevel.Info, SignalClientLogLevel.Info,
( (
@ -90,20 +92,20 @@ initLogger(
} else if (file) { } else if (file) {
fileString = ` ${file}`; fileString = ` ${file}`;
} }
const logString = `@signalapp/libsignal-client ${message} ${target}${fileString}`; const logString = `${message} ${target}${fileString}`;
if (level === SignalClientLogLevel.Trace) { if (level === SignalClientLogLevel.Trace) {
log.trace(logString); libSignalLog.trace(logString);
} else if (level === SignalClientLogLevel.Debug) { } else if (level === SignalClientLogLevel.Debug) {
log.debug(logString); libSignalLog.debug(logString);
} else if (level === SignalClientLogLevel.Info) { } else if (level === SignalClientLogLevel.Info) {
log.info(logString); libSignalLog.info(logString);
} else if (level === SignalClientLogLevel.Warn) { } else if (level === SignalClientLogLevel.Warn) {
log.warn(logString); libSignalLog.warn(logString);
} else if (level === SignalClientLogLevel.Error) { } else if (level === SignalClientLogLevel.Error) {
log.error(logString); libSignalLog.error(logString);
} else { } else {
log.error(`${logString} (unknown log level ${level})`); libSignalLog.error(`${logString} (unknown log level ${level})`);
} }
} }
); );

View file

@ -4,9 +4,11 @@
import type { IpcMainEvent } from 'electron'; import type { IpcMainEvent } from 'electron';
import { ipcMain as ipc } from 'electron'; import { ipcMain as ipc } from 'electron';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import type { IPCRequest, IPCResponse, ChallengeResponse } from '../challenge'; import type { IPCRequest, IPCResponse, ChallengeResponse } from '../challenge';
const log = createLogger('challengeMain');
export class ChallengeMainHandler { export class ChallengeMainHandler {
#handlers: Array<(response: ChallengeResponse) => void> = []; #handlers: Array<(response: ChallengeResponse) => void> = [];
@ -21,7 +23,7 @@ export class ChallengeMainHandler {
this.#handlers = []; this.#handlers = [];
log.info( log.info(
'challengeMain.handleCaptcha: sending captcha response to ' + 'handleCaptcha: sending captcha response to ' +
`${handlers.length} handlers` `${handlers.length} handlers`
); );
for (const resolve of handlers) { for (const resolve of handlers) {

View file

@ -5,7 +5,7 @@ import type { BrowserWindow } from 'electron';
import { ipcMain as ipc, session } from 'electron'; import { ipcMain as ipc, session } from 'electron';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import { userConfig } from '../../app/user_config'; import { userConfig } from '../../app/user_config';
import { ephemeralConfig } from '../../app/ephemeral_config'; import { ephemeralConfig } from '../../app/ephemeral_config';
import { installPermissionsHandler } from '../../app/permissions'; import { installPermissionsHandler } from '../../app/permissions';
@ -13,6 +13,8 @@ import { strictAssert } from '../util/assert';
import type { EphemeralSettings } from '../util/preload'; import type { EphemeralSettings } from '../util/preload';
const log = createLogger('settingsChannel');
const EPHEMERAL_NAME_MAP = new Map([ const EPHEMERAL_NAME_MAP = new Map([
['spellCheck', 'spell-check'], ['spellCheck', 'spell-check'],
['systemTraySetting', 'system-tray-setting'], ['systemTraySetting', 'system-tray-setting'],

View file

@ -4,7 +4,7 @@
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { fabric } from 'fabric'; import { fabric } from 'fabric';
import * as log from '../logging/log'; import { createLogger } from '../logging/log';
import type { ImageStateType } from './ImageStateType'; import type { ImageStateType } from './ImageStateType';
import { MediaEditorFabricAnalogTimeSticker } from './MediaEditorFabricAnalogTimeSticker'; import { MediaEditorFabricAnalogTimeSticker } from './MediaEditorFabricAnalogTimeSticker';
@ -15,6 +15,8 @@ import { MediaEditorFabricSticker } from './MediaEditorFabricSticker';
import { fabricEffectListener } from './fabricEffectListener'; import { fabricEffectListener } from './fabricEffectListener';
import { strictAssert } from '../util/assert'; import { strictAssert } from '../util/assert';
const log = createLogger('useFabricHistory');
type SnapshotStateType = { type SnapshotStateType = {
canvasState: string; canvasState: string;
imageState: ImageStateType; imageState: ImageStateType;

Some files were not shown because too many files have changed in this diff Show more