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,
} 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 { drop } from '../ts/util/drop';
import { parseUnknown } from '../ts/util/schemas';
const log = createLogger('OptionalResourceService');
const RESOURCES_DICT_PATH = join(
__dirname,
'..',
@ -75,12 +77,12 @@ export class OptionalResourceService {
timingSafeEqual(digest, Buffer.from(decl.digest, 'base64')) &&
onDisk.length === decl.size
) {
log.warn(`OptionalResourceService: loaded ${name} from disk`);
log.warn(`loaded ${name} from disk`);
this.#cache.set(name, onDisk);
return onDisk;
}
log.warn(`OptionalResourceService: ${name} is no longer valid on disk`);
log.warn(`${name} is no longer valid on disk`);
} catch (error) {
if (error.code !== 'ENOENT') {
throw error;
@ -135,10 +137,7 @@ export class OptionalResourceService {
try {
await unlink(fullPath);
} catch (error) {
log.error(
`OptionalResourceService: failed to cleanup ${subPath}`,
error
);
log.error(`failed to cleanup ${subPath}`, error);
}
})
);
@ -182,7 +181,7 @@ export class OptionalResourceService {
await mkdir(dirname(destPath), { recursive: true });
await writeFile(destPath, result);
} 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
}

View file

@ -2,7 +2,9 @@
// SPDX-License-Identifier: AGPL-3.0-only
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 {
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 { join } from 'node:path';
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';
const log = createLogger('SystemTrayService');
export type SystemTrayServiceOptionsType = Readonly<{
i18n: LocalizerType;

View file

@ -1,7 +1,7 @@
// Copyright 2017 Signal Messenger, LLC
// 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 {
parseSystemTraySetting,
@ -10,6 +10,8 @@ import {
import { isSystemTraySupported } from '../ts/types/Settings';
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
* process.

View file

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

View file

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

View file

@ -20,7 +20,9 @@ import {
} from '../ts/AttachmentCrypto';
import type { LocalAttachmentV2Type } from '../ts/types/Attachment';
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 AVATAR_PATH = 'avatars.noindex';

View file

@ -7,7 +7,9 @@ import { sync as writeFileSync } from 'write-file-atomic';
import { get } from 'lodash';
import { set } from 'lodash/fp';
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';

View file

@ -12,7 +12,9 @@ import {
setEnvironment,
parseEnvironment,
} 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
if (app.isPackaged) {
@ -52,7 +54,7 @@ const config: IConfig = require('config');
if (getEnvironment() !== Environment.PackagedApp) {
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 type { DNSFallbackType } from '../ts/types/DNSFallback';
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;

View file

@ -6,10 +6,12 @@ import os from 'node:os';
import * as Errors from '../ts/types/errors';
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 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.
let quitText = '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 * as Errors from '../ts/types/errors';
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 uploadDebugLog from '../ts/logging/uploadDebugLog';
import { explodePromise } from '../ts/util/explodePromise';
@ -125,6 +125,8 @@ import { getOwn } from '../ts/util/getOwn';
import { safeParseLoose, safeParseUnknown } from '../ts/util/schemas';
import { getAppErrorIcon } from '../ts/util/getAppErrorIcon';
const log = createLogger('app/main');
const animationSettings = systemPreferences.getAnimationSettings();
if (OS.isMacOS()) {

View file

@ -7,7 +7,9 @@
import type { session as ElectronSession, Session } from 'electron';
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> = {
// Allowed

View file

@ -15,7 +15,9 @@ import {
getTempPath,
getUpdateCachePath,
} 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;

View file

@ -11,9 +11,11 @@ import type { MenuListType } from '../ts/types/menu';
import type { LocalizerType } from '../ts/types/Util';
import { strictAssert } from '../ts/util/assert';
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';
const log = createLogger('spell_check');
export const FAKE_DEFAULT_LOCALE = 'und'; // 'und' is the BCP 47 subtag for "undetermined"
strictAssert(

View file

@ -4,9 +4,11 @@
import { app } from 'electron';
import packageJson from '../package.json';
import * as log from '../ts/logging/log';
import { createLogger } from '../ts/logging/log';
import * as GlobalErrors from './global_errors';
const log = createLogger('startup_config');
GlobalErrors.addHandler();
// 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 config from './config';
import * as log from '../ts/logging/log';
import { createLogger } from '../ts/logging/log';
import * as Errors from '../ts/types/errors';
const log = createLogger('user_config');
let userData: string | undefined;
// Use separate data directory for benchmarks & development
if (config.has('storagePath')) {

View file

@ -21,7 +21,7 @@ import {
import type { ChunkSizeChoice } from '@signalapp/libsignal-client/dist/incremental_mac';
import { isAbsolute } from 'path';
import * as log from './logging/log';
import { createLogger } from './logging/log';
import {
HashType,
CipherType,
@ -45,6 +45,8 @@ import { missingCaseError } from './util/missingCaseError';
import { getEnvironment, Environment } from './environment';
import { toBase64 } from './Bytes';
const log = createLogger('AttachmentCrypto');
// 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.

View file

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

View file

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

View file

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

View file

@ -11,7 +11,9 @@ import type {
CompatPreKeyType,
CompatSignedPreKeyType,
} 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 {
return typeof n === 'number' && n % 1 === 0 && n >= 0;

View file

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

View file

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

View file

@ -54,7 +54,7 @@ import { isServiceIdString, ServiceIdKind } from './types/ServiceId';
import type { Address } from './types/Address';
import type { QualifiedAddressStringType } 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 { MINUTE } from './util/durations';
import { conversationJobQueue } from './jobs/conversationJobQueue';
@ -65,6 +65,8 @@ import {
import { formatGroups, groupWhile } from './util/groupWhile';
import { parseUnknown } from './util/schemas';
const log = createLogger('SignalProtocolStore');
const TIMESTAMP_THRESHOLD = 5 * 1000; // 5 seconds
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
object[field] = cache as any;
}
@ -1203,7 +1205,7 @@ export class SignalProtocolStore extends EventEmitter {
this.#currentZone = 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) {
log.info(`SignalProtocolStore.leaveZone(${zone.name})`);
log.info(`leaveZone(${zone.name})`);
}
this.#currentZone = undefined;
@ -1245,8 +1247,7 @@ export class SignalProtocolStore extends EventEmitter {
}
log.info(
`SignalProtocolStore: running blocked ${toEnter.length} jobs in ` +
`zone ${next.zone.name}`
`running blocked ${toEnter.length} jobs in zone ${next.zone.name}`
);
for (const { callback } of toEnter) {
callback();
@ -1781,8 +1782,7 @@ export class SignalProtocolStore extends EventEmitter {
};
log.info(
`SignalProtocolStore: migrating identity key from ${record.fromDB.id} ` +
`to ${newRecord.id}`
`migrating identity key from ${record.fromDB.id} to ${newRecord.id}`
);
await this.#_saveIdentityKey(newRecord);
@ -2428,7 +2428,7 @@ export class SignalProtocolStore extends EventEmitter {
async removeOurOldPni(oldPni: PniString): Promise<void> {
const { storage } = window;
log.info(`SignalProtocolStore.removeOurOldPni(${oldPni})`);
log.info(`removeOurOldPni(${oldPni})`);
// Update caches
this.#ourIdentityKeys.delete(oldPni);

View file

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

View file

@ -148,7 +148,7 @@ import {
} from './types/ServiceId';
import { isAciString } from './util/isAciString';
import { normalizeAci } from './util/normalizeAci';
import * as log from './logging/log';
import { createLogger } from './logging/log';
import { deleteAllLogs } from './util/deleteAllLogs';
import { startInteractionMode } from './services/InteractionMode';
import { ReactionSource } from './reactions/ReactionSource';
@ -220,6 +220,8 @@ import { NavTab } from './state/ducks/nav';
import { Page } from './components/Preferences';
import { EditState } from './components/ProfileEditor';
const log = createLogger('background');
export function isOverHourIntoPast(timestamp: number): boolean {
return isNumber(timestamp) && isOlderThan(timestamp, HOUR);
}
@ -371,7 +373,7 @@ export async function startApp(): Promise<void> {
const { Message } = window.Signal.Types;
log.info('background page reloaded');
log.info('page reloaded');
log.info('environment:', getEnvironment());
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
window.Events = createIPCEvents({
shutdown: async () => {
log.info('background/shutdown');
log.info('shutdown');
flushMessageCounter();
@ -780,12 +782,12 @@ export async function startApp(): Promise<void> {
server !== undefined,
'WebAPI should be initialized together with MessageReceiver'
);
log.info('background/shutdown: shutting down messageReceiver');
log.info('shutdown: shutting down messageReceiver');
pauseProcessing('shutdown');
await window.waitForAllBatchers();
}
log.info('background/shutdown: flushing conversations');
log.info('shutdown: flushing conversations');
// Flush debounced updates for conversations
await Promise.all(
@ -797,27 +799,27 @@ export async function startApp(): Promise<void> {
sleeper.shutdown();
const shutdownQueues = async () => {
log.info('background/shutdown: shutting down queues');
log.info('shutdown: shutting down queues');
await Promise.allSettled([
StartupQueue.shutdown(),
shutdownAllJobQueues(),
]);
log.info('background/shutdown: shutting down conversation queues');
log.info('shutdown: shutting down conversation queues');
await Promise.allSettled(
window.ConversationController.getAll().map(async convo => {
try {
await convo.shutdownJobQueue();
} catch (err) {
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)
);
}
})
);
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
@ -827,7 +829,7 @@ export async function startApp(): Promise<void> {
new Promise<void>((resolve, _) => {
timeout = setTimeout(() => {
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;
resolve();
@ -838,7 +840,7 @@ export async function startApp(): Promise<void> {
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.
// 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(
'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
// resolve quickly
await attachmentDownloadStopPromise;
await attachmentBackupStopPromise;
log.info('background/shutdown: closing the database');
log.info('shutdown: closing the database');
// Shut down the data interface cleanly
await DataWriter.shutdown();
@ -1095,7 +1097,7 @@ export async function startApp(): Promise<void> {
);
} catch (error) {
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)
);
}
@ -1104,7 +1106,7 @@ export async function startApp(): Promise<void> {
await DataWriter.deleteSentProtosOlderThan(now - sentProtoMaxAge);
} catch (error) {
log.error(
'background/onready/setInterval: Error deleting sent protos: ',
'onready/setInterval: Error deleting sent protos: ',
Errors.toLogFormat(error)
);
}
@ -1135,7 +1137,7 @@ export async function startApp(): Promise<void> {
});
} catch (error) {
log.error(
'background/onready/setInterval: Error getting expired retry placeholders: ',
'onready/setInterval: Error getting expired retry placeholders: ',
Errors.toLogFormat(error)
);
}
@ -1162,7 +1164,7 @@ export async function startApp(): Promise<void> {
await window.ConversationController.checkForConflicts();
} catch (error) {
log.error(
'background.js: ConversationController failed to load:',
'js: ConversationController failed to load:',
Errors.toLogFormat(error)
);
} finally {
@ -1344,7 +1346,7 @@ export async function startApp(): Promise<void> {
});
if (reconnect) {
log.info('background: reconnecting websocket on user change');
log.info('reconnecting websocket on user change');
enqueueReconnectToWebSocket();
}
});
@ -1434,7 +1436,7 @@ export async function startApp(): Promise<void> {
return;
}
log.error('background: remote expiration detected, disabling reconnects');
log.error('remote expiration detected, disabling reconnects');
drop(window.storage.put('remoteBuildExpiration', Date.now()));
drop(server?.onExpiration('remote'));
remotelyExpired = true;
@ -1646,7 +1648,7 @@ export async function startApp(): Promise<void> {
strictAssert(server, 'server must be initialized');
const onOnline = () => {
log.info('background: online');
log.info('online');
drop(afterAuthSocketConnect());
};
@ -1658,7 +1660,7 @@ export async function startApp(): Promise<void> {
const hasAppEverBeenRegistered = Registration.everDone();
log.info('background: offline', {
log.info('offline', {
authSocketConnectCount,
hasInitialLoadCompleted,
appView,
@ -1679,19 +1681,17 @@ export async function startApp(): Promise<void> {
if (state.app.appView === AppViewType.Installer) {
if (state.installer.step === InstallScreenStep.LinkInProgress) {
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();
} 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
}
}
if (!hasInitialLoadCompleted) {
log.info(
'background: offline; initial load not completed; triggering onEmpty'
);
log.info('offline; initial load not completed; triggering onEmpty');
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() {
log.info('background: navigator offline');
log.info('navigator offline');
drop(server?.onNavigatorOffline());
}
function onNavigatorOnline() {
log.info('background: navigator online');
log.info('navigator online');
drop(server?.onNavigatorOnline());
}
@ -3247,7 +3247,7 @@ export async function startApp(): Promise<void> {
function onError(ev: ErrorEvent): void {
const { error } = ev;
log.error('background onError:', Errors.toLogFormat(error));
log.error('onError:', Errors.toLogFormat(error));
if (
error instanceof HTTPError &&
@ -3257,7 +3257,7 @@ export async function startApp(): Promise<void> {
return;
}
log.warn('background onError: Doing nothing with incoming error');
log.warn('onError: Doing nothing with incoming error');
}
function onViewOnceOpenSync(ev: ViewOnceOpenSyncEvent): void {

View file

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

View file

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

View file

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

View file

@ -19,11 +19,13 @@ import { missingCaseError } from './util/missingCaseError';
import type { StorageInterface } from './types/Storage.d';
import * as Errors from './types/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 { findRetryAfterTimeFromError } from './jobs/helpers/findRetryAfterTimeFromError';
import { MINUTE } from './util/durations';
const log = createLogger('challenge');
export type ChallengeResponse = Readonly<{
captcha: string;
}>;
@ -150,14 +152,14 @@ export class ChallengeHandler {
const challenges: ReadonlyArray<RegisteredChallengeType> =
this.options.storage.get(STORAGE_KEY) || [];
log.info(`challenge: loading ${challenges.length} challenges`);
log.info(`loading ${challenges.length} challenges`);
await Promise.all(
challenges.map(async challenge => {
const expireAfter = this.options.expireAfter || DEFAULT_EXPIRE_AFTER;
if (isOlderThan(challenge.createdAt, expireAfter)) {
log.info(
`challenge: expired challenge for conversation ${challenge.conversationId}`
`expired challenge for conversation ${challenge.conversationId}`
);
return;
}
@ -177,7 +179,7 @@ export class ChallengeHandler {
public async onOffline(): Promise<void> {
this.#isOnline = false;
log.info('challenge: offline');
log.info('offline');
}
public async onOnline(): Promise<void> {
@ -186,7 +188,7 @@ export class ChallengeHandler {
const pending = Array.from(this.#pendingStarts.values());
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
await this.#startAllQueues();
@ -321,9 +323,7 @@ export class ChallengeHandler {
conversationId: string,
source: string
): Promise<void> {
log.info(
`challenge: unregistered conversation ${conversationId} via ${source}`
);
log.info(`unregistered conversation ${conversationId} via ${source}`);
this.#registeredConversations.delete(conversationId);
this.#pendingStarts.delete(conversationId);
@ -374,7 +374,7 @@ export class ChallengeHandler {
}: {
force?: boolean;
} = {}): void {
log.info(`challenge: startAllQueues force=${force}`);
log.info(`startAllQueues force=${force}`);
Array.from(this.#registeredConversations.values())
.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 { BadgeType } from '../badges/types';
import type { LocalizerType } from '../types/Util';
import * as log from '../logging/log';
import { createLogger } from '../logging/log';
import { BadgeImageTheme } from '../badges/BadgeImageTheme';
import { HasStories } from '../types/Stories';
import { Spinner } from './Spinner';
@ -28,6 +28,8 @@ import { isBadgeVisible } from '../badges/isBadgeVisible';
import { SIGNAL_AVATAR_PATH } from '../types/SignalConversation';
import { getAvatarPlaceholderGradient } from '../utils/getAvatarPlaceholderGradient';
const log = createLogger('Avatar');
export enum AvatarBlur {
NoBlur,
BlurPicture,
@ -134,7 +136,7 @@ export function Avatar({
const image = new Image();
image.src = avatarUrl;
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);
};

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -7,7 +7,9 @@ import type {
LocalizerType,
ICUJSXMessageParamsByKeyType,
} 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> = {
/** The translation string id */

View file

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

View file

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

View file

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

View file

@ -15,7 +15,7 @@ import { assertDev } from '../util/assert';
import { getClassNamesFor } from '../util/getClassNamesFor';
import { useAnimated } from '../hooks/useAnimated';
import { useHasWrapped } from '../hooks/useHasWrapped';
import * as log from '../logging/log';
import { createLogger } from '../logging/log';
import {
isScrollOverflowVertical,
isScrollAtTop,
@ -23,6 +23,8 @@ import {
useScrollObserver,
} from '../hooks/useSizeObserver';
const log = createLogger('Modal');
type PropsType = {
children: ReactNode;
modalName: string;
@ -98,7 +100,7 @@ export function Modal({
}
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}`);
}, 0);
return () => {

View file

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

View file

@ -3,7 +3,9 @@
import type { ProfilerOnRenderCallback, ReactNode } 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<{
id: string;
@ -19,7 +21,7 @@ const onRender: ProfilerOnRenderCallback = (
commit
) => {
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 ` +
`commit=${commit.toFixed(1)}ms`
);

View file

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

View file

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

View file

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

View file

@ -25,7 +25,7 @@ import {
} from '../../util/callingNotification';
import { missingCaseError } from '../../util/missingCaseError';
import { Tooltip, TooltipPlacement } from '../Tooltip';
import * as log from '../../logging/log';
import { createLogger } from '../../logging/log';
import {
type ContextMenuTriggerType,
MessageContextMenu,
@ -41,6 +41,8 @@ import { isMoreRecentThan } from '../../util/timestamp';
import { InAnotherCallTooltip } from './InAnotherCallTooltip';
import type { InteractionModeType } from '../../state/ducks/conversations';
const log = createLogger('CallingNotification');
export type PropsActionsType = {
onOutgoingAudioCallInConversation: (conversationId: string) => void;
onOutgoingVideoCallInConversation: (conversationId: string) => void;
@ -239,7 +241,7 @@ function renderCallingNotificationButton(
break;
}
case CallMode.Adhoc:
log.warn('CallingNotification for adhoc call, should never happen');
log.warn('for adhoc call, should never happen');
return null;
default:
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 { ViewUserStoriesActionCreatorType } from '../../state/ducks/stories';
import { StoryViewModeType } from '../../types/Stories';
import * as log from '../../logging/log';
import { createLogger } from '../../logging/log';
import { Avatar, AvatarBlur, AvatarSize } from '../Avatar';
import { AvatarLightbox } from '../AvatarLightbox';
import { BadgeDialog } from '../BadgeDialog';
@ -32,6 +32,8 @@ import {
getTooltipContent,
} from './InAnotherCallTooltip';
const log = createLogger('ContactModal');
export type PropsDataType = {
areWeASubscriber: boolean;
areWeAdmin: boolean;
@ -216,7 +218,7 @@ export function ContactModal({
break;
case SubModalState.ToggleAdmin:
if (!conversation?.id) {
log.warn('ContactModal: ToggleAdmin state - missing conversationId');
log.warn('ToggleAdmin state - missing conversationId');
modalNode = undefined;
break;
}
@ -247,9 +249,7 @@ export function ContactModal({
break;
case SubModalState.MemberRemove:
if (!contact || !conversation?.id) {
log.warn(
'ContactModal: MemberRemove state - missing contact or conversationId'
);
log.warn('MemberRemove state - missing contact or conversationId');
modalNode = undefined;
break;
}
@ -291,7 +291,7 @@ export function ContactModal({
break;
default: {
const state: never = subModalState;
log.warn(`ContactModal: unexpected ${state}!`);
log.warn(`unexpected ${state}!`);
modalNode = undefined;
break;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -51,7 +51,7 @@ import { toLogFormat } from '../../types/errors';
import { shouldUseFullSizeLinkPreviewImage } from '../../linkPreviews/shouldUseFullSizeLinkPreviewImage';
import type { WidthBreakpoint } from '../_util';
import { OutgoingGiftBadgeModal } from '../OutgoingGiftBadgeModal';
import * as log from '../../logging/log';
import { createLogger } from '../../logging/log';
import { StoryViewModeType } from '../../types/Stories';
import type {
AttachmentForUIType,
@ -123,6 +123,8 @@ import {
} from '../fun/data/emojis';
import { useGroupedAndOrderedReactions } from '../../util/groupAndOrderReactions';
const log = createLogger('Message');
const GUESS_METADATA_WIDTH_TIMESTAMP_SIZE = 16;
const GUESS_METADATA_WIDTH_EXPIRE_TIMER_SIZE = 18;
const GUESS_METADATA_WIDTH_SMS_SIZE = 18;
@ -718,9 +720,7 @@ export class Message extends React.PureComponent<Props, State> {
public handleImageError = (): void => {
const { id } = this.props;
log.info(
`Message ${id}: Image failed to load; failing over to placeholder`
);
log.info(`${id}: Image failed to load; failing over to placeholder`);
this.setState({
imageBroken: true,
});
@ -813,7 +813,7 @@ export class Message extends React.PureComponent<Props, State> {
delta,
});
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 { MessageMetadata } from './MessageMetadata';
import * as log from '../../logging/log';
import { createLogger } from '../../logging/log';
import type { ActiveAudioPlayerStateType } from '../../state/ducks/audioPlayer';
import { PlaybackRateButton } from '../PlaybackRateButton';
import { PlaybackButton } from '../PlaybackButton';
@ -26,6 +26,8 @@ import { shouldNeverBeCalled } from '../../util/shouldNeverBeCalled';
import { formatFileSize } from '../../util/formatFileSize';
import { roundFractionForProgressBar } from '../../util/numbers';
const log = createLogger('MessageAudio');
export type OwnProps = Readonly<{
active:
| Pick<

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,10 +2,12 @@
// SPDX-License-Identifier: AGPL-3.0-only
import type { ReactNode, ErrorInfo } 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 { ToastType } from '../../../types/Toast';
const log = createLogger('FunErrorBoundary');
type ErrorBoundaryProps = Readonly<{
onError: (error: unknown, info: ErrorInfo) => void;
fallback: (error: unknown) => ReactNode;

View file

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

View file

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

View file

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

View file

@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
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.
export enum Environment {

View file

@ -12,7 +12,9 @@ import { missingCaseError } from './util/missingCaseError';
import type { GroupV2ChangeDetailType, GroupV2ChangeType } from './groups';
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
? ICUStringMessageParamsByKeyType

View file

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

View file

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

View file

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

View file

@ -2,7 +2,9 @@
// SPDX-License-Identifier: AGPL-3.0-only
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`.

View file

@ -2,7 +2,9 @@
// SPDX-License-Identifier: AGPL-3.0-only
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<{
isLocked(): boolean;

View file

@ -1,7 +1,9 @@
// Copyright 2018 Signal Messenger, LLC
// 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';

View file

@ -6,7 +6,7 @@ import { existsSync } from 'node:fs';
import { PassThrough } from 'node:stream';
import * as durations from '../util/durations';
import * as log from '../logging/log';
import { createLogger } from '../logging/log';
import { DataWriter } from '../sql/Client';
import * as Errors from '../types/errors';
@ -65,6 +65,8 @@ import { BackupCredentialType } from '../types/backups';
import { supportsIncrementalMac } from '../types/MIME';
import type { MIMEType } from '../types/MIME';
const log = createLogger('AttachmentBackupManager');
const MAX_CONCURRENT_JOBS = 3;
const RETRY_CONFIG = {
// 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> {
log.info('AttachmentBackupManager/starting');
log.info('starting');
await AttachmentBackupManager.instance.start();
}
static async stop(): Promise<void> {
log.info('AttachmentBackupManager/stopping');
log.info('stopping');
return AttachmentBackupManager._instance?.stop();
}

View file

@ -4,7 +4,7 @@ import { noop, omit, throttle } from 'lodash';
import { statfs } from 'node:fs/promises';
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 AttachmentDownloadJobTypeType,
@ -66,6 +66,8 @@ import {
import { formatCountForLogging } from '../logging/formatCountForLogging';
import { strictAssert } from '../util/assert';
const log = createLogger('AttachmentDownloadManager');
export { isPermanentlyUndownloadable };
// Type for adding a new job
@ -340,7 +342,7 @@ export class AttachmentDownloadManager extends JobManager<CoreAttachmentDownload
window.storage.get('backupMediaDownloadCompletedBytes', 0);
log.info(
'AttachmentDownloadManager.checkFreeDiskSpaceForBackupImport: insufficient disk space. ' +
'checkFreeDiskSpaceForBackupImport: insufficient disk space. ' +
`Available: ${formatCountForLogging(freeDiskSpace)}, ` +
`Needed: ${formatCountForLogging(remainingBackupBytesToDownload)} ` +
`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 * as durations from '../util/durations';
import * as log from '../logging/log';
import { createLogger } from '../logging/log';
import * as Errors from '../types/errors';
import { redactGenericText } from '../util/privacy';
@ -30,6 +30,8 @@ import {
getLocalBackupPathForMediaName,
} from '../services/backups/util/localBackup';
const log = createLogger('AttachmentLocalBackupManager');
const MAX_CONCURRENT_JOBS = 3;
const RETRY_CONFIG = {
maxAttempts: 3,
@ -81,12 +83,12 @@ export class AttachmentLocalBackupManager extends JobManager<CoreAttachmentLocal
}
static async start(): Promise<void> {
log.info('AttachmentLocalBackupManager/starting');
log.info('starting');
await AttachmentLocalBackupManager.instance.start();
}
static async stop(): Promise<void> {
log.info('AttachmentLocalBackupManager/stopping');
log.info('stopping');
return AttachmentLocalBackupManager.#instance?.stop();
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -3,7 +3,7 @@
import { z } from 'zod';
import type PQueue from 'p-queue';
import * as globalLogger from '../logging/log';
import { createLogger } from '../logging/log';
import * as durations from '../util/durations';
import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff';
@ -52,6 +52,8 @@ import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
import { FIBONACCI } from '../util/BackOff';
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
// these values, you'll likely need to write a database migration.
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
// accept data that doesn't look like our type specification.
const problem: never = type;
log.error(
`conversationJobQueue: Got job with type ${problem}; Cancelling job.`
);
log.error(`Got job with type ${problem}; Cancelling job.`);
}
}

View file

@ -3,11 +3,13 @@
import { assertDev } from '../../util/assert';
import { isDirectConversation } from '../../util/whatTypeOfConversation';
import * as log from '../../logging/log';
import { createLogger } from '../../logging/log';
import { isAciString } from '../../util/isAciString';
import type { reportSpamJobQueue } from '../reportSpamJobQueue';
import type { ConversationType } from '../../state/ducks/conversations';
const log = createLogger('addReportSpamJob');
export async function addReportSpamJob({
conversation,
getMessageServerGuidsForSpam,
@ -29,7 +31,7 @@ export async function addReportSpamJob({
const { serviceId: aci } = conversation;
if (!aci || !isAciString(aci)) {
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;
}
@ -39,9 +41,7 @@ export async function addReportSpamJob({
// 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
// may also indicate developer error, but that's not necessarily the case.)
log.info(
'addReportSpamJob got no server GUIDs from the database. Doing nothing'
);
log.info('got no server GUIDs from the database. Doing nothing');
return;
}

View file

@ -3,7 +3,7 @@
import type { AttachmentBackfillResponseSyncEvent } from '../../textsecure/messageReceiverEvents';
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 AttachmentType,
@ -44,6 +44,8 @@ import * as RemoteConfig from '../../RemoteConfig';
import { isTestOrMockEnvironment } from '../../environment';
import { BackfillFailureKind } from '../../components/BackfillFailureModal';
const log = createLogger('attachmentBackfill');
const REQUEST_TIMEOUT = isTestOrMockEnvironment() ? 5 * SECOND : 10 * SECOND;
const PLACEHOLDER_ATTACHMENT: AttachmentType = {

View file

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

View file

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

View file

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

View file

@ -59,7 +59,7 @@ export class ReportSpamJobQueue extends JobQueue<ReportSpamJobData> {
});
if (!isDeviceLinked()) {
log.info("reportSpamJobQueue: skipping this job because we're unlinked");
log.info("skipping this job because we're unlinked");
return undefined;
}
@ -89,15 +89,13 @@ export class ReportSpamJobQueue extends JobQueue<ReportSpamJobData> {
}
if (code === 508) {
log.info(
'reportSpamJobQueue: server responded with 508. Giving up on this job'
);
log.info('server responded with 508. Giving up on this job');
return undefined;
}
if (isRetriable4xxStatus(code) || is5xxStatus(code)) {
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(
RETRY_WAIT_TIME,
@ -108,7 +106,7 @@ export class ReportSpamJobQueue extends JobQueue<ReportSpamJobData> {
if (is4xxStatus(code)) {
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;
}

View file

@ -15,7 +15,9 @@ import {
} from '../types/MIME';
import type { LoggerType } from '../types/Logging';
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';

View file

@ -3,7 +3,7 @@
import pino from 'pino';
import type { LoggerType, LoggingFn } from '../types/Logging';
import type { LoggerType } from '../types/Logging';
import { Environment, getEnvironment } from '../environment';
import { reallyJsonStringify } from '../util/reallyJsonStringify';
import { getLogLevelString } from './shared';
@ -72,15 +72,17 @@ const pinoInstance = pino(
}
);
export const fatal: LoggingFn = pinoInstance.fatal.bind(pinoInstance);
export const error: LoggingFn = pinoInstance.error.bind(pinoInstance);
export const warn: LoggingFn = pinoInstance.error.bind(pinoInstance);
export const info: LoggingFn = pinoInstance.info.bind(pinoInstance);
export const debug: LoggingFn = pinoInstance.debug.bind(pinoInstance);
export const trace: LoggingFn = pinoInstance.trace.bind(pinoInstance);
export const child = createChild.bind(pinoInstance);
export const log: LoggerType = {
fatal: pinoInstance.fatal.bind(pinoInstance),
error: pinoInstance.error.bind(pinoInstance),
warn: pinoInstance.error.bind(pinoInstance),
info: pinoInstance.info.bind(pinoInstance),
debug: pinoInstance.debug.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}] ` });
return {
@ -90,7 +92,7 @@ function createChild(name: string): LoggerType {
info: instance.info.bind(instance),
debug: instance.debug.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 { redactAll } from '../util/privacy';
import * as log from './log';
import { setPinoDestination, log } from './log';
import type { FetchLogIpcData, LogEntryType } from './shared';
import { LogLevel, isLogEntry } from './shared';
@ -82,7 +82,7 @@ export async function initialize(
rotatingStream.on('close', onClose);
rotatingStream.on('error', onClose);
log.setPinoDestination(rotatingStream, redactAll);
setPinoDestination(rotatingStream, redactAll);
ipc.removeHandler('fetch-log');
ipc.handle('fetch-log', async () => {

View file

@ -11,7 +11,7 @@ import {
LogLevel as SignalClientLogLevel,
} from '@signalapp/libsignal-client';
import * as log from './log';
import { setPinoDestination, log } from './log';
import * as Errors from '../types/errors';
import { createRotatingPinoDest } from '../util/rotatingPinoDest';
import { redactAll } from '../util/privacy';
@ -45,7 +45,7 @@ export function initialize(): void {
stream.on('close', onClose);
stream.on('error', onClose);
log.setPinoDestination(stream, redactAll);
setPinoDestination(stream, redactAll);
}
function toLocation(source?: string, line?: number, column?: number) {
@ -75,6 +75,8 @@ window.addEventListener('unhandledrejection', rejectionEvent => {
log.error(`Top-level unhandled promise rejection: ${errorString}`);
});
const libSignalLog = log.child('@signalapp/libsignal-client');
initLogger(
SignalClientLogLevel.Info,
(
@ -90,20 +92,20 @@ initLogger(
} else if (file) {
fileString = ` ${file}`;
}
const logString = `@signalapp/libsignal-client ${message} ${target}${fileString}`;
const logString = `${message} ${target}${fileString}`;
if (level === SignalClientLogLevel.Trace) {
log.trace(logString);
libSignalLog.trace(logString);
} else if (level === SignalClientLogLevel.Debug) {
log.debug(logString);
libSignalLog.debug(logString);
} else if (level === SignalClientLogLevel.Info) {
log.info(logString);
libSignalLog.info(logString);
} else if (level === SignalClientLogLevel.Warn) {
log.warn(logString);
libSignalLog.warn(logString);
} else if (level === SignalClientLogLevel.Error) {
log.error(logString);
libSignalLog.error(logString);
} 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 { ipcMain as ipc } from 'electron';
import * as log from '../logging/log';
import { createLogger } from '../logging/log';
import type { IPCRequest, IPCResponse, ChallengeResponse } from '../challenge';
const log = createLogger('challengeMain');
export class ChallengeMainHandler {
#handlers: Array<(response: ChallengeResponse) => void> = [];
@ -21,7 +23,7 @@ export class ChallengeMainHandler {
this.#handlers = [];
log.info(
'challengeMain.handleCaptcha: sending captcha response to ' +
'handleCaptcha: sending captcha response to ' +
`${handlers.length} 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 { EventEmitter } from 'events';
import * as log from '../logging/log';
import { createLogger } from '../logging/log';
import { userConfig } from '../../app/user_config';
import { ephemeralConfig } from '../../app/ephemeral_config';
import { installPermissionsHandler } from '../../app/permissions';
@ -13,6 +13,8 @@ import { strictAssert } from '../util/assert';
import type { EphemeralSettings } from '../util/preload';
const log = createLogger('settingsChannel');
const EPHEMERAL_NAME_MAP = new Map([
['spellCheck', 'spell-check'],
['systemTraySetting', 'system-tray-setting'],

View file

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

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