feat(notifications): add structured observability for push wake and refresh flows
Introduce NotificationDebugEvents and [Notifications] console/panel logging for push handlers, token registration, refresh timing, schedule replacement, and WAKEUP_PING.
This commit is contained in:
111
src/services/notifications/notificationLog.ts
Normal file
111
src/services/notifications/notificationLog.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 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,
|
||||
): void {
|
||||
logNotification(
|
||||
`Refresh completed in ${Math.round(elapsedMsSince(startedAt))}ms (scheduled ${scheduledCount})`,
|
||||
);
|
||||
}
|
||||
|
||||
export function logRefreshFailure(
|
||||
startedAt: number,
|
||||
errorMessage: string,
|
||||
status?: number,
|
||||
): void {
|
||||
const statusPart = status != null ? ` HTTP ${status}` : "";
|
||||
logNotification(
|
||||
`Refresh failed in ${Math.round(elapsedMsSince(startedAt))}ms: ${errorMessage}${statusPart}`,
|
||||
);
|
||||
}
|
||||
|
||||
export function logNotificationClearing(method: string): void {
|
||||
logNotification(`Clearing notifications via ${method}`);
|
||||
}
|
||||
|
||||
export function logScheduleReplacement(count: number): void {
|
||||
logNotification(`Schedule replacement: ${count} notification(s)`);
|
||||
}
|
||||
Reference in New Issue
Block a user