Thread options.source through logRefreshSuccess and logRefreshFailure so WAKEUP_PING and debug-panel refreshes are grep-friendly end-to-end in Logcat and the Event Log without changing refresh behavior.
118 lines
3.3 KiB
TypeScript
118 lines
3.3 KiB
TypeScript
/**
|
|
* Shared observability helpers for notification flows (console + debug panel).
|
|
*/
|
|
|
|
import { logNotification } from "./NotificationDebugEvents";
|
|
|
|
export function truncateFcmTokenForLog(token: string): string {
|
|
const t = token.trim();
|
|
if (t.length <= 24) {
|
|
return t;
|
|
}
|
|
return `${t.slice(0, 12)}…${t.slice(-8)}`;
|
|
}
|
|
|
|
export function logPushNotificationReceived(notification: {
|
|
title?: string;
|
|
data?: Record<string, unknown>;
|
|
}): void {
|
|
const type =
|
|
typeof notification.data?.type === "string"
|
|
? notification.data.type
|
|
: "(none)";
|
|
logNotification(`pushNotificationReceived type=${type}`, {
|
|
title: notification.title,
|
|
dataType: type,
|
|
});
|
|
if (type === "WAKEUP_PING") {
|
|
logNotification("WAKEUP_PING received — will trigger refresh");
|
|
}
|
|
}
|
|
|
|
export function logPushNotificationActionPerformed(action: {
|
|
actionId?: string;
|
|
notification?: { title?: string; data?: Record<string, unknown> };
|
|
}): void {
|
|
const type =
|
|
typeof action.notification?.data?.type === "string"
|
|
? action.notification.data.type
|
|
: "(none)";
|
|
logNotification(
|
|
`pushNotificationActionPerformed actionId=${action.actionId ?? "(none)"} type=${type}`,
|
|
{
|
|
actionId: action.actionId,
|
|
dataType: type,
|
|
},
|
|
);
|
|
}
|
|
|
|
export function logTokenRegistrationStarted(token: string): void {
|
|
logNotification("Token registration started", {
|
|
token: truncateFcmTokenForLog(token),
|
|
});
|
|
}
|
|
|
|
export function logTokenRegistrationSuccess(token: string): void {
|
|
logNotification("Token registration success", {
|
|
token: truncateFcmTokenForLog(token),
|
|
});
|
|
}
|
|
|
|
export function logTokenRegistrationSkippedDuplicate(token: string): void {
|
|
logNotification("Token registration skipped (duplicate token)", {
|
|
token: truncateFcmTokenForLog(token),
|
|
});
|
|
}
|
|
|
|
export function logTokenRegistrationFailure(
|
|
token: string,
|
|
error: unknown,
|
|
): void {
|
|
const message = error instanceof Error ? error.message : String(error);
|
|
logNotification(`Token registration failure: ${message}`, {
|
|
token: truncateFcmTokenForLog(token),
|
|
});
|
|
}
|
|
|
|
export function logRefreshStarted(source?: string): void {
|
|
logNotification(source ? `Refresh started (${source})` : "Refresh started");
|
|
}
|
|
|
|
function elapsedMsSince(startedAt: number): number {
|
|
return performance.now() - startedAt;
|
|
}
|
|
|
|
export function logRefreshSuccess(
|
|
startedAt: number,
|
|
scheduledCount: number,
|
|
source?: string,
|
|
): void {
|
|
const elapsedMs = Math.round(elapsedMsSince(startedAt));
|
|
const message = source
|
|
? `Refresh completed (${source}) in ${elapsedMs}ms (scheduled ${scheduledCount})`
|
|
: `Refresh completed in ${elapsedMs}ms (scheduled ${scheduledCount})`;
|
|
logNotification(message);
|
|
}
|
|
|
|
export function logRefreshFailure(
|
|
startedAt: number,
|
|
errorMessage: string,
|
|
status?: number,
|
|
source?: string,
|
|
): void {
|
|
const statusPart = status != null ? ` HTTP ${status}` : "";
|
|
const elapsedMs = Math.round(elapsedMsSince(startedAt));
|
|
const message = source
|
|
? `Refresh failed (${source}) in ${elapsedMs}ms: ${errorMessage}${statusPart}`
|
|
: `Refresh failed in ${elapsedMs}ms: ${errorMessage}${statusPart}`;
|
|
logNotification(message);
|
|
}
|
|
|
|
export function logNotificationClearing(method: string): void {
|
|
logNotification(`Clearing notifications via ${method}`);
|
|
}
|
|
|
|
export function logScheduleReplacement(count: number): void {
|
|
logNotification(`Schedule replacement: ${count} notification(s)`);
|
|
}
|