소스 검색

[web] The great electron renaming (#1390)

- Expose on the globalThis
- Rename the deprecated loggers too
Manav Rathi 1 년 전
부모
커밋
9dc4a17593
100개의 변경된 파일977개의 추가작업 그리고 1084개의 파일을 삭제
  1. 2 2
      desktop/src/main/log.ts
  2. 1 1
      desktop/src/preload.ts
  3. 2 2
      web/apps/accounts/src/pages/account-handoff.tsx
  4. 4 4
      web/apps/accounts/src/pages/passkeys/flow/index.tsx
  5. 2 2
      web/apps/accounts/src/pages/passkeys/index.tsx
  6. 9 8
      web/apps/accounts/src/services/passkeysService.ts
  7. 5 8
      web/apps/auth/src/services/index.ts
  8. 3 3
      web/apps/cast/src/pages/slideshow.tsx
  9. 5 6
      web/apps/cast/src/services/cast/castService.ts
  10. 5 4
      web/apps/cast/src/services/readerService.ts
  11. 3 11
      web/apps/cast/src/services/typeDetectionService.ts
  12. 3 3
      web/apps/cast/src/utils/file/index.ts
  13. 5 5
      web/apps/photos/src/components/AuthenticateUserModal.tsx
  14. 3 10
      web/apps/photos/src/components/Collections/CollectionOptions/index.tsx
  15. 2 3
      web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx
  16. 3 3
      web/apps/photos/src/components/DeleteAccountModal.tsx
  17. 4 4
      web/apps/photos/src/components/Directory/index.tsx
  18. 3 4
      web/apps/photos/src/components/FilesDownloadProgress.tsx
  19. 5 5
      web/apps/photos/src/components/MachineLearning/MLSearchSettings/index.tsx
  20. 5 6
      web/apps/photos/src/components/MachineLearning/PeopleList.tsx
  21. 37 41
      web/apps/photos/src/components/PhotoFrame.tsx
  22. 2 2
      web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCaption.tsx
  23. 2 2
      web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCreationTime.tsx
  24. 2 2
      web/apps/photos/src/components/PhotoViewer/FileInfo/RenderFileName.tsx
  25. 10 11
      web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx
  26. 7 7
      web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx
  27. 9 9
      web/apps/photos/src/components/PhotoViewer/index.tsx
  28. 1 1
      web/apps/photos/src/components/Search/SearchBar/searchInput/MenuWithPeople.tsx
  29. 2 2
      web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx
  30. 11 18
      web/apps/photos/src/components/Sidebar/DebugSection.tsx
  31. 3 3
      web/apps/photos/src/components/Sidebar/MapSetting/ModifyMapEnabled.tsx
  32. 2 2
      web/apps/photos/src/components/Sidebar/UtilitySection.tsx
  33. 51 49
      web/apps/photos/src/components/Upload/Uploader.tsx
  34. 10 11
      web/apps/photos/src/components/WatchFolder/index.tsx
  35. 8 9
      web/apps/photos/src/components/pages/gallery/Avatar.tsx
  36. 2 2
      web/apps/photos/src/components/pages/gallery/PlanSelector/card/index.tsx
  37. 2 2
      web/apps/photos/src/components/pages/gallery/PreviewCard.tsx
  38. 14 18
      web/apps/photos/src/pages/_app.tsx
  39. 37 39
      web/apps/photos/src/pages/gallery/index.tsx
  40. 6 7
      web/apps/photos/src/pages/index.tsx
  41. 6 6
      web/apps/photos/src/pages/shared-albums/index.tsx
  42. 13 13
      web/apps/photos/src/services/billingService.ts
  43. 38 36
      web/apps/photos/src/services/clipService.ts
  44. 27 26
      web/apps/photos/src/services/collectionService.ts
  45. 3 3
      web/apps/photos/src/services/deduplicationService.ts
  46. 36 67
      web/apps/photos/src/services/download/index.ts
  47. 12 18
      web/apps/photos/src/services/embeddingService.ts
  48. 9 10
      web/apps/photos/src/services/entityService.ts
  49. 111 112
      web/apps/photos/src/services/export/index.ts
  50. 3 4
      web/apps/photos/src/services/ffmpeg/ffmpegFactory.ts
  51. 4 4
      web/apps/photos/src/services/ffmpeg/ffmpegService.ts
  52. 14 15
      web/apps/photos/src/services/fileService.ts
  53. 16 15
      web/apps/photos/src/services/heic-convert/service.ts
  54. 2 2
      web/apps/photos/src/services/heicConversionService.ts
  55. 10 9
      web/apps/photos/src/services/importService.ts
  56. 3 3
      web/apps/photos/src/services/locationSearchService.ts
  57. 10 10
      web/apps/photos/src/services/machineLearning/blazeFaceDetectionService.ts
  58. 1 1
      web/apps/photos/src/services/machineLearning/clusteringService.ts
  59. 1 1
      web/apps/photos/src/services/machineLearning/dbscanClusteringService.ts
  60. 10 10
      web/apps/photos/src/services/machineLearning/faceService.ts
  61. 1 1
      web/apps/photos/src/services/machineLearning/hdbscanClusteringService.ts
  62. 4 7
      web/apps/photos/src/services/machineLearning/imageSceneService.ts
  63. 2 2
      web/apps/photos/src/services/machineLearning/machineLearningFactory.ts
  64. 20 21
      web/apps/photos/src/services/machineLearning/machineLearningService.ts
  65. 20 21
      web/apps/photos/src/services/machineLearning/mlWorkManager.ts
  66. 2 2
      web/apps/photos/src/services/machineLearning/mobileFaceNetEmbeddingService.ts
  67. 6 6
      web/apps/photos/src/services/machineLearning/objectService.ts
  68. 3 3
      web/apps/photos/src/services/machineLearning/peopleService.ts
  69. 4 4
      web/apps/photos/src/services/machineLearning/readerService.ts
  70. 2 2
      web/apps/photos/src/services/machineLearning/ssdMobileNetV2Service.ts
  71. 6 6
      web/apps/photos/src/services/publicCollectionService.ts
  72. 5 4
      web/apps/photos/src/services/readerService.ts
  73. 10 12
      web/apps/photos/src/services/searchService.ts
  74. 7 9
      web/apps/photos/src/services/trashService.ts
  75. 3 12
      web/apps/photos/src/services/typeDetectionService.ts
  76. 3 3
      web/apps/photos/src/services/updateCreationTimeWithExif.ts
  77. 41 38
      web/apps/photos/src/services/upload/exifService.ts
  78. 7 9
      web/apps/photos/src/services/upload/fileService.ts
  79. 5 8
      web/apps/photos/src/services/upload/hashService.tsx
  80. 5 7
      web/apps/photos/src/services/upload/livePhotoService.ts
  81. 5 5
      web/apps/photos/src/services/upload/metadataService.ts
  82. 4 4
      web/apps/photos/src/services/upload/publicUploadHttpClient.ts
  83. 24 30
      web/apps/photos/src/services/upload/thumbnailService.ts
  84. 12 12
      web/apps/photos/src/services/upload/uploadHttpClient.ts
  85. 37 40
      web/apps/photos/src/services/upload/uploadManager.ts
  86. 3 3
      web/apps/photos/src/services/upload/uploadService.ts
  87. 5 6
      web/apps/photos/src/services/upload/videoMetadataService.ts
  88. 17 17
      web/apps/photos/src/services/userService.ts
  89. 5 6
      web/apps/photos/src/services/wasm/ffmpeg.ts
  90. 8 9
      web/apps/photos/src/services/watchFolder/watchFolderEventHandlers.ts
  91. 13 13
      web/apps/photos/src/services/watchFolder/watchFolderService.ts
  92. 5 6
      web/apps/photos/src/utils/billing/index.ts
  93. 12 14
      web/apps/photos/src/utils/collection/index.ts
  94. 5 5
      web/apps/photos/src/utils/common/job.ts
  95. 22 15
      web/apps/photos/src/utils/file/index.ts
  96. 1 1
      web/apps/photos/src/utils/image/index.ts
  97. 6 6
      web/apps/photos/src/utils/machineLearning/faceAlign.ts
  98. 3 3
      web/apps/photos/src/utils/machineLearning/faceCrop.ts
  99. 11 11
      web/apps/photos/src/utils/machineLearning/index.ts
  100. 2 5
      web/apps/photos/src/utils/photoFrame/index.ts

+ 2 - 2
desktop/src/main/log.ts

@@ -60,11 +60,11 @@ const logInfo = (...params: any[]) => {
         .map((p) => (typeof p == "string" ? p : util.inspect(p)))
         .map((p) => (typeof p == "string" ? p : util.inspect(p)))
         .join(" ");
         .join(" ");
     log.info(`[main] ${message}`);
     log.info(`[main] ${message}`);
-    if (isDev) console.log(message);
+    if (isDev) console.log(`[info] ${message}`);
 };
 };
 
 
 const logDebug = (param: () => any) => {
 const logDebug = (param: () => any) => {
-    if (isDev) console.log(`[main] [debug] ${util.inspect(param())}`);
+    if (isDev) console.log(`[debug] ${util.inspect(param())}`);
 };
 };
 
 
 /**
 /**

+ 1 - 1
desktop/src/preload.ts

@@ -307,7 +307,7 @@ const getDirFiles = (dirPath: string): Promise<ElectronFile[]> =>
 //
 //
 // The copy itself is relatively fast, but the problem with transfering large
 // The copy itself is relatively fast, but the problem with transfering large
 // amounts of data is potentially running out of memory during the copy.
 // amounts of data is potentially running out of memory during the copy.
-contextBridge.exposeInMainWorld("ElectronAPIs", {
+contextBridge.exposeInMainWorld("electron", {
     // - General
     // - General
     appVersion,
     appVersion,
     openDirectory,
     openDirectory,

+ 2 - 2
web/apps/accounts/src/pages/account-handoff.tsx

@@ -1,8 +1,8 @@
+import log from "@/next/log";
 import { VerticallyCentered } from "@ente/shared/components/Container";
 import { VerticallyCentered } from "@ente/shared/components/Container";
 import EnteSpinner from "@ente/shared/components/EnteSpinner";
 import EnteSpinner from "@ente/shared/components/EnteSpinner";
 import { ACCOUNTS_PAGES } from "@ente/shared/constants/pages";
 import { ACCOUNTS_PAGES } from "@ente/shared/constants/pages";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
-import { logError } from "@ente/shared/sentry";
 import { LS_KEYS, getData, setData } from "@ente/shared/storage/localStorage";
 import { LS_KEYS, getData, setData } from "@ente/shared/storage/localStorage";
 import { useRouter } from "next/router";
 import { useRouter } from "next/router";
 import { useEffect } from "react";
 import { useEffect } from "react";
@@ -16,7 +16,7 @@ const AccountHandoff = () => {
 
 
             router.push(ACCOUNTS_PAGES.PASSKEYS);
             router.push(ACCOUNTS_PAGES.PASSKEYS);
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed to deserialize and set passed user data");
+            log.error("Failed to deserialize and set passed user data", e);
             router.push(ACCOUNTS_PAGES.LOGIN);
             router.push(ACCOUNTS_PAGES.LOGIN);
         }
         }
     };
     };

+ 4 - 4
web/apps/accounts/src/pages/passkeys/flow/index.tsx

@@ -1,3 +1,4 @@
+import log from "@/next/log";
 import { APPS, CLIENT_PACKAGE_NAMES } from "@ente/shared/apps/constants";
 import { APPS, CLIENT_PACKAGE_NAMES } from "@ente/shared/apps/constants";
 import {
 import {
     CenteredFlex,
     CenteredFlex,
@@ -7,7 +8,6 @@ import EnteButton from "@ente/shared/components/EnteButton";
 import EnteSpinner from "@ente/shared/components/EnteSpinner";
 import EnteSpinner from "@ente/shared/components/EnteSpinner";
 import FormPaper from "@ente/shared/components/Form/FormPaper";
 import FormPaper from "@ente/shared/components/Form/FormPaper";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
-import { logError } from "@ente/shared/sentry";
 import { LS_KEYS, setData } from "@ente/shared/storage/localStorage";
 import { LS_KEYS, setData } from "@ente/shared/storage/localStorage";
 import InfoIcon from "@mui/icons-material/Info";
 import InfoIcon from "@mui/icons-material/Info";
 import { Box, Typography } from "@mui/material";
 import { Box, Typography } from "@mui/material";
@@ -73,7 +73,7 @@ const PasskeysFlow = () => {
         try {
         try {
             beginData = await beginAuthentication(passkeySessionID);
             beginData = await beginAuthentication(passkeySessionID);
         } catch (e) {
         } catch (e) {
-            logError(e, "Couldn't begin passkey authentication");
+            log.error("Couldn't begin passkey authentication", e);
             setErrored(true);
             setErrored(true);
             return;
             return;
         } finally {
         } finally {
@@ -89,7 +89,7 @@ const PasskeysFlow = () => {
             try {
             try {
                 credential = await getCredential(beginData.options.publicKey);
                 credential = await getCredential(beginData.options.publicKey);
             } catch (e) {
             } catch (e) {
-                logError(e, "Couldn't get credential");
+                log.error("Couldn't get credential", e);
                 continue;
                 continue;
             } finally {
             } finally {
                 tries++;
                 tries++;
@@ -117,7 +117,7 @@ const PasskeysFlow = () => {
                 beginData.ceremonySessionID,
                 beginData.ceremonySessionID,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "Couldn't finish passkey authentication");
+            log.error("Couldn't finish passkey authentication", e);
             setErrored(true);
             setErrored(true);
             setLoading(false);
             setLoading(false);
             return;
             return;

+ 2 - 2
web/apps/accounts/src/pages/passkeys/index.tsx

@@ -1,8 +1,8 @@
+import log from "@/next/log";
 import { CenteredFlex } from "@ente/shared/components/Container";
 import { CenteredFlex } from "@ente/shared/components/Container";
 import FormPaper from "@ente/shared/components/Form/FormPaper";
 import FormPaper from "@ente/shared/components/Form/FormPaper";
 import SingleInputForm from "@ente/shared/components/SingleInputForm";
 import SingleInputForm from "@ente/shared/components/SingleInputForm";
 import { ACCOUNTS_PAGES } from "@ente/shared/constants/pages";
 import { ACCOUNTS_PAGES } from "@ente/shared/constants/pages";
-import { logError } from "@ente/shared/sentry";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { Box, Typography } from "@mui/material";
 import { Box, Typography } from "@mui/material";
 import { t } from "i18next";
 import { t } from "i18next";
@@ -104,7 +104,7 @@ const Passkeys = () => {
         try {
         try {
             newCredential = await navigator.credentials.create(options);
             newCredential = await navigator.credentials.create(options);
         } catch (e) {
         } catch (e) {
-            logError(e, "Error creating credential");
+            log.error("Error creating credential", e);
             setFieldError("Failed to create credential");
             setFieldError("Failed to create credential");
             return;
             return;
         }
         }

+ 9 - 8
web/apps/accounts/src/services/passkeysService.ts

@@ -1,8 +1,9 @@
+import log from "@/next/log";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint } from "@ente/shared/network/api";
 import { getEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import _sodium from "libsodium-wrappers";
 import _sodium from "libsodium-wrappers";
+
 const ENDPOINT = getEndpoint();
 const ENDPOINT = getEndpoint();
 
 
 export const getPasskeys = async () => {
 export const getPasskeys = async () => {
@@ -16,7 +17,7 @@ export const getPasskeys = async () => {
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "get passkeys failed");
+        log.error("get passkeys failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -33,7 +34,7 @@ export const renamePasskey = async (id: string, name: string) => {
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "rename passkey failed");
+        log.error("rename passkey failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -50,7 +51,7 @@ export const deletePasskey = async (id: string) => {
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "delete passkey failed");
+        log.error("delete passkey failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -68,7 +69,7 @@ export const getPasskeyRegistrationOptions = async () => {
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "get passkey registration options failed");
+        log.error("get passkey registration options failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -116,7 +117,7 @@ export const finishPasskeyRegistration = async (
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "finish passkey registration failed");
+        log.error("finish passkey registration failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -142,7 +143,7 @@ export const beginPasskeyAuthentication = async (
 
 
         return data.data;
         return data.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "begin passkey authentication failed");
+        log.error("begin passkey authentication failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -194,7 +195,7 @@ export const finishPasskeyAuthentication = async (
 
 
         return data.data;
         return data.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "finish passkey authentication failed");
+        log.error("finish passkey authentication failed", e);
         throw e;
         throw e;
     }
     }
 };
 };

+ 5 - 8
web/apps/auth/src/services/index.ts

@@ -1,8 +1,8 @@
+import log from "@/next/log";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import { ApiError, CustomError } from "@ente/shared/error";
 import { ApiError, CustomError } from "@ente/shared/error";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint } from "@ente/shared/network/api";
 import { getEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getActualKey } from "@ente/shared/user";
 import { getActualKey } from "@ente/shared/user";
 import { HttpStatusCode } from "axios";
 import { HttpStatusCode } from "axios";
@@ -35,10 +35,7 @@ export const getAuthCodes = async (): Promise<Code[]> => {
                             );
                             );
                         return Code.fromRawData(entity.id, decryptedCode);
                         return Code.fromRawData(entity.id, decryptedCode);
                     } catch (e) {
                     } catch (e) {
-                        logError(
-                            Error("failed to parse code"),
-                            "codeId = " + entity.id,
-                        );
+                        log.error(`failed to parse codeId = ${entity.id}`);
                         return null;
                         return null;
                     }
                     }
                 }),
                 }),
@@ -62,7 +59,7 @@ export const getAuthCodes = async (): Promise<Code[]> => {
         return filteredAuthCodes;
         return filteredAuthCodes;
     } catch (e) {
     } catch (e) {
         if (e.message !== CustomError.AUTH_KEY_NOT_FOUND) {
         if (e.message !== CustomError.AUTH_KEY_NOT_FOUND) {
-            logError(e, "get authenticator entities failed");
+            log.error("get authenticator entities failed", e);
         }
         }
         throw e;
         throw e;
     }
     }
@@ -85,7 +82,7 @@ export const getAuthKey = async (): Promise<AuthKey> => {
         ) {
         ) {
             throw Error(CustomError.AUTH_KEY_NOT_FOUND);
             throw Error(CustomError.AUTH_KEY_NOT_FOUND);
         } else {
         } else {
-            logError(e, "Get key failed");
+            log.error("Get key failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -109,7 +106,7 @@ export const getDiff = async (
         );
         );
         return resp.data.diff;
         return resp.data.diff;
     } catch (e) {
     } catch (e) {
-        logError(e, "Get diff failed");
+        log.error("Get diff failed", e);
         throw e;
         throw e;
     }
     }
 };
 };

+ 3 - 3
web/apps/cast/src/pages/slideshow.tsx

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import PairedSuccessfullyOverlay from "components/PairedSuccessfullyOverlay";
 import PairedSuccessfullyOverlay from "components/PairedSuccessfullyOverlay";
 import Theatre from "components/Theatre";
 import Theatre from "components/Theatre";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
@@ -54,7 +54,7 @@ export default function Slideshow() {
                 );
                 );
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "error during sync");
+            log.error("error during sync", e);
             router.push("/");
             router.push("/");
         }
         }
     };
     };
@@ -107,7 +107,7 @@ export default function Slideshow() {
 
 
             return () => clearTimeout(timeoutId);
             return () => clearTimeout(timeoutId);
         } catch (e) {
         } catch (e) {
-            logError(e, "error during sync");
+            log.error("error during sync", e);
             router.push("/");
             router.push("/");
         }
         }
     }, []);
     }, []);

+ 5 - 6
web/apps/cast/src/services/cast/castService.ts

@@ -1,10 +1,9 @@
+import log from "@/next/log";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import { CustomError, parseSharingErrorCodes } from "@ente/shared/error";
 import { CustomError, parseSharingErrorCodes } from "@ente/shared/error";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint } from "@ente/shared/network/api";
 import { getEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import localForage from "@ente/shared/storage/localForage";
 import localForage from "@ente/shared/storage/localForage";
-
 import { Collection, CollectionPublicMagicMetadata } from "types/collection";
 import { Collection, CollectionPublicMagicMetadata } from "types/collection";
 import { EncryptedEnteFile, EnteFile } from "types/file";
 import { EncryptedEnteFile, EnteFile } from "types/file";
 import { decryptFile, mergeMetadata, sortFiles } from "utils/file";
 import { decryptFile, mergeMetadata, sortFiles } from "utils/file";
@@ -150,14 +149,14 @@ export const syncPublicFiles = async (
             setPublicFiles([...sortFiles(mergeMetadata(files), sortAsc)]);
             setPublicFiles([...sortFiles(mergeMetadata(files), sortAsc)]);
         } catch (e) {
         } catch (e) {
             const parsedError = parseSharingErrorCodes(e);
             const parsedError = parseSharingErrorCodes(e);
-            logError(e, "failed to sync shared collection files");
+            log.error("failed to sync shared collection files", e);
             if (parsedError.message === CustomError.TOKEN_EXPIRED) {
             if (parsedError.message === CustomError.TOKEN_EXPIRED) {
                 throw e;
                 throw e;
             }
             }
         }
         }
         return [...sortFiles(mergeMetadata(files), sortAsc)];
         return [...sortFiles(mergeMetadata(files), sortAsc)];
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get local  or sync shared collection files");
+        log.error("failed to get local  or sync shared collection files", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -217,7 +216,7 @@ const fetchFiles = async (
         } while (resp.data.hasMore);
         } while (resp.data.hasMore);
         return decryptedFiles;
         return decryptedFiles;
     } catch (e) {
     } catch (e) {
-        logError(e, "Get cast files failed");
+        log.error("Get cast files failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -264,7 +263,7 @@ export const getCastCollection = async (
         await saveCollection(collection);
         await saveCollection(collection);
         return collection;
         return collection;
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get cast collection");
+        log.error("failed to get cast collection", e);
         throw e;
         throw e;
     }
     }
 };
 };

+ 5 - 4
web/apps/cast/src/services/readerService.ts

@@ -1,13 +1,14 @@
 import { convertBytesToHumanReadable } from "@/next/file";
 import { convertBytesToHumanReadable } from "@/next/file";
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 
 
 export async function getUint8ArrayView(file: Blob): Promise<Uint8Array> {
 export async function getUint8ArrayView(file: Blob): Promise<Uint8Array> {
     try {
     try {
         return new Uint8Array(await file.arrayBuffer());
         return new Uint8Array(await file.arrayBuffer());
     } catch (e) {
     } catch (e) {
-        logError(e, "reading file blob failed", {
-            fileSize: convertBytesToHumanReadable(file.size),
-        });
+        log.error(
+            `Failed to read file blob of size ${convertBytesToHumanReadable(file.size)}`,
+            e,
+        );
         throw e;
         throw e;
     }
     }
 }
 }

+ 3 - 11
web/apps/cast/src/services/typeDetectionService.ts

@@ -1,6 +1,5 @@
-import { convertBytesToHumanReadable } from "@/next/file";
+import log from "@/next/log";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { logError } from "@ente/shared/sentry";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import {
 import {
     KNOWN_NON_MEDIA_FORMATS,
     KNOWN_NON_MEDIA_FORMATS,
@@ -42,7 +41,6 @@ export async function getFileType(receivedFile: File): Promise<FileTypeInfo> {
         };
         };
     } catch (e) {
     } catch (e) {
         const fileFormat = getFileExtension(receivedFile.name);
         const fileFormat = getFileExtension(receivedFile.name);
-        const fileSize = convertBytesToHumanReadable(receivedFile.size);
         const whiteListedFormat = WHITELISTED_FILE_FORMATS.find(
         const whiteListedFormat = WHITELISTED_FILE_FORMATS.find(
             (a) => a.exactType === fileFormat,
             (a) => a.exactType === fileFormat,
         );
         );
@@ -53,16 +51,10 @@ export async function getFileType(receivedFile: File): Promise<FileTypeInfo> {
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
         }
         }
         if (e.message === CustomError.NON_MEDIA_FILE) {
         if (e.message === CustomError.NON_MEDIA_FILE) {
-            logError(e, "unsupported file format", {
-                fileFormat,
-                fileSize,
-            });
+            log.error(`unsupported file format ${fileFormat}`, e);
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
         }
         }
-        logError(e, "type detection failed", {
-            fileFormat,
-            fileSize,
-        });
+        log.error(`type detection failed for format ${fileFormat}`, e);
         throw Error(CustomError.TYPE_DETECTION_FAILED(fileFormat));
         throw Error(CustomError.TYPE_DETECTION_FAILED(fileFormat));
     }
     }
 }
 }

+ 3 - 3
web/apps/cast/src/utils/file/index.ts

@@ -1,5 +1,5 @@
+import log from "@/next/log";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
-import { logError } from "@ente/shared/sentry";
 import { FILE_TYPE, RAW_FORMATS } from "constants/file";
 import { FILE_TYPE, RAW_FORMATS } from "constants/file";
 import CastDownloadManager from "services/castDownloadManager";
 import CastDownloadManager from "services/castDownloadManager";
 import { decodeLivePhoto } from "services/livePhotoService";
 import { decodeLivePhoto } from "services/livePhotoService";
@@ -80,7 +80,7 @@ export async function decryptFile(
             pubMagicMetadata: filePubMagicMetadata,
             pubMagicMetadata: filePubMagicMetadata,
         };
         };
     } catch (e) {
     } catch (e) {
-        logError(e, "file decryption failed");
+        log.error("file decryption failed", e);
         throw e;
         throw e;
     }
     }
 }
 }
@@ -160,6 +160,6 @@ export const getPreviewableImage = async (
         fileBlob = new Blob([fileBlob], { type: fileType.mimeType });
         fileBlob = new Blob([fileBlob], { type: fileType.mimeType });
         return fileBlob;
         return fileBlob;
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to download file");
+        log.error("failed to download file", e);
     }
     }
 };
 };

+ 5 - 5
web/apps/photos/src/components/AuthenticateUserModal.tsx

@@ -1,14 +1,14 @@
-import { useContext, useEffect, useState } from "react";
-
+import log from "@/next/log";
 import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
 import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
 import VerifyMasterPasswordForm, {
 import VerifyMasterPasswordForm, {
     VerifyMasterPasswordFormProps,
     VerifyMasterPasswordFormProps,
 } from "@ente/shared/components/VerifyMasterPasswordForm";
 } from "@ente/shared/components/VerifyMasterPasswordForm";
-import { logError } from "@ente/shared/sentry";
-import { getData, LS_KEYS } from "@ente/shared/storage/localStorage";
+import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import { KeyAttributes, User } from "@ente/shared/user/types";
 import { KeyAttributes, User } from "@ente/shared/user/types";
 import { t } from "i18next";
 import { t } from "i18next";
 import { AppContext } from "pages/_app";
 import { AppContext } from "pages/_app";
+import { useContext, useEffect, useState } from "react";
+
 interface Iprops {
 interface Iprops {
     open: boolean;
     open: boolean;
     onClose: () => void;
     onClose: () => void;
@@ -51,7 +51,7 @@ export default function AuthenticateUserModal({
                     setKeyAttributes(keyAttributes);
                     setKeyAttributes(keyAttributes);
                 }
                 }
             } catch (e) {
             } catch (e) {
-                logError(e, "AuthenticateUserModal initialization failed");
+                log.error("AuthenticateUserModal initialization failed", e);
                 onClose();
                 onClose();
                 somethingWentWrong();
                 somethingWentWrong();
             }
             }

+ 3 - 10
web/apps/photos/src/components/Collections/CollectionOptions/index.tsx

@@ -1,6 +1,6 @@
+import log from "@/next/log";
 import { HorizontalFlex } from "@ente/shared/components/Container";
 import { HorizontalFlex } from "@ente/shared/components/Container";
 import OverflowMenu from "@ente/shared/components/OverflowMenu/menu";
 import OverflowMenu from "@ente/shared/components/OverflowMenu/menu";
-import { logError } from "@ente/shared/sentry";
 import MoreHoriz from "@mui/icons-material/MoreHoriz";
 import MoreHoriz from "@mui/icons-material/MoreHoriz";
 import { Box } from "@mui/material";
 import { Box } from "@mui/material";
 import {
 import {
@@ -161,22 +161,15 @@ const CollectionOptions = (props: CollectionOptionsProps) => {
             case CollectionActions.SHOW_ALBUM_CAST_DIALOG:
             case CollectionActions.SHOW_ALBUM_CAST_DIALOG:
                 callback = showCastAlbumDialog;
                 callback = showCastAlbumDialog;
                 break;
                 break;
-
             default:
             default:
-                logError(
-                    Error("invalid collection action "),
-                    "handleCollectionAction failed",
-                );
-                {
-                    action;
-                }
+                log.error(`invalid collection action ${action}`);
         }
         }
         return async (...args: any) => {
         return async (...args: any) => {
             try {
             try {
                 loader && startLoading();
                 loader && startLoading();
                 await callback(...args);
                 await callback(...args);
             } catch (e) {
             } catch (e) {
-                logError(e, "collection action failed", { action });
+                log.error(`collection action ${action} failed`, e);
                 setDialogMessage({
                 setDialogMessage({
                     title: t("ERROR"),
                     title: t("ERROR"),
                     content: t("UNKNOWN_ERROR"),
                     content: t("UNKNOWN_ERROR"),

+ 2 - 3
web/apps/photos/src/components/Collections/CollectionShare/emailShare/ManageParticipant.tsx

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import BlockIcon from "@mui/icons-material/Block";
 import BlockIcon from "@mui/icons-material/Block";
 import DoneIcon from "@mui/icons-material/Done";
 import DoneIcon from "@mui/icons-material/Done";
 import ModeEditIcon from "@mui/icons-material/ModeEdit";
 import ModeEditIcon from "@mui/icons-material/ModeEdit";
@@ -63,8 +63,7 @@ export default function ManageParticipant({
             selectedParticipant.role = newRole;
             selectedParticipant.role = newRole;
             await galleryContext.syncWithRemote(false, true);
             await galleryContext.syncWithRemote(false, true);
         } catch (e) {
         } catch (e) {
-            const errorMessage = handleSharingErrors(e);
-            logError(e, errorMessage);
+            log.error(handleSharingErrors(e), e);
         }
         }
     };
     };
 
 

+ 3 - 3
web/apps/photos/src/components/DeleteAccountModal.tsx

@@ -1,8 +1,8 @@
+import log from "@/next/log";
 import { logoutUser } from "@ente/accounts/services/user";
 import { logoutUser } from "@ente/accounts/services/user";
 import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
 import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
 import EnteButton from "@ente/shared/components/EnteButton";
 import EnteButton from "@ente/shared/components/EnteButton";
 import { DELETE_ACCOUNT_EMAIL } from "@ente/shared/constants/urls";
 import { DELETE_ACCOUNT_EMAIL } from "@ente/shared/constants/urls";
-import { logError } from "@ente/shared/sentry";
 import { Button, Link, Stack } from "@mui/material";
 import { Button, Link, Stack } from "@mui/material";
 import { Formik, FormikHelpers } from "formik";
 import { Formik, FormikHelpers } from "formik";
 import { t } from "i18next";
 import { t } from "i18next";
@@ -92,7 +92,7 @@ const DeleteAccountModal = ({ open, onClose }: Iprops) => {
                 askToMailForDeletion();
                 askToMailForDeletion();
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "Error while initiating account deletion");
+            log.error("Error while initiating account deletion", e);
             somethingWentWrong();
             somethingWentWrong();
         } finally {
         } finally {
             setLoading(false);
             setLoading(false);
@@ -147,7 +147,7 @@ const DeleteAccountModal = ({ open, onClose }: Iprops) => {
             await deleteAccount(decryptedChallenge, reason, feedback);
             await deleteAccount(decryptedChallenge, reason, feedback);
             logoutUser();
             logoutUser();
         } catch (e) {
         } catch (e) {
-            logError(e, "solveChallengeAndDeleteAccount failed");
+            log.error("solveChallengeAndDeleteAccount failed", e);
             somethingWentWrong();
             somethingWentWrong();
         } finally {
         } finally {
             setLoading(false);
             setLoading(false);

+ 4 - 4
web/apps/photos/src/components/Directory/index.tsx

@@ -1,6 +1,6 @@
-import ElectronAPIs from "@/next/electron";
+import { ensureElectron } from "@/next/electron";
+import log from "@/next/log";
 import LinkButton from "@ente/shared/components/LinkButton";
 import LinkButton from "@ente/shared/components/LinkButton";
-import { logError } from "@ente/shared/sentry";
 import { Tooltip } from "@mui/material";
 import { Tooltip } from "@mui/material";
 import { styled } from "@mui/material/styles";
 import { styled } from "@mui/material/styles";
 
 
@@ -19,9 +19,9 @@ const DirectoryPathContainer = styled(LinkButton)(
 export const DirectoryPath = ({ width, path }) => {
 export const DirectoryPath = ({ width, path }) => {
     const handleClick = async () => {
     const handleClick = async () => {
         try {
         try {
-            await ElectronAPIs.openDirectory(path);
+            await ensureElectron().openDirectory(path);
         } catch (e) {
         } catch (e) {
-            logError(e, "openDirectory failed");
+            log.error("openDirectory failed", e);
         }
         }
     };
     };
     return (
     return (

+ 3 - 4
web/apps/photos/src/components/FilesDownloadProgress.tsx

@@ -1,7 +1,5 @@
-import ElectronAPIs from "@/next/electron";
 import Notification from "components/Notification";
 import Notification from "components/Notification";
 import { t } from "i18next";
 import { t } from "i18next";
-import isElectron from "is-electron";
 import { AppContext } from "pages/_app";
 import { AppContext } from "pages/_app";
 import { GalleryContext } from "pages/gallery";
 import { GalleryContext } from "pages/gallery";
 import { useContext } from "react";
 import { useContext } from "react";
@@ -101,8 +99,9 @@ export const FilesDownloadProgress: React.FC<FilesDownloadProgressProps> = ({
 
 
     const handleOnClick = (id: number) => () => {
     const handleOnClick = (id: number) => () => {
         const attributes = attributesList.find((attr) => attr.id === id);
         const attributes = attributesList.find((attr) => attr.id === id);
-        if (isElectron()) {
-            ElectronAPIs.openDirectory(attributes.downloadDirPath);
+        const electron = globalThis.electron;
+        if (electron) {
+            electron.openDirectory(attributes.downloadDirPath);
         } else {
         } else {
             if (attributes.isHidden) {
             if (attributes.isHidden) {
                 galleryContext.openHiddenSection(() => {
                 galleryContext.openHiddenSection(() => {

+ 5 - 5
web/apps/photos/src/components/MachineLearning/MLSearchSettings/index.tsx

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { Box, DialogProps, Typography } from "@mui/material";
 import { Box, DialogProps, Typography } from "@mui/material";
 import { EnteDrawer } from "components/EnteDrawer";
 import { EnteDrawer } from "components/EnteDrawer";
 import { t } from "i18next";
 import { t } from "i18next";
@@ -41,7 +41,7 @@ const MLSearchSettings = ({ open, onClose, onRootClose }) => {
                 updateMlSearchEnabled(true);
                 updateMlSearchEnabled(true);
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "Enable ML search failed");
+            log.error("Enable ML search failed", e);
             somethingWentWrong();
             somethingWentWrong();
         }
         }
     };
     };
@@ -54,7 +54,7 @@ const MLSearchSettings = ({ open, onClose, onRootClose }) => {
             closeEnableFaceSearch();
             closeEnableFaceSearch();
             finishLoading();
             finishLoading();
         } catch (e) {
         } catch (e) {
-            logError(e, "Enable face search failed");
+            log.error("Enable face search failed", e);
             somethingWentWrong();
             somethingWentWrong();
         }
         }
     };
     };
@@ -64,7 +64,7 @@ const MLSearchSettings = ({ open, onClose, onRootClose }) => {
             await updateMlSearchEnabled(false);
             await updateMlSearchEnabled(false);
             onClose();
             onClose();
         } catch (e) {
         } catch (e) {
-            logError(e, "Disable ML search failed");
+            log.error("Disable ML search failed", e);
             somethingWentWrong();
             somethingWentWrong();
         }
         }
     };
     };
@@ -76,7 +76,7 @@ const MLSearchSettings = ({ open, onClose, onRootClose }) => {
             await disableMlSearch();
             await disableMlSearch();
             finishLoading();
             finishLoading();
         } catch (e) {
         } catch (e) {
-            logError(e, "Disable face search failed");
+            log.error("Disable face search failed", e);
             somethingWentWrong();
             somethingWentWrong();
         }
         }
     };
     };

+ 5 - 6
web/apps/photos/src/components/MachineLearning/PeopleList.tsx

@@ -1,5 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { CACHES } from "@ente/shared/storage/cacheStorage/constants";
 import { CACHES } from "@ente/shared/storage/cacheStorage/constants";
 import { styled } from "@mui/material";
 import { styled } from "@mui/material";
 import { Legend } from "components/PhotoViewer/styledComponents/Legend";
 import { Legend } from "components/PhotoViewer/styledComponents/Legend";
@@ -87,11 +86,11 @@ export function PhotoPeopleList(props: PhotoPeopleListProps) {
         let didCancel = false;
         let didCancel = false;
 
 
         async function updateFaceImages() {
         async function updateFaceImages() {
-            addLogLine("calling getPeopleList");
+            log.info("calling getPeopleList");
             const startTime = Date.now();
             const startTime = Date.now();
             const people = await getPeopleList(props.file);
             const people = await getPeopleList(props.file);
-            addLogLine("getPeopleList", Date.now() - startTime, "ms");
-            addLogLine("getPeopleList done, didCancel: ", didCancel);
+            log.info(`getPeopleList ${Date.now() - startTime} ms`);
+            log.info(`getPeopleList done, didCancel: ${didCancel}`);
             !didCancel && setPeople(people);
             !didCancel && setPeople(people);
         }
         }
 
 
@@ -130,7 +129,7 @@ export function AllPeopleList(props: AllPeopleListProps) {
                 }
                 }
                 !didCancel && setPeople(people);
                 !didCancel && setPeople(people);
             } catch (e) {
             } catch (e) {
-                logError(e, "updateFaceImages failed");
+                log.error("updateFaceImages failed", e);
             }
             }
         }
         }
         updateFaceImages();
         updateFaceImages();

+ 37 - 41
web/apps/photos/src/components/PhotoFrame.tsx

@@ -1,8 +1,7 @@
+import log from "@/next/log";
 import { PHOTOS_PAGES } from "@ente/shared/constants/pages";
 import { PHOTOS_PAGES } from "@ente/shared/constants/pages";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
 import useMemoSingleThreaded from "@ente/shared/hooks/useMemoSingleThreaded";
 import useMemoSingleThreaded from "@ente/shared/hooks/useMemoSingleThreaded";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
 import { styled } from "@mui/material";
 import { styled } from "@mui/material";
 import PhotoViewer from "components/PhotoViewer";
 import PhotoViewer from "components/PhotoViewer";
 import { TRASH_SECTION } from "constants/collection";
 import { TRASH_SECTION } from "constants/collection";
@@ -184,7 +183,7 @@ const PhotoFrame = ({
             const file = displayFiles[index];
             const file = displayFiles[index];
             // this is to prevent outdated updateURL call from updating the wrong file
             // this is to prevent outdated updateURL call from updating the wrong file
             if (file.id !== id) {
             if (file.id !== id) {
-                addLogLine(
+                log.info(
                     `[${id}]PhotoSwipe: updateURL: file id mismatch: ${file.id} !== ${id}`,
                     `[${id}]PhotoSwipe: updateURL: file id mismatch: ${file.id} !== ${id}`,
                 );
                 );
                 throw Error(CustomError.UPDATE_URL_FILE_ID_MISMATCH);
                 throw Error(CustomError.UPDATE_URL_FILE_ID_MISMATCH);
@@ -204,7 +203,7 @@ const PhotoFrame = ({
         const file = displayFiles[index];
         const file = displayFiles[index];
         // this is to prevent outdate updateSrcURL call from updating the wrong file
         // this is to prevent outdate updateSrcURL call from updating the wrong file
         if (file.id !== id) {
         if (file.id !== id) {
-            addLogLine(
+            log.info(
                 `[${id}]PhotoSwipe: updateSrcURL: file id mismatch: ${file.id}`,
                 `[${id}]PhotoSwipe: updateSrcURL: file id mismatch: ${file.id}`,
             );
             );
             throw Error(CustomError.UPDATE_URL_FILE_ID_MISMATCH);
             throw Error(CustomError.UPDATE_URL_FILE_ID_MISMATCH);
@@ -212,7 +211,7 @@ const PhotoFrame = ({
         if (file.isSourceLoaded && !forceUpdate) {
         if (file.isSourceLoaded && !forceUpdate) {
             throw Error(CustomError.URL_ALREADY_SET);
             throw Error(CustomError.URL_ALREADY_SET);
         } else if (file.conversionFailed) {
         } else if (file.conversionFailed) {
-            addLogLine(`[${id}]PhotoSwipe: updateSrcURL: conversion failed`);
+            log.info(`[${id}]PhotoSwipe: updateSrcURL: conversion failed`);
             throw Error(CustomError.FILE_CONVERSION_FAILED);
             throw Error(CustomError.FILE_CONVERSION_FAILED);
         }
         }
 
 
@@ -308,7 +307,7 @@ const PhotoFrame = ({
         index: number,
         index: number,
         item: EnteFile,
         item: EnteFile,
     ) => {
     ) => {
-        addLogLine(
+        log.info(
             `[${
             `[${
                 item.id
                 item.id
             }] getSlideData called for thumbnail:${!!item.msrc} sourceLoaded:${
             }] getSlideData called for thumbnail:${!!item.msrc} sourceLoaded:${
@@ -319,17 +318,15 @@ const PhotoFrame = ({
         if (!item.msrc) {
         if (!item.msrc) {
             try {
             try {
                 if (thumbFetching[item.id]) {
                 if (thumbFetching[item.id]) {
-                    addLogLine(
-                        `[${item.id}] thumb download already in progress`,
-                    );
+                    log.info(`[${item.id}] thumb download already in progress`);
                     return;
                     return;
                 }
                 }
-                addLogLine(`[${item.id}] doesn't have thumbnail`);
+                log.info(`[${item.id}] doesn't have thumbnail`);
                 thumbFetching[item.id] = true;
                 thumbFetching[item.id] = true;
                 const url = await DownloadManager.getThumbnailForPreview(item);
                 const url = await DownloadManager.getThumbnailForPreview(item);
                 try {
                 try {
                     updateURL(index)(item.id, url);
                     updateURL(index)(item.id, url);
-                    addLogLine(
+                    log.info(
                         `[${
                         `[${
                             item.id
                             item.id
                         }] calling invalidateCurrItems for thumbnail msrc :${!!item.msrc}`,
                         }] calling invalidateCurrItems for thumbnail msrc :${!!item.msrc}`,
@@ -340,35 +337,35 @@ const PhotoFrame = ({
                     }
                     }
                 } catch (e) {
                 } catch (e) {
                     if (e.message !== CustomError.URL_ALREADY_SET) {
                     if (e.message !== CustomError.URL_ALREADY_SET) {
-                        logError(
-                            e,
+                        log.error(
                             "updating photoswipe after msrc url update failed",
                             "updating photoswipe after msrc url update failed",
+                            e,
                         );
                         );
                     }
                     }
                     // ignore
                     // ignore
                 }
                 }
             } catch (e) {
             } catch (e) {
-                logError(e, "getSlideData failed get msrc url failed");
+                log.error("getSlideData failed get msrc url failed", e);
                 thumbFetching[item.id] = false;
                 thumbFetching[item.id] = false;
             }
             }
         }
         }
 
 
         if (item.isSourceLoaded || item.conversionFailed) {
         if (item.isSourceLoaded || item.conversionFailed) {
             if (item.isSourceLoaded) {
             if (item.isSourceLoaded) {
-                addLogLine(`[${item.id}] source already loaded`);
+                log.info(`[${item.id}] source already loaded`);
             }
             }
             if (item.conversionFailed) {
             if (item.conversionFailed) {
-                addLogLine(`[${item.id}] conversion failed`);
+                log.info(`[${item.id}] conversion failed`);
             }
             }
             return;
             return;
         }
         }
         if (fetching[item.id]) {
         if (fetching[item.id]) {
-            addLogLine(`[${item.id}] file download already in progress`);
+            log.info(`[${item.id}] file download already in progress`);
             return;
             return;
         }
         }
 
 
         try {
         try {
-            addLogLine(`[${item.id}] new file src request`);
+            log.info(`[${item.id}] new file src request`);
             fetching[item.id] = true;
             fetching[item.id] = true;
             const srcURLs = await DownloadManager.getFileForPreview(item);
             const srcURLs = await DownloadManager.getFileForPreview(item);
             if (item.metadata.fileType === FILE_TYPE.LIVE_PHOTO) {
             if (item.metadata.fileType === FILE_TYPE.LIVE_PHOTO) {
@@ -383,7 +380,7 @@ const PhotoFrame = ({
                 };
                 };
                 try {
                 try {
                     await updateSrcURL(index, item.id, dummyImgSrcUrl);
                     await updateSrcURL(index, item.id, dummyImgSrcUrl);
-                    addLogLine(
+                    log.info(
                         `[${item.id}] calling invalidateCurrItems for live photo imgSrc, source loaded :${item.isSourceLoaded}`,
                         `[${item.id}] calling invalidateCurrItems for live photo imgSrc, source loaded :${item.isSourceLoaded}`,
                     );
                     );
                     instance.invalidateCurrItems();
                     instance.invalidateCurrItems();
@@ -392,9 +389,9 @@ const PhotoFrame = ({
                     }
                     }
                 } catch (e) {
                 } catch (e) {
                     if (e.message !== CustomError.URL_ALREADY_SET) {
                     if (e.message !== CustomError.URL_ALREADY_SET) {
-                        logError(
-                            e,
+                        log.error(
                             "updating photoswipe after for live photo imgSrc update failed",
                             "updating photoswipe after for live photo imgSrc update failed",
+                            e,
                         );
                         );
                     }
                     }
                 }
                 }
@@ -417,7 +414,7 @@ const PhotoFrame = ({
                         loadedLivePhotoSrcURL,
                         loadedLivePhotoSrcURL,
                         true,
                         true,
                     );
                     );
-                    addLogLine(
+                    log.info(
                         `[${item.id}] calling invalidateCurrItems for live photo complete, source loaded :${item.isSourceLoaded}`,
                         `[${item.id}] calling invalidateCurrItems for live photo complete, source loaded :${item.isSourceLoaded}`,
                     );
                     );
                     instance.invalidateCurrItems();
                     instance.invalidateCurrItems();
@@ -426,16 +423,16 @@ const PhotoFrame = ({
                     }
                     }
                 } catch (e) {
                 } catch (e) {
                     if (e.message !== CustomError.URL_ALREADY_SET) {
                     if (e.message !== CustomError.URL_ALREADY_SET) {
-                        logError(
-                            e,
+                        log.error(
                             "updating photoswipe for live photo complete update failed",
                             "updating photoswipe for live photo complete update failed",
+                            e,
                         );
                         );
                     }
                     }
                 }
                 }
             } else {
             } else {
                 try {
                 try {
                     await updateSrcURL(index, item.id, srcURLs);
                     await updateSrcURL(index, item.id, srcURLs);
-                    addLogLine(
+                    log.info(
                         `[${item.id}] calling invalidateCurrItems for src, source loaded :${item.isSourceLoaded}`,
                         `[${item.id}] calling invalidateCurrItems for src, source loaded :${item.isSourceLoaded}`,
                     );
                     );
                     instance.invalidateCurrItems();
                     instance.invalidateCurrItems();
@@ -444,15 +441,15 @@ const PhotoFrame = ({
                     }
                     }
                 } catch (e) {
                 } catch (e) {
                     if (e.message !== CustomError.URL_ALREADY_SET) {
                     if (e.message !== CustomError.URL_ALREADY_SET) {
-                        logError(
-                            e,
+                        log.error(
                             "updating photoswipe after src url update failed",
                             "updating photoswipe after src url update failed",
+                            e,
                         );
                         );
                     }
                     }
                 }
                 }
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "getSlideData failed get src url failed");
+            log.error("getSlideData failed get src url failed", e);
             fetching[item.id] = false;
             fetching[item.id] = false;
             // no-op
             // no-op
         }
         }
@@ -467,22 +464,18 @@ const PhotoFrame = ({
             item.metadata.fileType !== FILE_TYPE.VIDEO &&
             item.metadata.fileType !== FILE_TYPE.VIDEO &&
             item.metadata.fileType !== FILE_TYPE.LIVE_PHOTO
             item.metadata.fileType !== FILE_TYPE.LIVE_PHOTO
         ) {
         ) {
-            logError(
-                new Error(),
-                "getConvertedVideo called for non video file",
-            );
+            log.error("getConvertedVideo called for non video file");
             return;
             return;
         }
         }
         if (item.conversionFailed) {
         if (item.conversionFailed) {
-            logError(
-                new Error(),
+            log.error(
                 "getConvertedVideo called for file that conversion failed",
                 "getConvertedVideo called for file that conversion failed",
             );
             );
             return;
             return;
         }
         }
         try {
         try {
             updateURL(index)(item.id, item.msrc, true);
             updateURL(index)(item.id, item.msrc, true);
-            addLogLine(
+            log.info(
                 `[${
                 `[${
                     item.id
                     item.id
                 }] calling invalidateCurrItems for thumbnail msrc :${!!item.msrc}`,
                 }] calling invalidateCurrItems for thumbnail msrc :${!!item.msrc}`,
@@ -493,12 +486,15 @@ const PhotoFrame = ({
             }
             }
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.URL_ALREADY_SET) {
             if (e.message !== CustomError.URL_ALREADY_SET) {
-                logError(e, "updating photoswipe after msrc url update failed");
+                log.error(
+                    "updating photoswipe after msrc url update failed",
+                    e,
+                );
             }
             }
             // ignore
             // ignore
         }
         }
         try {
         try {
-            addLogLine(
+            log.info(
                 `[${item.id}] new file getConvertedVideo request- ${item.metadata.title}}`,
                 `[${item.id}] new file getConvertedVideo request- ${item.metadata.title}}`,
             );
             );
             fetching[item.id] = true;
             fetching[item.id] = true;
@@ -507,7 +503,7 @@ const PhotoFrame = ({
 
 
             try {
             try {
                 await updateSrcURL(index, item.id, srcURL, true);
                 await updateSrcURL(index, item.id, srcURL, true);
-                addLogLine(
+                log.info(
                     `[${item.id}] calling invalidateCurrItems for src, source loaded :${item.isSourceLoaded}`,
                     `[${item.id}] calling invalidateCurrItems for src, source loaded :${item.isSourceLoaded}`,
                 );
                 );
                 instance.invalidateCurrItems();
                 instance.invalidateCurrItems();
@@ -516,15 +512,15 @@ const PhotoFrame = ({
                 }
                 }
             } catch (e) {
             } catch (e) {
                 if (e.message !== CustomError.URL_ALREADY_SET) {
                 if (e.message !== CustomError.URL_ALREADY_SET) {
-                    logError(
-                        e,
+                    log.error(
                         "updating photoswipe after src url update failed",
                         "updating photoswipe after src url update failed",
+                        e,
                     );
                     );
                 }
                 }
                 throw e;
                 throw e;
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "getConvertedVideo failed get src url failed");
+            log.error("getConvertedVideo failed get src url failed", e);
             fetching[item.id] = false;
             fetching[item.id] = false;
             // no-op
             // no-op
         }
         }

+ 2 - 2
web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCaption.tsx

@@ -1,5 +1,5 @@
+import log from "@/next/log";
 import { FlexWrapper } from "@ente/shared/components/Container";
 import { FlexWrapper } from "@ente/shared/components/Container";
-import { logError } from "@ente/shared/sentry";
 import Close from "@mui/icons-material/Close";
 import Close from "@mui/icons-material/Close";
 import Done from "@mui/icons-material/Done";
 import Done from "@mui/icons-material/Done";
 import { Box, IconButton, TextField } from "@mui/material";
 import { Box, IconButton, TextField } from "@mui/material";
@@ -48,7 +48,7 @@ export function RenderCaption({
                 scheduleUpdate();
                 scheduleUpdate();
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to update caption");
+            log.error("failed to update caption", e);
         }
         }
     };
     };
 
 

+ 2 - 2
web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCreationTime.tsx

@@ -1,5 +1,5 @@
+import log from "@/next/log";
 import { FlexWrapper } from "@ente/shared/components/Container";
 import { FlexWrapper } from "@ente/shared/components/Container";
-import { logError } from "@ente/shared/sentry";
 import { formatDate, formatTime } from "@ente/shared/time/format";
 import { formatDate, formatTime } from "@ente/shared/time/format";
 import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
 import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
 import EnteDateTimePicker from "components/EnteDateTimePicker";
 import EnteDateTimePicker from "components/EnteDateTimePicker";
@@ -44,7 +44,7 @@ export function RenderCreationTime({
                 scheduleUpdate();
                 scheduleUpdate();
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to update creationTime");
+            log.error("failed to update creationTime", e);
         } finally {
         } finally {
             closeEditMode();
             closeEditMode();
             setLoading(false);
             setLoading(false);

+ 2 - 2
web/apps/photos/src/components/PhotoViewer/FileInfo/RenderFileName.tsx

@@ -1,5 +1,5 @@
+import log from "@/next/log";
 import { FlexWrapper } from "@ente/shared/components/Container";
 import { FlexWrapper } from "@ente/shared/components/Container";
-import { logError } from "@ente/shared/sentry";
 import PhotoOutlined from "@mui/icons-material/PhotoOutlined";
 import PhotoOutlined from "@mui/icons-material/PhotoOutlined";
 import VideocamOutlined from "@mui/icons-material/VideocamOutlined";
 import VideocamOutlined from "@mui/icons-material/VideocamOutlined";
 import Box from "@mui/material/Box";
 import Box from "@mui/material/Box";
@@ -86,7 +86,7 @@ export function RenderFileName({
                 scheduleUpdate();
                 scheduleUpdate();
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to update file name");
+            log.error("failed to update file name", e);
             throw e;
             throw e;
         }
         }
     };
     };

+ 10 - 11
web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/TransformMenu.tsx

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import Crop169Icon from "@mui/icons-material/Crop169";
 import Crop169Icon from "@mui/icons-material/Crop169";
 import Crop32Icon from "@mui/icons-material/Crop32";
 import Crop32Icon from "@mui/icons-material/Crop32";
 import CropSquareIcon from "@mui/icons-material/CropSquare";
 import CropSquareIcon from "@mui/icons-material/CropSquare";
@@ -172,10 +172,13 @@ const TransformMenu = () => {
                 setCanvasLoading(false);
                 setCanvasLoading(false);
                 setTransformationPerformed(true);
                 setTransformationPerformed(true);
             } catch (e) {
             } catch (e) {
-                logError(e, "crop handler failed", {
-                    widthRatio,
-                    heightRatio,
-                });
+                log.error(
+                    `crop handler failed - ${JSON.stringify({
+                        widthRatio,
+                        heightRatio,
+                    })}`,
+                    e,
+                );
             }
             }
         };
         };
     const createRotationHandler = (rotation: "left" | "right") => () => {
     const createRotationHandler = (rotation: "left" | "right") => () => {
@@ -189,9 +192,7 @@ const TransformMenu = () => {
             setCanvasLoading(false);
             setCanvasLoading(false);
             setTransformationPerformed(true);
             setTransformationPerformed(true);
         } catch (e) {
         } catch (e) {
-            logError(e, "rotation handler failed", {
-                rotation,
-            });
+            log.error(`rotation handler (${rotation}) failed`, e);
         }
         }
     };
     };
 
 
@@ -204,9 +205,7 @@ const TransformMenu = () => {
                 setCanvasLoading(false);
                 setCanvasLoading(false);
                 setTransformationPerformed(true);
                 setTransformationPerformed(true);
             } catch (e) {
             } catch (e) {
-                logError(e, "flip handler failed", {
-                    direction,
-                });
+                log.error(`flip handler ${direction} failed`, e);
             }
             }
         };
         };
 
 

+ 7 - 7
web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx

@@ -1,3 +1,4 @@
+import log from "@/next/log";
 import {
 import {
     Backdrop,
     Backdrop,
     Box,
     Box,
@@ -23,7 +24,6 @@ import {
     HorizontalFlex,
     HorizontalFlex,
 } from "@ente/shared/components/Container";
 } from "@ente/shared/components/Container";
 import EnteButton from "@ente/shared/components/EnteButton";
 import EnteButton from "@ente/shared/components/EnteButton";
-import { logError } from "@ente/shared/sentry";
 import { downloadUsingAnchor } from "@ente/shared/utils";
 import { downloadUsingAnchor } from "@ente/shared/utils";
 import ChevronRightIcon from "@mui/icons-material/ChevronRight";
 import ChevronRightIcon from "@mui/icons-material/ChevronRight";
 import CloseIcon from "@mui/icons-material/Close";
 import CloseIcon from "@mui/icons-material/Close";
@@ -275,7 +275,7 @@ const ImageEditorOverlay = (props: IProps) => {
                     invert !== FILTER_DEFAULT_VALUES.invert,
                     invert !== FILTER_DEFAULT_VALUES.invert,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "Error applying filters");
+            log.error("Error applying filters", e);
         }
         }
     }, [brightness, contrast, blur, saturation, invert, canvasRef, fileURL]);
     }, [brightness, contrast, blur, saturation, invert, canvasRef, fileURL]);
 
 
@@ -329,7 +329,7 @@ const ImageEditorOverlay = (props: IProps) => {
                 });
                 });
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "Error applying filters");
+            log.error("Error applying filters", e);
             throw e;
             throw e;
         }
         }
     };
     };
@@ -422,7 +422,7 @@ const ImageEditorOverlay = (props: IProps) => {
                 };
                 };
             });
             });
         } catch (e) {
         } catch (e) {
-            logError(e, "Error loading canvas");
+            log.error("Error loading canvas", e);
         }
         }
     };
     };
 
 
@@ -447,7 +447,7 @@ const ImageEditorOverlay = (props: IProps) => {
                 canvas.toBlob(resolve, mimeType);
                 canvas.toBlob(resolve, mimeType);
             });
             });
         } catch (e) {
         } catch (e) {
-            logError(e, "Error exporting canvas to blob");
+            log.error("Error exporting canvas to blob", e);
             throw e;
             throw e;
         }
         }
     };
     };
@@ -492,7 +492,7 @@ const ImageEditorOverlay = (props: IProps) => {
             );
             );
             downloadUsingAnchor(tempImgURL, editedFile.name);
             downloadUsingAnchor(tempImgURL, editedFile.name);
         } catch (e) {
         } catch (e) {
-            logError(e, "Error downloading edited photo");
+            log.error("Error downloading edited photo", e);
         }
         }
     };
     };
 
 
@@ -520,7 +520,7 @@ const ImageEditorOverlay = (props: IProps) => {
             props.onClose();
             props.onClose();
             props.closePhotoViewer();
             props.closePhotoViewer();
         } catch (e) {
         } catch (e) {
-            logError(e, "Error saving copy to ente");
+            log.error("Error saving copy to ente", e);
         }
         }
     };
     };
     return (
     return (

+ 9 - 9
web/apps/photos/src/components/PhotoViewer/index.tsx

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import Photoswipe from "photoswipe";
 import Photoswipe from "photoswipe";
 import PhotoswipeUIDefault from "photoswipe/dist/photoswipe-ui-default";
 import PhotoswipeUIDefault from "photoswipe/dist/photoswipe-ui-default";
 import { useContext, useEffect, useMemo, useRef, useState } from "react";
 import { useContext, useEffect, useMemo, useRef, useState } from "react";
@@ -16,7 +16,6 @@ import {
     isSupportedRawFormat,
     isSupportedRawFormat,
 } from "utils/file";
 } from "utils/file";
 
 
-import log from "@/next/log";
 import { FlexWrapper } from "@ente/shared/components/Container";
 import { FlexWrapper } from "@ente/shared/components/Container";
 import EnteSpinner from "@ente/shared/components/EnteSpinner";
 import EnteSpinner from "@ente/shared/components/EnteSpinner";
 import AlbumOutlined from "@mui/icons-material/AlbumOutlined";
 import AlbumOutlined from "@mui/icons-material/AlbumOutlined";
@@ -496,7 +495,7 @@ function PhotoViewer(props: Iprops) {
             }
             }
             needUpdate.current = true;
             needUpdate.current = true;
         } catch (e) {
         } catch (e) {
-            logError(e, "onFavClick failed");
+            log.error("onFavClick failed", e);
         }
         }
     };
     };
 
 
@@ -511,7 +510,7 @@ function PhotoViewer(props: Iprops) {
             updateItems(props.items.filter((item) => item.id !== file.id));
             updateItems(props.items.filter((item) => item.id !== file.id));
             needUpdate.current = true;
             needUpdate.current = true;
         } catch (e) {
         } catch (e) {
-            logError(e, "trashFile failed");
+            log.error("trashFile failed", e);
         }
         }
     };
     };
 
 
@@ -562,7 +561,7 @@ function PhotoViewer(props: Iprops) {
                 }
                 }
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "updateItems failed");
+            log.error("updateItems failed", e);
         }
         }
     };
     };
 
 
@@ -573,7 +572,7 @@ function PhotoViewer(props: Iprops) {
                 photoSwipe.updateSize(true);
                 photoSwipe.updateSize(true);
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "refreshPhotoswipe failed");
+            log.error("refreshPhotoswipe failed", e);
         }
         }
     };
     };
 
 
@@ -613,9 +612,10 @@ function PhotoViewer(props: Iprops) {
         } catch (e) {
         } catch (e) {
             setExif({ key: file.src, value: null });
             setExif({ key: file.src, value: null });
             const fileExtension = getFileExtension(file.metadata.title);
             const fileExtension = getFileExtension(file.metadata.title);
-            logError(e, "checkExifAvailable failed", {
-                extension: fileExtension,
-            });
+            log.error(
+                `checkExifAvailable failed for extension ${fileExtension}`,
+                e,
+            );
         }
         }
     };
     };
 
 

+ 1 - 1
web/apps/photos/src/components/Search/SearchBar/searchInput/MenuWithPeople.tsx

@@ -25,7 +25,7 @@ const Caption = styled("span")`
 
 
 const MenuWithPeople = (props) => {
 const MenuWithPeople = (props) => {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);
-    // addLogLine("props.selectProps.options: ", selectRef);
+    // log.info("props.selectProps.options: ", selectRef);
     const peopleSuggestions = props.selectProps.options.filter(
     const peopleSuggestions = props.selectProps.options.filter(
         (o) => o.type === SuggestionType.PERSON,
         (o) => o.type === SuggestionType.PERSON,
     );
     );

+ 2 - 2
web/apps/photos/src/components/Sidebar/AdvancedSettings.tsx

@@ -1,3 +1,4 @@
+import log from "@/next/log";
 import ChevronRight from "@mui/icons-material/ChevronRight";
 import ChevronRight from "@mui/icons-material/ChevronRight";
 import ScienceIcon from "@mui/icons-material/Science";
 import ScienceIcon from "@mui/icons-material/Science";
 import { Box, DialogProps, Stack, Typography } from "@mui/material";
 import { Box, DialogProps, Stack, Typography } from "@mui/material";
@@ -9,7 +10,6 @@ import { t } from "i18next";
 import { useContext, useEffect, useState } from "react";
 import { useContext, useEffect, useState } from "react";
 
 
 import { VerticallyCenteredFlex } from "@ente/shared/components/Container";
 import { VerticallyCenteredFlex } from "@ente/shared/components/Container";
-import { logError } from "@ente/shared/sentry";
 import { EnteMenuItem } from "components/Menu/EnteMenuItem";
 import { EnteMenuItem } from "components/Menu/EnteMenuItem";
 import { MenuItemGroup } from "components/Menu/MenuItemGroup";
 import { MenuItemGroup } from "components/Menu/MenuItemGroup";
 import isElectron from "is-electron";
 import isElectron from "is-electron";
@@ -41,7 +41,7 @@ export default function AdvancedSettings({ open, onClose, onRootClose }) {
         try {
         try {
             appContext.setIsCFProxyDisabled(!appContext.isCFProxyDisabled);
             appContext.setIsCFProxyDisabled(!appContext.isCFProxyDisabled);
         } catch (e) {
         } catch (e) {
-            logError(e, "toggleFasterUpload failed");
+            log.error("toggleFasterUpload failed", e);
         }
         }
     };
     };
     const [indexingStatus, setIndexingStatus] = useState<ClipExtractionStatus>({
     const [indexingStatus, setIndexingStatus] = useState<ClipExtractionStatus>({

+ 11 - 18
web/apps/photos/src/components/Sidebar/DebugSection.tsx

@@ -1,15 +1,12 @@
-import { t } from "i18next";
-import { AppContext } from "pages/_app";
-import { useContext, useEffect, useState } from "react";
-import { Trans } from "react-i18next";
-
-import ElectronAPIs from "@/next/electron";
+import log from "@/next/log";
 import { savedLogs } from "@/next/log-web";
 import { savedLogs } from "@/next/log-web";
-import { addLogLine } from "@ente/shared/logging";
 import { downloadAsFile } from "@ente/shared/utils";
 import { downloadAsFile } from "@ente/shared/utils";
 import Typography from "@mui/material/Typography";
 import Typography from "@mui/material/Typography";
 import { EnteMenuItem } from "components/Menu/EnteMenuItem";
 import { EnteMenuItem } from "components/Menu/EnteMenuItem";
-import isElectron from "is-electron";
+import { t } from "i18next";
+import { AppContext } from "pages/_app";
+import { useContext, useEffect, useState } from "react";
+import { Trans } from "react-i18next";
 import { isInternalUser } from "utils/user";
 import { isInternalUser } from "utils/user";
 import { testUpload } from "../../../tests/upload.test";
 import { testUpload } from "../../../tests/upload.test";
 import {
 import {
@@ -19,16 +16,12 @@ import {
 
 
 export default function DebugSection() {
 export default function DebugSection() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);
-    const [appVersion, setAppVersion] = useState<string>(null);
+    const [appVersion, setAppVersion] = useState<string | undefined>();
+
+    const electron = globalThis.electron;
 
 
     useEffect(() => {
     useEffect(() => {
-        const main = async () => {
-            if (isElectron()) {
-                const appVersion = await ElectronAPIs.appVersion();
-                setAppVersion(appVersion);
-            }
-        };
-        main();
+        electron?.appVersion().then((v) => setAppVersion(v));
     });
     });
 
 
     const confirmLogDownload = () =>
     const confirmLogDownload = () =>
@@ -46,8 +39,8 @@ export default function DebugSection() {
         });
         });
 
 
     const downloadLogs = () => {
     const downloadLogs = () => {
-        addLogLine("Downloading logs");
-        if (isElectron()) ElectronAPIs.openLogDirectory();
+        log.info("Downloading logs");
+        if (electron) electron.openLogDirectory();
         else downloadAsFile(`debug_logs_${Date.now()}.txt`, savedLogs());
         else downloadAsFile(`debug_logs_${Date.now()}.txt`, savedLogs());
     };
     };
 
 

+ 3 - 3
web/apps/photos/src/components/Sidebar/MapSetting/ModifyMapEnabled.tsx

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { Box, DialogProps } from "@mui/material";
 import { Box, DialogProps } from "@mui/material";
 import { EnteDrawer } from "components/EnteDrawer";
 import { EnteDrawer } from "components/EnteDrawer";
 import { AppContext } from "pages/_app";
 import { AppContext } from "pages/_app";
@@ -14,7 +14,7 @@ const ModifyMapEnabled = ({ open, onClose, onRootClose, mapEnabled }) => {
             await updateMapEnabled(false);
             await updateMapEnabled(false);
             onClose();
             onClose();
         } catch (e) {
         } catch (e) {
-            logError(e, "Disable Map failed");
+            log.error("Disable Map failed", e);
             somethingWentWrong();
             somethingWentWrong();
         }
         }
     };
     };
@@ -24,7 +24,7 @@ const ModifyMapEnabled = ({ open, onClose, onRootClose, mapEnabled }) => {
             await updateMapEnabled(true);
             await updateMapEnabled(true);
             onClose();
             onClose();
         } catch (e) {
         } catch (e) {
-            logError(e, "Enable Map failed");
+            log.error("Enable Map failed", e);
             somethingWentWrong();
             somethingWentWrong();
         }
         }
     };
     };

+ 2 - 2
web/apps/photos/src/components/Sidebar/UtilitySection.tsx

@@ -1,3 +1,4 @@
+import log from "@/next/log";
 import RecoveryKey from "@ente/shared/components/RecoveryKey";
 import RecoveryKey from "@ente/shared/components/RecoveryKey";
 import {
 import {
     ACCOUNTS_PAGES,
     ACCOUNTS_PAGES,
@@ -21,7 +22,6 @@ import {
     generateEncryptionKey,
     generateEncryptionKey,
 } from "@ente/shared/crypto/internal/libsodium";
 } from "@ente/shared/crypto/internal/libsodium";
 import { getAccountsURL } from "@ente/shared/network/api";
 import { getAccountsURL } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import { THEME_COLOR } from "@ente/shared/themes/constants";
 import { THEME_COLOR } from "@ente/shared/themes/constants";
 import { EnteMenuItem } from "components/Menu/EnteMenuItem";
 import { EnteMenuItem } from "components/Menu/EnteMenuItem";
 import WatchFolder from "components/WatchFolder";
 import WatchFolder from "components/WatchFolder";
@@ -109,7 +109,7 @@ export default function UtilitySection({ closeSidebar }) {
                 )}&token=${accountsToken}`,
                 )}&token=${accountsToken}`,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to redirect to accounts page");
+            log.error("failed to redirect to accounts page", e);
         }
         }
     };
     };
 
 

+ 51 - 49
web/apps/photos/src/components/Upload/Uploader.tsx

@@ -1,7 +1,6 @@
-import ElectronAPIs from "@/next/electron";
+import log from "@/next/log";
+import type { Electron } from "@/next/types/ipc";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
 import { isPromise } from "@ente/shared/utils";
 import { isPromise } from "@ente/shared/utils";
 import DiscFullIcon from "@mui/icons-material/DiscFull";
 import DiscFullIcon from "@mui/icons-material/DiscFull";
 import UserNameInputDialog from "components/UserNameInputDialog";
 import UserNameInputDialog from "components/UserNameInputDialog";
@@ -133,6 +132,8 @@ export default function Uploader(props: Props) {
     const uploaderNameRef = useRef<string>(null);
     const uploaderNameRef = useRef<string>(null);
     const isDragAndDrop = useRef(false);
     const isDragAndDrop = useRef(false);
 
 
+    const electron = globalThis.electron;
+
     const closeUploadProgress = () => setUploadProgressView(false);
     const closeUploadProgress = () => setUploadProgressView(false);
     const showUserNameInputDialog = () => setUserNameInputDialogView(true);
     const showUserNameInputDialog = () => setUserNameInputDialogView(true);
 
 
@@ -178,9 +179,7 @@ export default function Uploader(props: Props) {
         if (isElectron()) {
         if (isElectron()) {
             ImportService.getPendingUploads().then(
             ImportService.getPendingUploads().then(
                 ({ files: electronFiles, collectionName, type }) => {
                 ({ files: electronFiles, collectionName, type }) => {
-                    addLogLine(
-                        `found pending desktop upload, resuming uploads`,
-                    );
+                    log.info(`found pending desktop upload, resuming uploads`);
                     resumeDesktopUpload(type, electronFiles, collectionName);
                     resumeDesktopUpload(type, electronFiles, collectionName);
                 },
                 },
             );
             );
@@ -211,29 +210,29 @@ export default function Uploader(props: Props) {
             pickedUploadType.current === PICKED_UPLOAD_TYPE.FOLDERS &&
             pickedUploadType.current === PICKED_UPLOAD_TYPE.FOLDERS &&
             props.webFolderSelectorFiles?.length > 0
             props.webFolderSelectorFiles?.length > 0
         ) {
         ) {
-            addLogLine(`received folder upload request`);
+            log.info(`received folder upload request`);
             setWebFiles(props.webFolderSelectorFiles);
             setWebFiles(props.webFolderSelectorFiles);
         } else if (
         } else if (
             pickedUploadType.current === PICKED_UPLOAD_TYPE.FILES &&
             pickedUploadType.current === PICKED_UPLOAD_TYPE.FILES &&
             props.webFileSelectorFiles?.length > 0
             props.webFileSelectorFiles?.length > 0
         ) {
         ) {
-            addLogLine(`received file upload request`);
+            log.info(`received file upload request`);
             setWebFiles(props.webFileSelectorFiles);
             setWebFiles(props.webFileSelectorFiles);
         } else if (props.dragAndDropFiles?.length > 0) {
         } else if (props.dragAndDropFiles?.length > 0) {
             isDragAndDrop.current = true;
             isDragAndDrop.current = true;
-            if (isElectron()) {
+            if (electron) {
                 const main = async () => {
                 const main = async () => {
                     try {
                     try {
-                        addLogLine(`uploading dropped files from desktop app`);
+                        log.info(`uploading dropped files from desktop app`);
                         // check and parse dropped files which are zip files
                         // check and parse dropped files which are zip files
                         let electronFiles = [] as ElectronFile[];
                         let electronFiles = [] as ElectronFile[];
                         for (const file of props.dragAndDropFiles) {
                         for (const file of props.dragAndDropFiles) {
                             if (file.name.endsWith(".zip")) {
                             if (file.name.endsWith(".zip")) {
                                 const zipFiles =
                                 const zipFiles =
-                                    await ElectronAPIs.getElectronFilesFromGoogleZip(
+                                    await electron.getElectronFilesFromGoogleZip(
                                         (file as any).path,
                                         (file as any).path,
                                     );
                                     );
-                                addLogLine(
+                                log.info(
                                     `zip file - ${file.name} contains ${zipFiles.length} files`,
                                     `zip file - ${file.name} contains ${zipFiles.length} files`,
                                 );
                                 );
                                 electronFiles = [...electronFiles, ...zipFiles];
                                 electronFiles = [...electronFiles, ...zipFiles];
@@ -251,18 +250,18 @@ export default function Uploader(props: Props) {
                                 );
                                 );
                             }
                             }
                         }
                         }
-                        addLogLine(
+                        log.info(
                             `uploading dropped files from desktop app - ${electronFiles.length} files found`,
                             `uploading dropped files from desktop app - ${electronFiles.length} files found`,
                         );
                         );
                         setElectronFiles(electronFiles);
                         setElectronFiles(electronFiles);
                     } catch (e) {
                     } catch (e) {
-                        logError(e, "failed to upload desktop dropped files");
+                        log.error("failed to upload desktop dropped files", e);
                         setWebFiles(props.dragAndDropFiles);
                         setWebFiles(props.dragAndDropFiles);
                     }
                     }
                 };
                 };
                 main();
                 main();
             } else {
             } else {
-                addLogLine(`uploading dropped files from web app`);
+                log.info(`uploading dropped files from web app`);
                 setWebFiles(props.dragAndDropFiles);
                 setWebFiles(props.dragAndDropFiles);
             }
             }
         }
         }
@@ -278,7 +277,7 @@ export default function Uploader(props: Props) {
             webFiles?.length > 0 ||
             webFiles?.length > 0 ||
             appContext.sharedFiles?.length > 0
             appContext.sharedFiles?.length > 0
         ) {
         ) {
-            addLogLine(
+            log.info(
                 `upload request type:${
                 `upload request type:${
                     electronFiles?.length > 0
                     electronFiles?.length > 0
                         ? "electronFiles"
                         ? "electronFiles"
@@ -293,13 +292,13 @@ export default function Uploader(props: Props) {
             );
             );
             if (uploadManager.isUploadRunning()) {
             if (uploadManager.isUploadRunning()) {
                 if (watchFolderService.isUploadRunning()) {
                 if (watchFolderService.isUploadRunning()) {
-                    addLogLine(
+                    log.info(
                         "watchFolder upload was running, pausing it to run user upload",
                         "watchFolder upload was running, pausing it to run user upload",
                     );
                     );
                     // pause watch folder service on user upload
                     // pause watch folder service on user upload
                     watchFolderService.pauseRunningSync();
                     watchFolderService.pauseRunningSync();
                 } else {
                 } else {
-                    addLogLine(
+                    log.info(
                         "an upload is already running, rejecting new upload request",
                         "an upload is already running, rejecting new upload request",
                     );
                     );
                     // no-op
                     // no-op
@@ -371,7 +370,7 @@ export default function Uploader(props: Props) {
         uploaderName?: string,
         uploaderName?: string,
     ) => {
     ) => {
         try {
         try {
-            addLogLine(
+            log.info(
                 `upload file to an existing collection name:${collection.name}, collectionID:${collection.id}`,
                 `upload file to an existing collection name:${collection.name}, collectionID:${collection.id}`,
             );
             );
             await preCollectionCreationAction();
             await preCollectionCreationAction();
@@ -387,7 +386,7 @@ export default function Uploader(props: Props) {
                 uploaderName,
                 uploaderName,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed to upload files to existing collections");
+            log.error("Failed to upload files to existing collections", e);
         }
         }
     };
     };
 
 
@@ -396,7 +395,7 @@ export default function Uploader(props: Props) {
         collectionName?: string,
         collectionName?: string,
     ) => {
     ) => {
         try {
         try {
-            addLogLine(
+            log.info(
                 `upload file to an new collections strategy:${strategy} ,collectionName:${collectionName}`,
                 `upload file to an new collections strategy:${strategy} ,collectionName:${collectionName}`,
             );
             );
             await preCollectionCreationAction();
             await preCollectionCreationAction();
@@ -416,7 +415,7 @@ export default function Uploader(props: Props) {
                     toUploadFiles.current,
                     toUploadFiles.current,
                 );
                 );
             }
             }
-            addLogLine(
+            log.info(
                 `upload collections - [${[...collectionNameToFilesMap.keys()]}]`,
                 `upload collections - [${[...collectionNameToFilesMap.keys()]}]`,
             );
             );
             try {
             try {
@@ -446,7 +445,7 @@ export default function Uploader(props: Props) {
                 }
                 }
             } catch (e) {
             } catch (e) {
                 closeUploadProgress();
                 closeUploadProgress();
-                logError(e, "Failed to create album");
+                log.error("Failed to create album", e);
                 appContext.setDialogMessage({
                 appContext.setDialogMessage({
                     title: t("ERROR"),
                     title: t("ERROR"),
 
 
@@ -461,7 +460,7 @@ export default function Uploader(props: Props) {
             );
             );
             toUploadFiles.current = null;
             toUploadFiles.current = null;
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed to upload files to new collections");
+            log.error("Failed to upload files to new collections", e);
         }
         }
     };
     };
 
 
@@ -501,22 +500,22 @@ export default function Uploader(props: Props) {
         uploaderName?: string,
         uploaderName?: string,
     ) => {
     ) => {
         try {
         try {
-            addLogLine("uploadFiles called");
+            log.info("uploadFiles called");
             preUploadAction();
             preUploadAction();
             if (
             if (
-                isElectron() &&
+                electron &&
                 !isPendingDesktopUpload.current &&
                 !isPendingDesktopUpload.current &&
                 !watchFolderService.isUploadRunning()
                 !watchFolderService.isUploadRunning()
             ) {
             ) {
                 await ImportService.setToUploadCollection(collections);
                 await ImportService.setToUploadCollection(collections);
                 if (zipPaths.current) {
                 if (zipPaths.current) {
-                    await ElectronAPIs.setToUploadFiles(
+                    await electron.setToUploadFiles(
                         PICKED_UPLOAD_TYPE.ZIPS,
                         PICKED_UPLOAD_TYPE.ZIPS,
                         zipPaths.current,
                         zipPaths.current,
                     );
                     );
                     zipPaths.current = null;
                     zipPaths.current = null;
                 }
                 }
-                await ElectronAPIs.setToUploadFiles(
+                await electron.setToUploadFiles(
                     PICKED_UPLOAD_TYPE.FILES,
                     PICKED_UPLOAD_TYPE.FILES,
                     filesWithCollectionToUploadIn.map(
                     filesWithCollectionToUploadIn.map(
                         ({ file }) => (file as ElectronFile).path,
                         ({ file }) => (file as ElectronFile).path,
@@ -543,9 +542,9 @@ export default function Uploader(props: Props) {
                     watchFolderService.resumePausedSync();
                     watchFolderService.resumePausedSync();
                 }
                 }
             }
             }
-        } catch (err) {
-            logError(err, "failed to upload files");
-            showUserFacingError(err.message);
+        } catch (e) {
+            log.error("failed to upload files", e);
+            showUserFacingError(e.message);
             closeUploadProgress();
             closeUploadProgress();
         } finally {
         } finally {
             postUploadAction();
             postUploadAction();
@@ -554,7 +553,7 @@ export default function Uploader(props: Props) {
 
 
     const retryFailed = async () => {
     const retryFailed = async () => {
         try {
         try {
-            addLogLine("user retrying failed  upload");
+            log.info("user retrying failed  upload");
             const filesWithCollections =
             const filesWithCollections =
                 uploadManager.getFailedFilesWithCollections();
                 uploadManager.getFailedFilesWithCollections();
             const uploaderName = uploadManager.getUploaderName();
             const uploaderName = uploadManager.getUploaderName();
@@ -564,9 +563,9 @@ export default function Uploader(props: Props) {
                 filesWithCollections.collections,
                 filesWithCollections.collections,
                 uploaderName,
                 uploaderName,
             );
             );
-        } catch (err) {
-            logError(err, "retry failed files failed");
-            showUserFacingError(err.message);
+        } catch (e) {
+            log.error("retry failed files failed", e);
+            showUserFacingError(e.message);
             closeUploadProgress();
             closeUploadProgress();
         } finally {
         } finally {
             postUploadAction();
             postUploadAction();
@@ -629,7 +628,7 @@ export default function Uploader(props: Props) {
     ) => {
     ) => {
         try {
         try {
             if (accessedThroughSharedURL) {
             if (accessedThroughSharedURL) {
-                addLogLine(
+                log.info(
                     `uploading files to pulbic collection - ${props.uploadCollection.name}  - ${props.uploadCollection.id}`,
                     `uploading files to pulbic collection - ${props.uploadCollection.name}  - ${props.uploadCollection.id}`,
                 );
                 );
                 const uploaderName = await getPublicCollectionUploaderName(
                 const uploaderName = await getPublicCollectionUploaderName(
@@ -644,7 +643,7 @@ export default function Uploader(props: Props) {
             if (isPendingDesktopUpload.current) {
             if (isPendingDesktopUpload.current) {
                 isPendingDesktopUpload.current = false;
                 isPendingDesktopUpload.current = false;
                 if (pendingDesktopUploadCollectionName.current) {
                 if (pendingDesktopUploadCollectionName.current) {
-                    addLogLine(
+                    log.info(
                         `upload pending files to collection - ${pendingDesktopUploadCollectionName.current}`,
                         `upload pending files to collection - ${pendingDesktopUploadCollectionName.current}`,
                     );
                     );
                     uploadFilesToNewCollections(
                     uploadFilesToNewCollections(
@@ -653,7 +652,7 @@ export default function Uploader(props: Props) {
                     );
                     );
                     pendingDesktopUploadCollectionName.current = null;
                     pendingDesktopUploadCollectionName.current = null;
                 } else {
                 } else {
-                    addLogLine(
+                    log.info(
                         `pending upload - strategy - "multiple collections" `,
                         `pending upload - strategy - "multiple collections" `,
                     );
                     );
                     uploadFilesToNewCollections(
                     uploadFilesToNewCollections(
@@ -663,7 +662,7 @@ export default function Uploader(props: Props) {
                 return;
                 return;
             }
             }
             if (isElectron() && pickedUploadType === PICKED_UPLOAD_TYPE.ZIPS) {
             if (isElectron() && pickedUploadType === PICKED_UPLOAD_TYPE.ZIPS) {
-                addLogLine("uploading zip files");
+                log.info("uploading zip files");
                 uploadFilesToNewCollections(
                 uploadFilesToNewCollections(
                     UPLOAD_STRATEGY.COLLECTION_PER_FOLDER,
                     UPLOAD_STRATEGY.COLLECTION_PER_FOLDER,
                 );
                 );
@@ -684,7 +683,7 @@ export default function Uploader(props: Props) {
             }
             }
             let showNextModal = () => {};
             let showNextModal = () => {};
             if (importSuggestion.hasNestedFolders) {
             if (importSuggestion.hasNestedFolders) {
-                addLogLine(`nested folders detected`);
+                log.info(`nested folders detected`);
                 showNextModal = () => setChoiceModalView(true);
                 showNextModal = () => setChoiceModalView(true);
             } else {
             } else {
                 showNextModal = () =>
                 showNextModal = () =>
@@ -697,24 +696,27 @@ export default function Uploader(props: Props) {
                 intent: CollectionSelectorIntent.upload,
                 intent: CollectionSelectorIntent.upload,
             });
             });
         } catch (e) {
         } catch (e) {
-            logError(e, "handleCollectionCreationAndUpload failed");
+            log.error("handleCollectionCreationAndUpload failed", e);
         }
         }
     };
     };
 
 
-    const handleDesktopUpload = async (type: PICKED_UPLOAD_TYPE) => {
+    const handleDesktopUpload = async (
+        type: PICKED_UPLOAD_TYPE,
+        electron: Electron,
+    ) => {
         let files: ElectronFile[];
         let files: ElectronFile[];
         pickedUploadType.current = type;
         pickedUploadType.current = type;
         if (type === PICKED_UPLOAD_TYPE.FILES) {
         if (type === PICKED_UPLOAD_TYPE.FILES) {
-            files = await ElectronAPIs.showUploadFilesDialog();
+            files = await electron.showUploadFilesDialog();
         } else if (type === PICKED_UPLOAD_TYPE.FOLDERS) {
         } else if (type === PICKED_UPLOAD_TYPE.FOLDERS) {
-            files = await ElectronAPIs.showUploadDirsDialog();
+            files = await electron.showUploadDirsDialog();
         } else {
         } else {
-            const response = await ElectronAPIs.showUploadZipDialog();
+            const response = await electron.showUploadZipDialog();
             files = response.files;
             files = response.files;
             zipPaths.current = response.zipPaths;
             zipPaths.current = response.zipPaths;
         }
         }
         if (files?.length > 0) {
         if (files?.length > 0) {
-            addLogLine(
+            log.info(
                 ` desktop upload for type:${type} and fileCount: ${files?.length} requested`,
                 ` desktop upload for type:${type} and fileCount: ${files?.length} requested`,
             );
             );
             setElectronFiles(files);
             setElectronFiles(files);
@@ -738,8 +740,8 @@ export default function Uploader(props: Props) {
     };
     };
 
 
     const handleUpload = (type) => () => {
     const handleUpload = (type) => () => {
-        if (isElectron()) {
-            handleDesktopUpload(type);
+        if (electron) {
+            handleDesktopUpload(type, electron);
         } else {
         } else {
             handleWebUpload(type);
             handleWebUpload(type);
         }
         }
@@ -767,7 +769,7 @@ export default function Uploader(props: Props) {
                 uploaderName,
                 uploaderName,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "public upload failed ");
+            log.error("public upload failed ", e);
         }
         }
     };
     };
 
 

+ 10 - 11
web/apps/photos/src/components/WatchFolder/index.tsx

@@ -1,17 +1,14 @@
+import DialogTitleWithCloseButton from "@ente/shared/components/DialogBox/TitleWithCloseButton";
 import { Button, Dialog, DialogContent, Stack } from "@mui/material";
 import { Button, Dialog, DialogContent, Stack } from "@mui/material";
+import UploadStrategyChoiceModal from "components/Upload/UploadStrategyChoiceModal";
+import { PICKED_UPLOAD_TYPE, UPLOAD_STRATEGY } from "constants/upload";
 import { t } from "i18next";
 import { t } from "i18next";
 import { AppContext } from "pages/_app";
 import { AppContext } from "pages/_app";
 import { useContext, useEffect, useState } from "react";
 import { useContext, useEffect, useState } from "react";
 import watchFolderService from "services/watchFolder/watchFolderService";
 import watchFolderService from "services/watchFolder/watchFolderService";
 import { WatchMapping } from "types/watchFolder";
 import { WatchMapping } from "types/watchFolder";
-import { MappingList } from "./mappingList";
-
-import ElectronAPIs from "@/next/electron";
-import DialogTitleWithCloseButton from "@ente/shared/components/DialogBox/TitleWithCloseButton";
-import UploadStrategyChoiceModal from "components/Upload/UploadStrategyChoiceModal";
-import { PICKED_UPLOAD_TYPE, UPLOAD_STRATEGY } from "constants/upload";
-import isElectron from "is-electron";
 import { getImportSuggestion } from "utils/upload";
 import { getImportSuggestion } from "utils/upload";
+import { MappingList } from "./mappingList";
 
 
 interface Iprops {
 interface Iprops {
     open: boolean;
     open: boolean;
@@ -24,10 +21,10 @@ export default function WatchFolder({ open, onClose }: Iprops) {
     const [choiceModalOpen, setChoiceModalOpen] = useState(false);
     const [choiceModalOpen, setChoiceModalOpen] = useState(false);
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);
 
 
+    const electron = globalThis.electron;
+
     useEffect(() => {
     useEffect(() => {
-        if (!isElectron()) {
-            return;
-        }
+        if (!electron) return;
         watchFolderService.getWatchMappings().then((m) => setMappings(m));
         watchFolderService.getWatchMappings().then((m) => setMappings(m));
     }, []);
     }, []);
 
 
@@ -52,8 +49,10 @@ export default function WatchFolder({ open, onClose }: Iprops) {
     };
     };
 
 
     const addFolderForWatching = async (path: string) => {
     const addFolderForWatching = async (path: string) => {
+        if (!electron) return;
+
         setInputFolderPath(path);
         setInputFolderPath(path);
-        const files = await ElectronAPIs.getDirFiles(path);
+        const files = await electron.getDirFiles(path);
         const analysisResult = getImportSuggestion(
         const analysisResult = getImportSuggestion(
             PICKED_UPLOAD_TYPE.FOLDERS,
             PICKED_UPLOAD_TYPE.FOLDERS,
             files,
             files,

+ 8 - 9
web/apps/photos/src/components/pages/gallery/Avatar.tsx

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { styled } from "@mui/material";
 import { styled } from "@mui/material";
 import { useTheme } from "@mui/material/styles";
 import { useTheme } from "@mui/material/styles";
 import { GalleryContext } from "pages/gallery";
 import { GalleryContext } from "pages/gallery";
@@ -47,7 +47,7 @@ const Avatar: React.FC<AvatarProps> = ({ file, email, opacity }) => {
                 // getting email from in-memory id-email map
                 // getting email from in-memory id-email map
                 const email = userIDToEmailMap.get(file.ownerID);
                 const email = userIDToEmailMap.get(file.ownerID);
                 if (!email) {
                 if (!email) {
-                    logError(Error(), "email not found in userIDToEmailMap");
+                    log.error("email not found in userIDToEmailMap");
                     return;
                     return;
                 }
                 }
                 const colorIndex =
                 const colorIndex =
@@ -58,8 +58,7 @@ const Avatar: React.FC<AvatarProps> = ({ file, email, opacity }) => {
             } else if (file.ownerID === user.id) {
             } else if (file.ownerID === user.id) {
                 const uploaderName = file.pubMagicMetadata.data.uploaderName;
                 const uploaderName = file.pubMagicMetadata.data.uploaderName;
                 if (!uploaderName) {
                 if (!uploaderName) {
-                    logError(
-                        Error(),
+                    log.error(
                         "uploaderName not found in file.pubMagicMetadata.data",
                         "uploaderName not found in file.pubMagicMetadata.data",
                     );
                     );
                     return;
                     return;
@@ -67,8 +66,8 @@ const Avatar: React.FC<AvatarProps> = ({ file, email, opacity }) => {
                 setUserLetter(uploaderName[0].toUpperCase());
                 setUserLetter(uploaderName[0].toUpperCase());
                 setColorCode(PUBLIC_COLLECTED_FILES_AVATAR_COLOR_CODE);
                 setColorCode(PUBLIC_COLLECTED_FILES_AVATAR_COLOR_CODE);
             }
             }
-        } catch (err) {
-            logError(err, "AvatarIcon.tsx - useLayoutEffect file failed");
+        } catch (e) {
+            log.error("AvatarIcon.tsx - useLayoutEffect file failed", e);
         }
         }
     }, [file]);
     }, [file]);
 
 
@@ -87,15 +86,15 @@ const Avatar: React.FC<AvatarProps> = ({ file, email, opacity }) => {
                 (key) => userIDToEmailMap.get(key) === email,
                 (key) => userIDToEmailMap.get(key) === email,
             );
             );
             if (!id) {
             if (!id) {
-                logError(Error(), `ID not found for email: ${email}`);
+                log.error(`ID not found for email: ${email}`);
                 return;
                 return;
             }
             }
             const colorIndex = id % theme.colors.avatarColors.length;
             const colorIndex = id % theme.colors.avatarColors.length;
             const colorCode = theme.colors.avatarColors[colorIndex];
             const colorCode = theme.colors.avatarColors[colorIndex];
             setUserLetter(email[0].toUpperCase());
             setUserLetter(email[0].toUpperCase());
             setColorCode(colorCode);
             setColorCode(colorCode);
-        } catch (err) {
-            logError(err, "AvatarIcon.tsx - useLayoutEffect email failed");
+        } catch (e) {
+            log.error("AvatarIcon.tsx - useLayoutEffect email failed", e);
         }
         }
     }, [email]);
     }, [email]);
 
 

+ 2 - 2
web/apps/photos/src/components/pages/gallery/PlanSelector/card/index.tsx

@@ -1,6 +1,6 @@
+import log from "@/next/log";
 import { SUPPORT_EMAIL } from "@ente/shared/constants/urls";
 import { SUPPORT_EMAIL } from "@ente/shared/constants/urls";
 import { useLocalState } from "@ente/shared/hooks/useLocalState";
 import { useLocalState } from "@ente/shared/hooks/useLocalState";
-import { logError } from "@ente/shared/sentry";
 import { LS_KEYS } from "@ente/shared/storage/localStorage";
 import { LS_KEYS } from "@ente/shared/storage/localStorage";
 import { Link, Stack } from "@mui/material";
 import { Link, Stack } from "@mui/material";
 import { PLAN_PERIOD } from "constants/gallery";
 import { PLAN_PERIOD } from "constants/gallery";
@@ -92,7 +92,7 @@ function PlanSelectorCard(props: Props) {
                 }
                 }
                 setPlans(plans);
                 setPlans(plans);
             } catch (e) {
             } catch (e) {
-                logError(e, "plan selector modal open failed");
+                log.error("plan selector modal open failed", e);
                 props.closeModal();
                 props.closeModal();
                 appContext.setDialogMessage({
                 appContext.setDialogMessage({
                     title: t("OPEN_PLAN_SELECTOR_MODAL_FAILED"),
                     title: t("OPEN_PLAN_SELECTOR_MODAL_FAILED"),

+ 2 - 2
web/apps/photos/src/components/pages/gallery/PreviewCard.tsx

@@ -1,7 +1,7 @@
+import log from "@/next/log";
 import { Overlay } from "@ente/shared/components/Container";
 import { Overlay } from "@ente/shared/components/Container";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
 import useLongPress from "@ente/shared/hooks/useLongPress";
 import useLongPress from "@ente/shared/hooks/useLongPress";
-import { logError } from "@ente/shared/sentry";
 import { formatDateRelative } from "@ente/shared/time/format";
 import { formatDateRelative } from "@ente/shared/time/format";
 import AlbumOutlined from "@mui/icons-material/AlbumOutlined";
 import AlbumOutlined from "@mui/icons-material/AlbumOutlined";
 import PlayCircleOutlineOutlinedIcon from "@mui/icons-material/PlayCircleOutlineOutlined";
 import PlayCircleOutlineOutlinedIcon from "@mui/icons-material/PlayCircleOutlineOutlined";
@@ -271,7 +271,7 @@ export default function PreviewCard(props: IProps) {
                 updateURL(file.id, url);
                 updateURL(file.id, url);
             } catch (e) {
             } catch (e) {
                 if (e.message !== CustomError.URL_ALREADY_SET) {
                 if (e.message !== CustomError.URL_ALREADY_SET) {
-                    logError(e, "preview card useEffect failed");
+                    log.error("preview card useEffect failed", e);
                 }
                 }
                 // no-op
                 // no-op
             }
             }

+ 14 - 18
web/apps/photos/src/pages/_app.tsx

@@ -1,6 +1,6 @@
 import { CustomHead } from "@/next/components/Head";
 import { CustomHead } from "@/next/components/Head";
-import ElectronAPIs from "@/next/electron";
 import { setupI18n } from "@/next/i18n";
 import { setupI18n } from "@/next/i18n";
+import log from "@/next/log";
 import { logStartupBanner } from "@/next/log-web";
 import { logStartupBanner } from "@/next/log-web";
 import { AppUpdateInfo } from "@/next/types/ipc";
 import { AppUpdateInfo } from "@/next/types/ipc";
 import {
 import {
@@ -23,12 +23,9 @@ import EnteSpinner from "@ente/shared/components/EnteSpinner";
 import { MessageContainer } from "@ente/shared/components/MessageContainer";
 import { MessageContainer } from "@ente/shared/components/MessageContainer";
 import AppNavbar from "@ente/shared/components/Navbar/app";
 import AppNavbar from "@ente/shared/components/Navbar/app";
 import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
 import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
-import { CustomError } from "@ente/shared/error";
 import { Events, eventBus } from "@ente/shared/events";
 import { Events, eventBus } from "@ente/shared/events";
 import { useLocalState } from "@ente/shared/hooks/useLocalState";
 import { useLocalState } from "@ente/shared/hooks/useLocalState";
-import { addLogLine } from "@ente/shared/logging";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
-import { logError } from "@ente/shared/sentry";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import {
 import {
     getLocalMapEnabled,
     getLocalMapEnabled,
@@ -156,7 +153,8 @@ export default function App({ Component, pageProps }: AppProps) {
     }, []);
     }, []);
 
 
     useEffect(() => {
     useEffect(() => {
-        if (isElectron()) {
+        const electron = globalThis.electron;
+        if (electron) {
             const showUpdateDialog = (updateInfo: AppUpdateInfo) => {
             const showUpdateDialog = (updateInfo: AppUpdateInfo) => {
                 if (updateInfo.autoUpdatable) {
                 if (updateInfo.autoUpdatable) {
                     setDialogMessage(
                     setDialogMessage(
@@ -176,7 +174,7 @@ export default function App({ Component, pageProps }: AppProps) {
                     });
                     });
                 }
                 }
             };
             };
-            ElectronAPIs.registerUpdateEventListener(showUpdateDialog);
+            electron.registerUpdateEventListener(showUpdateDialog);
         }
         }
     }, []);
     }, []);
 
 
@@ -190,7 +188,7 @@ export default function App({ Component, pageProps }: AppProps) {
                 setMlSearchEnabled(mlSearchConfig.enabled);
                 setMlSearchEnabled(mlSearchConfig.enabled);
                 mlWorkManager.setMlSearchEnabled(mlSearchConfig.enabled);
                 mlWorkManager.setMlSearchEnabled(mlSearchConfig.enabled);
             } catch (e) {
             } catch (e) {
-                logError(e, "Error while loading mlSearchEnabled");
+                log.error("Error while loading mlSearchEnabled", e);
             }
             }
         };
         };
         loadMlSearchState();
         loadMlSearchState();
@@ -200,7 +198,7 @@ export default function App({ Component, pageProps }: AppProps) {
                 mlWorkManager.setMlSearchEnabled(false);
                 mlWorkManager.setMlSearchEnabled(false);
             });
             });
         } catch (e) {
         } catch (e) {
-            logError(e, "Error while subscribing to logout event");
+            log.error("Error while subscribing to logout event", e);
         }
         }
     }, []);
     }, []);
 
 
@@ -214,10 +212,10 @@ export default function App({ Component, pageProps }: AppProps) {
         }
         }
         const initExport = async () => {
         const initExport = async () => {
             try {
             try {
-                addLogLine("init export");
+                log.info("init export");
                 const token = getToken();
                 const token = getToken();
                 if (!token) {
                 if (!token) {
-                    addLogLine(
+                    log.info(
                         "User not logged in, not starting export continuous sync job",
                         "User not logged in, not starting export continuous sync job",
                     );
                     );
                     return;
                     return;
@@ -238,11 +236,11 @@ export default function App({ Component, pageProps }: AppProps) {
                     exportService.enableContinuousExport();
                     exportService.enableContinuousExport();
                 }
                 }
                 if (isExportInProgress(exportRecord.stage)) {
                 if (isExportInProgress(exportRecord.stage)) {
-                    addLogLine("export was in progress, resuming");
+                    log.info("export was in progress, resuming");
                     exportService.scheduleExport();
                     exportService.scheduleExport();
                 }
                 }
             } catch (e) {
             } catch (e) {
-                logError(e, "init export failed");
+                log.error("init export failed", e);
             }
             }
         };
         };
         initExport();
         initExport();
@@ -251,7 +249,7 @@ export default function App({ Component, pageProps }: AppProps) {
                 exportService.disableContinuousExport();
                 exportService.disableContinuousExport();
             });
             });
         } catch (e) {
         } catch (e) {
-            logError(e, "Error while subscribing to logout event");
+            log.error("Error while subscribing to logout event", e);
         }
         }
     }, []);
     }, []);
 
 
@@ -268,9 +266,7 @@ export default function App({ Component, pageProps }: AppProps) {
                 const redirectAction = redirectMap.get(redirect);
                 const redirectAction = redirectMap.get(redirect);
                 window.location.href = await redirectAction();
                 window.location.href = await redirectAction();
             } else {
             } else {
-                logError(CustomError.BAD_REQUEST, "invalid redirection", {
-                    redirect,
-                });
+                log.error(`invalid redirection ${redirect}`);
             }
             }
         };
         };
 
 
@@ -337,7 +333,7 @@ export default function App({ Component, pageProps }: AppProps) {
             setMlSearchEnabled(enabled);
             setMlSearchEnabled(enabled);
             mlWorkManager.setMlSearchEnabled(enabled);
             mlWorkManager.setMlSearchEnabled(enabled);
         } catch (e) {
         } catch (e) {
-            logError(e, "Error while updating mlSearchEnabled");
+            log.error("Error while updating mlSearchEnabled", e);
         }
         }
     };
     };
 
 
@@ -347,7 +343,7 @@ export default function App({ Component, pageProps }: AppProps) {
             setLocalMapEnabled(enabled);
             setLocalMapEnabled(enabled);
             setMapEnabled(enabled);
             setMapEnabled(enabled);
         } catch (e) {
         } catch (e) {
-            logError(e, "Error while updating mapEnabled");
+            log.error("Error while updating mapEnabled", e);
         }
         }
     };
     };
 
 

+ 37 - 39
web/apps/photos/src/pages/gallery/index.tsx

@@ -60,38 +60,11 @@ import {
     sortFiles,
     sortFiles,
 } from "utils/file";
 } from "utils/file";
 
 
-import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
-import { CustomError } from "@ente/shared/error";
-import { logError } from "@ente/shared/sentry";
-import CollectionNamer, {
-    CollectionNamerAttributes,
-} from "components/Collections/CollectionNamer";
-import Uploader from "components/Upload/Uploader";
-import PlanSelector from "components/pages/gallery/PlanSelector";
-import {
-    ALL_SECTION,
-    ARCHIVE_SECTION,
-    CollectionSummaryType,
-    DUMMY_UNCATEGORIZED_COLLECTION,
-    HIDDEN_ITEMS_SECTION,
-    TRASH_SECTION,
-} from "constants/collection";
-import { AppContext } from "pages/_app";
-import { getLocalTrashedFiles, syncTrash } from "services/trashService";
-import {
-    COLLECTION_OPS_TYPE,
-    constructCollectionNameMap,
-    getArchivedCollections,
-    getDefaultHiddenCollectionIDs,
-    getSelectedCollection,
-    handleCollectionOps,
-    hasNonSystemCollections,
-    splitNormalAndHiddenCollections,
-} from "utils/collection";
-
-import ElectronAPIs from "@/next/electron";
+import log from "@/next/log";
 import { APPS } from "@ente/shared/apps/constants";
 import { APPS } from "@ente/shared/apps/constants";
 import { CenteredFlex } from "@ente/shared/components/Container";
 import { CenteredFlex } from "@ente/shared/components/Container";
+import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
+import { CustomError } from "@ente/shared/error";
 import useFileInput from "@ente/shared/hooks/useFileInput";
 import useFileInput from "@ente/shared/hooks/useFileInput";
 import useMemoSingleThreaded from "@ente/shared/hooks/useMemoSingleThreaded";
 import useMemoSingleThreaded from "@ente/shared/hooks/useMemoSingleThreaded";
 import InMemoryStore, { MS_KEYS } from "@ente/shared/storage/InMemoryStore";
 import InMemoryStore, { MS_KEYS } from "@ente/shared/storage/InMemoryStore";
@@ -101,6 +74,9 @@ import { User } from "@ente/shared/user/types";
 import { isPromise } from "@ente/shared/utils";
 import { isPromise } from "@ente/shared/utils";
 import AuthenticateUserModal from "components/AuthenticateUserModal";
 import AuthenticateUserModal from "components/AuthenticateUserModal";
 import Collections from "components/Collections";
 import Collections from "components/Collections";
+import CollectionNamer, {
+    CollectionNamerAttributes,
+} from "components/Collections/CollectionNamer";
 import ExportModal from "components/ExportModal";
 import ExportModal from "components/ExportModal";
 import {
 import {
     FilesDownloadProgress,
     FilesDownloadProgress,
@@ -112,16 +88,27 @@ import FixCreationTime, {
 import GalleryEmptyState from "components/GalleryEmptyState";
 import GalleryEmptyState from "components/GalleryEmptyState";
 import { ITEM_TYPE, TimeStampListItem } from "components/PhotoList";
 import { ITEM_TYPE, TimeStampListItem } from "components/PhotoList";
 import SearchResultInfo from "components/Search/SearchResultInfo";
 import SearchResultInfo from "components/Search/SearchResultInfo";
+import Uploader from "components/Upload/Uploader";
 import UploadInputs from "components/UploadSelectorInputs";
 import UploadInputs from "components/UploadSelectorInputs";
 import { GalleryNavbar } from "components/pages/gallery/Navbar";
 import { GalleryNavbar } from "components/pages/gallery/Navbar";
+import PlanSelector from "components/pages/gallery/PlanSelector";
+import {
+    ALL_SECTION,
+    ARCHIVE_SECTION,
+    CollectionSummaryType,
+    DUMMY_UNCATEGORIZED_COLLECTION,
+    HIDDEN_ITEMS_SECTION,
+    TRASH_SECTION,
+} from "constants/collection";
 import { SYNC_INTERVAL_IN_MICROSECONDS } from "constants/gallery";
 import { SYNC_INTERVAL_IN_MICROSECONDS } from "constants/gallery";
-import isElectron from "is-electron";
+import { AppContext } from "pages/_app";
 import { ClipService } from "services/clipService";
 import { ClipService } from "services/clipService";
 import { constructUserIDToEmailMap } from "services/collectionService";
 import { constructUserIDToEmailMap } from "services/collectionService";
 import downloadManager from "services/download";
 import downloadManager from "services/download";
 import { syncEmbeddings } from "services/embeddingService";
 import { syncEmbeddings } from "services/embeddingService";
 import { syncEntities } from "services/entityService";
 import { syncEntities } from "services/entityService";
 import locationSearchService from "services/locationSearchService";
 import locationSearchService from "services/locationSearchService";
+import { getLocalTrashedFiles, syncTrash } from "services/trashService";
 import uploadManager from "services/upload/uploadManager";
 import uploadManager from "services/upload/uploadManager";
 import { Collection, CollectionSummaries } from "types/collection";
 import { Collection, CollectionSummaries } from "types/collection";
 import { EnteFile } from "types/file";
 import { EnteFile } from "types/file";
@@ -134,6 +121,16 @@ import {
 } from "types/gallery";
 } from "types/gallery";
 import { Search, SearchResultSummary, UpdateSearch } from "types/search";
 import { Search, SearchResultSummary, UpdateSearch } from "types/search";
 import { FamilyData } from "types/user";
 import { FamilyData } from "types/user";
+import {
+    COLLECTION_OPS_TYPE,
+    constructCollectionNameMap,
+    getArchivedCollections,
+    getDefaultHiddenCollectionIDs,
+    getSelectedCollection,
+    handleCollectionOps,
+    hasNonSystemCollections,
+    splitNormalAndHiddenCollections,
+} from "utils/collection";
 import ComlinkSearchWorker from "utils/comlink/ComlinkSearchWorker";
 import ComlinkSearchWorker from "utils/comlink/ComlinkSearchWorker";
 import { isArchivedFile } from "utils/magicMetadata";
 import { isArchivedFile } from "utils/magicMetadata";
 import { getSessionExpiredMessage } from "utils/ui";
 import { getSessionExpiredMessage } from "utils/ui";
@@ -321,6 +318,7 @@ export default function Gallery() {
             return;
             return;
         }
         }
         preloadImage("/images/subscription-card-background");
         preloadImage("/images/subscription-card-background");
+        const electron = globalThis.electron;
         const main = async () => {
         const main = async () => {
             const valid = await validateKey();
             const valid = await validateKey();
             if (!valid) {
             if (!valid) {
@@ -363,9 +361,9 @@ export default function Gallery() {
             syncInterval.current = setInterval(() => {
             syncInterval.current = setInterval(() => {
                 syncWithRemote(false, true);
                 syncWithRemote(false, true);
             }, SYNC_INTERVAL_IN_MICROSECONDS);
             }, SYNC_INTERVAL_IN_MICROSECONDS);
-            if (isElectron()) {
+            if (electron) {
                 void ClipService.setupOnFileUploadListener();
                 void ClipService.setupOnFileUploadListener();
-                ElectronAPIs.registerForegroundEventListener(() => {
+                electron.registerForegroundEventListener(() => {
                     syncWithRemote(false, true);
                     syncWithRemote(false, true);
                 });
                 });
             }
             }
@@ -373,8 +371,8 @@ export default function Gallery() {
         main();
         main();
         return () => {
         return () => {
             clearInterval(syncInterval.current);
             clearInterval(syncInterval.current);
-            if (isElectron()) {
-                ElectronAPIs.registerForegroundEventListener(() => {});
+            if (electron) {
+                electron.registerForegroundEventListener(() => {});
                 ClipService.removeOnFileUploadListener();
                 ClipService.removeOnFileUploadListener();
             }
             }
         };
         };
@@ -719,7 +717,7 @@ export default function Gallery() {
                     router.push(PAGES.CREDENTIALS);
                     router.push(PAGES.CREDENTIALS);
                     break;
                     break;
                 default:
                 default:
-                    logError(e, "syncWithRemote failed");
+                    log.error("syncWithRemote failed", e);
             }
             }
         } finally {
         } finally {
             setTempDeletedFileIds(new Set());
             setTempDeletedFileIds(new Set());
@@ -871,7 +869,7 @@ export default function Gallery() {
                 clearSelection();
                 clearSelection();
                 await syncWithRemote(false, true);
                 await syncWithRemote(false, true);
             } catch (e) {
             } catch (e) {
-                logError(e, "collection ops failed", { ops });
+                log.error(`collection ops (${ops}) failed`, e);
                 setDialogMessage({
                 setDialogMessage({
                     title: t("ERROR"),
                     title: t("ERROR"),
 
 
@@ -916,7 +914,7 @@ export default function Gallery() {
             clearSelection();
             clearSelection();
             await syncWithRemote(false, true);
             await syncWithRemote(false, true);
         } catch (e) {
         } catch (e) {
-            logError(e, "file ops failed", { ops });
+            log.error(`file ops (${ops}) failed`, e);
             setDialogMessage({
             setDialogMessage({
                 title: t("ERROR"),
                 title: t("ERROR"),
 
 
@@ -935,7 +933,7 @@ export default function Gallery() {
                 const collection = await createAlbum(collectionName);
                 const collection = await createAlbum(collectionName);
                 await collectionOpsHelper(ops)(collection);
                 await collectionOpsHelper(ops)(collection);
             } catch (e) {
             } catch (e) {
-                logError(e, "create and collection ops failed", { ops });
+                log.error(`create and collection ops (${ops}) failed`, e);
                 setDialogMessage({
                 setDialogMessage({
                     title: t("ERROR"),
                     title: t("ERROR"),
 
 

+ 6 - 7
web/apps/photos/src/pages/index.tsx

@@ -1,4 +1,4 @@
-import ElectronAPIs from "@/next/electron";
+import log from "@/next/log";
 import Login from "@ente/accounts/components/Login";
 import Login from "@ente/accounts/components/Login";
 import SignUp from "@ente/accounts/components/SignUp";
 import SignUp from "@ente/accounts/components/SignUp";
 import { APPS } from "@ente/shared/apps/constants";
 import { APPS } from "@ente/shared/apps/constants";
@@ -7,14 +7,12 @@ import EnteSpinner from "@ente/shared/components/EnteSpinner";
 import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
 import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
 import { saveKeyInSessionStore } from "@ente/shared/crypto/helpers";
 import { saveKeyInSessionStore } from "@ente/shared/crypto/helpers";
 import { getAlbumsURL } from "@ente/shared/network/api";
 import { getAlbumsURL } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import localForage from "@ente/shared/storage/localForage";
 import localForage from "@ente/shared/storage/localForage";
 import { getData, LS_KEYS } from "@ente/shared/storage/localStorage";
 import { getData, LS_KEYS } from "@ente/shared/storage/localStorage";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getKey, SESSION_KEYS } from "@ente/shared/storage/sessionStorage";
 import { getKey, SESSION_KEYS } from "@ente/shared/storage/sessionStorage";
 import { Button, styled, Typography, TypographyProps } from "@mui/material";
 import { Button, styled, Typography, TypographyProps } from "@mui/material";
 import { t } from "i18next";
 import { t } from "i18next";
-import isElectron from "is-electron";
 import { useRouter } from "next/router";
 import { useRouter } from "next/router";
 import { CarouselProvider, DotGroup, Slide, Slider } from "pure-react-carousel";
 import { CarouselProvider, DotGroup, Slide, Slider } from "pure-react-carousel";
 import "pure-react-carousel/dist/react-carousel.es.css";
 import "pure-react-carousel/dist/react-carousel.es.css";
@@ -132,11 +130,12 @@ export default function LandingPage() {
     const handleNormalRedirect = async () => {
     const handleNormalRedirect = async () => {
         const user = getData(LS_KEYS.USER);
         const user = getData(LS_KEYS.USER);
         let key = getKey(SESSION_KEYS.ENCRYPTION_KEY);
         let key = getKey(SESSION_KEYS.ENCRYPTION_KEY);
-        if (!key && isElectron()) {
+        const electron = globalThis.electron;
+        if (!key && electron) {
             try {
             try {
-                key = await ElectronAPIs.getEncryptionKey();
+                key = await electron.getEncryptionKey();
             } catch (e) {
             } catch (e) {
-                logError(e, "getEncryptionKey failed");
+                log.error("getEncryptionKey failed", e);
             }
             }
             if (key) {
             if (key) {
                 await saveKeyInSessionStore(
                 await saveKeyInSessionStore(
@@ -160,7 +159,7 @@ export default function LandingPage() {
         try {
         try {
             await localForage.ready();
             await localForage.ready();
         } catch (e) {
         } catch (e) {
-            logError(e, "usage in incognito mode tried");
+            log.error("usage in incognito mode tried", e);
             appContext.setDialogMessage({
             appContext.setDialogMessage({
                 title: t("LOCAL_STORAGE_NOT_ACCESSIBLE"),
                 title: t("LOCAL_STORAGE_NOT_ACCESSIBLE"),
 
 

+ 6 - 6
web/apps/photos/src/pages/shared-albums/index.tsx

@@ -1,3 +1,4 @@
+import log from "@/next/log";
 import {
 import {
     CenteredFlex,
     CenteredFlex,
     SpaceBetweenFlex,
     SpaceBetweenFlex,
@@ -46,7 +47,6 @@ import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
 import { ENTE_WEBSITE_LINK } from "@ente/shared/constants/urls";
 import { ENTE_WEBSITE_LINK } from "@ente/shared/constants/urls";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import useFileInput from "@ente/shared/hooks/useFileInput";
 import useFileInput from "@ente/shared/hooks/useFileInput";
-import { logError } from "@ente/shared/sentry";
 import AddPhotoAlternateOutlined from "@mui/icons-material/AddPhotoAlternateOutlined";
 import AddPhotoAlternateOutlined from "@mui/icons-material/AddPhotoAlternateOutlined";
 import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
 import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
 import MoreHoriz from "@mui/icons-material/MoreHoriz";
 import MoreHoriz from "@mui/icons-material/MoreHoriz";
@@ -292,7 +292,7 @@ export default function PublicCollectionGallery() {
                 setFilesDownloadProgressAttributes,
                 setFilesDownloadProgressAttributes,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to downloads shared album all files");
+            log.error("failed to downloads shared album all files", e);
         }
         }
     };
     };
 
 
@@ -417,7 +417,7 @@ export default function PublicCollectionGallery() {
                 setPublicCollection(null);
                 setPublicCollection(null);
                 setPublicFiles(null);
                 setPublicFiles(null);
             } else {
             } else {
-                logError(e, "failed to sync public album with remote");
+                log.error("failed to sync public album with remote", e);
             }
             }
         } finally {
         } finally {
             appContext.finishLoading();
             appContext.finishLoading();
@@ -441,7 +441,7 @@ export default function PublicCollectionGallery() {
                     publicUrl.memLimit,
                     publicUrl.memLimit,
                 );
                 );
             } catch (e) {
             } catch (e) {
-                logError(e, "failed to derive key for verifyLinkPassword");
+                log.error("failed to derive key for verifyLinkPassword", e);
                 setFieldError(`${t("UNKNOWN_ERROR")} ${e.message}`);
                 setFieldError(`${t("UNKNOWN_ERROR")} ${e.message}`);
                 return;
                 return;
             }
             }
@@ -468,7 +468,7 @@ export default function PublicCollectionGallery() {
             await syncWithRemote();
             await syncWithRemote();
             appContext.finishLoading();
             appContext.finishLoading();
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to verifyLinkPassword");
+            log.error("failed to verifyLinkPassword", e);
             setFieldError(`${t("UNKNOWN_ERROR")} ${e.message}`);
             setFieldError(`${t("UNKNOWN_ERROR")} ${e.message}`);
         }
         }
     };
     };
@@ -528,7 +528,7 @@ export default function PublicCollectionGallery() {
             );
             );
             clearSelection();
             clearSelection();
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to download selected files");
+            log.error("failed to download selected files", e);
         }
         }
     };
     };
 
 

+ 13 - 13
web/apps/photos/src/services/billingService.ts

@@ -1,6 +1,6 @@
+import log from "@/next/log";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint, getPaymentsURL } from "@ente/shared/network/api";
 import { getEndpoint, getPaymentsURL } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import {
 import {
     LS_KEYS,
     LS_KEYS,
     removeData,
     removeData,
@@ -40,7 +40,7 @@ class billingService {
             const { plans } = response.data;
             const { plans } = response.data;
             return plans;
             return plans;
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to get plans");
+            log.error("failed to get plans", e);
         }
         }
     }
     }
 
 
@@ -56,7 +56,7 @@ class billingService {
             const { subscription } = response.data;
             const { subscription } = response.data;
             setData(LS_KEYS.SUBSCRIPTION, subscription);
             setData(LS_KEYS.SUBSCRIPTION, subscription);
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to get user's subscription details");
+            log.error("failed to get user's subscription details", e);
         }
         }
     }
     }
 
 
@@ -69,7 +69,7 @@ class billingService {
                 PaymentActionType.Buy,
                 PaymentActionType.Buy,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "unable to buy subscription");
+            log.error("unable to buy subscription", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -83,7 +83,7 @@ class billingService {
                 PaymentActionType.Update,
                 PaymentActionType.Update,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "subscription update failed");
+            log.error("subscription update failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -101,7 +101,7 @@ class billingService {
             const { subscription } = response.data;
             const { subscription } = response.data;
             setData(LS_KEYS.SUBSCRIPTION, subscription);
             setData(LS_KEYS.SUBSCRIPTION, subscription);
         } catch (e) {
         } catch (e) {
-            logError(e, "subscription cancel failed");
+            log.error("subscription cancel failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -119,7 +119,7 @@ class billingService {
             const { subscription } = response.data;
             const { subscription } = response.data;
             setData(LS_KEYS.SUBSCRIPTION, subscription);
             setData(LS_KEYS.SUBSCRIPTION, subscription);
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to activate subscription");
+            log.error("failed to activate subscription", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -147,9 +147,9 @@ class billingService {
             const { subscription } = response.data;
             const { subscription } = response.data;
             setData(LS_KEYS.SUBSCRIPTION, subscription);
             setData(LS_KEYS.SUBSCRIPTION, subscription);
             return subscription;
             return subscription;
-        } catch (err) {
-            logError(err, "Error while verifying subscription");
-            throw err;
+        } catch (e) {
+            log.error("Error while verifying subscription", e);
+            throw e;
         }
         }
     }
     }
 
 
@@ -163,7 +163,7 @@ class billingService {
             });
             });
             removeData(LS_KEYS.FAMILY_DATA);
             removeData(LS_KEYS.FAMILY_DATA);
         } catch (e) {
         } catch (e) {
-            logError(e, "/family/leave failed");
+            log.error("/family/leave failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -177,7 +177,7 @@ class billingService {
             const redirectURL = this.getRedirectURL();
             const redirectURL = this.getRedirectURL();
             window.location.href = `${getPaymentsURL()}?productID=${productID}&paymentToken=${paymentToken}&action=${action}&redirectURL=${redirectURL}`;
             window.location.href = `${getPaymentsURL()}?productID=${productID}&paymentToken=${paymentToken}&action=${action}&redirectURL=${redirectURL}`;
         } catch (e) {
         } catch (e) {
-            logError(e, "unable to get payments url");
+            log.error("unable to get payments url", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -194,7 +194,7 @@ class billingService {
             );
             );
             window.location.href = response.data.url;
             window.location.href = response.data.url;
         } catch (e) {
         } catch (e) {
-            logError(e, "unable to get customer portal url");
+            log.error("unable to get customer portal url", e);
             throw e;
             throw e;
         }
         }
     }
     }

+ 38 - 36
web/apps/photos/src/services/clipService.ts

@@ -1,9 +1,8 @@
-import ElectronAPIs from "@/next/electron";
+import { ensureElectron } from "@/next/electron";
+import log from "@/next/log";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
 import { Events, eventBus } from "@ente/shared/events";
 import { Events, eventBus } from "@ente/shared/events";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import isElectron from "is-electron";
 import isElectron from "is-electron";
@@ -63,36 +62,36 @@ class ClipServiceImpl {
                 return;
                 return;
             }
             }
             if (this.onFileUploadedHandler) {
             if (this.onFileUploadedHandler) {
-                addLogLine("file upload listener already setup");
+                log.info("file upload listener already setup");
                 return;
                 return;
             }
             }
-            addLogLine("setting up file upload listener");
+            log.info("setting up file upload listener");
             this.onFileUploadedHandler = (args) => {
             this.onFileUploadedHandler = (args) => {
                 this.runLocalFileClipExtraction(args);
                 this.runLocalFileClipExtraction(args);
             };
             };
             eventBus.on(Events.FILE_UPLOADED, this.onFileUploadedHandler, this);
             eventBus.on(Events.FILE_UPLOADED, this.onFileUploadedHandler, this);
-            addLogLine("setup file upload listener successfully");
+            log.info("setup file upload listener successfully");
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to setup clip service");
+            log.error("failed to setup clip service", e);
         }
         }
     };
     };
 
 
     removeOnFileUploadListener = async () => {
     removeOnFileUploadListener = async () => {
         try {
         try {
             if (!this.onFileUploadedHandler) {
             if (!this.onFileUploadedHandler) {
-                addLogLine("file upload listener already removed");
+                log.info("file upload listener already removed");
                 return;
                 return;
             }
             }
-            addLogLine("removing file upload listener");
+            log.info("removing file upload listener");
             eventBus.removeListener(
             eventBus.removeListener(
                 Events.FILE_UPLOADED,
                 Events.FILE_UPLOADED,
                 this.onFileUploadedHandler,
                 this.onFileUploadedHandler,
                 this,
                 this,
             );
             );
             this.onFileUploadedHandler = null;
             this.onFileUploadedHandler = null;
-            addLogLine("removed file upload listener successfully");
+            log.info("removed file upload listener successfully");
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to remove clip service");
+            log.error("failed to remove clip service", e);
         }
         }
     };
     };
 
 
@@ -107,7 +106,7 @@ class ClipServiceImpl {
             }
             }
             return this.clipExtractionStatus;
             return this.clipExtractionStatus;
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to get clip indexing status");
+            log.error("failed to get clip indexing status", e);
         }
         }
     };
     };
 
 
@@ -121,13 +120,13 @@ class ClipServiceImpl {
     ) => {
     ) => {
         try {
         try {
             if (this.embeddingExtractionInProgress) {
             if (this.embeddingExtractionInProgress) {
-                addLogLine(
+                log.info(
                     "clip embedding extraction already in progress, scheduling re-run",
                     "clip embedding extraction already in progress, scheduling re-run",
                 );
                 );
                 this.reRunNeeded = true;
                 this.reRunNeeded = true;
                 return;
                 return;
             } else {
             } else {
-                addLogLine(
+                log.info(
                     "clip embedding extraction not in progress, starting clip embedding extraction",
                     "clip embedding extraction not in progress, starting clip embedding extraction",
                 );
                 );
             }
             }
@@ -139,7 +138,7 @@ class ClipServiceImpl {
                 this.embeddingExtractionInProgress = null;
                 this.embeddingExtractionInProgress = null;
                 if (!canceller.signal.aborted && this.reRunNeeded) {
                 if (!canceller.signal.aborted && this.reRunNeeded) {
                     this.reRunNeeded = false;
                     this.reRunNeeded = false;
-                    addLogLine("re-running clip embedding extraction");
+                    log.info("re-running clip embedding extraction");
                     setTimeout(
                     setTimeout(
                         () => this.scheduleImageEmbeddingExtraction(),
                         () => this.scheduleImageEmbeddingExtraction(),
                         0,
                         0,
@@ -148,7 +147,7 @@ class ClipServiceImpl {
             }
             }
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.REQUEST_CANCELLED) {
             if (e.message !== CustomError.REQUEST_CANCELLED) {
-                logError(e, "failed to schedule clip embedding extraction");
+                log.error("failed to schedule clip embedding extraction", e);
             }
             }
         }
         }
     };
     };
@@ -158,12 +157,12 @@ class ClipServiceImpl {
         model: Model = Model.ONNX_CLIP,
         model: Model = Model.ONNX_CLIP,
     ): Promise<Float32Array> => {
     ): Promise<Float32Array> => {
         try {
         try {
-            return ElectronAPIs.computeTextEmbedding(model, text);
+            return ensureElectron().computeTextEmbedding(model, text);
         } catch (e) {
         } catch (e) {
             if (e?.message?.includes(CustomError.UNSUPPORTED_PLATFORM)) {
             if (e?.message?.includes(CustomError.UNSUPPORTED_PLATFORM)) {
                 this.unsupportedPlatform = true;
                 this.unsupportedPlatform = true;
             }
             }
-            logError(e, "failed to compute text embedding");
+            log.error("failed to compute text embedding", e);
             throw e;
             throw e;
         }
         }
     };
     };
@@ -174,7 +173,7 @@ class ClipServiceImpl {
     ) => {
     ) => {
         try {
         try {
             if (this.unsupportedPlatform) {
             if (this.unsupportedPlatform) {
-                addLogLine(
+                log.info(
                     `skipping clip embedding extraction, platform unsupported`,
                     `skipping clip embedding extraction, platform unsupported`,
                 );
                 );
                 return;
                 return;
@@ -194,15 +193,15 @@ class ClipServiceImpl {
                 pending: pendingFiles.length,
                 pending: pendingFiles.length,
             });
             });
             if (pendingFiles.length === 0) {
             if (pendingFiles.length === 0) {
-                addLogLine("no clip embedding extraction needed, all done");
+                log.info("no clip embedding extraction needed, all done");
                 return;
                 return;
             }
             }
-            addLogLine(
+            log.info(
                 `starting clip embedding extraction for ${pendingFiles.length} files`,
                 `starting clip embedding extraction for ${pendingFiles.length} files`,
             );
             );
             for (const file of pendingFiles) {
             for (const file of pendingFiles) {
                 try {
                 try {
-                    addLogLine(
+                    log.info(
                         `extracting clip embedding for file: ${file.metadata.title} fileID: ${file.id}`,
                         `extracting clip embedding for file: ${file.metadata.title} fileID: ${file.id}`,
                     );
                     );
                     if (canceller.signal.aborted) {
                     if (canceller.signal.aborted) {
@@ -210,7 +209,7 @@ class ClipServiceImpl {
                     }
                     }
                     const embeddingData =
                     const embeddingData =
                         await this.extractFileClipImageEmbedding(model, file);
                         await this.extractFileClipImageEmbedding(model, file);
-                    addLogLine(
+                    log.info(
                         `successfully extracted clip embedding for file: ${file.metadata.title} fileID: ${file.id} embedding length: ${embeddingData?.length}`,
                         `successfully extracted clip embedding for file: ${file.metadata.title} fileID: ${file.id} embedding length: ${embeddingData?.length}`,
                     );
                     );
                     await this.encryptAndUploadEmbedding(
                     await this.encryptAndUploadEmbedding(
@@ -219,14 +218,14 @@ class ClipServiceImpl {
                         embeddingData,
                         embeddingData,
                     );
                     );
                     this.onSuccessStatusUpdater();
                     this.onSuccessStatusUpdater();
-                    addLogLine(
+                    log.info(
                         `successfully put clip embedding to server for file: ${file.metadata.title} fileID: ${file.id}`,
                         `successfully put clip embedding to server for file: ${file.metadata.title} fileID: ${file.id}`,
                     );
                     );
                 } catch (e) {
                 } catch (e) {
                     if (e?.message !== CustomError.REQUEST_CANCELLED) {
                     if (e?.message !== CustomError.REQUEST_CANCELLED) {
-                        logError(
-                            e,
+                        log.error(
                             "failed to extract clip embedding for file",
                             "failed to extract clip embedding for file",
+                            e,
                         );
                         );
                     }
                     }
                     if (
                     if (
@@ -244,7 +243,7 @@ class ClipServiceImpl {
             }
             }
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.REQUEST_CANCELLED) {
             if (e.message !== CustomError.REQUEST_CANCELLED) {
-                logError(e, "failed to extract clip embedding");
+                log.error("failed to extract clip embedding", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -258,24 +257,24 @@ class ClipServiceImpl {
         model: Model = Model.ONNX_CLIP,
         model: Model = Model.ONNX_CLIP,
     ) {
     ) {
         const { enteFile, localFile } = arg;
         const { enteFile, localFile } = arg;
-        addLogLine(
+        log.info(
             `clip embedding extraction onFileUploadedHandler file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
             `clip embedding extraction onFileUploadedHandler file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
             enteFile.id,
             enteFile.id,
         );
         );
         if (enteFile.metadata.fileType === FILE_TYPE.VIDEO) {
         if (enteFile.metadata.fileType === FILE_TYPE.VIDEO) {
-            addLogLine(
+            log.info(
                 `skipping video file for clip embedding extraction file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
                 `skipping video file for clip embedding extraction file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
             );
             );
             return;
             return;
         }
         }
         const extension = enteFile.metadata.title.split(".").pop();
         const extension = enteFile.metadata.title.split(".").pop();
         if (!extension || !["jpg", "jpeg"].includes(extension)) {
         if (!extension || !["jpg", "jpeg"].includes(extension)) {
-            addLogLine(
+            log.info(
                 `skipping non jpg file for clip embedding extraction file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
                 `skipping non jpg file for clip embedding extraction file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
             );
             );
             return;
             return;
         }
         }
-        addLogLine(
+        log.info(
             `queuing up for local clip embedding extraction for file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
             `queuing up for local clip embedding extraction for file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
         );
         );
         try {
         try {
@@ -290,11 +289,11 @@ class ClipServiceImpl {
                     embedding,
                     embedding,
                 );
                 );
             });
             });
-            addLogLine(
+            log.info(
                 `successfully extracted clip embedding for file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
                 `successfully extracted clip embedding for file: ${enteFile.metadata.title} fileID: ${enteFile.id}`,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed in ML onFileUploadedHandler");
+            log.error("Failed in ML onFileUploadedHandler", e);
         }
         }
     }
     }
 
 
@@ -305,7 +304,10 @@ class ClipServiceImpl {
         const file = await localFile
         const file = await localFile
             .arrayBuffer()
             .arrayBuffer()
             .then((buffer) => new Uint8Array(buffer));
             .then((buffer) => new Uint8Array(buffer));
-        const embedding = await ElectronAPIs.computeImageEmbedding(model, file);
+        const embedding = await ensureElectron().computeImageEmbedding(
+            model,
+            file,
+        );
         return embedding;
         return embedding;
     };
     };
 
 
@@ -322,7 +324,7 @@ class ClipServiceImpl {
         const comlinkCryptoWorker = await ComlinkCryptoWorker.getInstance();
         const comlinkCryptoWorker = await ComlinkCryptoWorker.getInstance();
         const { file: encryptedEmbeddingData } =
         const { file: encryptedEmbeddingData } =
             await comlinkCryptoWorker.encryptEmbedding(embeddingData, file.key);
             await comlinkCryptoWorker.encryptEmbedding(embeddingData, file.key);
-        addLogLine(
+        log.info(
             `putting clip embedding to server for file: ${file.metadata.title} fileID: ${file.id}`,
             `putting clip embedding to server for file: ${file.metadata.title} fileID: ${file.id}`,
         );
         );
         await putEmbedding({
         await putEmbedding({
@@ -345,7 +347,7 @@ class ClipServiceImpl {
         file: EnteFile,
         file: EnteFile,
     ) => {
     ) => {
         const thumb = await downloadManager.getThumbnail(file);
         const thumb = await downloadManager.getThumbnail(file);
-        const embedding = await ElectronAPIs.computeImageEmbedding(
+        const embedding = await ensureElectron().computeImageEmbedding(
             model,
             model,
             thumb,
             thumb,
         );
         );

+ 27 - 26
web/apps/photos/src/services/collectionService.ts

@@ -2,10 +2,10 @@ import { getEndpoint } from "@ente/shared/network/api";
 import localForage from "@ente/shared/storage/localForage";
 import localForage from "@ente/shared/storage/localForage";
 import { getData, LS_KEYS } from "@ente/shared/storage/localStorage";
 import { getData, LS_KEYS } from "@ente/shared/storage/localStorage";
 
 
+import log from "@/next/log";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
-import { logError } from "@ente/shared/sentry";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getActualKey } from "@ente/shared/user";
 import { getActualKey } from "@ente/shared/user";
 import { User } from "@ente/shared/user/types";
 import { User } from "@ente/shared/user/types";
@@ -198,9 +198,10 @@ const getCollections = async (
                     try {
                     try {
                         return await getCollectionWithSecrets(collection, key);
                         return await getCollectionWithSecrets(collection, key);
                     } catch (e) {
                     } catch (e) {
-                        logError(e, `decryption failed for collection`, {
-                            collectionID: collection.id,
-                        });
+                        log.error(
+                            `decryption failed for collection with ID ${collection.id}`,
+                            e,
+                        );
                         return collection;
                         return collection;
                     }
                     }
                 },
                 },
@@ -212,7 +213,7 @@ const getCollections = async (
         );
         );
         return collections;
         return collections;
     } catch (e) {
     } catch (e) {
-        logError(e, "getCollections failed");
+        log.error("getCollections failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -340,7 +341,7 @@ export const getCollection = async (
         );
         );
         return collectionWithSecrets;
         return collectionWithSecrets;
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get collection");
+        log.error("failed to get collection", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -462,7 +463,7 @@ const createCollection = async (
         );
         );
         return decryptedCreatedCollection;
         return decryptedCreatedCollection;
     } catch (e) {
     } catch (e) {
-        logError(e, "create collection failed");
+        log.error("create collection failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -480,7 +481,7 @@ const postCollection = async (
         );
         );
         return response.data.collection;
         return response.data.collection;
     } catch (e) {
     } catch (e) {
-        logError(e, "post Collection failed ");
+        log.error("post Collection failed ", e);
     }
     }
 };
 };
 
 
@@ -496,7 +497,7 @@ export const addToFavorites = async (file: EnteFile) => {
         }
         }
         await addToCollection(favCollection, [file]);
         await addToCollection(favCollection, [file]);
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to add to favorite");
+        log.error("failed to add to favorite", e);
     }
     }
 };
 };
 
 
@@ -508,7 +509,7 @@ export const removeFromFavorites = async (file: EnteFile) => {
         }
         }
         await removeFromCollection(favCollection.id, [file]);
         await removeFromCollection(favCollection.id, [file]);
     } catch (e) {
     } catch (e) {
-        logError(e, "remove from favorite failed");
+        log.error("remove from favorite failed", e);
     }
     }
 };
 };
 
 
@@ -537,7 +538,7 @@ export const addToCollection = async (
             );
             );
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "Add to collection Failed ");
+        log.error("Add to collection Failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -567,7 +568,7 @@ export const restoreToCollection = async (
             );
             );
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "restore to collection Failed ");
+        log.error("restore to collection Failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -598,7 +599,7 @@ export const moveToCollection = async (
             );
             );
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "move to collection Failed ");
+        log.error("move to collection Failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -649,7 +650,7 @@ export const removeFromCollection = async (
             await removeUserFiles(collectionID, userFiles, allFiles);
             await removeUserFiles(collectionID, userFiles, allFiles);
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "remove from collection failed ");
+        log.error("remove from collection failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -715,7 +716,7 @@ export const removeUserFiles = async (
             leftFiles,
             leftFiles,
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "remove user files failed ");
+        log.error("remove user files failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -742,7 +743,7 @@ export const removeNonUserFiles = async (
             );
             );
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "remove non user files failed ");
+        log.error("remove non user files failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -768,7 +769,7 @@ export const deleteCollection = async (
             { "X-Auth-Token": token },
             { "X-Auth-Token": token },
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "delete collection failed ");
+        log.error("delete collection failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -784,7 +785,7 @@ export const leaveSharedAlbum = async (collectionID: number) => {
             { "X-Auth-Token": token },
             { "X-Auth-Token": token },
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "leave shared album failed ");
+        log.error("leave shared album failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -976,7 +977,7 @@ export const shareCollection = async (
             },
             },
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "share collection failed ");
+        log.error("share collection failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -1000,7 +1001,7 @@ export const unshareCollection = async (
             },
             },
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "unshare collection failed ");
+        log.error("unshare collection failed ", e);
     }
     }
 };
 };
 
 
@@ -1023,7 +1024,7 @@ export const createShareableURL = async (collection: Collection) => {
         );
         );
         return resp.data.result as PublicURL;
         return resp.data.result as PublicURL;
     } catch (e) {
     } catch (e) {
-        logError(e, "createShareableURL failed ");
+        log.error("createShareableURL failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -1043,7 +1044,7 @@ export const deleteShareableURL = async (collection: Collection) => {
             },
             },
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "deleteShareableURL failed ");
+        log.error("deleteShareableURL failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -1066,7 +1067,7 @@ export const updateShareableURL = async (
         );
         );
         return res.data.result as PublicURL;
         return res.data.result as PublicURL;
     } catch (e) {
     } catch (e) {
-        logError(e, "updateShareableURL failed ");
+        log.error("updateShareableURL failed ", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -1392,7 +1393,7 @@ export async function moveToHiddenCollection(files: EnteFile[]) {
             await moveToCollection(collectionID, hiddenCollection, files);
             await moveToCollection(collectionID, hiddenCollection, files);
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "move to hidden collection failed ");
+        log.error("move to hidden collection failed ", e);
         throw e;
         throw e;
     }
     }
 }
 }
@@ -1411,7 +1412,7 @@ export async function unhideToCollection(
             await moveToCollection(collectionID, collection, files);
             await moveToCollection(collectionID, collection, files);
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "unhide to collection failed ");
+        log.error("unhide to collection failed ", e);
         throw e;
         throw e;
     }
     }
 }
 }
@@ -1436,7 +1437,7 @@ export const constructUserIDToEmailMap = (
         });
         });
         return userIDToEmailMap;
         return userIDToEmailMap;
     } catch (e) {
     } catch (e) {
-        logError("Error Mapping UserId to email:", e);
+        log.error("Error Mapping UserId to email:", e);
         return new Map<number, string>();
         return new Map<number, string>();
     }
     }
 };
 };

+ 3 - 3
web/apps/photos/src/services/deduplicationService.ts

@@ -1,6 +1,6 @@
+import log from "@/next/log";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint } from "@ente/shared/network/api";
 import { getEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import { EnteFile } from "types/file";
 import { EnteFile } from "types/file";
@@ -64,7 +64,7 @@ export async function getDuplicates(
 
 
         return result;
         return result;
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get duplicate files");
+        log.error("failed to get duplicate files", e);
     }
     }
 }
 }
 
 
@@ -156,7 +156,7 @@ async function fetchDuplicateFileIDs() {
         );
         );
         return (response.data as DuplicatesResponse).duplicates;
         return (response.data as DuplicatesResponse).duplicates;
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to fetch duplicate file IDs");
+        log.error("failed to fetch duplicate file IDs", e);
     }
     }
 }
 }
 
 

+ 36 - 67
web/apps/photos/src/services/download/index.ts

@@ -1,22 +1,20 @@
-import { EnteFile } from "types/file";
-import {
-    generateStreamFromArrayBuffer,
-    getRenderableFileURL,
-} from "utils/file";
-
+import log from "@/next/log";
 import { APPS } from "@ente/shared/apps/constants";
 import { APPS } from "@ente/shared/apps/constants";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
 import { Events, eventBus } from "@ente/shared/events";
 import { Events, eventBus } from "@ente/shared/events";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
 import { CacheStorageService } from "@ente/shared/storage/cacheStorage";
 import { CacheStorageService } from "@ente/shared/storage/cacheStorage";
 import { CACHES } from "@ente/shared/storage/cacheStorage/constants";
 import { CACHES } from "@ente/shared/storage/cacheStorage/constants";
 import { LimitedCache } from "@ente/shared/storage/cacheStorage/types";
 import { LimitedCache } from "@ente/shared/storage/cacheStorage/types";
 import { Remote } from "comlink";
 import { Remote } from "comlink";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import isElectron from "is-electron";
 import isElectron from "is-electron";
+import { EnteFile } from "types/file";
+import {
+    generateStreamFromArrayBuffer,
+    getRenderableFileURL,
+} from "utils/file";
 import { isInternalUser } from "utils/user";
 import { isInternalUser } from "utils/user";
 import { PhotosDownloadClient } from "./clients/photos";
 import { PhotosDownloadClient } from "./clients/photos";
 import { PublicAlbumsDownloadClient } from "./clients/publicAlbums";
 import { PublicAlbumsDownloadClient } from "./clients/publicAlbums";
@@ -80,7 +78,7 @@ class DownloadManagerImpl {
     ) {
     ) {
         try {
         try {
             if (this.ready) {
             if (this.ready) {
-                addLogLine("DownloadManager already initialized");
+                log.info("DownloadManager already initialized");
                 return;
                 return;
             }
             }
             this.downloadClient = createDownloadClient(app, tokens, timeout);
             this.downloadClient = createDownloadClient(app, tokens, timeout);
@@ -90,14 +88,14 @@ class DownloadManagerImpl {
             this.ready = true;
             this.ready = true;
             eventBus.on(Events.LOGOUT, this.logoutHandler.bind(this), this);
             eventBus.on(Events.LOGOUT, this.logoutHandler.bind(this), this);
         } catch (e) {
         } catch (e) {
-            logError(e, "DownloadManager init failed");
+            log.error("DownloadManager init failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
 
 
     private async logoutHandler() {
     private async logoutHandler() {
         try {
         try {
-            addLogLine("downloadManger logoutHandler started");
+            log.info("downloadManger logoutHandler started");
             this.ready = false;
             this.ready = false;
             this.cryptoWorker = null;
             this.cryptoWorker = null;
             this.downloadClient = null;
             this.downloadClient = null;
@@ -106,9 +104,9 @@ class DownloadManagerImpl {
             this.thumbnailObjectURLPromises.clear();
             this.thumbnailObjectURLPromises.clear();
             this.fileDownloadProgress.clear();
             this.fileDownloadProgress.clear();
             this.progressUpdater = () => {};
             this.progressUpdater = () => {};
-            addLogLine("downloadManager logoutHandler completed");
+            log.info("downloadManager logoutHandler completed");
         } catch (e) {
         } catch (e) {
-            logError(e, "downloadManager logoutHandler failed");
+            log.error("downloadManager logoutHandler failed", e);
         }
         }
     }
     }
 
 
@@ -138,7 +136,7 @@ class DownloadManagerImpl {
                 return new Uint8Array(await cacheResp.arrayBuffer());
                 return new Uint8Array(await cacheResp.arrayBuffer());
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to get cached thumbnail");
+            log.error("failed to get cached thumbnail", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -153,7 +151,7 @@ class DownloadManagerImpl {
             );
             );
             return cacheResp?.clone();
             return cacheResp?.clone();
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to get cached file");
+            log.error("failed to get cached file", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -185,12 +183,12 @@ class DownloadManagerImpl {
             this.thumbnailCache
             this.thumbnailCache
                 ?.put(file.id.toString(), new Response(thumb))
                 ?.put(file.id.toString(), new Response(thumb))
                 .catch((e) => {
                 .catch((e) => {
-                    logError(e, "thumb cache put failed");
+                    log.error("thumb cache put failed", e);
                     // TODO: handle storage full exception.
                     // TODO: handle storage full exception.
                 });
                 });
             return thumb;
             return thumb;
         } catch (e) {
         } catch (e) {
-            logError(e, "getThumbnail failed");
+            log.error("getThumbnail failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -215,7 +213,7 @@ class DownloadManagerImpl {
             return thumb;
             return thumb;
         } catch (e) {
         } catch (e) {
             this.thumbnailObjectURLPromises.delete(file.id);
             this.thumbnailObjectURLPromises.delete(file.id);
-            logError(e, "get DownloadManager preview Failed");
+            log.error("get DownloadManager preview Failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -253,7 +251,7 @@ class DownloadManagerImpl {
             return fileURLs;
             return fileURLs;
         } catch (e) {
         } catch (e) {
             this.fileConversionPromises.delete(file.id);
             this.fileConversionPromises.delete(file.id);
-            logError(e, "download manager getFileForPreview Failed");
+            log.error("download manager getFileForPreview Failed", e);
             throw e;
             throw e;
         }
         }
     };
     };
@@ -291,7 +289,7 @@ class DownloadManagerImpl {
             }
             }
         } catch (e) {
         } catch (e) {
             this.fileObjectURLPromises.delete(file.id);
             this.fileObjectURLPromises.delete(file.id);
-            logError(e, "download manager getFile Failed");
+            log.error("download manager getFile Failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -300,7 +298,7 @@ class DownloadManagerImpl {
         file: EnteFile,
         file: EnteFile,
     ): Promise<ReadableStream<Uint8Array>> {
     ): Promise<ReadableStream<Uint8Array>> {
         try {
         try {
-            addLogLine(`download attempted for fileID:${file.id}`);
+            log.info(`download attempted for fileID:${file.id}`);
             const onDownloadProgress = this.trackDownloadProgress(
             const onDownloadProgress = this.trackDownloadProgress(
                 file.id,
                 file.id,
                 file.info?.fileSize,
                 file.info?.fileSize,
@@ -321,7 +319,7 @@ class DownloadManagerImpl {
                         this.diskFileCache
                         this.diskFileCache
                             .put(file.id.toString(), encrypted.clone())
                             .put(file.id.toString(), encrypted.clone())
                             .catch((e) => {
                             .catch((e) => {
-                                logError(e, "file cache put failed");
+                                log.error("file cache put failed", e);
                                 // TODO: handle storage full exception.
                                 // TODO: handle storage full exception.
                             });
                             });
                     }
                     }
@@ -338,15 +336,9 @@ class DownloadManagerImpl {
                     return generateStreamFromArrayBuffer(decrypted);
                     return generateStreamFromArrayBuffer(decrypted);
                 } catch (e) {
                 } catch (e) {
                     if (e.message === CustomError.PROCESSING_FAILED) {
                     if (e.message === CustomError.PROCESSING_FAILED) {
-                        logError(e, "Failed to process file", {
-                            fileID: file.id,
-                            fromMobile:
-                                !!file.metadata.localID ||
-                                !!file.metadata.deviceFolder ||
-                                !!file.metadata.version,
-                        });
-                        addLogLine(
-                            `Failed to process file with fileID:${file.id}, localID: ${file.metadata.localID}, version: ${file.metadata.version}, deviceFolder:${file.metadata.deviceFolder} with error: ${e.message}`,
+                        log.error(
+                            `Failed to process file with fileID:${file.id}, localID: ${file.metadata.localID}, version: ${file.metadata.version}, deviceFolder:${file.metadata.deviceFolder}`,
+                            e,
                         );
                         );
                     }
                     }
                     throw e;
                     throw e;
@@ -360,7 +352,7 @@ class DownloadManagerImpl {
                     this.diskFileCache
                     this.diskFileCache
                         .put(file.id.toString(), resp.clone())
                         .put(file.id.toString(), resp.clone())
                         .catch((e) => {
                         .catch((e) => {
-                            logError(e, "file cache put failed");
+                            log.error("file cache put failed", e);
                         });
                         });
                 }
                 }
             }
             }
@@ -430,22 +422,9 @@ class DownloadManagerImpl {
                                                     e.message ===
                                                     e.message ===
                                                     CustomError.PROCESSING_FAILED
                                                     CustomError.PROCESSING_FAILED
                                                 ) {
                                                 ) {
-                                                    logError(
+                                                    log.error(
+                                                        `Failed to process file ${file.id} from localID: ${file.metadata.localID} version: ${file.metadata.version} deviceFolder:${file.metadata.deviceFolder}`,
                                                         e,
                                                         e,
-                                                        "Failed to process file",
-                                                        {
-                                                            fileID: file.id,
-                                                            fromMobile:
-                                                                !!file.metadata
-                                                                    .localID ||
-                                                                !!file.metadata
-                                                                    .deviceFolder ||
-                                                                !!file.metadata
-                                                                    .version,
-                                                        },
-                                                    );
-                                                    addLogLine(
-                                                        `Failed to process file ${file.id} from localID: ${file.metadata.localID} version: ${file.metadata.version} deviceFolder:${file.metadata.deviceFolder} with error: ${e.message}`,
                                                     );
                                                     );
                                                 }
                                                 }
                                                 throw e;
                                                 throw e;
@@ -471,22 +450,9 @@ class DownloadManagerImpl {
                                                     e.message ===
                                                     e.message ===
                                                     CustomError.PROCESSING_FAILED
                                                     CustomError.PROCESSING_FAILED
                                                 ) {
                                                 ) {
-                                                    logError(
+                                                    log.error(
+                                                        `Failed to process file ${file.id} from localID: ${file.metadata.localID} version: ${file.metadata.version} deviceFolder:${file.metadata.deviceFolder}`,
                                                         e,
                                                         e,
-                                                        "Failed to process file",
-                                                        {
-                                                            fileID: file.id,
-                                                            fromMobile:
-                                                                !!file.metadata
-                                                                    .localID ||
-                                                                !!file.metadata
-                                                                    .deviceFolder ||
-                                                                !!file.metadata
-                                                                    .version,
-                                                        },
-                                                    );
-                                                    addLogLine(
-                                                        `Failed to process file ${file.id} from localID: ${file.metadata.localID} version: ${file.metadata.version} deviceFolder:${file.metadata.deviceFolder} with error: ${e.message}`,
                                                     );
                                                     );
                                                 }
                                                 }
                                                 throw e;
                                                 throw e;
@@ -495,7 +461,10 @@ class DownloadManagerImpl {
                                         controller.close();
                                         controller.close();
                                     }
                                     }
                                 } catch (e) {
                                 } catch (e) {
-                                    logError(e, "Failed to process file chunk");
+                                    log.error(
+                                        "Failed to process file chunk",
+                                        e,
+                                    );
                                     controller.error(e);
                                     controller.error(e);
                                 }
                                 }
                             });
                             });
@@ -503,14 +472,14 @@ class DownloadManagerImpl {
 
 
                         push();
                         push();
                     } catch (e) {
                     } catch (e) {
-                        logError(e, "Failed to process file stream");
+                        log.error("Failed to process file stream", e);
                         controller.error(e);
                         controller.error(e);
                     }
                     }
                 },
                 },
             });
             });
             return stream;
             return stream;
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed to download file");
+            log.error("Failed to download file", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -549,7 +518,7 @@ async function openThumbnailCache() {
     try {
     try {
         return await CacheStorageService.open(CACHES.THUMBS);
         return await CacheStorageService.open(CACHES.THUMBS);
     } catch (e) {
     } catch (e) {
-        logError(e, "Failed to open thumbnail cache");
+        log.error("Failed to open thumbnail cache", e);
         if (isInternalUser()) {
         if (isInternalUser()) {
             throw e;
             throw e;
         } else {
         } else {
@@ -565,7 +534,7 @@ async function openDiskFileCache() {
         }
         }
         return await CacheStorageService.open(CACHES.FILES);
         return await CacheStorageService.open(CACHES.FILES);
     } catch (e) {
     } catch (e) {
-        logError(e, "Failed to open file cache");
+        log.error("Failed to open file cache", e);
         if (isInternalUser()) {
         if (isInternalUser()) {
             throw e;
             throw e;
         } else {
         } else {

+ 12 - 18
web/apps/photos/src/services/embeddingService.ts

@@ -1,9 +1,8 @@
+import log from "@/next/log";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { addLogLine } from "@ente/shared/logging";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint } from "@ente/shared/network/api";
 import { getEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import localForage from "@ente/shared/storage/localForage";
 import localForage from "@ente/shared/storage/localForage";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import {
 import {
@@ -68,10 +67,10 @@ export const syncEmbeddings = async (models: Model[] = [Model.ONNX_CLIP]) => {
             fileIdToKeyMap.set(file.id, file.key);
             fileIdToKeyMap.set(file.id, file.key);
         });
         });
         await cleanupDeletedEmbeddings(allLocalFiles, allEmbeddings);
         await cleanupDeletedEmbeddings(allLocalFiles, allEmbeddings);
-        addLogLine(`Syncing embeddings localCount: ${allEmbeddings.length}`);
+        log.info(`Syncing embeddings localCount: ${allEmbeddings.length}`);
         for (const model of models) {
         for (const model of models) {
             let modelLastSinceTime = await getModelEmbeddingSyncTime(model);
             let modelLastSinceTime = await getModelEmbeddingSyncTime(model);
-            addLogLine(
+            log.info(
                 `Syncing ${model} model's embeddings sinceTime: ${modelLastSinceTime}`,
                 `Syncing ${model} model's embeddings sinceTime: ${modelLastSinceTime}`,
             );
             );
             let response: GetEmbeddingDiffResponse;
             let response: GetEmbeddingDiffResponse;
@@ -107,18 +106,13 @@ export const syncEmbeddings = async (models: Model[] = [Model.ONNX_CLIP]) => {
                                 embedding: decryptedData,
                                 embedding: decryptedData,
                             } as Embedding;
                             } as Embedding;
                         } catch (e) {
                         } catch (e) {
-                            let info: Record<string, unknown>;
+                            let hasHiddenAlbums = false;
                             if (e.message === CustomError.FILE_NOT_FOUND) {
                             if (e.message === CustomError.FILE_NOT_FOUND) {
-                                const hasHiddenAlbums =
-                                    hiddenAlbums?.length > 0;
-                                info = {
-                                    hasHiddenAlbums,
-                                };
+                                hasHiddenAlbums = hiddenAlbums?.length > 0;
                             }
                             }
-                            logError(
+                            log.error(
+                                `decryptEmbedding failed for file (hasHiddenAlbums: ${hasHiddenAlbums})`,
                                 e,
                                 e,
-                                "decryptEmbedding failed for file",
-                                info,
                             );
                             );
                         }
                         }
                     }),
                     }),
@@ -132,13 +126,13 @@ export const syncEmbeddings = async (models: Model[] = [Model.ONNX_CLIP]) => {
                 }
                 }
                 await localForage.setItem(EMBEDDINGS_TABLE, allEmbeddings);
                 await localForage.setItem(EMBEDDINGS_TABLE, allEmbeddings);
                 await setModelEmbeddingSyncTime(model, modelLastSinceTime);
                 await setModelEmbeddingSyncTime(model, modelLastSinceTime);
-                addLogLine(
+                log.info(
                     `Syncing embeddings syncedEmbeddingsCount: ${allEmbeddings.length}`,
                     `Syncing embeddings syncedEmbeddingsCount: ${allEmbeddings.length}`,
                 );
                 );
             } while (response.diff.length === DIFF_LIMIT);
             } while (response.diff.length === DIFF_LIMIT);
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "Sync embeddings failed");
+        log.error("Sync embeddings failed", e);
     }
     }
 };
 };
 
 
@@ -164,7 +158,7 @@ export const getEmbeddingsDiff = async (
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "get embeddings diff failed");
+        log.error("get embeddings diff failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -187,7 +181,7 @@ export const putEmbedding = async (
         );
         );
         return resp.data;
         return resp.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "put embedding failed");
+        log.error("put embedding failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -205,7 +199,7 @@ export const cleanupDeletedEmbeddings = async (
         activeFileIds.has(embedding.fileID),
         activeFileIds.has(embedding.fileID),
     );
     );
     if (allLocalEmbeddings.length !== remainingEmbeddings.length) {
     if (allLocalEmbeddings.length !== remainingEmbeddings.length) {
-        addLogLine(
+        log.info(
             `cleanupDeletedEmbeddings embeddingsCount: ${allLocalEmbeddings.length} remainingEmbeddingsCount: ${remainingEmbeddings.length}`,
             `cleanupDeletedEmbeddings embeddingsCount: ${allLocalEmbeddings.length} remainingEmbeddingsCount: ${remainingEmbeddings.length}`,
         );
         );
         await localForage.setItem(EMBEDDINGS_TABLE, remainingEmbeddings);
         await localForage.setItem(EMBEDDINGS_TABLE, remainingEmbeddings);

+ 9 - 10
web/apps/photos/src/services/entityService.ts

@@ -1,8 +1,7 @@
+import log from "@/next/log";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
-import { addLogLine } from "@ente/shared/logging";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint } from "@ente/shared/network/api";
 import { getEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import localForage from "@ente/shared/storage/localForage";
 import localForage from "@ente/shared/storage/localForage";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getActualKey } from "@ente/shared/user";
 import { getActualKey } from "@ente/shared/user";
@@ -82,7 +81,7 @@ const getEntityKey = async (type: EntityType) => {
         localForage.setItem(ENTITY_KEY_TABLES[type], decryptedEntityKey);
         localForage.setItem(ENTITY_KEY_TABLES[type], decryptedEntityKey);
         return decryptedEntityKey;
         return decryptedEntityKey;
     } catch (e) {
     } catch (e) {
-        logError(e, "Get entity key failed");
+        log.error("Get entity key failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -92,7 +91,7 @@ export const getLatestEntities = async <T>(type: EntityType) => {
         await syncEntity<T>(type);
         await syncEntity<T>(type);
         return await getLocalEntity<T>(type);
         return await getLocalEntity<T>(type);
     } catch (e) {
     } catch (e) {
-        logError(e, "Sync entities failed");
+        log.error("Sync entities failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -101,7 +100,7 @@ export const syncEntities = async () => {
     try {
     try {
         await syncEntity(EntityType.LOCATION_TAG);
         await syncEntity(EntityType.LOCATION_TAG);
     } catch (e) {
     } catch (e) {
-        logError(e, "Sync entities failed");
+        log.error("Sync entities failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -109,11 +108,11 @@ export const syncEntities = async () => {
 const syncEntity = async <T>(type: EntityType): Promise<Entity<T>> => {
 const syncEntity = async <T>(type: EntityType): Promise<Entity<T>> => {
     try {
     try {
         let entities = await getLocalEntity(type);
         let entities = await getLocalEntity(type);
-        addLogLine(
+        log.info(
             `Syncing ${type} entities localEntitiesCount: ${entities.length}`,
             `Syncing ${type} entities localEntitiesCount: ${entities.length}`,
         );
         );
         let syncTime = await getEntityLastSyncTime(type);
         let syncTime = await getEntityLastSyncTime(type);
-        addLogLine(`Syncing ${type} entities syncTime: ${syncTime}`);
+        log.info(`Syncing ${type} entities syncTime: ${syncTime}`);
         let response: EntitySyncDiffResponse;
         let response: EntitySyncDiffResponse;
         do {
         do {
             response = await getEntityDiff(type, syncTime);
             response = await getEntityDiff(type, syncTime);
@@ -157,12 +156,12 @@ const syncEntity = async <T>(type: EntityType): Promise<Entity<T>> => {
             }
             }
             await localForage.setItem(ENTITY_TABLES[type], nonDeletedEntities);
             await localForage.setItem(ENTITY_TABLES[type], nonDeletedEntities);
             await localForage.setItem(ENTITY_SYNC_TIME_TABLES[type], syncTime);
             await localForage.setItem(ENTITY_SYNC_TIME_TABLES[type], syncTime);
-            addLogLine(
+            log.info(
                 `Syncing ${type} entities syncedEntitiesCount: ${nonDeletedEntities.length}`,
                 `Syncing ${type} entities syncedEntitiesCount: ${nonDeletedEntities.length}`,
             );
             );
         } while (response.diff.length === DIFF_LIMIT);
         } while (response.diff.length === DIFF_LIMIT);
     } catch (e) {
     } catch (e) {
-        logError(e, "Sync entity failed");
+        log.error("Sync entity failed", e);
     }
     }
 };
 };
 
 
@@ -189,7 +188,7 @@ const getEntityDiff = async (
 
 
         return resp.data;
         return resp.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "Get entity diff failed");
+        log.error("Get entity diff failed", e);
         throw e;
         throw e;
     }
     }
 };
 };

+ 111 - 112
web/apps/photos/src/services/export/index.ts

@@ -1,7 +1,29 @@
-import { logError } from "@ente/shared/sentry";
+import { ensureElectron } from "@/next/electron";
+import log from "@/next/log";
+import { CustomError } from "@ente/shared/error";
+import { Events, eventBus } from "@ente/shared/events";
 import { LS_KEYS, getData, setData } from "@ente/shared/storage/localStorage";
 import { LS_KEYS, getData, setData } from "@ente/shared/storage/localStorage";
+import { User } from "@ente/shared/user/types";
 import { sleep } from "@ente/shared/utils";
 import { sleep } from "@ente/shared/utils";
+import QueueProcessor, {
+    CancellationStatus,
+    RequestCanceller,
+} from "@ente/shared/utils/queueProcessor";
+import { ExportStage } from "constants/export";
+import { FILE_TYPE } from "constants/file";
+import { Collection } from "types/collection";
+import {
+    ExportProgress,
+    ExportRecord,
+    ExportSettings,
+    ExportUIUpdaters,
+} from "types/export";
 import { EnteFile } from "types/file";
 import { EnteFile } from "types/file";
+import {
+    constructCollectionNameMap,
+    getCollectionUserFacingName,
+    getNonEmptyPersonalCollections,
+} from "utils/collection";
 import {
 import {
     convertCollectionIDExportNameObjectToMap,
     convertCollectionIDExportNameObjectToMap,
     convertFileIDExportNameObjectToMap,
     convertFileIDExportNameObjectToMap,
@@ -25,41 +47,16 @@ import {
     isLivePhotoExportName,
     isLivePhotoExportName,
     parseLivePhotoExportName,
     parseLivePhotoExportName,
 } from "utils/export";
 } from "utils/export";
-import { getAllLocalCollections } from "../collectionService";
-import downloadManager from "../download";
-import { getAllLocalFiles } from "../fileService";
-
 import {
 import {
     generateStreamFromArrayBuffer,
     generateStreamFromArrayBuffer,
     getPersonalFiles,
     getPersonalFiles,
     getUpdatedEXIFFileForDownload,
     getUpdatedEXIFFileForDownload,
     mergeMetadata,
     mergeMetadata,
 } from "utils/file";
 } from "utils/file";
+import { getAllLocalCollections } from "../collectionService";
+import downloadManager from "../download";
+import { getAllLocalFiles } from "../fileService";
 import { decodeLivePhoto } from "../livePhotoService";
 import { decodeLivePhoto } from "../livePhotoService";
-
-import ElectronAPIs from "@/next/electron";
-import { CustomError } from "@ente/shared/error";
-import { Events, eventBus } from "@ente/shared/events";
-import { addLogLine } from "@ente/shared/logging";
-import { User } from "@ente/shared/user/types";
-import QueueProcessor, {
-    CancellationStatus,
-    RequestCanceller,
-} from "@ente/shared/utils/queueProcessor";
-import { ExportStage } from "constants/export";
-import { FILE_TYPE } from "constants/file";
-import { Collection } from "types/collection";
-import {
-    ExportProgress,
-    ExportRecord,
-    ExportSettings,
-    ExportUIUpdaters,
-} from "types/export";
-import {
-    constructCollectionNameMap,
-    getCollectionUserFacingName,
-    getNonEmptyPersonalCollections,
-} from "utils/collection";
 import { migrateExport } from "./migration";
 import { migrateExport } from "./migration";
 
 
 const EXPORT_RECORD_FILE_NAME = "export_status.json";
 const EXPORT_RECORD_FILE_NAME = "export_status.json";
@@ -102,7 +99,7 @@ class ExportService {
             this.exportSettings = exportSettings;
             this.exportSettings = exportSettings;
             return exportSettings;
             return exportSettings;
         } catch (e) {
         } catch (e) {
-            logError(e, "getExportSettings failed");
+            log.error("getExportSettings failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -114,7 +111,7 @@ class ExportService {
             this.exportSettings = newSettings;
             this.exportSettings = newSettings;
             setData(LS_KEYS.EXPORT, newSettings);
             setData(LS_KEYS.EXPORT, newSettings);
         } catch (e) {
         } catch (e) {
-            logError(e, "updateExportSettings failed");
+            log.error("updateExportSettings failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -125,11 +122,11 @@ class ExportService {
         updateProgress: (progress: ExportProgress) => void,
         updateProgress: (progress: ExportProgress) => void,
     ) {
     ) {
         try {
         try {
-            addLogLine("running migration");
+            log.info("running migration");
             await migrateExport(exportDir, exportRecord, updateProgress);
             await migrateExport(exportDir, exportRecord, updateProgress);
-            addLogLine("migration completed");
+            log.info("migration completed");
         } catch (e) {
         } catch (e) {
-            logError(e, "migration failed");
+            log.error("migration failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -160,16 +157,16 @@ class ExportService {
 
 
     async changeExportDirectory() {
     async changeExportDirectory() {
         try {
         try {
-            const newRootDir = await ElectronAPIs.selectDirectory();
+            const newRootDir = await ensureElectron().selectDirectory();
             if (!newRootDir) {
             if (!newRootDir) {
                 throw Error(CustomError.SELECT_FOLDER_ABORTED);
                 throw Error(CustomError.SELECT_FOLDER_ABORTED);
             }
             }
             const newExportDir = `${newRootDir}/${ENTE_EXPORT_DIRECTORY}`;
             const newExportDir = `${newRootDir}/${ENTE_EXPORT_DIRECTORY}`;
-            await ElectronAPIs.checkExistsAndCreateDir(newExportDir);
+            await ensureElectron().checkExistsAndCreateDir(newExportDir);
             return newExportDir;
             return newExportDir;
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.SELECT_FOLDER_ABORTED) {
             if (e.message !== CustomError.SELECT_FOLDER_ABORTED) {
-                logError(e, "changeExportDirectory failed");
+                log.error("changeExportDirectory failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -178,10 +175,10 @@ class ExportService {
     enableContinuousExport() {
     enableContinuousExport() {
         try {
         try {
             if (this.continuousExportEventHandler) {
             if (this.continuousExportEventHandler) {
-                addLogLine("continuous export already enabled");
+                log.info("continuous export already enabled");
                 return;
                 return;
             }
             }
-            addLogLine("enabling continuous export");
+            log.info("enabling continuous export");
             this.continuousExportEventHandler = () => {
             this.continuousExportEventHandler = () => {
                 this.scheduleExport();
                 this.scheduleExport();
             };
             };
@@ -191,7 +188,7 @@ class ExportService {
                 this.continuousExportEventHandler,
                 this.continuousExportEventHandler,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to enableContinuousExport ");
+            log.error("failed to enableContinuousExport ", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -199,17 +196,17 @@ class ExportService {
     disableContinuousExport() {
     disableContinuousExport() {
         try {
         try {
             if (!this.continuousExportEventHandler) {
             if (!this.continuousExportEventHandler) {
-                addLogLine("continuous export already disabled");
+                log.info("continuous export already disabled");
                 return;
                 return;
             }
             }
-            addLogLine("disabling continuous export");
+            log.info("disabling continuous export");
             eventBus.removeListener(
             eventBus.removeListener(
                 Events.LOCAL_FILES_UPDATED,
                 Events.LOCAL_FILES_UPDATED,
                 this.continuousExportEventHandler,
                 this.continuousExportEventHandler,
             );
             );
             this.continuousExportEventHandler = null;
             this.continuousExportEventHandler = null;
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to disableContinuousExport");
+            log.error("failed to disableContinuousExport", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -239,7 +236,7 @@ class ExportService {
             );
             );
             return unExportedFiles;
             return unExportedFiles;
         } catch (e) {
         } catch (e) {
-            logError(e, "getUpdateFileLists failed");
+            log.error("getUpdateFileLists failed", e);
             throw e;
             throw e;
         }
         }
     };
     };
@@ -271,30 +268,30 @@ class ExportService {
             const pendingExports = await this.getPendingExports(exportRecord);
             const pendingExports = await this.getPendingExports(exportRecord);
             this.uiUpdater.setPendingExports(pendingExports);
             this.uiUpdater.setPendingExports(pendingExports);
         } catch (e) {
         } catch (e) {
-            logError(e, "postExport failed");
+            log.error("postExport failed", e);
         }
         }
     }
     }
 
 
     async stopRunningExport() {
     async stopRunningExport() {
         try {
         try {
-            addLogLine("user requested export cancellation");
+            log.info("user requested export cancellation");
             this.exportInProgress.exec();
             this.exportInProgress.exec();
             this.exportInProgress = null;
             this.exportInProgress = null;
             this.reRunNeeded = false;
             this.reRunNeeded = false;
             await this.postExport();
             await this.postExport();
         } catch (e) {
         } catch (e) {
-            logError(e, "stopRunningExport failed");
+            log.error("stopRunningExport failed", e);
         }
         }
     }
     }
 
 
     scheduleExport = async () => {
     scheduleExport = async () => {
         try {
         try {
             if (this.exportInProgress) {
             if (this.exportInProgress) {
-                addLogLine("export in progress, scheduling re-run");
+                log.info("export in progress, scheduling re-run");
                 this.reRunNeeded = true;
                 this.reRunNeeded = true;
                 return;
                 return;
             } else {
             } else {
-                addLogLine("export not in progress, starting export");
+                log.info("export not in progress, starting export");
             }
             }
 
 
             const isCanceled: CancellationStatus = { status: false };
             const isCanceled: CancellationStatus = { status: false };
@@ -307,22 +304,22 @@ class ExportService {
             try {
             try {
                 const exportFolder = this.getExportSettings()?.folder;
                 const exportFolder = this.getExportSettings()?.folder;
                 await this.preExport(exportFolder);
                 await this.preExport(exportFolder);
-                addLogLine("export started");
+                log.info("export started");
                 await this.runExport(exportFolder, isCanceled);
                 await this.runExport(exportFolder, isCanceled);
-                addLogLine("export completed");
+                log.info("export completed");
             } finally {
             } finally {
                 if (isCanceled.status) {
                 if (isCanceled.status) {
-                    addLogLine("export cancellation done");
+                    log.info("export cancellation done");
                     if (!this.exportInProgress) {
                     if (!this.exportInProgress) {
                         await this.postExport();
                         await this.postExport();
                     }
                     }
                 } else {
                 } else {
                     await this.postExport();
                     await this.postExport();
-                    addLogLine("resetting export in progress after completion");
+                    log.info("resetting export in progress after completion");
                     this.exportInProgress = null;
                     this.exportInProgress = null;
                     if (this.reRunNeeded) {
                     if (this.reRunNeeded) {
                         this.reRunNeeded = false;
                         this.reRunNeeded = false;
-                        addLogLine("re-running export");
+                        log.info("re-running export");
                         setTimeout(() => this.scheduleExport(), 0);
                         setTimeout(() => this.scheduleExport(), 0);
                     }
                     }
                 }
                 }
@@ -332,7 +329,7 @@ class ExportService {
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_STOPPED
                 e.message !== CustomError.EXPORT_STOPPED
             ) {
             ) {
-                logError(e, "scheduleExport failed");
+                log.error("scheduleExport failed", e);
             }
             }
         }
         }
     };
     };
@@ -390,7 +387,7 @@ class ExportService {
                 exportRecord,
                 exportRecord,
             );
             );
 
 
-            addLogLine(
+            log.info(
                 `personal files:${personalFiles.length} unexported files: ${filesToExport.length}, deleted exported files: ${removedFileUIDs.length}, renamed collections: ${renamedCollections.length}, deleted collections: ${deletedExportedCollections.length}`,
                 `personal files:${personalFiles.length} unexported files: ${filesToExport.length}, deleted exported files: ${removedFileUIDs.length}, renamed collections: ${renamedCollections.length}, deleted collections: ${deletedExportedCollections.length}`,
             );
             );
             let success = 0;
             let success = 0;
@@ -416,7 +413,7 @@ class ExportService {
             };
             };
             if (renamedCollections?.length > 0) {
             if (renamedCollections?.length > 0) {
                 this.updateExportStage(ExportStage.RENAMING_COLLECTION_FOLDERS);
                 this.updateExportStage(ExportStage.RENAMING_COLLECTION_FOLDERS);
-                addLogLine(`renaming ${renamedCollections.length} collections`);
+                log.info(`renaming ${renamedCollections.length} collections`);
                 await this.collectionRenamer(
                 await this.collectionRenamer(
                     exportFolder,
                     exportFolder,
                     collectionIDExportNameMap,
                     collectionIDExportNameMap,
@@ -427,7 +424,7 @@ class ExportService {
 
 
             if (removedFileUIDs?.length > 0) {
             if (removedFileUIDs?.length > 0) {
                 this.updateExportStage(ExportStage.TRASHING_DELETED_FILES);
                 this.updateExportStage(ExportStage.TRASHING_DELETED_FILES);
-                addLogLine(`trashing ${removedFileUIDs.length} files`);
+                log.info(`trashing ${removedFileUIDs.length} files`);
                 await this.fileTrasher(
                 await this.fileTrasher(
                     exportFolder,
                     exportFolder,
                     collectionIDExportNameMap,
                     collectionIDExportNameMap,
@@ -437,7 +434,7 @@ class ExportService {
             }
             }
             if (filesToExport?.length > 0) {
             if (filesToExport?.length > 0) {
                 this.updateExportStage(ExportStage.EXPORTING_FILES);
                 this.updateExportStage(ExportStage.EXPORTING_FILES);
-                addLogLine(`exporting ${filesToExport.length} files`);
+                log.info(`exporting ${filesToExport.length} files`);
                 await this.fileExporter(
                 await this.fileExporter(
                     filesToExport,
                     filesToExport,
                     collectionIDNameMap,
                     collectionIDNameMap,
@@ -452,7 +449,7 @@ class ExportService {
                 this.updateExportStage(
                 this.updateExportStage(
                     ExportStage.TRASHING_DELETED_COLLECTIONS,
                     ExportStage.TRASHING_DELETED_COLLECTIONS,
                 );
                 );
-                addLogLine(
+                log.info(
                     `removing ${deletedExportedCollections.length} collections`,
                     `removing ${deletedExportedCollections.length} collections`,
                 );
                 );
                 await this.collectionRemover(
                 await this.collectionRemover(
@@ -466,7 +463,7 @@ class ExportService {
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_STOPPED
                 e.message !== CustomError.EXPORT_STOPPED
             ) {
             ) {
-                logError(e, "runExport failed");
+                log.error("runExport failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -497,7 +494,7 @@ class ExportService {
                             exportFolder,
                             exportFolder,
                             getCollectionUserFacingName(collection),
                             getCollectionUserFacingName(collection),
                         );
                         );
-                    addLogLine(
+                    log.info(
                         `renaming collection with id ${collection.id} from ${oldCollectionExportName} to ${newCollectionExportName}`,
                         `renaming collection with id ${collection.id} from ${oldCollectionExportName} to ${newCollectionExportName}`,
                     );
                     );
                     const newCollectionExportPath = getCollectionExportPath(
                     const newCollectionExportPath = getCollectionExportPath(
@@ -515,7 +512,7 @@ class ExportService {
                         newCollectionExportName,
                         newCollectionExportName,
                     );
                     );
                     try {
                     try {
-                        await ElectronAPIs.rename(
+                        await ensureElectron().rename(
                             oldCollectionExportPath,
                             oldCollectionExportPath,
                             newCollectionExportPath,
                             newCollectionExportPath,
                         );
                         );
@@ -531,11 +528,11 @@ class ExportService {
                         );
                         );
                         throw e;
                         throw e;
                     }
                     }
-                    addLogLine(
+                    log.info(
                         `renaming collection with id ${collection.id} from ${oldCollectionExportName} to ${newCollectionExportName} successful`,
                         `renaming collection with id ${collection.id} from ${oldCollectionExportName} to ${newCollectionExportName} successful`,
                     );
                     );
                 } catch (e) {
                 } catch (e) {
-                    logError(e, "collectionRenamer failed a collection");
+                    log.error("collectionRenamer failed a collection", e);
                     if (
                     if (
                         e.message ===
                         e.message ===
                             CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
                             CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
@@ -552,7 +549,7 @@ class ExportService {
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_STOPPED
                 e.message !== CustomError.EXPORT_STOPPED
             ) {
             ) {
-                logError(e, "collectionRenamer failed");
+                log.error("collectionRenamer failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -575,7 +572,7 @@ class ExportService {
                         throw Error(CustomError.EXPORT_STOPPED);
                         throw Error(CustomError.EXPORT_STOPPED);
                     }
                     }
                     await this.verifyExportFolderExists(exportFolder);
                     await this.verifyExportFolderExists(exportFolder);
-                    addLogLine(
+                    log.info(
                         `removing collection with id ${collectionID} from export folder`,
                         `removing collection with id ${collectionID} from export folder`,
                     );
                     );
                     const collectionExportName =
                     const collectionExportName =
@@ -600,11 +597,13 @@ class ExportService {
                     );
                     );
                     try {
                     try {
                         // delete the collection metadata folder
                         // delete the collection metadata folder
-                        await ElectronAPIs.deleteFolder(
+                        await ensureElectron().deleteFolder(
                             getMetadataFolderExportPath(collectionExportPath),
                             getMetadataFolderExportPath(collectionExportPath),
                         );
                         );
                         // delete the collection folder
                         // delete the collection folder
-                        await ElectronAPIs.deleteFolder(collectionExportPath);
+                        await ensureElectron().deleteFolder(
+                            collectionExportPath,
+                        );
                     } catch (e) {
                     } catch (e) {
                         await this.addCollectionExportedRecord(
                         await this.addCollectionExportedRecord(
                             exportFolder,
                             exportFolder,
@@ -613,11 +612,11 @@ class ExportService {
                         );
                         );
                         throw e;
                         throw e;
                     }
                     }
-                    addLogLine(
+                    log.info(
                         `removing collection with id ${collectionID} from export folder successful`,
                         `removing collection with id ${collectionID} from export folder successful`,
                     );
                     );
                 } catch (e) {
                 } catch (e) {
-                    logError(e, "collectionRemover failed a collection");
+                    log.error("collectionRemover failed a collection", e);
                     if (
                     if (
                         e.message ===
                         e.message ===
                             CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
                             CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
@@ -634,7 +633,7 @@ class ExportService {
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_STOPPED
                 e.message !== CustomError.EXPORT_STOPPED
             ) {
             ) {
-                logError(e, "collectionRemover failed");
+                log.error("collectionRemover failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -651,7 +650,7 @@ class ExportService {
     ): Promise<void> {
     ): Promise<void> {
         try {
         try {
             for (const file of files) {
             for (const file of files) {
-                addLogLine(
+                log.info(
                     `exporting file ${file.metadata.title} with id ${
                     `exporting file ${file.metadata.title} with id ${
                         file.id
                         file.id
                     } from collection ${collectionIDNameMap.get(
                     } from collection ${collectionIDNameMap.get(
@@ -687,10 +686,10 @@ class ExportService {
                         exportDir,
                         exportDir,
                         collectionExportName,
                         collectionExportName,
                     );
                     );
-                    await ElectronAPIs.checkExistsAndCreateDir(
+                    await ensureElectron().checkExistsAndCreateDir(
                         collectionExportPath,
                         collectionExportPath,
                     );
                     );
-                    await ElectronAPIs.checkExistsAndCreateDir(
+                    await ensureElectron().checkExistsAndCreateDir(
                         getMetadataFolderExportPath(collectionExportPath),
                         getMetadataFolderExportPath(collectionExportPath),
                     );
                     );
                     await this.downloadAndSave(
                     await this.downloadAndSave(
@@ -699,7 +698,7 @@ class ExportService {
                         file,
                         file,
                     );
                     );
                     incrementSuccess();
                     incrementSuccess();
-                    addLogLine(
+                    log.info(
                         `exporting file ${file.metadata.title} with id ${
                         `exporting file ${file.metadata.title} with id ${
                             file.id
                             file.id
                         } from collection ${collectionIDNameMap.get(
                         } from collection ${collectionIDNameMap.get(
@@ -708,7 +707,7 @@ class ExportService {
                     );
                     );
                 } catch (e) {
                 } catch (e) {
                     incrementFailed();
                     incrementFailed();
-                    logError(e, "export failed for a file");
+                    log.error("export failed for a file", e);
                     if (
                     if (
                         e.message ===
                         e.message ===
                             CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
                             CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
@@ -725,7 +724,7 @@ class ExportService {
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_STOPPED
                 e.message !== CustomError.EXPORT_STOPPED
             ) {
             ) {
-                logError(e, "fileExporter failed");
+                log.error("fileExporter failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -744,7 +743,7 @@ class ExportService {
             );
             );
             for (const fileUID of removedFileUIDs) {
             for (const fileUID of removedFileUIDs) {
                 await this.verifyExportFolderExists(exportDir);
                 await this.verifyExportFolderExists(exportDir);
-                addLogLine(`trashing file with id ${fileUID}`);
+                log.info(`trashing file with id ${fileUID}`);
                 if (isCanceled.status) {
                 if (isCanceled.status) {
                     throw Error(CustomError.EXPORT_STOPPED);
                     throw Error(CustomError.EXPORT_STOPPED);
                 }
                 }
@@ -766,11 +765,11 @@ class ExportService {
                                 collectionExportPath,
                                 collectionExportPath,
                                 imageExportName,
                                 imageExportName,
                             );
                             );
-                            addLogLine(
+                            log.info(
                                 `moving image file ${imageExportPath} to trash folder`,
                                 `moving image file ${imageExportPath} to trash folder`,
                             );
                             );
                             if (await this.exists(imageExportPath)) {
                             if (await this.exists(imageExportPath)) {
-                                await ElectronAPIs.moveFile(
+                                await ensureElectron().moveFile(
                                     imageExportPath,
                                     imageExportPath,
                                     await getTrashedFileExportPath(
                                     await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -785,7 +784,7 @@ class ExportService {
                             if (
                             if (
                                 await this.exists(imageMetadataFileExportPath)
                                 await this.exists(imageMetadataFileExportPath)
                             ) {
                             ) {
-                                await ElectronAPIs.moveFile(
+                                await ensureElectron().moveFile(
                                     imageMetadataFileExportPath,
                                     imageMetadataFileExportPath,
                                     await getTrashedFileExportPath(
                                     await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -798,11 +797,11 @@ class ExportService {
                                 collectionExportPath,
                                 collectionExportPath,
                                 videoExportName,
                                 videoExportName,
                             );
                             );
-                            addLogLine(
+                            log.info(
                                 `moving video file ${videoExportPath} to trash folder`,
                                 `moving video file ${videoExportPath} to trash folder`,
                             );
                             );
                             if (await this.exists(videoExportPath)) {
                             if (await this.exists(videoExportPath)) {
-                                await ElectronAPIs.moveFile(
+                                await ensureElectron().moveFile(
                                     videoExportPath,
                                     videoExportPath,
                                     await getTrashedFileExportPath(
                                     await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -815,7 +814,7 @@ class ExportService {
                             if (
                             if (
                                 await this.exists(videoMetadataFileExportPath)
                                 await this.exists(videoMetadataFileExportPath)
                             ) {
                             ) {
-                                await ElectronAPIs.moveFile(
+                                await ensureElectron().moveFile(
                                     videoMetadataFileExportPath,
                                     videoMetadataFileExportPath,
                                     await getTrashedFileExportPath(
                                     await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -833,11 +832,11 @@ class ExportService {
                                     exportDir,
                                     exportDir,
                                     fileExportPath,
                                     fileExportPath,
                                 );
                                 );
-                            addLogLine(
+                            log.info(
                                 `moving file ${fileExportPath} to ${trashedFilePath} trash folder`,
                                 `moving file ${fileExportPath} to ${trashedFilePath} trash folder`,
                             );
                             );
                             if (await this.exists(fileExportPath)) {
                             if (await this.exists(fileExportPath)) {
-                                await ElectronAPIs.moveFile(
+                                await ensureElectron().moveFile(
                                     fileExportPath,
                                     fileExportPath,
                                     trashedFilePath,
                                     trashedFilePath,
                                 );
                                 );
@@ -845,7 +844,7 @@ class ExportService {
                             const metadataFileExportPath =
                             const metadataFileExportPath =
                                 getMetadataFileExportPath(fileExportPath);
                                 getMetadataFileExportPath(fileExportPath);
                             if (await this.exists(metadataFileExportPath)) {
                             if (await this.exists(metadataFileExportPath)) {
-                                await ElectronAPIs.moveFile(
+                                await ensureElectron().moveFile(
                                     metadataFileExportPath,
                                     metadataFileExportPath,
                                     await getTrashedFileExportPath(
                                     await getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -862,9 +861,9 @@ class ExportService {
                         );
                         );
                         throw e;
                         throw e;
                     }
                     }
-                    addLogLine(`trashing file with id ${fileUID} successful`);
+                    log.info(`trashing file with id ${fileUID} successful`);
                 } catch (e) {
                 } catch (e) {
-                    logError(e, "trashing failed for a file");
+                    log.error("trashing failed for a file", e);
                     if (
                     if (
                         e.message ===
                         e.message ===
                             CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
                             CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
@@ -881,7 +880,7 @@ class ExportService {
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST &&
                 e.message !== CustomError.EXPORT_STOPPED
                 e.message !== CustomError.EXPORT_STOPPED
             ) {
             ) {
-                logError(e, "fileTrasher failed");
+                log.error("fileTrasher failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -904,7 +903,7 @@ class ExportService {
             await this.updateExportRecord(folder, exportRecord);
             await this.updateExportRecord(folder, exportRecord);
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
-                logError(e, "addFileExportedRecord failed");
+                log.error("addFileExportedRecord failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -928,7 +927,7 @@ class ExportService {
             await this.updateExportRecord(folder, exportRecord);
             await this.updateExportRecord(folder, exportRecord);
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
-                logError(e, "addCollectionExportedRecord failed");
+                log.error("addCollectionExportedRecord failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -947,7 +946,7 @@ class ExportService {
             await this.updateExportRecord(folder, exportRecord);
             await this.updateExportRecord(folder, exportRecord);
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
-                logError(e, "removeCollectionExportedRecord failed");
+                log.error("removeCollectionExportedRecord failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -964,7 +963,7 @@ class ExportService {
             await this.updateExportRecord(folder, exportRecord);
             await this.updateExportRecord(folder, exportRecord);
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
-                logError(e, "removeFileExportedRecord failed");
+                log.error("removeFileExportedRecord failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -984,7 +983,7 @@ class ExportService {
         try {
         try {
             const exportRecord = await this.getExportRecord(folder);
             const exportRecord = await this.getExportRecord(folder);
             const newRecord: ExportRecord = { ...exportRecord, ...newData };
             const newRecord: ExportRecord = { ...exportRecord, ...newData };
-            await ElectronAPIs.saveFileToDisk(
+            await ensureElectron().saveFileToDisk(
                 `${folder}/${EXPORT_RECORD_FILE_NAME}`,
                 `${folder}/${EXPORT_RECORD_FILE_NAME}`,
                 JSON.stringify(newRecord, null, 2),
                 JSON.stringify(newRecord, null, 2),
             );
             );
@@ -993,7 +992,7 @@ class ExportService {
             if (e.message === CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
             if (e.message === CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
                 throw e;
                 throw e;
             }
             }
-            logError(e, "error updating Export Record");
+            log.error("error updating Export Record", e);
             throw Error(CustomError.UPDATE_EXPORTED_RECORD_FAILED);
             throw Error(CustomError.UPDATE_EXPORTED_RECORD_FAILED);
         }
         }
     }
     }
@@ -1006,7 +1005,7 @@ class ExportService {
                 return this.createEmptyExportRecord(exportRecordJSONPath);
                 return this.createEmptyExportRecord(exportRecordJSONPath);
             }
             }
             const recordFile =
             const recordFile =
-                await ElectronAPIs.readTextFile(exportRecordJSONPath);
+                await ensureElectron().readTextFile(exportRecordJSONPath);
             try {
             try {
                 return JSON.parse(recordFile);
                 return JSON.parse(recordFile);
             } catch (e) {
             } catch (e) {
@@ -1021,7 +1020,7 @@ class ExportService {
                 return await this.getExportRecord(folder, false);
                 return await this.getExportRecord(folder, false);
             }
             }
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
-                logError(e, "export Record JSON parsing failed");
+                log.error("export Record JSON parsing failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -1042,8 +1041,8 @@ class ExportService {
             exportFolder,
             exportFolder,
             collectionExportName,
             collectionExportName,
         );
         );
-        await ElectronAPIs.checkExistsAndCreateDir(collectionExportPath);
-        await ElectronAPIs.checkExistsAndCreateDir(
+        await ensureElectron().checkExistsAndCreateDir(collectionExportPath);
+        await ensureElectron().checkExistsAndCreateDir(
             getMetadataFolderExportPath(collectionExportPath),
             getMetadataFolderExportPath(collectionExportPath),
         );
         );
 
 
@@ -1090,7 +1089,7 @@ class ExportService {
                         fileExportName,
                         fileExportName,
                         file,
                         file,
                     );
                     );
-                    await ElectronAPIs.saveStreamToDisk(
+                    await ensureElectron().saveStreamToDisk(
                         getFileExportPath(collectionExportPath, fileExportName),
                         getFileExportPath(collectionExportPath, fileExportName),
                         updatedFileStream,
                         updatedFileStream,
                     );
                     );
@@ -1100,7 +1099,7 @@ class ExportService {
                 }
                 }
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "download and save failed");
+            log.error("download and save failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -1138,7 +1137,7 @@ class ExportService {
                 imageExportName,
                 imageExportName,
                 file,
                 file,
             );
             );
-            await ElectronAPIs.saveStreamToDisk(
+            await ensureElectron().saveStreamToDisk(
                 getFileExportPath(collectionExportPath, imageExportName),
                 getFileExportPath(collectionExportPath, imageExportName),
                 imageStream,
                 imageStream,
             );
             );
@@ -1150,12 +1149,12 @@ class ExportService {
                 file,
                 file,
             );
             );
             try {
             try {
-                await ElectronAPIs.saveStreamToDisk(
+                await ensureElectron().saveStreamToDisk(
                     getFileExportPath(collectionExportPath, videoExportName),
                     getFileExportPath(collectionExportPath, videoExportName),
                     videoStream,
                     videoStream,
                 );
                 );
             } catch (e) {
             } catch (e) {
-                await ElectronAPIs.deleteFile(
+                await ensureElectron().deleteFile(
                     getFileExportPath(collectionExportPath, imageExportName),
                     getFileExportPath(collectionExportPath, imageExportName),
                 );
                 );
                 throw e;
                 throw e;
@@ -1171,7 +1170,7 @@ class ExportService {
         fileExportName: string,
         fileExportName: string,
         file: EnteFile,
         file: EnteFile,
     ) {
     ) {
-        await ElectronAPIs.saveFileToDisk(
+        await ensureElectron().saveFileToDisk(
             getFileMetadataExportPath(collectionExportPath, fileExportName),
             getFileMetadataExportPath(collectionExportPath, fileExportName),
             getGoogleLikeMetadataFile(fileExportName, file),
             getGoogleLikeMetadataFile(fileExportName, file),
         );
         );
@@ -1182,15 +1181,15 @@ class ExportService {
     };
     };
 
 
     exists = (path: string) => {
     exists = (path: string) => {
-        return ElectronAPIs.fs.exists(path);
+        return ensureElectron().fs.exists(path);
     };
     };
 
 
     rename = (oldPath: string, newPath: string) => {
     rename = (oldPath: string, newPath: string) => {
-        return ElectronAPIs.rename(oldPath, newPath);
+        return ensureElectron().rename(oldPath, newPath);
     };
     };
 
 
     checkExistsAndCreateDir = (path: string) => {
     checkExistsAndCreateDir = (path: string) => {
-        return ElectronAPIs.checkExistsAndCreateDir(path);
+        return ensureElectron().checkExistsAndCreateDir(path);
     };
     };
 
 
     exportFolderExists = async (exportFolder: string) => {
     exportFolderExists = async (exportFolder: string) => {
@@ -1204,7 +1203,7 @@ class ExportService {
             }
             }
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
             if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
-                logError(e, "verifyExportFolderExists failed");
+                log.error("verifyExportFolderExists failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -1212,7 +1211,7 @@ class ExportService {
 
 
     private createEmptyExportRecord = async (exportRecordJSONPath: string) => {
     private createEmptyExportRecord = async (exportRecordJSONPath: string) => {
         const exportRecord: ExportRecord = NULL_EXPORT_RECORD;
         const exportRecord: ExportRecord = NULL_EXPORT_RECORD;
-        await ElectronAPIs.saveFileToDisk(
+        await ensureElectron().saveFileToDisk(
             exportRecordJSONPath,
             exportRecordJSONPath,
             JSON.stringify(exportRecord, null, 2),
             JSON.stringify(exportRecord, null, 2),
         );
         );

+ 3 - 4
web/apps/photos/src/services/ffmpeg/ffmpegFactory.ts

@@ -1,5 +1,3 @@
-import ElectronAPIs from "@/next/electron";
-import isElectron from "is-electron";
 import { ElectronFile } from "types/upload";
 import { ElectronFile } from "types/upload";
 import ComlinkFFmpegWorker from "utils/comlink/ComlinkFFmpegWorker";
 import ComlinkFFmpegWorker from "utils/comlink/ComlinkFFmpegWorker";
 
 
@@ -16,10 +14,11 @@ class FFmpegFactory {
     private client: IFFmpeg;
     private client: IFFmpeg;
     async getFFmpegClient() {
     async getFFmpegClient() {
         if (!this.client) {
         if (!this.client) {
-            if (isElectron()) {
+            const electron = globalThis.electron;
+            if (electron) {
                 this.client = {
                 this.client = {
                     run(cmd, inputFile, outputFilename, dontTimeout) {
                     run(cmd, inputFile, outputFilename, dontTimeout) {
-                        return ElectronAPIs.runFFmpegCmd(
+                        return electron.runFFmpegCmd(
                             cmd,
                             cmd,
                             inputFile,
                             inputFile,
                             outputFilename,
                             outputFilename,

+ 4 - 4
web/apps/photos/src/services/ffmpeg/ffmpegService.ts

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import {
 import {
     FFMPEG_PLACEHOLDER,
     FFMPEG_PLACEHOLDER,
     INPUT_PATH_PLACEHOLDER,
     INPUT_PATH_PLACEHOLDER,
@@ -40,7 +40,7 @@ export async function generateVideoThumbnail(
             seekTime--;
             seekTime--;
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "ffmpeg generateVideoThumbnail failed");
+        log.error("ffmpeg generateVideoThumbnail failed", e);
         throw e;
         throw e;
     }
     }
 }
 }
@@ -72,7 +72,7 @@ export async function extractVideoMetadata(file: File | ElectronFile) {
             new Uint8Array(await metadata.arrayBuffer()),
             new Uint8Array(await metadata.arrayBuffer()),
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "ffmpeg extractVideoMetadata failed");
+        log.error("ffmpeg extractVideoMetadata failed", e);
         throw e;
         throw e;
     }
     }
 }
 }
@@ -94,7 +94,7 @@ export async function convertToMP4(file: File | ElectronFile) {
             true,
             true,
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "ffmpeg convertToMP4 failed");
+        log.error("ffmpeg convertToMP4 failed", e);
         throw e;
         throw e;
     }
     }
 }
 }

+ 14 - 15
web/apps/photos/src/services/fileService.ts

@@ -1,11 +1,9 @@
-import { getEndpoint } from "@ente/shared/network/api";
-import localForage from "@ente/shared/storage/localForage";
-
+import log from "@/next/log";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import { Events, eventBus } from "@ente/shared/events";
 import { Events, eventBus } from "@ente/shared/events";
-import { addLogLine } from "@ente/shared/logging";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
-import { logError } from "@ente/shared/sentry";
+import { getEndpoint } from "@ente/shared/network/api";
+import localForage from "@ente/shared/storage/localForage";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { REQUEST_BATCH_SIZE } from "constants/api";
 import { REQUEST_BATCH_SIZE } from "constants/api";
 import { Collection } from "types/collection";
 import { Collection } from "types/collection";
@@ -48,18 +46,19 @@ const setLocalFiles = async (type: "normal" | "hidden", files: EnteFile[]) => {
         try {
         try {
             eventBus.emit(Events.LOCAL_FILES_UPDATED);
             eventBus.emit(Events.LOCAL_FILES_UPDATED);
         } catch (e) {
         } catch (e) {
-            logError(e, "Error in localFileUpdated handlers");
+            log.error("Error in localFileUpdated handlers", e);
         }
         }
     } catch (e1) {
     } catch (e1) {
         try {
         try {
             const storageEstimate = await navigator.storage.estimate();
             const storageEstimate = await navigator.storage.estimate();
-            logError(e1, "failed to save files to indexedDB", {
-                storageEstimate,
-            });
-            addLogLine(`storage estimate ${JSON.stringify(storageEstimate)}`);
+            log.error(
+                `failed to save files to indexedDB (storageEstimate was ${storageEstimate}`,
+                e1,
+            );
+            log.info(`storage estimate ${JSON.stringify(storageEstimate)}`);
         } catch (e2) {
         } catch (e2) {
-            logError(e1, "failed to save files to indexedDB");
-            logError(e2, "failed to get storage stats");
+            log.error("failed to save files to indexedDB", e1);
+            log.error("failed to get storage stats", e2);
         }
         }
         throw e1;
         throw e1;
     }
     }
@@ -151,7 +150,7 @@ export const getFiles = async (
         } while (resp.data.hasMore);
         } while (resp.data.hasMore);
         return decryptedFiles;
         return decryptedFiles;
     } catch (e) {
     } catch (e) {
-        logError(e, "Get files failed");
+        log.error("Get files failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -192,7 +191,7 @@ export const trashFiles = async (filesToTrash: EnteFile[]) => {
             );
             );
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "trash file failed");
+        log.error("trash file failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -216,7 +215,7 @@ export const deleteFromTrash = async (filesToDelete: number[]) => {
             );
             );
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "deleteFromTrash failed");
+        log.error("deleteFromTrash failed", e);
         throw e;
         throw e;
     }
     }
 };
 };

+ 16 - 15
web/apps/photos/src/services/heic-convert/service.ts

@@ -1,8 +1,7 @@
 import { convertBytesToHumanReadable } from "@/next/file";
 import { convertBytesToHumanReadable } from "@/next/file";
+import log from "@/next/log";
 import { ComlinkWorker } from "@/next/worker/comlink-worker";
 import { ComlinkWorker } from "@/next/worker/comlink-worker";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
 import { retryAsyncFunction } from "@ente/shared/utils";
 import { retryAsyncFunction } from "@ente/shared/utils";
 import QueueProcessor from "@ente/shared/utils/queueProcessor";
 import QueueProcessor from "@ente/shared/utils/queueProcessor";
 import { getDedicatedConvertWorker } from "utils/comlink/ComlinkConvertWorker";
 import { getDedicatedConvertWorker } from "utils/comlink/ComlinkConvertWorker";
@@ -46,7 +45,7 @@ class HEICConverter {
                                         await worker.convertHEICToJPEG(
                                         await worker.convertHEICToJPEG(
                                             fileBlob,
                                             fileBlob,
                                         );
                                         );
-                                    addLogLine(
+                                    log.info(
                                         `originalFileSize:${convertBytesToHumanReadable(
                                         `originalFileSize:${convertBytesToHumanReadable(
                                             fileBlob?.size,
                                             fileBlob?.size,
                                         )},convertedFileSize:${convertBytesToHumanReadable(
                                         )},convertedFileSize:${convertBytesToHumanReadable(
@@ -65,17 +64,19 @@ class HEICConverter {
                         },
                         },
                     );
                     );
                     if (!convertedHEIC || convertedHEIC?.size === 0) {
                     if (!convertedHEIC || convertedHEIC?.size === 0) {
-                        logError(
-                            Error(`converted heic fileSize is Zero`),
-                            "converted heic fileSize is Zero",
-                            {
-                                originalFileSize: convertBytesToHumanReadable(
-                                    fileBlob?.size ?? 0,
-                                ),
-                                convertedFileSize: convertBytesToHumanReadable(
-                                    convertedHEIC?.size ?? 0,
-                                ),
-                            },
+                        log.error(
+                            `converted heic fileSize is Zero - ${JSON.stringify(
+                                {
+                                    originalFileSize:
+                                        convertBytesToHumanReadable(
+                                            fileBlob?.size ?? 0,
+                                        ),
+                                    convertedFileSize:
+                                        convertBytesToHumanReadable(
+                                            convertedHEIC?.size ?? 0,
+                                        ),
+                                },
+                            )}`,
                         );
                         );
                     }
                     }
                     await new Promise((resolve) => {
                     await new Promise((resolve) => {
@@ -87,7 +88,7 @@ class HEICConverter {
                     this.workerPool.push(convertWorker);
                     this.workerPool.push(convertWorker);
                     return convertedHEIC;
                     return convertedHEIC;
                 } catch (e) {
                 } catch (e) {
-                    logError(e, "heic conversion failed");
+                    log.error("heic conversion failed", e);
                     convertWorker.terminate();
                     convertWorker.terminate();
                     this.workerPool.push(getDedicatedConvertWorker());
                     this.workerPool.push(getDedicatedConvertWorker());
                     throw e;
                     throw e;

+ 2 - 2
web/apps/photos/src/services/heicConversionService.ts

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import WasmHEICConverterService from "./heic-convert/service";
 import WasmHEICConverterService from "./heic-convert/service";
 
 
 class HeicConversionService {
 class HeicConversionService {
@@ -6,7 +6,7 @@ class HeicConversionService {
         try {
         try {
             return await WasmHEICConverterService.convert(heicFileData);
             return await WasmHEICConverterService.convert(heicFileData);
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to convert heic file");
+            log.error("failed to convert heic file", e);
             throw e;
             throw e;
         }
         }
     }
     }

+ 10 - 9
web/apps/photos/src/services/importService.ts

@@ -1,5 +1,5 @@
-import ElectronAPIs from "@/next/electron";
-import { logError } from "@ente/shared/sentry";
+import { ensureElectron } from "@/next/electron";
+import log from "@/next/log";
 import { PICKED_UPLOAD_TYPE } from "constants/upload";
 import { PICKED_UPLOAD_TYPE } from "constants/upload";
 import { Collection } from "types/collection";
 import { Collection } from "types/collection";
 import { ElectronFile, FileWithCollection } from "types/upload";
 import { ElectronFile, FileWithCollection } from "types/upload";
@@ -14,13 +14,13 @@ class ImportService {
     async getPendingUploads(): Promise<PendingUploads> {
     async getPendingUploads(): Promise<PendingUploads> {
         try {
         try {
             const pendingUploads =
             const pendingUploads =
-                (await ElectronAPIs.getPendingUploads()) as PendingUploads;
+                (await ensureElectron().getPendingUploads()) as PendingUploads;
             return pendingUploads;
             return pendingUploads;
         } catch (e) {
         } catch (e) {
             if (e?.message?.includes("ENOENT: no such file or directory")) {
             if (e?.message?.includes("ENOENT: no such file or directory")) {
                 // ignore
                 // ignore
             } else {
             } else {
-                logError(e, "failed to getPendingUploads ");
+                log.error("failed to getPendingUploads ", e);
             }
             }
             return { files: [], collectionName: null, type: null };
             return { files: [], collectionName: null, type: null };
         }
         }
@@ -40,7 +40,7 @@ class ImportService {
         if (collections.length === 1) {
         if (collections.length === 1) {
             collectionName = collections[0].name;
             collectionName = collections[0].name;
         }
         }
-        await ElectronAPIs.setToUploadCollection(collectionName);
+        await ensureElectron().setToUploadCollection(collectionName);
     }
     }
 
 
     async updatePendingUploads(files: FileWithCollection[]) {
     async updatePendingUploads(files: FileWithCollection[]) {
@@ -57,16 +57,17 @@ class ImportService {
                 filePaths.push((fileWithCollection.file as ElectronFile).path);
                 filePaths.push((fileWithCollection.file as ElectronFile).path);
             }
             }
         }
         }
-        await ElectronAPIs.setToUploadFiles(
+        await ensureElectron().setToUploadFiles(
             PICKED_UPLOAD_TYPE.FILES,
             PICKED_UPLOAD_TYPE.FILES,
             filePaths,
             filePaths,
         );
         );
     }
     }
 
 
     async cancelRemainingUploads() {
     async cancelRemainingUploads() {
-        await ElectronAPIs.setToUploadCollection(null);
-        await ElectronAPIs.setToUploadFiles(PICKED_UPLOAD_TYPE.ZIPS, []);
-        await ElectronAPIs.setToUploadFiles(PICKED_UPLOAD_TYPE.FILES, []);
+        const electron = ensureElectron();
+        await electron.setToUploadCollection(null);
+        await electron.setToUploadFiles(PICKED_UPLOAD_TYPE.ZIPS, []);
+        await electron.setToUploadFiles(PICKED_UPLOAD_TYPE.FILES, []);
     }
     }
 }
 }
 
 

+ 3 - 3
web/apps/photos/src/services/locationSearchService.ts

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { LocationTagData } from "types/entity";
 import { LocationTagData } from "types/entity";
 import { Location } from "types/upload";
 import { Location } from "types/upload";
 
 
@@ -30,7 +30,7 @@ class LocationSearchService {
             });
             });
             await this.citiesPromise;
             await this.citiesPromise;
         } catch (e) {
         } catch (e) {
-            logError(e, "LocationSearchService loadCities failed");
+            log.error("LocationSearchService loadCities failed", e);
             this.citiesPromise = null;
             this.citiesPromise = null;
         }
         }
     }
     }
@@ -47,7 +47,7 @@ class LocationSearchService {
                     .startsWith(searchTerm.toLowerCase());
                     .startsWith(searchTerm.toLowerCase());
             });
             });
         } catch (e) {
         } catch (e) {
-            logError(e, "LocationSearchService searchCities failed");
+            log.error("LocationSearchService searchCities failed", e);
             throw e;
             throw e;
         }
         }
     }
     }

+ 10 - 10
web/apps/photos/src/services/machineLearning/blazeFaceDetectionService.ts

@@ -1,4 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
+import log from "@/next/log";
 import { GraphModel } from "@tensorflow/tfjs-converter";
 import { GraphModel } from "@tensorflow/tfjs-converter";
 import * as tf from "@tensorflow/tfjs-core";
 import * as tf from "@tensorflow/tfjs-core";
 import {
 import {
@@ -60,7 +60,7 @@ class BlazeFaceDetectionService implements FaceDetectionService {
             inputHeight: BLAZEFACE_INPUT_SIZE,
             inputHeight: BLAZEFACE_INPUT_SIZE,
             inputWidth: BLAZEFACE_INPUT_SIZE,
             inputWidth: BLAZEFACE_INPUT_SIZE,
         });
         });
-        addLogLine(
+        log.info(
             "loaded blazeFaceModel: ",
             "loaded blazeFaceModel: ",
             // await this.blazeFaceModel,
             // await this.blazeFaceModel,
             // eslint-disable-next-line @typescript-eslint/await-thenable
             // eslint-disable-next-line @typescript-eslint/await-thenable
@@ -121,20 +121,20 @@ class BlazeFaceDetectionService implements FaceDetectionService {
         let desiredDist = desiredRightEyeX - this.desiredLeftEye[0];
         let desiredDist = desiredRightEyeX - this.desiredLeftEye[0];
         desiredDist *= this.desiredFaceSize;
         desiredDist *= this.desiredFaceSize;
         const scale = desiredDist / dist;
         const scale = desiredDist / dist;
-        // addLogLine("scale: ", scale);
+        // log.info("scale: ", scale);
 
 
         const eyesCenter = [];
         const eyesCenter = [];
         eyesCenter[0] = Math.floor((leftEye[0] + rightEye[0]) / 2);
         eyesCenter[0] = Math.floor((leftEye[0] + rightEye[0]) / 2);
         eyesCenter[1] = Math.floor((leftEye[1] + rightEye[1]) / 2);
         eyesCenter[1] = Math.floor((leftEye[1] + rightEye[1]) / 2);
-        // addLogLine("eyesCenter: ", eyesCenter);
+        // log.info("eyesCenter: ", eyesCenter);
 
 
         const faceWidth = this.desiredFaceSize / scale;
         const faceWidth = this.desiredFaceSize / scale;
         const faceHeight = this.desiredFaceSize / scale;
         const faceHeight = this.desiredFaceSize / scale;
-        // addLogLine("faceWidth: ", faceWidth, "faceHeight: ", faceHeight)
+        // log.info("faceWidth: ", faceWidth, "faceHeight: ", faceHeight)
 
 
         const tx = eyesCenter[0] - faceWidth * 0.5;
         const tx = eyesCenter[0] - faceWidth * 0.5;
         const ty = eyesCenter[1] - faceHeight * this.desiredLeftEye[1];
         const ty = eyesCenter[1] - faceHeight * this.desiredLeftEye[1];
-        // addLogLine("tx: ", tx, "ty: ", ty);
+        // log.info("tx: ", tx, "ty: ", ty);
 
 
         return new Box({
         return new Box({
             left: tx,
             left: tx,
@@ -155,7 +155,7 @@ class BlazeFaceDetectionService implements FaceDetectionService {
         const normalizedImage = tf.sub(tf.div(reshapedImage, 127.5), 1.0);
         const normalizedImage = tf.sub(tf.div(reshapedImage, 127.5), 1.0);
         // eslint-disable-next-line @typescript-eslint/await-thenable
         // eslint-disable-next-line @typescript-eslint/await-thenable
         const results = await this.blazeFaceBackModel.predict(normalizedImage);
         const results = await this.blazeFaceBackModel.predict(normalizedImage);
-        // addLogLine('onFacesDetected: ', results);
+        // log.info('onFacesDetected: ', results);
         return results;
         return results;
     }
     }
 
 
@@ -180,7 +180,7 @@ class BlazeFaceDetectionService implements FaceDetectionService {
         const inBox = newBox(0, 0, resized.width, resized.height);
         const inBox = newBox(0, 0, resized.width, resized.height);
         const toBox = newBox(0, 0, imageBitmap.width, imageBitmap.height);
         const toBox = newBox(0, 0, imageBitmap.width, imageBitmap.height);
         const transform = computeTransformToBox(inBox, toBox);
         const transform = computeTransformToBox(inBox, toBox);
-        // addLogLine("1st pass: ", { transform });
+        // log.info("1st pass: ", { transform });
 
 
         const faceDetections: Array<FaceDetection> = faces?.map((f) => {
         const faceDetections: Array<FaceDetection> = faces?.map((f) => {
             const box = transformBox(normFaceBox(f), transform);
             const box = transformBox(normFaceBox(f), transform);
@@ -223,7 +223,7 @@ class BlazeFaceDetectionService implements FaceDetectionService {
             );
             );
             let selected = pass2Detections?.[0];
             let selected = pass2Detections?.[0];
             if (pass2Detections?.length > 1) {
             if (pass2Detections?.length > 1) {
-                // addLogLine('2nd pass >1 face', pass2Detections.length);
+                // log.info('2nd pass >1 face', pass2Detections.length);
                 selected = getNearestDetection(
                 selected = getNearestDetection(
                     pass1Detection,
                     pass1Detection,
                     pass2Detections,
                     pass2Detections,
@@ -234,7 +234,7 @@ class BlazeFaceDetectionService implements FaceDetectionService {
             // we might miss 1st pass face actually having score within threshold
             // we might miss 1st pass face actually having score within threshold
             // it is ok as results will be consistent with 2nd pass only detections
             // it is ok as results will be consistent with 2nd pass only detections
             if (selected && selected.probability >= BLAZEFACE_SCORE_THRESHOLD) {
             if (selected && selected.probability >= BLAZEFACE_SCORE_THRESHOLD) {
-                // addLogLine("pass2: ", { imageBox, paddedBox, transform, selected });
+                // log.info("pass2: ", { imageBox, paddedBox, transform, selected });
                 detections.push(selected);
                 detections.push(selected);
             }
             }
         }
         }

+ 1 - 1
web/apps/photos/src/services/machineLearning/clusteringService.ts

@@ -26,7 +26,7 @@ class ClusteringService {
         epsilon: number = 1.0,
         epsilon: number = 1.0,
         minPts: number = 2,
         minPts: number = 2,
     ): ClusteringResults {
     ): ClusteringResults {
-        // addLogLine("distanceFunction", DBSCAN._);
+        // log.info("distanceFunction", DBSCAN._);
         const clusters = this.dbscan.run(dataset, epsilon, minPts);
         const clusters = this.dbscan.run(dataset, epsilon, minPts);
         const noise = this.dbscan.noise;
         const noise = this.dbscan.noise;
         return { clusters, noise };
         return { clusters, noise };

+ 1 - 1
web/apps/photos/src/services/machineLearning/dbscanClusteringService.ts

@@ -22,7 +22,7 @@ class DbscanClusteringService implements ClusteringService {
         input: ClusteringInput,
         input: ClusteringInput,
         config: ClusteringConfig,
         config: ClusteringConfig,
     ): Promise<HdbscanResults> {
     ): Promise<HdbscanResults> {
-        // addLogLine('Clustering input: ', input);
+        // log.info('Clustering input: ', input);
         const dbscan = new DBSCAN();
         const dbscan = new DBSCAN();
         const clusters = dbscan.run(
         const clusters = dbscan.run(
             input,
             input,

+ 10 - 10
web/apps/photos/src/services/machineLearning/faceService.ts

@@ -1,4 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
+import log from "@/next/log";
 import {
 import {
     DetectedFace,
     DetectedFace,
     Face,
     Face,
@@ -51,7 +51,7 @@ class FaceService {
         );
         );
         const faceDetections =
         const faceDetections =
             await syncContext.faceDetectionService.detectFaces(imageBitmap);
             await syncContext.faceDetectionService.detectFaces(imageBitmap);
-        // addLogLine('3 TF Memory stats: ',JSON.stringify(tf.memory()));
+        // log.info('3 TF Memory stats: ',JSON.stringify(tf.memory()));
         // TODO: reenable faces filtering based on width
         // TODO: reenable faces filtering based on width
         const detectedFaces = faceDetections?.map((detection) => {
         const detectedFaces = faceDetections?.map((detection) => {
             return {
             return {
@@ -66,7 +66,7 @@ class FaceService {
         // ?.filter((f) =>
         // ?.filter((f) =>
         //     f.box.width > syncContext.config.faceDetection.minFaceSize
         //     f.box.width > syncContext.config.faceDetection.minFaceSize
         // );
         // );
-        addLogLine("[MLService] Detected Faces: ", newMlFile.faces?.length);
+        log.info("[MLService] Detected Faces: ", newMlFile.faces?.length);
     }
     }
 
 
     async syncFileFaceCrops(
     async syncFileFaceCrops(
@@ -128,8 +128,8 @@ class FaceService {
                 face.detection,
                 face.detection,
             );
             );
         }
         }
-        addLogLine("[MLService] alignedFaces: ", newMlFile.faces?.length);
-        // addLogLine('4 TF Memory stats: ',JSON.stringify(tf.memory()));
+        log.info("[MLService] alignedFaces: ", newMlFile.faces?.length);
+        // log.info('4 TF Memory stats: ',JSON.stringify(tf.memory()));
     }
     }
 
 
     async syncFileFaceEmbeddings(
     async syncFileFaceEmbeddings(
@@ -168,8 +168,8 @@ class FaceService {
         faceImages.forEach((faceImage) => faceImage.close());
         faceImages.forEach((faceImage) => faceImage.close());
         newMlFile.faces.forEach((f, i) => (f.embedding = embeddings[i]));
         newMlFile.faces.forEach((f, i) => (f.embedding = embeddings[i]));
 
 
-        addLogLine("[MLService] facesWithEmbeddings: ", newMlFile.faces.length);
-        // addLogLine('5 TF Memory stats: ',JSON.stringify(tf.memory()));
+        log.info("[MLService] facesWithEmbeddings: ", newMlFile.faces.length);
+        // log.info('5 TF Memory stats: ',JSON.stringify(tf.memory()));
     }
     }
 
 
     async saveFaceCrop(
     async saveFaceCrop(
@@ -210,14 +210,14 @@ class FaceService {
         const clusteringConfig = syncContext.config.faceClustering;
         const clusteringConfig = syncContext.config.faceClustering;
 
 
         if (!allFaces || allFaces.length < clusteringConfig.minInputSize) {
         if (!allFaces || allFaces.length < clusteringConfig.minInputSize) {
-            addLogLine(
+            log.info(
                 "[MLService] Too few faces to cluster, not running clustering: ",
                 "[MLService] Too few faces to cluster, not running clustering: ",
                 allFaces.length,
                 allFaces.length,
             );
             );
             return;
             return;
         }
         }
 
 
-        addLogLine("Running clustering allFaces: ", allFaces.length);
+        log.info("Running clustering allFaces: ", allFaces.length);
         syncContext.mlLibraryData.faceClusteringResults =
         syncContext.mlLibraryData.faceClusteringResults =
             await syncContext.faceClusteringService.cluster(
             await syncContext.faceClusteringService.cluster(
                 allFaces.map((f) => Array.from(f.embedding)),
                 allFaces.map((f) => Array.from(f.embedding)),
@@ -225,7 +225,7 @@ class FaceService {
             );
             );
         syncContext.mlLibraryData.faceClusteringMethod =
         syncContext.mlLibraryData.faceClusteringMethod =
             syncContext.faceClusteringService.method;
             syncContext.faceClusteringService.method;
-        addLogLine(
+        log.info(
             "[MLService] Got face clustering results: ",
             "[MLService] Got face clustering results: ",
             JSON.stringify(syncContext.mlLibraryData.faceClusteringResults),
             JSON.stringify(syncContext.mlLibraryData.faceClusteringResults),
         );
         );

+ 1 - 1
web/apps/photos/src/services/machineLearning/hdbscanClusteringService.ts

@@ -22,7 +22,7 @@ class HdbscanClusteringService implements ClusteringService {
         input: ClusteringInput,
         input: ClusteringInput,
         config: ClusteringConfig,
         config: ClusteringConfig,
     ): Promise<HdbscanResults> {
     ): Promise<HdbscanResults> {
-        // addLogLine('Clustering input: ', input);
+        // log.info('Clustering input: ', input);
         const hdbscan = new Hdbscan({
         const hdbscan = new Hdbscan({
             input,
             input,
 
 

+ 4 - 7
web/apps/photos/src/services/machineLearning/imageSceneService.ts

@@ -1,4 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
+import log from "@/next/log";
 import * as tfjsConverter from "@tensorflow/tfjs-converter";
 import * as tfjsConverter from "@tensorflow/tfjs-converter";
 import * as tf from "@tensorflow/tfjs-core";
 import * as tf from "@tensorflow/tfjs-core";
 import { SCENE_DETECTION_IMAGE_SIZE } from "constants/mlConfig";
 import { SCENE_DETECTION_IMAGE_SIZE } from "constants/mlConfig";
@@ -26,7 +26,7 @@ class ImageScene implements SceneDetectionService {
     }
     }
 
 
     private async init() {
     private async init() {
-        addLogLine(`[${this.workerID}]`, "ImageScene init called");
+        log.info(`[${this.workerID}]`, "ImageScene init called");
         if (this.model) {
         if (this.model) {
             return;
             return;
         }
         }
@@ -38,7 +38,7 @@ class ImageScene implements SceneDetectionService {
         this.model = await tfjsConverter.loadGraphModel(
         this.model = await tfjsConverter.loadGraphModel(
             "/models/imagescene/model.json",
             "/models/imagescene/model.json",
         );
         );
-        addLogLine(
+        log.info(
             `[${this.workerID}]`,
             `[${this.workerID}]`,
             "loaded ImageScene model",
             "loaded ImageScene model",
             tf.getBackend(),
             tf.getBackend(),
@@ -52,10 +52,7 @@ class ImageScene implements SceneDetectionService {
     }
     }
 
 
     private async getImageSceneModel() {
     private async getImageSceneModel() {
-        addLogLine(
-            `[${this.workerID}]`,
-            "ImageScene getImageSceneModel called",
-        );
+        log.info(`[${this.workerID}]`, "ImageScene getImageSceneModel called");
         if (!this.ready) {
         if (!this.ready) {
             this.ready = this.init();
             this.ready = this.init();
         }
         }

+ 2 - 2
web/apps/photos/src/services/machineLearning/machineLearningFactory.ts

@@ -1,8 +1,8 @@
 import { haveWindow } from "@/next/env";
 import { haveWindow } from "@/next/env";
+import log from "@/next/log";
 import { ComlinkWorker } from "@/next/worker/comlink-worker";
 import { ComlinkWorker } from "@/next/worker/comlink-worker";
 import { getDedicatedCryptoWorker } from "@ente/shared/crypto";
 import { getDedicatedCryptoWorker } from "@ente/shared/crypto";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
-import { addLogLine } from "@ente/shared/logging";
 import PQueue from "p-queue";
 import PQueue from "p-queue";
 import { EnteFile } from "types/file";
 import { EnteFile } from "types/file";
 import {
 import {
@@ -198,7 +198,7 @@ export class LocalMLSyncContext implements MLSyncContext {
 
 
         this.concurrency = concurrency || getConcurrency();
         this.concurrency = concurrency || getConcurrency();
 
 
-        addLogLine("Using concurrency: ", this.concurrency);
+        log.info("Using concurrency: ", this.concurrency);
         // timeout is added on downloads
         // timeout is added on downloads
         // timeout on queue will keep the operation open till worker is terminated
         // timeout on queue will keep the operation open till worker is terminated
         this.syncQueue = new PQueue({ concurrency: this.concurrency });
         this.syncQueue = new PQueue({ concurrency: this.concurrency });

+ 20 - 21
web/apps/photos/src/services/machineLearning/machineLearningService.ts

@@ -1,7 +1,6 @@
+import log from "@/next/log";
 import { APPS } from "@ente/shared/apps/constants";
 import { APPS } from "@ente/shared/apps/constants";
 import { CustomError, parseUploadErrorCodes } from "@ente/shared/error";
 import { CustomError, parseUploadErrorCodes } from "@ente/shared/error";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
 import "@tensorflow/tfjs-backend-cpu";
 import "@tensorflow/tfjs-backend-cpu";
 import "@tensorflow/tfjs-backend-webgl";
 import "@tensorflow/tfjs-backend-webgl";
 import * as tf from "@tensorflow/tfjs-core";
 import * as tf from "@tensorflow/tfjs-core";
@@ -79,10 +78,10 @@ class MachineLearningService {
             tsne: syncContext.tsne,
             tsne: syncContext.tsne,
             error: syncContext.error,
             error: syncContext.error,
         };
         };
-        // addLogLine('[MLService] sync results: ', mlSyncResult);
+        // log.info('[MLService] sync results: ', mlSyncResult);
 
 
         // await syncContext.dispose();
         // await syncContext.dispose();
-        addLogLine("Final TF Memory stats: ", JSON.stringify(tf.memory()));
+        log.info("Final TF Memory stats: ", JSON.stringify(tf.memory()));
 
 
         return mlSyncResult;
         return mlSyncResult;
     }
     }
@@ -140,7 +139,7 @@ class MachineLearningService {
 
 
         let updated = false;
         let updated = false;
         if (newFileIds.length > 0) {
         if (newFileIds.length > 0) {
-            addLogLine("newFiles: ", newFileIds.length);
+            log.info("newFiles: ", newFileIds.length);
             const newFiles = newFileIds.map((fileId) => this.newMlData(fileId));
             const newFiles = newFileIds.map((fileId) => this.newMlData(fileId));
             await mlIDbStorage.putAllFiles(newFiles, tx);
             await mlIDbStorage.putAllFiles(newFiles, tx);
             updated = true;
             updated = true;
@@ -154,7 +153,7 @@ class MachineLearningService {
         }
         }
 
 
         if (removedFileIds.length > 0) {
         if (removedFileIds.length > 0) {
-            addLogLine("removedFiles: ", removedFileIds.length);
+            log.info("removedFiles: ", removedFileIds.length);
             await mlIDbStorage.removeAllFiles(removedFileIds, tx);
             await mlIDbStorage.removeAllFiles(removedFileIds, tx);
             updated = true;
             updated = true;
         }
         }
@@ -166,7 +165,7 @@ class MachineLearningService {
             await mlIDbStorage.incrementIndexVersion("files");
             await mlIDbStorage.incrementIndexVersion("files");
         }
         }
 
 
-        addLogLine("syncLocalFiles", Date.now() - startTime, "ms");
+        log.info("syncLocalFiles", Date.now() - startTime, "ms");
     }
     }
 
 
     private async getOutOfSyncFiles(syncContext: MLSyncContext) {
     private async getOutOfSyncFiles(syncContext: MLSyncContext) {
@@ -177,13 +176,13 @@ class MachineLearningService {
             MAX_ML_SYNC_ERROR_COUNT,
             MAX_ML_SYNC_ERROR_COUNT,
         );
         );
 
 
-        addLogLine("fileIds: ", JSON.stringify(fileIds));
+        log.info("fileIds: ", JSON.stringify(fileIds));
 
 
         const localFilesMap = await this.getLocalFilesMap(syncContext);
         const localFilesMap = await this.getLocalFilesMap(syncContext);
         syncContext.outOfSyncFiles = fileIds.map((fileId) =>
         syncContext.outOfSyncFiles = fileIds.map((fileId) =>
             localFilesMap.get(fileId),
             localFilesMap.get(fileId),
         );
         );
-        addLogLine("getOutOfSyncFiles", Date.now() - startTime, "ms");
+        log.info("getOutOfSyncFiles", Date.now() - startTime, "ms");
     }
     }
 
 
     private async syncFiles(syncContext: MLSyncContext) {
     private async syncFiles(syncContext: MLSyncContext) {
@@ -206,7 +205,7 @@ class MachineLearningService {
             syncContext.error = error;
             syncContext.error = error;
         }
         }
         await syncContext.syncQueue.onIdle();
         await syncContext.syncQueue.onIdle();
-        addLogLine("allFaces: ", syncContext.nSyncedFaces);
+        log.info("allFaces: ", syncContext.nSyncedFaces);
 
 
         // TODO: In case syncJob has to use multiple ml workers
         // TODO: In case syncJob has to use multiple ml workers
         // do in same transaction with each file update
         // do in same transaction with each file update
@@ -217,32 +216,32 @@ class MachineLearningService {
 
 
     private async getSyncContext(token: string, userID: number) {
     private async getSyncContext(token: string, userID: number) {
         if (!this.syncContext) {
         if (!this.syncContext) {
-            addLogLine("Creating syncContext");
+            log.info("Creating syncContext");
 
 
             this.syncContext = getMLSyncConfig().then((mlSyncConfig) =>
             this.syncContext = getMLSyncConfig().then((mlSyncConfig) =>
                 MLFactory.getMLSyncContext(token, userID, mlSyncConfig, true),
                 MLFactory.getMLSyncContext(token, userID, mlSyncConfig, true),
             );
             );
         } else {
         } else {
-            addLogLine("reusing existing syncContext");
+            log.info("reusing existing syncContext");
         }
         }
         return this.syncContext;
         return this.syncContext;
     }
     }
 
 
     private async getLocalSyncContext(token: string, userID: number) {
     private async getLocalSyncContext(token: string, userID: number) {
         if (!this.localSyncContext) {
         if (!this.localSyncContext) {
-            addLogLine("Creating localSyncContext");
+            log.info("Creating localSyncContext");
             this.localSyncContext = getMLSyncConfig().then((mlSyncConfig) =>
             this.localSyncContext = getMLSyncConfig().then((mlSyncConfig) =>
                 MLFactory.getMLSyncContext(token, userID, mlSyncConfig, false),
                 MLFactory.getMLSyncContext(token, userID, mlSyncConfig, false),
             );
             );
         } else {
         } else {
-            addLogLine("reusing existing localSyncContext");
+            log.info("reusing existing localSyncContext");
         }
         }
         return this.localSyncContext;
         return this.localSyncContext;
     }
     }
 
 
     public async closeLocalSyncContext() {
     public async closeLocalSyncContext() {
         if (this.localSyncContext) {
         if (this.localSyncContext) {
-            addLogLine("Closing localSyncContext");
+            log.info("Closing localSyncContext");
             const syncContext = await this.localSyncContext;
             const syncContext = await this.localSyncContext;
             await syncContext.dispose();
             await syncContext.dispose();
             this.localSyncContext = undefined;
             this.localSyncContext = undefined;
@@ -294,7 +293,7 @@ class MachineLearningService {
             syncContext.nSyncedFiles += 1;
             syncContext.nSyncedFiles += 1;
             return mlFileData;
             return mlFileData;
         } catch (e) {
         } catch (e) {
-            logError(e, "ML syncFile failed");
+            log.error("ML syncFile failed", e);
             let error = e;
             let error = e;
             console.error(
             console.error(
                 "Error in ml sync, fileId: ",
                 "Error in ml sync, fileId: ",
@@ -320,7 +319,7 @@ class MachineLearningService {
             await this.persistMLFileSyncError(syncContext, enteFile, error);
             await this.persistMLFileSyncError(syncContext, enteFile, error);
             syncContext.nSyncedFiles += 1;
             syncContext.nSyncedFiles += 1;
         } finally {
         } finally {
-            addLogLine("TF Memory stats: ", JSON.stringify(tf.memory()));
+            log.info("TF Memory stats: ", JSON.stringify(tf.memory()));
         }
         }
     }
     }
 
 
@@ -362,13 +361,13 @@ class MachineLearningService {
             newMlFile.lastErrorMessage = undefined;
             newMlFile.lastErrorMessage = undefined;
             await this.persistMLFileData(syncContext, newMlFile);
             await this.persistMLFileData(syncContext, newMlFile);
         } catch (e) {
         } catch (e) {
-            logError(e, "ml detection failed");
+            log.error("ml detection failed", e);
             newMlFile.mlVersion = oldMlFile.mlVersion;
             newMlFile.mlVersion = oldMlFile.mlVersion;
             throw e;
             throw e;
         } finally {
         } finally {
             fileContext.tfImage && fileContext.tfImage.dispose();
             fileContext.tfImage && fileContext.tfImage.dispose();
             fileContext.imageBitmap && fileContext.imageBitmap.close();
             fileContext.imageBitmap && fileContext.imageBitmap.close();
-            // addLogLine('8 TF Memory stats: ',JSON.stringify(tf.memory()));
+            // log.info('8 TF Memory stats: ',JSON.stringify(tf.memory()));
 
 
             // TODO: enable once faceId changes go in
             // TODO: enable once faceId changes go in
             // await removeOldFaceCrops(
             // await removeOldFaceCrops(
@@ -387,7 +386,7 @@ class MachineLearningService {
 
 
         await tf.ready();
         await tf.ready();
 
 
-        addLogLine("01 TF Memory stats: ", JSON.stringify(tf.memory()));
+        log.info("01 TF Memory stats: ", JSON.stringify(tf.memory()));
 
 
         this.initialized = true;
         this.initialized = true;
     }
     }
@@ -464,7 +463,7 @@ class MachineLearningService {
 
 
             await FaceService.syncFileFaceEmbeddings(syncContext, fileContext);
             await FaceService.syncFileFaceEmbeddings(syncContext, fileContext);
         }
         }
-        addLogLine(
+        log.info(
             `face detection time taken ${fileContext.enteFile.id}`,
             `face detection time taken ${fileContext.enteFile.id}`,
             Date.now() - startTime,
             Date.now() - startTime,
             "ms",
             "ms",

+ 20 - 21
web/apps/photos/src/services/machineLearning/mlWorkManager.ts

@@ -1,7 +1,6 @@
+import log from "@/next/log";
 import { ComlinkWorker } from "@/next/worker/comlink-worker";
 import { ComlinkWorker } from "@/next/worker/comlink-worker";
 import { eventBus, Events } from "@ente/shared/events";
 import { eventBus, Events } from "@ente/shared/events";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
 import { getToken, getUserID } from "@ente/shared/storage/localStorage/helpers";
 import { getToken, getUserID } from "@ente/shared/storage/localStorage/helpers";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import debounce from "debounce";
 import debounce from "debounce";
@@ -51,7 +50,7 @@ class MLWorkManager {
 
 
     public async setMlSearchEnabled(enabled: boolean) {
     public async setMlSearchEnabled(enabled: boolean) {
         if (!this.mlSearchEnabled && enabled) {
         if (!this.mlSearchEnabled && enabled) {
-            addLogLine("Enabling MLWorkManager");
+            log.info("Enabling MLWorkManager");
             this.mlSearchEnabled = true;
             this.mlSearchEnabled = true;
 
 
             logQueueStats(this.liveSyncQueue, "livesync");
             logQueueStats(this.liveSyncQueue, "livesync");
@@ -70,7 +69,7 @@ class MLWorkManager {
 
 
             await this.startSyncJob();
             await this.startSyncJob();
         } else if (this.mlSearchEnabled && !enabled) {
         } else if (this.mlSearchEnabled && !enabled) {
-            addLogLine("Disabling MLWorkManager");
+            log.info("Disabling MLWorkManager");
             this.mlSearchEnabled = false;
             this.mlSearchEnabled = false;
 
 
             this.liveSyncQueue.removeAllListeners();
             this.liveSyncQueue.removeAllListeners();
@@ -92,23 +91,23 @@ class MLWorkManager {
 
 
     // Handlers
     // Handlers
     private async appStartHandler() {
     private async appStartHandler() {
-        addLogLine("appStartHandler");
+        log.info("appStartHandler");
         try {
         try {
             this.startSyncJob();
             this.startSyncJob();
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed in ML appStart Handler");
+            log.error("Failed in ML appStart Handler", e);
         }
         }
     }
     }
 
 
     private async logoutHandler() {
     private async logoutHandler() {
-        addLogLine("logoutHandler");
+        log.info("logoutHandler");
         try {
         try {
             this.stopSyncJob();
             this.stopSyncJob();
             this.mlSyncJob = undefined;
             this.mlSyncJob = undefined;
             await this.terminateLiveSyncWorker();
             await this.terminateLiveSyncWorker();
             await mlIDbStorage.clearMLDB();
             await mlIDbStorage.clearMLDB();
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed in ML logout Handler");
+            log.error("Failed in ML logout Handler", e);
         }
         }
     }
     }
 
 
@@ -119,9 +118,9 @@ class MLWorkManager {
         if (!this.mlSearchEnabled) {
         if (!this.mlSearchEnabled) {
             return;
             return;
         }
         }
-        addLogLine("fileUploadedHandler: ", arg.enteFile.id);
+        log.info("fileUploadedHandler: ", arg.enteFile.id);
         if (arg.enteFile.metadata.fileType !== FILE_TYPE.IMAGE) {
         if (arg.enteFile.metadata.fileType !== FILE_TYPE.IMAGE) {
-            addLogLine("Skipping non image file for local file processing");
+            log.info("Skipping non image file for local file processing");
             return;
             return;
         }
         }
         try {
         try {
@@ -134,7 +133,7 @@ class MLWorkManager {
     }
     }
 
 
     private async localFilesUpdatedHandler() {
     private async localFilesUpdatedHandler() {
-        addLogLine("Local files updated");
+        log.info("Local files updated");
         this.startSyncJob();
         this.startSyncJob();
     }
     }
 
 
@@ -165,7 +164,7 @@ class MLWorkManager {
     }
     }
 
 
     private async onLiveSyncIdle() {
     private async onLiveSyncIdle() {
-        addLogLine("Live sync idle");
+        log.info("Live sync idle");
         await this.terminateLiveSyncWorker();
         await this.terminateLiveSyncWorker();
         this.mlSearchEnabled && this.startSyncJob();
         this.mlSearchEnabled && this.startSyncJob();
     }
     }
@@ -206,7 +205,7 @@ class MLWorkManager {
             // TODO: skipping is not required if we are caching chunks through service worker
             // TODO: skipping is not required if we are caching chunks through service worker
             // currently worker chunk itself is not loaded when network is not there
             // currently worker chunk itself is not loaded when network is not there
             if (!navigator.onLine) {
             if (!navigator.onLine) {
-                addLogLine(
+                log.info(
                     "Skipping ml-sync job run as not connected to internet.",
                     "Skipping ml-sync job run as not connected to internet.",
                 );
                 );
                 return {
                 return {
@@ -227,25 +226,25 @@ class MLWorkManager {
                     !!mlSyncResult.error || mlSyncResult.nOutOfSyncFiles < 1,
                     !!mlSyncResult.error || mlSyncResult.nOutOfSyncFiles < 1,
                 mlSyncResult,
                 mlSyncResult,
             };
             };
-            addLogLine("ML Sync Job result: ", JSON.stringify(jobResult));
+            log.info("ML Sync Job result: ", JSON.stringify(jobResult));
 
 
             // TODO: redirect/refresh to gallery in case of session_expired, stop ml sync job
             // TODO: redirect/refresh to gallery in case of session_expired, stop ml sync job
 
 
             return jobResult;
             return jobResult;
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed to run MLSync Job");
+            log.error("Failed to run MLSync Job", e);
         }
         }
     }
     }
 
 
     public async startSyncJob() {
     public async startSyncJob() {
         try {
         try {
-            addLogLine("MLWorkManager.startSyncJob");
+            log.info("MLWorkManager.startSyncJob");
             if (!this.mlSearchEnabled) {
             if (!this.mlSearchEnabled) {
-                addLogLine("ML Search disabled, not starting ml sync job");
+                log.info("ML Search disabled, not starting ml sync job");
                 return;
                 return;
             }
             }
             if (!getToken()) {
             if (!getToken()) {
-                addLogLine("User not logged in, not starting ml sync job");
+                log.info("User not logged in, not starting ml sync job");
                 return;
                 return;
             }
             }
             const mlSyncJobConfig = await getMLSyncJobConfig();
             const mlSyncJobConfig = await getMLSyncJobConfig();
@@ -256,17 +255,17 @@ class MLWorkManager {
             }
             }
             this.mlSyncJob.start();
             this.mlSyncJob.start();
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed to start MLSync Job");
+            log.error("Failed to start MLSync Job", e);
         }
         }
     }
     }
 
 
     public stopSyncJob(terminateWorker: boolean = true) {
     public stopSyncJob(terminateWorker: boolean = true) {
         try {
         try {
-            addLogLine("MLWorkManager.stopSyncJob");
+            log.info("MLWorkManager.stopSyncJob");
             this.mlSyncJob?.stop();
             this.mlSyncJob?.stop();
             terminateWorker && this.terminateSyncJobWorker();
             terminateWorker && this.terminateSyncJobWorker();
         } catch (e) {
         } catch (e) {
-            logError(e, "Failed to stop MLSync Job");
+            log.error("Failed to stop MLSync Job", e);
         }
         }
     }
     }
 }
 }

+ 2 - 2
web/apps/photos/src/services/machineLearning/mobileFaceNetEmbeddingService.ts

@@ -1,4 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
+import log from "@/next/log";
 import * as tf from "@tensorflow/tfjs-core";
 import * as tf from "@tensorflow/tfjs-core";
 import { TFLiteModel } from "@tensorflow/tfjs-tflite";
 import { TFLiteModel } from "@tensorflow/tfjs-tflite";
 import { MOBILEFACENET_FACE_SIZE } from "constants/mlConfig";
 import { MOBILEFACENET_FACE_SIZE } from "constants/mlConfig";
@@ -37,7 +37,7 @@ class MobileFaceNetEmbeddingService implements FaceEmbeddingService {
             "/models/mobilefacenet/mobilefacenet.tflite",
             "/models/mobilefacenet/mobilefacenet.tflite",
         );
         );
 
 
-        addLogLine("loaded mobileFaceNetModel: ", tf.getBackend());
+        log.info("loaded mobileFaceNetModel: ", tf.getBackend());
     }
     }
 
 
     private async getMobileFaceNetModel() {
     private async getMobileFaceNetModel() {

+ 6 - 6
web/apps/photos/src/services/machineLearning/objectService.ts

@@ -1,4 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
+import log from "@/next/log";
 import {
 import {
     DetectedObject,
     DetectedObject,
     MLSyncContext,
     MLSyncContext,
@@ -61,7 +61,7 @@ class ObjectService {
                 syncContext.config.sceneDetection.minScore,
                 syncContext.config.sceneDetection.minScore,
             )),
             )),
         );
         );
-        // addLogLine('3 TF Memory stats: ',JSON.stringify(tf.memory()));
+        // log.info('3 TF Memory stats: ',JSON.stringify(tf.memory()));
         // TODO: reenable faces filtering based on width
         // TODO: reenable faces filtering based on width
         const detectedObjects = objectDetections?.map((detection) => {
         const detectedObjects = objectDetections?.map((detection) => {
             return {
             return {
@@ -77,13 +77,13 @@ class ObjectService {
         // ?.filter((f) =>
         // ?.filter((f) =>
         //     f.box.width > syncContext.config.faceDetection.minFaceSize
         //     f.box.width > syncContext.config.faceDetection.minFaceSize
         // );
         // );
-        addLogLine(
+        log.info(
             `object detection time taken ${fileContext.enteFile.id}`,
             `object detection time taken ${fileContext.enteFile.id}`,
             Date.now() - startTime,
             Date.now() - startTime,
             "ms",
             "ms",
         );
         );
 
 
-        addLogLine("[MLService] Detected Objects: ", newMlFile.objects?.length);
+        log.info("[MLService] Detected Objects: ", newMlFile.objects?.length);
     }
     }
 
 
     async getAllSyncedObjectsMap(syncContext: MLSyncContext) {
     async getAllSyncedObjectsMap(syncContext: MLSyncContext) {
@@ -115,9 +115,9 @@ class ObjectService {
 
 
     async syncThingsIndex(syncContext: MLSyncContext) {
     async syncThingsIndex(syncContext: MLSyncContext) {
         const filesVersion = await mlIDbStorage.getIndexVersion("files");
         const filesVersion = await mlIDbStorage.getIndexVersion("files");
-        addLogLine("things", await mlIDbStorage.getIndexVersion("things"));
+        log.info("things", await mlIDbStorage.getIndexVersion("things"));
         if (filesVersion <= (await mlIDbStorage.getIndexVersion("things"))) {
         if (filesVersion <= (await mlIDbStorage.getIndexVersion("things"))) {
-            addLogLine(
+            log.info(
                 "[MLService] Skipping people index as already synced to latest version",
                 "[MLService] Skipping people index as already synced to latest version",
             );
             );
             return;
             return;

+ 3 - 3
web/apps/photos/src/services/machineLearning/peopleService.ts

@@ -1,4 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
+import log from "@/next/log";
 import { Face, MLSyncContext, Person } from "types/machineLearning";
 import { Face, MLSyncContext, Person } from "types/machineLearning";
 import {
 import {
     findFirstIfSorted,
     findFirstIfSorted,
@@ -20,7 +20,7 @@ class PeopleService {
                 syncContext.faceClusteringService.method,
                 syncContext.faceClusteringService.method,
             )
             )
         ) {
         ) {
-            addLogLine(
+            log.info(
                 "[MLService] Skipping people index as already synced to latest version",
                 "[MLService] Skipping people index as already synced to latest version",
             );
             );
             return;
             return;
@@ -84,7 +84,7 @@ class PeopleService {
             faces.forEach((face) => {
             faces.forEach((face) => {
                 face.personId = person.id;
                 face.personId = person.id;
             });
             });
-            // addLogLine("Creating person: ", person, faces);
+            // log.info("Creating person: ", person, faces);
         }
         }
 
 
         await mlIDbStorage.updateFaces(allFacesMap);
         await mlIDbStorage.updateFaces(allFacesMap);

+ 4 - 4
web/apps/photos/src/services/machineLearning/readerService.ts

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import { MLSyncContext, MLSyncFileContext } from "types/machineLearning";
 import { MLSyncContext, MLSyncFileContext } from "types/machineLearning";
 import {
 import {
@@ -16,7 +16,7 @@ class ReaderService {
             if (fileContext.imageBitmap) {
             if (fileContext.imageBitmap) {
                 return fileContext.imageBitmap;
                 return fileContext.imageBitmap;
             }
             }
-            // addLogLine('1 TF Memory stats: ',JSON.stringify(tf.memory()));
+            // log.info('1 TF Memory stats: ',JSON.stringify(tf.memory()));
             if (fileContext.localFile) {
             if (fileContext.localFile) {
                 if (
                 if (
                     fileContext.enteFile.metadata.fileType !== FILE_TYPE.IMAGE
                     fileContext.enteFile.metadata.fileType !== FILE_TYPE.IMAGE
@@ -47,11 +47,11 @@ class ReaderService {
             fileContext.newMlFile.imageSource = syncContext.config.imageSource;
             fileContext.newMlFile.imageSource = syncContext.config.imageSource;
             const { width, height } = fileContext.imageBitmap;
             const { width, height } = fileContext.imageBitmap;
             fileContext.newMlFile.imageDimensions = { width, height };
             fileContext.newMlFile.imageDimensions = { width, height };
-            // addLogLine('2 TF Memory stats: ',JSON.stringify(tf.memory()));
+            // log.info('2 TF Memory stats: ',JSON.stringify(tf.memory()));
 
 
             return fileContext.imageBitmap;
             return fileContext.imageBitmap;
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to create image bitmap");
+            log.error("failed to create image bitmap", e);
             throw e;
             throw e;
         }
         }
     }
     }

+ 2 - 2
web/apps/photos/src/services/machineLearning/ssdMobileNetV2Service.ts

@@ -1,3 +1,4 @@
+import log from "@/next/log";
 import * as tf from "@tensorflow/tfjs-core";
 import * as tf from "@tensorflow/tfjs-core";
 import {
 import {
     ObjectDetection,
     ObjectDetection,
@@ -6,7 +7,6 @@ import {
     Versioned,
     Versioned,
 } from "types/machineLearning";
 } from "types/machineLearning";
 
 
-import { addLogLine } from "@ente/shared/logging";
 import * as SSDMobileNet from "@tensorflow-models/coco-ssd";
 import * as SSDMobileNet from "@tensorflow-models/coco-ssd";
 import { OBJECT_DETECTION_IMAGE_SIZE } from "constants/mlConfig";
 import { OBJECT_DETECTION_IMAGE_SIZE } from "constants/mlConfig";
 import { resizeToSquare } from "utils/image";
 import { resizeToSquare } from "utils/image";
@@ -28,7 +28,7 @@ class SSDMobileNetV2 implements ObjectDetectionService {
             base: "mobilenet_v2",
             base: "mobilenet_v2",
             modelUrl: "/models/ssdmobilenet/model.json",
             modelUrl: "/models/ssdmobilenet/model.json",
         });
         });
-        addLogLine("loaded ssdMobileNetV2Model", tf.getBackend());
+        log.info("loaded ssdMobileNetV2Model", tf.getBackend());
     }
     }
 
 
     private async getSSDMobileNetV2Model() {
     private async getSSDMobileNetV2Model() {

+ 6 - 6
web/apps/photos/src/services/publicCollectionService.ts

@@ -1,8 +1,8 @@
+import log from "@/next/log";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import { CustomError, parseSharingErrorCodes } from "@ente/shared/error";
 import { CustomError, parseSharingErrorCodes } from "@ente/shared/error";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint } from "@ente/shared/network/api";
 import { getEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import localForage from "@ente/shared/storage/localForage";
 import localForage from "@ente/shared/storage/localForage";
 import { Collection, CollectionPublicMagicMetadata } from "types/collection";
 import { Collection, CollectionPublicMagicMetadata } from "types/collection";
 import { EncryptedEnteFile, EnteFile } from "types/file";
 import { EncryptedEnteFile, EnteFile } from "types/file";
@@ -223,14 +223,14 @@ export const syncPublicFiles = async (
             setPublicFiles([...sortFiles(mergeMetadata(files), sortAsc)]);
             setPublicFiles([...sortFiles(mergeMetadata(files), sortAsc)]);
         } catch (e) {
         } catch (e) {
             const parsedError = parseSharingErrorCodes(e);
             const parsedError = parseSharingErrorCodes(e);
-            logError(e, "failed to sync shared collection files");
+            log.error("failed to sync shared collection files", e);
             if (parsedError.message === CustomError.TOKEN_EXPIRED) {
             if (parsedError.message === CustomError.TOKEN_EXPIRED) {
                 throw e;
                 throw e;
             }
             }
         }
         }
         return [...sortFiles(mergeMetadata(files), sortAsc)];
         return [...sortFiles(mergeMetadata(files), sortAsc)];
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get local  or sync shared collection files");
+        log.error("failed to get local  or sync shared collection files", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -294,7 +294,7 @@ const getPublicFiles = async (
         } while (resp.data.hasMore);
         } while (resp.data.hasMore);
         return decryptedFiles;
         return decryptedFiles;
     } catch (e) {
     } catch (e) {
-        logError(e, "Get public  files failed");
+        log.error("Get public  files failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -347,7 +347,7 @@ export const getPublicCollection = async (
         await saveReferralCode(referralCode);
         await saveReferralCode(referralCode);
         return [collection, referralCode];
         return [collection, referralCode];
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get public collection");
+        log.error("failed to get public collection", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -366,7 +366,7 @@ export const verifyPublicCollectionPassword = async (
         const jwtToken = resp.data.jwtToken;
         const jwtToken = resp.data.jwtToken;
         return jwtToken;
         return jwtToken;
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to verify public collection password");
+        log.error("failed to verify public collection password", e);
         throw e;
         throw e;
     }
     }
 };
 };

+ 5 - 4
web/apps/photos/src/services/readerService.ts

@@ -1,5 +1,5 @@
 import { convertBytesToHumanReadable } from "@/next/file";
 import { convertBytesToHumanReadable } from "@/next/file";
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { ElectronFile } from "types/upload";
 import { ElectronFile } from "types/upload";
 
 
 export async function getUint8ArrayView(
 export async function getUint8ArrayView(
@@ -8,9 +8,10 @@ export async function getUint8ArrayView(
     try {
     try {
         return new Uint8Array(await file.arrayBuffer());
         return new Uint8Array(await file.arrayBuffer());
     } catch (e) {
     } catch (e) {
-        logError(e, "reading file blob failed", {
-            fileSize: convertBytesToHumanReadable(file.size),
-        });
+        log.error(
+            `Failed to read file blob of size ${convertBytesToHumanReadable(file.size)}`,
+            e,
+        );
         throw e;
         throw e;
     }
     }
 }
 }

+ 10 - 12
web/apps/photos/src/services/searchService.ts

@@ -1,11 +1,8 @@
-import * as chrono from "chrono-node";
-import { t } from "i18next";
-import { getAllPeople } from "utils/machineLearning";
-
+import log from "@/next/log";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
+import * as chrono from "chrono-node";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
+import { t } from "i18next";
 import { Collection } from "types/collection";
 import { Collection } from "types/collection";
 import { Model } from "types/embedding";
 import { Model } from "types/embedding";
 import { EntityType, LocationTag, LocationTagData } from "types/entity";
 import { EntityType, LocationTag, LocationTagData } from "types/entity";
@@ -21,6 +18,7 @@ import {
 } from "types/search";
 } from "types/search";
 import ComlinkSearchWorker from "utils/comlink/ComlinkSearchWorker";
 import ComlinkSearchWorker from "utils/comlink/ComlinkSearchWorker";
 import { getUniqueFiles } from "utils/file";
 import { getUniqueFiles } from "utils/file";
+import { getAllPeople } from "utils/machineLearning";
 import { getMLSyncConfig } from "utils/machineLearning/config";
 import { getMLSyncConfig } from "utils/machineLearning/config";
 import { getFormattedDate } from "utils/search";
 import { getFormattedDate } from "utils/search";
 import mlIDbStorage from "utils/storage/mlIDbStorage";
 import mlIDbStorage from "utils/storage/mlIDbStorage";
@@ -64,7 +62,7 @@ export const getAutoCompleteSuggestions =
 
 
             return convertSuggestionsToOptions(suggestions);
             return convertSuggestionsToOptions(suggestions);
         } catch (e) {
         } catch (e) {
-            logError(e, "getAutoCompleteSuggestions failed");
+            log.error("getAutoCompleteSuggestions failed", e);
             return [];
             return [];
         }
         }
     };
     };
@@ -159,7 +157,7 @@ function getYearSuggestion(searchPhrase: string): Suggestion[] {
                 ];
                 ];
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "getYearSuggestion failed");
+            log.error("getYearSuggestion failed", e);
         }
         }
     }
     }
     return [];
     return [];
@@ -175,7 +173,7 @@ export async function getAllPeopleSuggestion(): Promise<Array<Suggestion>> {
             hide: true,
             hide: true,
         }));
         }));
     } catch (e) {
     } catch (e) {
-        logError(e, "getAllPeopleSuggestion failed");
+        log.error("getAllPeopleSuggestion failed", e);
         return [];
         return [];
     }
     }
 }
 }
@@ -205,7 +203,7 @@ export async function getIndexStatusSuggestion(): Promise<Suggestion> {
             hide: true,
             hide: true,
         };
         };
     } catch (e) {
     } catch (e) {
-        logError(e, "getIndexStatusSuggestion failed");
+        log.error("getIndexStatusSuggestion failed", e);
     }
     }
 }
 }
 
 
@@ -319,7 +317,7 @@ async function getClipSuggestion(searchPhrase: string): Promise<Suggestion> {
         };
         };
     } catch (e) {
     } catch (e) {
         if (!e.message?.includes(CustomError.MODEL_DOWNLOAD_PENDING)) {
         if (!e.message?.includes(CustomError.MODEL_DOWNLOAD_PENDING)) {
-            logError(e, "getClipSuggestion failed");
+            log.error("getClipSuggestion failed", e);
         }
         }
         return null;
         return null;
     }
     }
@@ -383,7 +381,7 @@ async function searchLocationTag(searchPhrase: string): Promise<LocationTag[]> {
         locationTag.data.name.toLowerCase().includes(searchPhrase),
         locationTag.data.name.toLowerCase().includes(searchPhrase),
     );
     );
     if (matchedLocationTags.length > 0) {
     if (matchedLocationTags.length > 0) {
-        addLogLine(
+        log.info(
             `Found ${matchedLocationTags.length} location tags for search phrase`,
             `Found ${matchedLocationTags.length} location tags for search phrase`,
         );
         );
     }
     }

+ 7 - 9
web/apps/photos/src/services/trashService.ts

@@ -1,16 +1,14 @@
+import log from "@/next/log";
+import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint } from "@ente/shared/network/api";
 import { getEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import localForage from "@ente/shared/storage/localForage";
 import localForage from "@ente/shared/storage/localForage";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { Collection } from "types/collection";
 import { Collection } from "types/collection";
-import { SetFiles } from "types/gallery";
-import { decryptFile, sortTrashFiles } from "utils/file";
-import { getCollection } from "./collectionService";
-
-import HTTPService from "@ente/shared/network/HTTPService";
 import { EnteFile } from "types/file";
 import { EnteFile } from "types/file";
+import { SetFiles } from "types/gallery";
 import { EncryptedTrashItem, Trash } from "types/trash";
 import { EncryptedTrashItem, Trash } from "types/trash";
-import { mergeMetadata } from "utils/file";
+import { decryptFile, mergeMetadata, sortTrashFiles } from "utils/file";
+import { getCollection } from "./collectionService";
 
 
 const TRASH = "file-trash";
 const TRASH = "file-trash";
 const TRASH_TIME = "trash-time";
 const TRASH_TIME = "trash-time";
@@ -135,7 +133,7 @@ export const updateTrash = async (
         } while (resp.data.hasMore);
         } while (resp.data.hasMore);
         return updatedTrash;
         return updatedTrash;
     } catch (e) {
     } catch (e) {
-        logError(e, "Get trash files failed");
+        log.error("Get trash files failed", e);
     }
     }
     return currentTrash;
     return currentTrash;
 };
 };
@@ -170,7 +168,7 @@ export const emptyTrash = async () => {
             },
             },
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "empty trash failed");
+        log.error("empty trash failed", e);
         throw e;
         throw e;
     }
     }
 };
 };

+ 3 - 12
web/apps/photos/src/services/typeDetectionService.ts

@@ -1,6 +1,5 @@
-import { convertBytesToHumanReadable } from "@/next/file";
+import log from "@/next/log";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { logError } from "@ente/shared/sentry";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import {
 import {
     KNOWN_NON_MEDIA_FORMATS,
     KNOWN_NON_MEDIA_FORMATS,
@@ -10,7 +9,6 @@ import FileType, { FileTypeResult } from "file-type";
 import { ElectronFile, FileTypeInfo } from "types/upload";
 import { ElectronFile, FileTypeInfo } from "types/upload";
 import { getFileExtension } from "utils/file";
 import { getFileExtension } from "utils/file";
 import { getUint8ArrayView } from "./readerService";
 import { getUint8ArrayView } from "./readerService";
-import { getFileSize } from "./upload/fileService";
 
 
 const TYPE_VIDEO = "video";
 const TYPE_VIDEO = "video";
 const TYPE_IMAGE = "image";
 const TYPE_IMAGE = "image";
@@ -51,7 +49,6 @@ export async function getFileType(
         };
         };
     } catch (e) {
     } catch (e) {
         const fileFormat = getFileExtension(receivedFile.name);
         const fileFormat = getFileExtension(receivedFile.name);
-        const fileSize = convertBytesToHumanReadable(getFileSize(receivedFile));
         const whiteListedFormat = WHITELISTED_FILE_FORMATS.find(
         const whiteListedFormat = WHITELISTED_FILE_FORMATS.find(
             (a) => a.exactType === fileFormat,
             (a) => a.exactType === fileFormat,
         );
         );
@@ -62,16 +59,10 @@ export async function getFileType(
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
         }
         }
         if (e.message === CustomError.NON_MEDIA_FILE) {
         if (e.message === CustomError.NON_MEDIA_FILE) {
-            logError(e, "unsupported file format", {
-                fileFormat,
-                fileSize,
-            });
+            log.error(`unsupported file format ${fileFormat}`, e);
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
         }
         }
-        logError(e, "type detection failed", {
-            fileFormat,
-            fileSize,
-        });
+        log.error(`type detection failed for format ${fileFormat}`, e);
         throw Error(CustomError.TYPE_DETECTION_FAILED(fileFormat));
         throw Error(CustomError.TYPE_DETECTION_FAILED(fileFormat));
     }
     }
 }
 }

+ 3 - 3
web/apps/photos/src/services/updateCreationTimeWithExif.ts

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time";
 import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time";
 import type { FixOption } from "components/FixCreationTime";
 import type { FixOption } from "components/FixCreationTime";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
@@ -88,7 +88,7 @@ export async function updateCreationTimeWithExif(
                     updateExistingFilePubMetadata(file, updatedFile);
                     updateExistingFilePubMetadata(file, updatedFile);
                 }
                 }
             } catch (e) {
             } catch (e) {
-                logError(e, "failed to updated a CreationTime With Exif");
+                log.error("failed to updated a CreationTime With Exif", e);
                 completedWithError = true;
                 completedWithError = true;
             } finally {
             } finally {
                 setProgressTracker({
                 setProgressTracker({
@@ -98,7 +98,7 @@ export async function updateCreationTimeWithExif(
             }
             }
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "update CreationTime With Exif failed");
+        log.error("update CreationTime With Exif failed", e);
         completedWithError = true;
         completedWithError = true;
     }
     }
     return completedWithError;
     return completedWithError;

+ 41 - 38
web/apps/photos/src/services/upload/exifService.ts

@@ -1,5 +1,5 @@
+import log from "@/next/log";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { logError } from "@ente/shared/sentry";
 import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time";
 import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time";
 import { EXIFLESS_FORMATS, NULL_LOCATION } from "constants/upload";
 import { EXIFLESS_FORMATS, NULL_LOCATION } from "constants/upload";
 import exifr from "exifr";
 import exifr from "exifr";
@@ -67,13 +67,15 @@ export async function getParsedExifData(
         return parseExifData(filteredExifData);
         return parseExifData(filteredExifData);
     } catch (e) {
     } catch (e) {
         if (e.message === EXIFR_UNSUPPORTED_FILE_FORMAT_MESSAGE) {
         if (e.message === EXIFR_UNSUPPORTED_FILE_FORMAT_MESSAGE) {
-            logError(e, "exif library unsupported format", {
-                fileType: fileTypeInfo.exactType,
-            });
+            log.error(
+                `exif library unsupported format ${fileTypeInfo.exactType}`,
+                e,
+            );
         } else {
         } else {
-            logError(e, "get parsed exif data failed", {
-                fileType: fileTypeInfo.exactType,
-            });
+            log.error(
+                `get parsed exif data failed for file type ${fileTypeInfo.exactType}`,
+                e,
+            );
             throw e;
             throw e;
         }
         }
     }
     }
@@ -128,13 +130,13 @@ function parseExifData(exifData: RawEXIFData): ParsedEXIFData {
             parsedExif.imageWidth = ImageWidth;
             parsedExif.imageWidth = ImageWidth;
             parsedExif.imageHeight = ImageHeight;
             parsedExif.imageHeight = ImageHeight;
         } else {
         } else {
-            logError(
-                new Error("ImageWidth or ImageHeight is not a number"),
-                "Image dimension parsing failed",
-                {
-                    ImageWidth,
-                    ImageHeight,
-                },
+            log.error(
+                `Image dimension parsing failed - ImageWidth or ImageHeight is not a number ${JSON.stringify(
+                    {
+                        ImageWidth,
+                        ImageHeight,
+                    },
+                )}`,
             );
             );
         }
         }
     } else if (ExifImageWidth && ExifImageHeight) {
     } else if (ExifImageWidth && ExifImageHeight) {
@@ -145,13 +147,13 @@ function parseExifData(exifData: RawEXIFData): ParsedEXIFData {
             parsedExif.imageWidth = ExifImageWidth;
             parsedExif.imageWidth = ExifImageWidth;
             parsedExif.imageHeight = ExifImageHeight;
             parsedExif.imageHeight = ExifImageHeight;
         } else {
         } else {
-            logError(
-                new Error("ExifImageWidth or ExifImageHeight is not a number"),
-                "Image dimension parsing failed",
-                {
-                    ExifImageWidth,
-                    ExifImageHeight,
-                },
+            log.error(
+                `Image dimension parsing failed - ExifImageWidth or ExifImageHeight is not a number ${JSON.stringify(
+                    {
+                        ExifImageWidth,
+                        ExifImageHeight,
+                    },
+                )}`,
             );
             );
         }
         }
     } else if (PixelXDimension && PixelYDimension) {
     } else if (PixelXDimension && PixelYDimension) {
@@ -162,13 +164,13 @@ function parseExifData(exifData: RawEXIFData): ParsedEXIFData {
             parsedExif.imageWidth = PixelXDimension;
             parsedExif.imageWidth = PixelXDimension;
             parsedExif.imageHeight = PixelYDimension;
             parsedExif.imageHeight = PixelYDimension;
         } else {
         } else {
-            logError(
-                new Error("PixelXDimension or PixelYDimension is not a number"),
-                "Image dimension parsing failed",
-                {
-                    PixelXDimension,
-                    PixelYDimension,
-                },
+            log.error(
+                `Image dimension parsing failed - PixelXDimension or PixelYDimension is not a number ${JSON.stringify(
+                    {
+                        PixelXDimension,
+                        PixelYDimension,
+                    },
+                )}`,
             );
             );
         }
         }
     }
     }
@@ -229,9 +231,7 @@ function parseEXIFDate(dateTimeString: string) {
         }
         }
         return date;
         return date;
     } catch (e) {
     } catch (e) {
-        logError(e, "parseEXIFDate failed", {
-            dateTimeString,
-        });
+        log.error(`Failed to parseEXIFDate ${dateTimeString}`, e);
         return null;
         return null;
     }
     }
 }
 }
@@ -265,12 +265,15 @@ export function parseEXIFLocation(
         );
         );
         return { latitude, longitude };
         return { latitude, longitude };
     } catch (e) {
     } catch (e) {
-        logError(e, "parseEXIFLocation failed", {
-            gpsLatitude,
-            gpsLatitudeRef,
-            gpsLongitude,
-            gpsLongitudeRef,
-        });
+        log.error(
+            `Failed to parseEXIFLocation ${JSON.stringify({
+                gpsLatitude,
+                gpsLatitudeRef,
+                gpsLongitude,
+                gpsLongitudeRef,
+            })}`,
+            e,
+        );
         return NULL_LOCATION;
         return NULL_LOCATION;
     }
     }
 }
 }
@@ -330,7 +333,7 @@ export async function updateFileCreationDateInEXIF(
         const exifInsertedFile = piexif.insert(exifBytes, imageDataURL);
         const exifInsertedFile = piexif.insert(exifBytes, imageDataURL);
         return dataURIToBlob(exifInsertedFile);
         return dataURIToBlob(exifInsertedFile);
     } catch (e) {
     } catch (e) {
-        logError(e, "updateFileModifyDateInEXIF failed");
+        log.error("updateFileModifyDateInEXIF failed", e);
         return fileBlob;
         return fileBlob;
     }
     }
 }
 }

+ 7 - 9
web/apps/photos/src/services/upload/fileService.ts

@@ -1,7 +1,9 @@
 import { getFileNameSize } from "@/next/file";
 import { getFileNameSize } from "@/next/file";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
+import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
+import { Remote } from "comlink";
 import { FILE_READER_CHUNK_SIZE, MULTIPART_PART_SIZE } from "constants/upload";
 import { FILE_READER_CHUNK_SIZE, MULTIPART_PART_SIZE } from "constants/upload";
+import { EncryptedMagicMetadata } from "types/magicMetadata";
 import {
 import {
     DataStream,
     DataStream,
     ElectronFile,
     ElectronFile,
@@ -13,10 +15,6 @@ import {
     ParsedMetadataJSON,
     ParsedMetadataJSON,
     ParsedMetadataJSONMap,
     ParsedMetadataJSONMap,
 } from "types/upload";
 } from "types/upload";
-
-import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
-import { Remote } from "comlink";
-import { EncryptedMagicMetadata } from "types/magicMetadata";
 import {
 import {
     getElectronFileStream,
     getElectronFileStream,
     getFileStream,
     getFileStream,
@@ -47,7 +45,7 @@ export async function readFile(
         rawFile,
         rawFile,
         fileTypeInfo,
         fileTypeInfo,
     );
     );
-    addLogLine(`reading file data ${getFileNameSize(rawFile)} `);
+    log.info(`reading file data ${getFileNameSize(rawFile)} `);
     let filedata: Uint8Array | DataStream;
     let filedata: Uint8Array | DataStream;
     if (!(rawFile instanceof File)) {
     if (!(rawFile instanceof File)) {
         if (rawFile.size > MULTIPART_PART_SIZE) {
         if (rawFile.size > MULTIPART_PART_SIZE) {
@@ -64,7 +62,7 @@ export async function readFile(
         filedata = await getUint8ArrayView(rawFile);
         filedata = await getUint8ArrayView(rawFile);
     }
     }
 
 
-    addLogLine(`read file data successfully ${getFileNameSize(rawFile)} `);
+    log.info(`read file data successfully ${getFileNameSize(rawFile)} `);
 
 
     return {
     return {
         filedata,
         filedata,
@@ -152,7 +150,7 @@ export async function encryptFile(
         };
         };
         return result;
         return result;
     } catch (e) {
     } catch (e) {
-        logError(e, "Error encrypting files");
+        log.error("Error encrypting files", e);
         throw e;
         throw e;
     }
     }
 }
 }

+ 5 - 8
web/apps/photos/src/services/upload/hashService.tsx

@@ -1,8 +1,7 @@
 import { getFileNameSize } from "@/next/file";
 import { getFileNameSize } from "@/next/file";
+import log from "@/next/log";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
 import { Remote } from "comlink";
 import { Remote } from "comlink";
 import { FILE_READER_CHUNK_SIZE } from "constants/upload";
 import { FILE_READER_CHUNK_SIZE } from "constants/upload";
 import { getElectronFileStream, getFileStream } from "services/readerService";
 import { getElectronFileStream, getFileStream } from "services/readerService";
@@ -13,7 +12,7 @@ export async function getFileHash(
     file: File | ElectronFile,
     file: File | ElectronFile,
 ) {
 ) {
     try {
     try {
-        addLogLine(`getFileHash called for ${getFileNameSize(file)}`);
+        log.info(`getFileHash called for ${getFileNameSize(file)}`);
         let filedata: DataStream;
         let filedata: DataStream;
         if (file instanceof File) {
         if (file instanceof File) {
             filedata = getFileStream(file, FILE_READER_CHUNK_SIZE);
             filedata = getFileStream(file, FILE_READER_CHUNK_SIZE);
@@ -38,14 +37,12 @@ export async function getFileHash(
             throw Error(CustomError.CHUNK_MORE_THAN_EXPECTED);
             throw Error(CustomError.CHUNK_MORE_THAN_EXPECTED);
         }
         }
         const hash = await worker.completeChunkHashing(hashState);
         const hash = await worker.completeChunkHashing(hashState);
-        addLogLine(
+        log.info(
             `file hashing completed successfully ${getFileNameSize(file)}`,
             `file hashing completed successfully ${getFileNameSize(file)}`,
         );
         );
         return hash;
         return hash;
     } catch (e) {
     } catch (e) {
-        logError(e, "getFileHash failed");
-        addLogLine(
-            `file hashing failed ${getFileNameSize(file)} ,${e.message} `,
-        );
+        log.error("getFileHash failed", e);
+        log.info(`file hashing failed ${getFileNameSize(file)} ,${e.message} `);
     }
     }
 }
 }

+ 5 - 7
web/apps/photos/src/services/upload/livePhotoService.ts

@@ -1,6 +1,6 @@
+import log from "@/next/log";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { logError } from "@ente/shared/sentry";
 import { Remote } from "comlink";
 import { Remote } from "comlink";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import { LIVE_PHOTO_ASSET_SIZE_LIMIT } from "constants/upload";
 import { LIVE_PHOTO_ASSET_SIZE_LIMIT } from "constants/upload";
@@ -213,7 +213,7 @@ export async function clusterLivePhotoFiles(mediaFiles: FileWithCollection[]) {
         if (e.message === CustomError.UPLOAD_CANCELLED) {
         if (e.message === CustomError.UPLOAD_CANCELLED) {
             throw e;
             throw e;
         } else {
         } else {
-            logError(e, "failed to cluster live photo");
+            log.error("failed to cluster live photo", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -265,15 +265,13 @@ function areFilesLivePhotoAssets(
         ) {
         ) {
             return true;
             return true;
         } else {
         } else {
-            logError(
-                new Error(CustomError.TOO_LARGE_LIVE_PHOTO_ASSETS),
-                CustomError.TOO_LARGE_LIVE_PHOTO_ASSETS,
-                {
+            log.error(
+                `${CustomError.TOO_LARGE_LIVE_PHOTO_ASSETS} - ${JSON.stringify({
                     fileSizes: [
                     fileSizes: [
                         firstFileIdentifier.size,
                         firstFileIdentifier.size,
                         secondFileIdentifier.size,
                         secondFileIdentifier.size,
                     ],
                     ],
-                },
+                })}`,
             );
             );
         }
         }
     }
     }

+ 5 - 5
web/apps/photos/src/services/upload/metadataService.ts

@@ -1,5 +1,5 @@
+import log from "@/next/log";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
-import { logError } from "@ente/shared/sentry";
 import {
 import {
     parseDateFromFusedDateString,
     parseDateFromFusedDateString,
     tryToParseDateTime,
     tryToParseDateTime,
@@ -109,7 +109,7 @@ export async function getImageMetadata(
             height: exifData?.imageHeight ?? null,
             height: exifData?.imageHeight ?? null,
         };
         };
     } catch (e) {
     } catch (e) {
-        logError(e, "getExifData failed");
+        log.error("getExifData failed", e);
     }
     }
     return imageMetadata;
     return imageMetadata;
 }
 }
@@ -206,7 +206,7 @@ export async function parseMetadataJSON(receivedFile: File | ElectronFile) {
         }
         }
         return parsedMetadataJSON;
         return parsedMetadataJSON;
     } catch (e) {
     } catch (e) {
-        logError(e, "parseMetadataJSON failed");
+        log.error("parseMetadataJSON failed", e);
         // ignore
         // ignore
     }
     }
 }
 }
@@ -237,7 +237,7 @@ export function extractDateFromFileName(filename: string): number {
         }
         }
         return validateAndGetCreationUnixTimeInMicroSeconds(parsedDate);
         return validateAndGetCreationUnixTimeInMicroSeconds(parsedDate);
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to extract date From FileName ");
+        log.error("failed to extract date From FileName ", e);
         return null;
         return null;
     }
     }
 }
 }
@@ -250,7 +250,7 @@ function convertSignalNameToFusedDateString(filename: string) {
 const EDITED_FILE_SUFFIX = "-edited";
 const EDITED_FILE_SUFFIX = "-edited";
 
 
 /*
 /*
-    Get the original file name for edited file to associate it to original file's metadataJSON file 
+    Get the original file name for edited file to associate it to original file's metadataJSON file
     as edited file doesn't have their own metadata file
     as edited file doesn't have their own metadata file
 */
 */
 function getFileOriginalName(fileName: string) {
 function getFileOriginalName(fileName: string) {

+ 4 - 4
web/apps/photos/src/services/upload/publicUploadHttpClient.ts

@@ -1,7 +1,7 @@
+import log from "@/next/log";
 import { CustomError, handleUploadError } from "@ente/shared/error";
 import { CustomError, handleUploadError } from "@ente/shared/error";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint } from "@ente/shared/network/api";
 import { getEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import { EnteFile } from "types/file";
 import { EnteFile } from "types/file";
 import { MultipartUploadURLs, UploadFile, UploadURL } from "types/upload";
 import { MultipartUploadURLs, UploadFile, UploadURL } from "types/upload";
 import { retryHTTPCall } from "utils/upload/uploadRetrier";
 import { retryHTTPCall } from "utils/upload/uploadRetrier";
@@ -39,7 +39,7 @@ class PublicUploadHttpClient {
             );
             );
             return response.data;
             return response.data;
         } catch (e) {
         } catch (e) {
-            logError(e, "upload public File Failed");
+            log.error("upload public File Failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -78,7 +78,7 @@ class PublicUploadHttpClient {
             }
             }
             return this.uploadURLFetchInProgress;
             return this.uploadURLFetchInProgress;
         } catch (e) {
         } catch (e) {
-            logError(e, "fetch public upload-url failed ");
+            log.error("fetch public upload-url failed ", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -107,7 +107,7 @@ class PublicUploadHttpClient {
 
 
             return response.data["urls"];
             return response.data["urls"];
         } catch (e) {
         } catch (e) {
-            logError(e, "fetch public multipart-upload-url failed");
+            log.error("fetch public multipart-upload-url failed", e);
             throw e;
             throw e;
         }
         }
     }
     }

+ 24 - 30
web/apps/photos/src/services/upload/thumbnailService.ts

@@ -1,8 +1,7 @@
-import ElectronAPIs from "@/next/electron";
+import { ensureElectron } from "@/next/electron";
 import { convertBytesToHumanReadable, getFileNameSize } from "@/next/file";
 import { convertBytesToHumanReadable, getFileNameSize } from "@/next/file";
+import log from "@/next/log";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import { BLACK_THUMBNAIL_BASE64 } from "constants/upload";
 import { BLACK_THUMBNAIL_BASE64 } from "constants/upload";
 import isElectron from "is-electron";
 import isElectron from "is-electron";
@@ -30,7 +29,7 @@ export async function generateThumbnail(
     fileTypeInfo: FileTypeInfo,
     fileTypeInfo: FileTypeInfo,
 ): Promise<{ thumbnail: Uint8Array; hasStaticThumbnail: boolean }> {
 ): Promise<{ thumbnail: Uint8Array; hasStaticThumbnail: boolean }> {
     try {
     try {
-        addLogLine(`generating thumbnail for ${getFileNameSize(file)}`);
+        log.info(`generating thumbnail for ${getFileNameSize(file)}`);
         let hasStaticThumbnail = false;
         let hasStaticThumbnail = false;
         let thumbnail: Uint8Array;
         let thumbnail: Uint8Array;
         try {
         try {
@@ -40,32 +39,26 @@ export async function generateThumbnail(
                 thumbnail = await generateVideoThumbnail(file, fileTypeInfo);
                 thumbnail = await generateVideoThumbnail(file, fileTypeInfo);
             }
             }
             if (thumbnail.length > 1.5 * MAX_THUMBNAIL_SIZE) {
             if (thumbnail.length > 1.5 * MAX_THUMBNAIL_SIZE) {
-                logError(
-                    Error("thumbnail_too_large"),
-                    "thumbnail greater than max limit",
-                    {
+                log.error(
+                    `thumbnail greater than max limit - ${JSON.stringify({
                         thumbnailSize: convertBytesToHumanReadable(
                         thumbnailSize: convertBytesToHumanReadable(
                             thumbnail.length,
                             thumbnail.length,
                         ),
                         ),
                         fileSize: convertBytesToHumanReadable(file.size),
                         fileSize: convertBytesToHumanReadable(file.size),
                         fileType: fileTypeInfo.exactType,
                         fileType: fileTypeInfo.exactType,
-                    },
+                    })}`,
                 );
                 );
             }
             }
             if (thumbnail.length === 0) {
             if (thumbnail.length === 0) {
                 throw Error("EMPTY THUMBNAIL");
                 throw Error("EMPTY THUMBNAIL");
             }
             }
-            addLogLine(
+            log.info(
                 `thumbnail successfully generated ${getFileNameSize(file)}`,
                 `thumbnail successfully generated ${getFileNameSize(file)}`,
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "uploading static thumbnail", {
-                fileFormat: fileTypeInfo.exactType,
-            });
-            addLogLine(
-                `thumbnail generation failed ${getFileNameSize(file)} error: ${
-                    e.message
-                }`,
+            log.error(
+                `thumbnail generation failed ${getFileNameSize(file)} with format ${fileTypeInfo.exactType}`,
+                e,
             );
             );
             thumbnail = Uint8Array.from(atob(BLACK_THUMBNAIL_BASE64), (c) =>
             thumbnail = Uint8Array.from(atob(BLACK_THUMBNAIL_BASE64), (c) =>
                 c.charCodeAt(0),
                 c.charCodeAt(0),
@@ -74,7 +67,7 @@ export async function generateThumbnail(
         }
         }
         return { thumbnail, hasStaticThumbnail };
         return { thumbnail, hasStaticThumbnail };
     } catch (e) {
     } catch (e) {
-        logError(e, "Error generating static thumbnail");
+        log.error("Error generating static thumbnail", e);
         throw e;
         throw e;
     }
     }
 }
 }
@@ -105,12 +98,12 @@ const generateImageThumbnailInElectron = async (
 ): Promise<Uint8Array> => {
 ): Promise<Uint8Array> => {
     try {
     try {
         const startTime = Date.now();
         const startTime = Date.now();
-        const thumb = await ElectronAPIs.generateImageThumbnail(
+        const thumb = await ensureElectron().generateImageThumbnail(
             inputFile,
             inputFile,
             maxDimension,
             maxDimension,
             maxSize,
             maxSize,
         );
         );
-        addLogLine(
+        log.info(
             `originalFileSize:${convertBytesToHumanReadable(
             `originalFileSize:${convertBytesToHumanReadable(
                 inputFile?.size,
                 inputFile?.size,
             )},thumbFileSize:${convertBytesToHumanReadable(
             )},thumbFileSize:${convertBytesToHumanReadable(
@@ -125,7 +118,7 @@ const generateImageThumbnailInElectron = async (
             e.message !==
             e.message !==
             CustomError.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED
             CustomError.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED
         ) {
         ) {
-            logError(e, "failed to generate image thumbnail natively");
+            log.error("failed to generate image thumbnail natively", e);
         }
         }
         throw e;
         throw e;
     }
     }
@@ -142,12 +135,12 @@ export async function generateImageThumbnailUsingCanvas(
     let timeout = null;
     let timeout = null;
     const isHEIC = isFileHEIC(fileTypeInfo.exactType);
     const isHEIC = isFileHEIC(fileTypeInfo.exactType);
     if (isHEIC) {
     if (isHEIC) {
-        addLogLine(`HEICConverter called for ${getFileNameSize(file)}`);
+        log.info(`HEICConverter called for ${getFileNameSize(file)}`);
         const convertedBlob = await HeicConversionService.convert(
         const convertedBlob = await HeicConversionService.convert(
             new Blob([await file.arrayBuffer()]),
             new Blob([await file.arrayBuffer()]),
         );
         );
         file = new File([convertedBlob], file.name);
         file = new File([convertedBlob], file.name);
-        addLogLine(`${getFileNameSize(file)} successfully converted`);
+        log.info(`${getFileNameSize(file)} successfully converted`);
     }
     }
     let image = new Image();
     let image = new Image();
     imageURL = URL.createObjectURL(new Blob([await file.arrayBuffer()]));
     imageURL = URL.createObjectURL(new Blob([await file.arrayBuffer()]));
@@ -198,24 +191,25 @@ async function generateVideoThumbnail(
 ) {
 ) {
     let thumbnail: Uint8Array;
     let thumbnail: Uint8Array;
     try {
     try {
-        addLogLine(
+        log.info(
             `ffmpeg generateThumbnail called for ${getFileNameSize(file)}`,
             `ffmpeg generateThumbnail called for ${getFileNameSize(file)}`,
         );
         );
 
 
         const thumbnail = await FFmpegService.generateVideoThumbnail(file);
         const thumbnail = await FFmpegService.generateVideoThumbnail(file);
-        addLogLine(
+        log.info(
             `ffmpeg thumbnail successfully generated ${getFileNameSize(file)}`,
             `ffmpeg thumbnail successfully generated ${getFileNameSize(file)}`,
         );
         );
         return await getUint8ArrayView(thumbnail);
         return await getUint8ArrayView(thumbnail);
     } catch (e) {
     } catch (e) {
-        addLogLine(
+        log.info(
             `ffmpeg thumbnail generated failed  ${getFileNameSize(
             `ffmpeg thumbnail generated failed  ${getFileNameSize(
                 file,
                 file,
             )} error: ${e.message}`,
             )} error: ${e.message}`,
         );
         );
-        logError(e, "failed to generate thumbnail using ffmpeg", {
-            fileFormat: fileTypeInfo.exactType,
-        });
+        log.error(
+            `failed to generate thumbnail using ffmpeg for format ${fileTypeInfo.exactType}`,
+            e,
+        );
         thumbnail = await generateVideoThumbnailUsingCanvas(file);
         thumbnail = await generateVideoThumbnailUsingCanvas(file);
     }
     }
     return thumbnail;
     return thumbnail;
@@ -265,7 +259,7 @@ export async function generateVideoThumbnailUsingCanvas(
                 const err = Error(
                 const err = Error(
                     `${CustomError.THUMBNAIL_GENERATION_FAILED} err: ${e}`,
                     `${CustomError.THUMBNAIL_GENERATION_FAILED} err: ${e}`,
                 );
                 );
-                logError(e, CustomError.THUMBNAIL_GENERATION_FAILED);
+                log.error(CustomError.THUMBNAIL_GENERATION_FAILED, e);
                 reject(err);
                 reject(err);
             }
             }
         });
         });

+ 12 - 12
web/apps/photos/src/services/upload/uploadHttpClient.ts

@@ -1,7 +1,7 @@
+import log from "@/next/log";
 import { CustomError, handleUploadError } from "@ente/shared/error";
 import { CustomError, handleUploadError } from "@ente/shared/error";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint, getUploadEndpoint } from "@ente/shared/network/api";
 import { getEndpoint, getUploadEndpoint } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { getToken } from "@ente/shared/storage/localStorage/helpers";
 import { EnteFile } from "types/file";
 import { EnteFile } from "types/file";
 import { MultipartUploadURLs, UploadFile, UploadURL } from "types/upload";
 import { MultipartUploadURLs, UploadFile, UploadURL } from "types/upload";
@@ -30,7 +30,7 @@ class UploadHttpClient {
             );
             );
             return response.data;
             return response.data;
         } catch (e) {
         } catch (e) {
-            logError(e, "upload Files Failed");
+            log.error("upload Files Failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -60,7 +60,7 @@ class UploadHttpClient {
             }
             }
             return this.uploadURLFetchInProgress;
             return this.uploadURLFetchInProgress;
         } catch (e) {
         } catch (e) {
-            logError(e, "fetch upload-url failed ");
+            log.error("fetch upload-url failed ", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -83,7 +83,7 @@ class UploadHttpClient {
 
 
             return response.data["urls"];
             return response.data["urls"];
         } catch (e) {
         } catch (e) {
-            logError(e, "fetch multipart-upload-url failed");
+            log.error("fetch multipart-upload-url failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -108,7 +108,7 @@ class UploadHttpClient {
             return fileUploadURL.objectKey;
             return fileUploadURL.objectKey;
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
-                logError(e, "putFile to dataStore failed ");
+                log.error("putFile to dataStore failed ", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -134,7 +134,7 @@ class UploadHttpClient {
             return fileUploadURL.objectKey;
             return fileUploadURL.objectKey;
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
-                logError(e, "putFile to dataStore failed ");
+                log.error("putFile to dataStore failed ", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -156,7 +156,7 @@ class UploadHttpClient {
                 );
                 );
                 if (!resp?.headers?.etag) {
                 if (!resp?.headers?.etag) {
                     const err = Error(CustomError.ETAG_MISSING);
                     const err = Error(CustomError.ETAG_MISSING);
-                    logError(err, "putFile in parts failed");
+                    log.error("putFile in parts failed", err);
                     throw err;
                     throw err;
                 }
                 }
                 return resp;
                 return resp;
@@ -164,7 +164,7 @@ class UploadHttpClient {
             return response.headers.etag as string;
             return response.headers.etag as string;
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
-                logError(e, "put filePart failed");
+                log.error("put filePart failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -188,7 +188,7 @@ class UploadHttpClient {
                 );
                 );
                 if (!resp?.data?.etag) {
                 if (!resp?.data?.etag) {
                     const err = Error(CustomError.ETAG_MISSING);
                     const err = Error(CustomError.ETAG_MISSING);
-                    logError(err, "putFile in parts failed");
+                    log.error("putFile in parts failed", err);
                     throw err;
                     throw err;
                 }
                 }
                 return resp;
                 return resp;
@@ -196,7 +196,7 @@ class UploadHttpClient {
             return response.data.etag as string;
             return response.data.etag as string;
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
-                logError(e, "put filePart failed");
+                log.error("put filePart failed", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -210,7 +210,7 @@ class UploadHttpClient {
                 }),
                 }),
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "put file in parts failed");
+            log.error("put file in parts failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -229,7 +229,7 @@ class UploadHttpClient {
                 ),
                 ),
             );
             );
         } catch (e) {
         } catch (e) {
-            logError(e, "put file in parts failed");
+            log.error("put file in parts failed", e);
             throw e;
             throw e;
         }
         }
     }
     }

+ 37 - 40
web/apps/photos/src/services/upload/uploadManager.ts

@@ -1,6 +1,20 @@
+import { getFileNameSize } from "@/next/file";
+import log from "@/next/log";
+import { ComlinkWorker } from "@/next/worker/comlink-worker";
+import { getDedicatedCryptoWorker } from "@ente/shared/crypto";
+import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
 import { Events, eventBus } from "@ente/shared/events";
 import { Events, eventBus } from "@ente/shared/events";
-import { logError } from "@ente/shared/sentry";
+import { Remote } from "comlink";
+import { UPLOAD_RESULT, UPLOAD_STAGES } from "constants/upload";
+import isElectron from "is-electron";
+import ImportService from "services/importService";
+import {
+    getLocalPublicFiles,
+    getPublicCollectionUID,
+} from "services/publicCollectionService";
+import { getDisableCFUploadProxyFlag } from "services/userService";
+import watchFolderService from "services/watchFolder/watchFolderService";
 import { Collection } from "types/collection";
 import { Collection } from "types/collection";
 import { EncryptedEnteFile, EnteFile } from "types/file";
 import { EncryptedEnteFile, EnteFile } from "types/file";
 import { SetFiles } from "types/gallery";
 import { SetFiles } from "types/gallery";
@@ -10,6 +24,7 @@ import {
     ParsedMetadataJSONMap,
     ParsedMetadataJSONMap,
     PublicUploadProps,
     PublicUploadProps,
 } from "types/upload";
 } from "types/upload";
+import { ProgressUpdater } from "types/upload/ui";
 import { decryptFile, getUserOwnedFiles, sortFiles } from "utils/file";
 import { decryptFile, getUserOwnedFiles, sortFiles } from "utils/file";
 import {
 import {
     areFileWithCollectionsSame,
     areFileWithCollectionsSame,
@@ -20,29 +35,11 @@ import {
     getMetadataJSONMapKeyForJSON,
     getMetadataJSONMapKeyForJSON,
     parseMetadataJSON,
     parseMetadataJSON,
 } from "./metadataService";
 } from "./metadataService";
-import UIService from "./uiService";
+import { default as UIService, default as uiService } from "./uiService";
+import uploadCancelService from "./uploadCancelService";
 import UploadService from "./uploadService";
 import UploadService from "./uploadService";
 import uploader from "./uploader";
 import uploader from "./uploader";
 
 
-import { getFileNameSize } from "@/next/file";
-import { ComlinkWorker } from "@/next/worker/comlink-worker";
-import { getDedicatedCryptoWorker } from "@ente/shared/crypto";
-import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
-import { addLogLine } from "@ente/shared/logging";
-import { Remote } from "comlink";
-import { UPLOAD_RESULT, UPLOAD_STAGES } from "constants/upload";
-import isElectron from "is-electron";
-import ImportService from "services/importService";
-import {
-    getLocalPublicFiles,
-    getPublicCollectionUID,
-} from "services/publicCollectionService";
-import { getDisableCFUploadProxyFlag } from "services/userService";
-import watchFolderService from "services/watchFolder/watchFolderService";
-import { ProgressUpdater } from "types/upload/ui";
-import uiService from "./uiService";
-import uploadCancelService from "./uploadCancelService";
-
 const MAX_CONCURRENT_UPLOADS = 4;
 const MAX_CONCURRENT_UPLOADS = 4;
 
 
 class UploadManager {
 class UploadManager {
@@ -126,7 +123,7 @@ class UploadManager {
             this.uploadInProgress = true;
             this.uploadInProgress = true;
             await this.updateExistingFilesAndCollections(collections);
             await this.updateExistingFilesAndCollections(collections);
             this.uploaderName = uploaderName;
             this.uploaderName = uploaderName;
-            addLogLine(
+            log.info(
                 `received ${filesWithCollectionToUploadIn.length} files to upload`,
                 `received ${filesWithCollectionToUploadIn.length} files to upload`,
             );
             );
             uiService.setFilenames(
             uiService.setFilenames(
@@ -139,8 +136,8 @@ class UploadManager {
             );
             );
             const { metadataJSONFiles, mediaFiles } =
             const { metadataJSONFiles, mediaFiles } =
                 segregateMetadataAndMediaFiles(filesWithCollectionToUploadIn);
                 segregateMetadataAndMediaFiles(filesWithCollectionToUploadIn);
-            addLogLine(`has ${metadataJSONFiles.length} metadata json files`);
-            addLogLine(`has ${mediaFiles.length} media files`);
+            log.info(`has ${metadataJSONFiles.length} metadata json files`);
+            log.info(`has ${mediaFiles.length} media files`);
             if (metadataJSONFiles.length) {
             if (metadataJSONFiles.length) {
                 UIService.setUploadStage(
                 UIService.setUploadStage(
                     UPLOAD_STAGES.READING_GOOGLE_METADATA_FILES,
                     UPLOAD_STAGES.READING_GOOGLE_METADATA_FILES,
@@ -152,11 +149,11 @@ class UploadManager {
                 );
                 );
             }
             }
             if (mediaFiles.length) {
             if (mediaFiles.length) {
-                addLogLine(`clusterLivePhotoFiles started`);
+                log.info(`clusterLivePhotoFiles started`);
                 const analysedMediaFiles =
                 const analysedMediaFiles =
                     await UploadService.clusterLivePhotoFiles(mediaFiles);
                     await UploadService.clusterLivePhotoFiles(mediaFiles);
-                addLogLine(`clusterLivePhotoFiles ended`);
-                addLogLine(
+                log.info(`clusterLivePhotoFiles ended`);
+                log.info(
                     `got live photos: ${
                     `got live photos: ${
                         mediaFiles.length !== analysedMediaFiles.length
                         mediaFiles.length !== analysedMediaFiles.length
                     }`,
                     }`,
@@ -183,7 +180,7 @@ class UploadManager {
                     await ImportService.cancelRemainingUploads();
                     await ImportService.cancelRemainingUploads();
                 }
                 }
             } else {
             } else {
-                logError(e, "uploading failed with error");
+                log.error("uploading failed with error", e);
                 throw e;
                 throw e;
             }
             }
         } finally {
         } finally {
@@ -200,14 +197,14 @@ class UploadManager {
                 return false;
                 return false;
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, " failed to return shouldCloseProgressBar");
+            log.error(" failed to return shouldCloseProgressBar", e);
             return false;
             return false;
         }
         }
     }
     }
 
 
     private async parseMetadataJSONFiles(metadataFiles: FileWithCollection[]) {
     private async parseMetadataJSONFiles(metadataFiles: FileWithCollection[]) {
         try {
         try {
-            addLogLine(`parseMetadataJSONFiles function executed `);
+            log.info(`parseMetadataJSONFiles function executed `);
 
 
             UIService.reset(metadataFiles.length);
             UIService.reset(metadataFiles.length);
 
 
@@ -216,7 +213,7 @@ class UploadManager {
                     if (uploadCancelService.isUploadCancelationRequested()) {
                     if (uploadCancelService.isUploadCancelationRequested()) {
                         throw Error(CustomError.UPLOAD_CANCELLED);
                         throw Error(CustomError.UPLOAD_CANCELLED);
                     }
                     }
-                    addLogLine(
+                    log.info(
                         `parsing metadata json file ${getFileNameSize(file)}`,
                         `parsing metadata json file ${getFileNameSize(file)}`,
                     );
                     );
 
 
@@ -231,7 +228,7 @@ class UploadManager {
                         );
                         );
                         UIService.increaseFileUploaded();
                         UIService.increaseFileUploaded();
                     }
                     }
-                    addLogLine(
+                    log.info(
                         `successfully parsed metadata json file ${getFileNameSize(
                         `successfully parsed metadata json file ${getFileNameSize(
                             file,
                             file,
                         )}`,
                         )}`,
@@ -241,8 +238,8 @@ class UploadManager {
                         throw e;
                         throw e;
                     } else {
                     } else {
                         // and don't break for subsequent files just log and move on
                         // and don't break for subsequent files just log and move on
-                        logError(e, "parsing failed for a file");
-                        addLogLine(
+                        log.error("parsing failed for a file", e);
+                        log.info(
                             `failed to parse metadata json file ${getFileNameSize(
                             `failed to parse metadata json file ${getFileNameSize(
                                 file,
                                 file,
                             )} error: ${e.message}`,
                             )} error: ${e.message}`,
@@ -252,14 +249,14 @@ class UploadManager {
             }
             }
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
-                logError(e, "error seeding MetadataMap");
+                log.error("error seeding MetadataMap", e);
             }
             }
             throw e;
             throw e;
         }
         }
     }
     }
 
 
     private async uploadMediaFiles(mediaFiles: FileWithCollection[]) {
     private async uploadMediaFiles(mediaFiles: FileWithCollection[]) {
-        addLogLine(`uploadMediaFiles called`);
+        log.info(`uploadMediaFiles called`);
         this.filesToBeUploaded = [...this.filesToBeUploaded, ...mediaFiles];
         this.filesToBeUploaded = [...this.filesToBeUploaded, ...mediaFiles];
 
 
         if (isElectron()) {
         if (isElectron()) {
@@ -323,7 +320,7 @@ class UploadManager {
     ) {
     ) {
         try {
         try {
             let decryptedFile: EnteFile;
             let decryptedFile: EnteFile;
-            addLogLine(
+            log.info(
                 `post upload action -> fileUploadResult: ${fileUploadResult} uploadedFile present ${!!uploadedFile}`,
                 `post upload action -> fileUploadResult: ${fileUploadResult} uploadedFile present ${!!uploadedFile}`,
             );
             );
             await this.updateElectronRemainingFiles(fileWithCollection);
             await this.updateElectronRemainingFiles(fileWithCollection);
@@ -368,7 +365,7 @@ class UploadManager {
                             fileWithCollection.livePhotoAssets.image,
                             fileWithCollection.livePhotoAssets.image,
                     });
                     });
                 } catch (e) {
                 } catch (e) {
-                    logError(e, "Error in fileUploaded handlers");
+                    log.error("Error in fileUploaded handlers", e);
                 }
                 }
                 this.updateExistingFiles(decryptedFile);
                 this.updateExistingFiles(decryptedFile);
             }
             }
@@ -379,7 +376,7 @@ class UploadManager {
             );
             );
             return fileUploadResult;
             return fileUploadResult;
         } catch (e) {
         } catch (e) {
-            logError(e, "failed to do post file upload action");
+            log.error("failed to do post file upload action", e);
             return UPLOAD_RESULT.FAILED;
             return UPLOAD_RESULT.FAILED;
         }
         }
     }
     }
@@ -399,7 +396,7 @@ class UploadManager {
     }
     }
 
 
     public cancelRunningUpload() {
     public cancelRunningUpload() {
-        addLogLine("user cancelled running upload");
+        log.info("user cancelled running upload");
         UIService.setUploadStage(UPLOAD_STAGES.CANCELLING);
         UIService.setUploadStage(UPLOAD_STAGES.CANCELLING);
         uploadCancelService.requestUploadCancelation();
         uploadCancelService.requestUploadCancelation();
     }
     }

+ 3 - 3
web/apps/photos/src/services/upload/uploadService.ts

@@ -1,7 +1,7 @@
+import log from "@/next/log";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
 import { B64EncryptionResult } from "@ente/shared/crypto/types";
 import { B64EncryptionResult } from "@ente/shared/crypto/types";
 import { CustomError, handleUploadError } from "@ente/shared/error";
 import { CustomError, handleUploadError } from "@ente/shared/error";
-import { logError } from "@ente/shared/sentry";
 import { Remote } from "comlink";
 import { Remote } from "comlink";
 import { Collection } from "types/collection";
 import { Collection } from "types/collection";
 import { FilePublicMagicMetadataProps } from "types/file";
 import { FilePublicMagicMetadataProps } from "types/file";
@@ -231,7 +231,7 @@ class UploadService {
             return backupedFile;
             return backupedFile;
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
             if (e.message !== CustomError.UPLOAD_CANCELLED) {
-                logError(e, "error uploading to bucket");
+                log.error("error uploading to bucket", e);
             }
             }
             throw e;
             throw e;
         }
         }
@@ -264,7 +264,7 @@ class UploadService {
             await this.fetchUploadURLs();
             await this.fetchUploadURLs();
             // checking for any subscription related errors
             // checking for any subscription related errors
         } catch (e) {
         } catch (e) {
-            logError(e, "prefetch uploadURL failed");
+            log.error("prefetch uploadURL failed", e);
             handleUploadError(e);
             handleUploadError(e);
         }
         }
     }
     }

+ 5 - 6
web/apps/photos/src/services/upload/videoMetadataService.ts

@@ -1,6 +1,5 @@
 import { getFileNameSize } from "@/next/file";
 import { getFileNameSize } from "@/next/file";
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { NULL_EXTRACTED_METADATA } from "constants/upload";
 import { NULL_EXTRACTED_METADATA } from "constants/upload";
 import * as ffmpegService from "services/ffmpeg/ffmpegService";
 import * as ffmpegService from "services/ffmpeg/ffmpegService";
 import { ElectronFile } from "types/upload";
 import { ElectronFile } from "types/upload";
@@ -8,14 +7,14 @@ import { ElectronFile } from "types/upload";
 export async function getVideoMetadata(file: File | ElectronFile) {
 export async function getVideoMetadata(file: File | ElectronFile) {
     let videoMetadata = NULL_EXTRACTED_METADATA;
     let videoMetadata = NULL_EXTRACTED_METADATA;
     try {
     try {
-        addLogLine(`getVideoMetadata called for ${getFileNameSize(file)}`);
+        log.info(`getVideoMetadata called for ${getFileNameSize(file)}`);
         videoMetadata = await ffmpegService.extractVideoMetadata(file);
         videoMetadata = await ffmpegService.extractVideoMetadata(file);
-        addLogLine(
+        log.info(
             `videoMetadata successfully extracted ${getFileNameSize(file)}`,
             `videoMetadata successfully extracted ${getFileNameSize(file)}`,
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get video metadata");
-        addLogLine(
+        log.error("failed to get video metadata", e);
+        log.info(
             `videoMetadata extracted failed ${getFileNameSize(file)} ,${
             `videoMetadata extracted failed ${getFileNameSize(file)} ,${
                 e.message
                 e.message
             } `,
             } `,

+ 17 - 17
web/apps/photos/src/services/userService.ts

@@ -1,10 +1,10 @@
+import log from "@/next/log";
 import { putAttributes } from "@ente/accounts/api/user";
 import { putAttributes } from "@ente/accounts/api/user";
 import { logoutUser } from "@ente/accounts/services/user";
 import { logoutUser } from "@ente/accounts/services/user";
 import { getRecoveryKey } from "@ente/shared/crypto/helpers";
 import { getRecoveryKey } from "@ente/shared/crypto/helpers";
 import { ApiError } from "@ente/shared/error";
 import { ApiError } from "@ente/shared/error";
 import HTTPService from "@ente/shared/network/HTTPService";
 import HTTPService from "@ente/shared/network/HTTPService";
 import { getEndpoint, getFamilyPortalURL } from "@ente/shared/network/api";
 import { getEndpoint, getFamilyPortalURL } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import localForage from "@ente/shared/storage/localForage";
 import localForage from "@ente/shared/storage/localForage";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import {
 import {
@@ -63,7 +63,7 @@ export const getFamiliesToken = async () => {
         );
         );
         return resp.data["familiesToken"];
         return resp.data["familiesToken"];
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get family token");
+        log.error("failed to get family token", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -81,7 +81,7 @@ export const getAccountsToken = async () => {
         );
         );
         return resp.data["accountsToken"];
         return resp.data["accountsToken"];
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get accounts token");
+        log.error("failed to get accounts token", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -99,7 +99,7 @@ export const getRoadmapRedirectURL = async () => {
         );
         );
         return resp.data["url"];
         return resp.data["url"];
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get roadmap url");
+        log.error("failed to get roadmap url", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -128,15 +128,15 @@ export const isTokenValid = async (token: string) => {
                         getData(LS_KEYS.ORIGINAL_KEY_ATTRIBUTES),
                         getData(LS_KEYS.ORIGINAL_KEY_ATTRIBUTES),
                     );
                     );
                 } catch (e) {
                 } catch (e) {
-                    logError(e, "put attribute failed");
+                    log.error("put attribute failed", e);
                 }
                 }
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, "hasSetKeys not set in session validity response");
+            log.error("hasSetKeys not set in session validity response", e);
         }
         }
         return true;
         return true;
     } catch (e) {
     } catch (e) {
-        logError(e, "session-validity api call failed");
+        log.error("session-validity api call failed", e);
         if (
         if (
             e instanceof ApiError &&
             e instanceof ApiError &&
             e.httpStatusCode === HttpStatusCode.Unauthorized
             e.httpStatusCode === HttpStatusCode.Unauthorized
@@ -172,7 +172,7 @@ export const getUserDetailsV2 = async (): Promise<UserDetails> => {
         );
         );
         return resp.data;
         return resp.data;
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get user details v2");
+        log.error("failed to get user details v2", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -185,7 +185,7 @@ export const getFamilyPortalRedirectURL = async () => {
             window.location.origin
             window.location.origin
         }/gallery`;
         }/gallery`;
     } catch (e) {
     } catch (e) {
-        logError(e, "unable to generate to family portal URL");
+        log.error("unable to generate to family portal URL", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -203,7 +203,7 @@ export const getAccountDeleteChallenge = async () => {
         );
         );
         return resp.data as DeleteChallengeResponse;
         return resp.data as DeleteChallengeResponse;
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get account delete challenge");
+        log.error("failed to get account delete challenge", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -228,7 +228,7 @@ export const deleteAccount = async (
             },
             },
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "deleteAccount api call failed");
+        log.error("deleteAccount api call failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -262,7 +262,7 @@ export const getFaceSearchEnabledStatus = async () => {
             );
             );
         return resp.data.value === "true";
         return resp.data.value === "true";
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get face search enabled status");
+        log.error("failed to get face search enabled status", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -282,7 +282,7 @@ export const updateFaceSearchEnabledStatus = async (newStatus: boolean) => {
             },
             },
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to update face search enabled status");
+        log.error("failed to update face search enabled status", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -292,7 +292,7 @@ export const syncMapEnabled = async () => {
         const status = await getMapEnabledStatus();
         const status = await getMapEnabledStatus();
         setLocalMapEnabled(status);
         setLocalMapEnabled(status);
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to sync map enabled status");
+        log.error("failed to sync map enabled status", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -313,7 +313,7 @@ export const getMapEnabledStatus = async () => {
             );
             );
         return resp.data.value === "true";
         return resp.data.value === "true";
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get map enabled status");
+        log.error("failed to get map enabled status", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -333,7 +333,7 @@ export const updateMapEnabledStatus = async (newStatus: boolean) => {
             },
             },
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to update map enabled status");
+        log.error("failed to update map enabled status", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -363,7 +363,7 @@ export async function getDisableCFUploadProxyFlag(): Promise<boolean> {
         ).json() as GetFeatureFlagResponse;
         ).json() as GetFeatureFlagResponse;
         return featureFlags.disableCFUploadProxy;
         return featureFlags.disableCFUploadProxy;
     } catch (e) {
     } catch (e) {
-        logError(e, "failed to get feature flags");
+        log.error("failed to get feature flags", e);
         return false;
         return false;
     }
     }
 }
 }

+ 5 - 6
web/apps/photos/src/services/wasm/ffmpeg.ts

@@ -1,5 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { promiseWithTimeout } from "@ente/shared/utils";
 import { promiseWithTimeout } from "@ente/shared/utils";
 import QueueProcessor from "@ente/shared/utils/queueProcessor";
 import QueueProcessor from "@ente/shared/utils/queueProcessor";
 import { generateTempName } from "@ente/shared/utils/temp";
 import { generateTempName } from "@ente/shared/utils/temp";
@@ -51,7 +50,7 @@ export class WasmFFmpeg {
         try {
         try {
             return await response.promise;
             return await response.promise;
         } catch (e) {
         } catch (e) {
-            logError(e, "ffmpeg run failed");
+            log.error("ffmpeg run failed", e);
             throw e;
             throw e;
         }
         }
     }
     }
@@ -86,7 +85,7 @@ export class WasmFFmpeg {
                     return cmdPart;
                     return cmdPart;
                 }
                 }
             });
             });
-            addLogLine(`${cmd}`);
+            log.info(`${cmd}`);
             await this.ffmpeg.run(...cmd);
             await this.ffmpeg.run(...cmd);
             return new File(
             return new File(
                 [this.ffmpeg.FS("readFile", tempOutputFilePath)],
                 [this.ffmpeg.FS("readFile", tempOutputFilePath)],
@@ -96,12 +95,12 @@ export class WasmFFmpeg {
             try {
             try {
                 this.ffmpeg.FS("unlink", tempInputFilePath);
                 this.ffmpeg.FS("unlink", tempInputFilePath);
             } catch (e) {
             } catch (e) {
-                logError(e, "unlink input file failed");
+                log.error("unlink input file failed", e);
             }
             }
             try {
             try {
                 this.ffmpeg.FS("unlink", tempOutputFilePath);
                 this.ffmpeg.FS("unlink", tempOutputFilePath);
             } catch (e) {
             } catch (e) {
-                logError(e, "unlink output file failed");
+                log.error("unlink output file failed", e);
             }
             }
         }
         }
     }
     }

+ 8 - 9
web/apps/photos/src/services/watchFolder/watchFolderEventHandlers.ts

@@ -1,5 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { ElectronFile } from "types/upload";
 import { ElectronFile } from "types/upload";
 import { EventQueueItem } from "types/watchFolder";
 import { EventQueueItem } from "types/watchFolder";
 import watchFolderService from "./watchFolderService";
 import watchFolderService from "./watchFolderService";
@@ -22,11 +21,11 @@ export async function diskFileAddedCallback(file: ElectronFile) {
             files: [file],
             files: [file],
         };
         };
         watchFolderService.pushEvent(event);
         watchFolderService.pushEvent(event);
-        addLogLine(
+        log.info(
             `added (upload) to event queue, collectionName:${event.collectionName} folderPath:${event.folderPath}, filesCount: ${event.files.length}`,
             `added (upload) to event queue, collectionName:${event.collectionName} folderPath:${event.folderPath}, filesCount: ${event.files.length}`,
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "error while calling diskFileAddedCallback");
+        log.error("error while calling diskFileAddedCallback", e);
     }
     }
 }
 }
 
 
@@ -48,11 +47,11 @@ export async function diskFileRemovedCallback(filePath: string) {
             paths: [filePath],
             paths: [filePath],
         };
         };
         watchFolderService.pushEvent(event);
         watchFolderService.pushEvent(event);
-        addLogLine(
+        log.info(
             `added (trash) to event queue collectionName:${event.collectionName} folderPath:${event.folderPath} , pathsCount: ${event.paths.length}`,
             `added (trash) to event queue collectionName:${event.collectionName} folderPath:${event.folderPath} , pathsCount: ${event.paths.length}`,
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "error while calling diskFileRemovedCallback");
+        log.error("error while calling diskFileRemovedCallback", e);
     }
     }
 }
 }
 
 
@@ -63,12 +62,12 @@ export async function diskFolderRemovedCallback(folderPath: string) {
             (mapping) => mapping.folderPath === folderPath,
             (mapping) => mapping.folderPath === folderPath,
         );
         );
         if (!mapping) {
         if (!mapping) {
-            addLogLine(`folder not found in mappings, ${folderPath}`);
+            log.info(`folder not found in mappings, ${folderPath}`);
             throw Error(`Watch mapping not found`);
             throw Error(`Watch mapping not found`);
         }
         }
         watchFolderService.pushTrashedDir(folderPath);
         watchFolderService.pushTrashedDir(folderPath);
-        addLogLine(`added trashedDir, ${folderPath}`);
+        log.info(`added trashedDir, ${folderPath}`);
     } catch (e) {
     } catch (e) {
-        logError(e, "error while calling diskFolderRemovedCallback");
+        log.error("error while calling diskFolderRemovedCallback", e);
     }
     }
 }
 }

+ 13 - 13
web/apps/photos/src/services/watchFolder/watchFolderService.ts

@@ -1,4 +1,4 @@
-import ElectronAPIs from "@/next/electron";
+import { ensureElectron } from "@/next/electron";
 import log from "@/next/log";
 import log from "@/next/log";
 import { UPLOAD_RESULT, UPLOAD_STRATEGY } from "constants/upload";
 import { UPLOAD_RESULT, UPLOAD_STRATEGY } from "constants/upload";
 import debounce from "debounce";
 import debounce from "debounce";
@@ -83,7 +83,7 @@ class watchFolderService {
 
 
             for (const mapping of mappings) {
             for (const mapping of mappings) {
                 const filesOnDisk: ElectronFile[] =
                 const filesOnDisk: ElectronFile[] =
-                    await ElectronAPIs.getDirFiles(mapping.folderPath);
+                    await ensureElectron().getDirFiles(mapping.folderPath);
 
 
                 this.uploadDiffOfFiles(mapping, filesOnDisk);
                 this.uploadDiffOfFiles(mapping, filesOnDisk);
                 this.trashDiffOfFiles(mapping, filesOnDisk);
                 this.trashDiffOfFiles(mapping, filesOnDisk);
@@ -150,11 +150,11 @@ class watchFolderService {
     ): Promise<WatchMapping[]> {
     ): Promise<WatchMapping[]> {
         const notDeletedMappings = [];
         const notDeletedMappings = [];
         for (const mapping of mappings) {
         for (const mapping of mappings) {
-            const mappingExists = await ElectronAPIs.isFolder(
+            const mappingExists = await ensureElectron().isFolder(
                 mapping.folderPath,
                 mapping.folderPath,
             );
             );
             if (!mappingExists) {
             if (!mappingExists) {
-                ElectronAPIs.removeWatchMapping(mapping.folderPath);
+                ensureElectron().removeWatchMapping(mapping.folderPath);
             } else {
             } else {
                 notDeletedMappings.push(mapping);
                 notDeletedMappings.push(mapping);
             }
             }
@@ -172,7 +172,7 @@ class watchFolderService {
     }
     }
 
 
     private setupWatcherFunctions() {
     private setupWatcherFunctions() {
-        ElectronAPIs.registerWatcherFunctions(
+        ensureElectron().registerWatcherFunctions(
             diskFileAddedCallback,
             diskFileAddedCallback,
             diskFileRemovedCallback,
             diskFileRemovedCallback,
             diskFolderRemovedCallback,
             diskFolderRemovedCallback,
@@ -185,7 +185,7 @@ class watchFolderService {
         uploadStrategy: UPLOAD_STRATEGY,
         uploadStrategy: UPLOAD_STRATEGY,
     ) {
     ) {
         try {
         try {
-            await ElectronAPIs.addWatchMapping(
+            await ensureElectron().addWatchMapping(
                 rootFolderName,
                 rootFolderName,
                 folderPath,
                 folderPath,
                 uploadStrategy,
                 uploadStrategy,
@@ -198,7 +198,7 @@ class watchFolderService {
 
 
     async removeWatchMapping(folderPath: string) {
     async removeWatchMapping(folderPath: string) {
         try {
         try {
-            await ElectronAPIs.removeWatchMapping(folderPath);
+            await ensureElectron().removeWatchMapping(folderPath);
         } catch (e) {
         } catch (e) {
             log.error("error while removing watch mapping", e);
             log.error("error while removing watch mapping", e);
         }
         }
@@ -206,7 +206,7 @@ class watchFolderService {
 
 
     async getWatchMappings(): Promise<WatchMapping[]> {
     async getWatchMappings(): Promise<WatchMapping[]> {
         try {
         try {
-            return (await ElectronAPIs.getWatchMappings()) ?? [];
+            return (await ensureElectron().getWatchMappings()) ?? [];
         } catch (e) {
         } catch (e) {
             log.error("error while getting watch mappings", e);
             log.error("error while getting watch mappings", e);
             return [];
             return [];
@@ -378,7 +378,7 @@ class watchFolderService {
                     ...this.currentlySyncedMapping.syncedFiles,
                     ...this.currentlySyncedMapping.syncedFiles,
                     ...syncedFiles,
                     ...syncedFiles,
                 ];
                 ];
-                await ElectronAPIs.updateWatchMappingSyncedFiles(
+                await ensureElectron().updateWatchMappingSyncedFiles(
                     this.currentlySyncedMapping.folderPath,
                     this.currentlySyncedMapping.folderPath,
                     this.currentlySyncedMapping.syncedFiles,
                     this.currentlySyncedMapping.syncedFiles,
                 );
                 );
@@ -388,7 +388,7 @@ class watchFolderService {
                     ...this.currentlySyncedMapping.ignoredFiles,
                     ...this.currentlySyncedMapping.ignoredFiles,
                     ...ignoredFiles,
                     ...ignoredFiles,
                 ];
                 ];
-                await ElectronAPIs.updateWatchMappingIgnoredFiles(
+                await ensureElectron().updateWatchMappingIgnoredFiles(
                     this.currentlySyncedMapping.folderPath,
                     this.currentlySyncedMapping.folderPath,
                     this.currentlySyncedMapping.ignoredFiles,
                     this.currentlySyncedMapping.ignoredFiles,
                 );
                 );
@@ -503,7 +503,7 @@ class watchFolderService {
                 this.currentlySyncedMapping.syncedFiles.filter(
                 this.currentlySyncedMapping.syncedFiles.filter(
                     (file) => !filePathsToRemove.has(file.path),
                     (file) => !filePathsToRemove.has(file.path),
                 );
                 );
-            await ElectronAPIs.updateWatchMappingSyncedFiles(
+            await ensureElectron().updateWatchMappingSyncedFiles(
                 this.currentlySyncedMapping.folderPath,
                 this.currentlySyncedMapping.folderPath,
                 this.currentlySyncedMapping.syncedFiles,
                 this.currentlySyncedMapping.syncedFiles,
             );
             );
@@ -595,7 +595,7 @@ class watchFolderService {
 
 
     async selectFolder(): Promise<string> {
     async selectFolder(): Promise<string> {
         try {
         try {
-            const folderPath = await ElectronAPIs.selectDirectory();
+            const folderPath = await ensureElectron().selectDirectory();
             return folderPath;
             return folderPath;
         } catch (e) {
         } catch (e) {
             log.error("error while selecting folder", e);
             log.error("error while selecting folder", e);
@@ -623,7 +623,7 @@ class watchFolderService {
 
 
     async isFolder(folderPath: string) {
     async isFolder(folderPath: string) {
         try {
         try {
-            const isFolder = await ElectronAPIs.isFolder(folderPath);
+            const isFolder = await ensureElectron().isFolder(folderPath);
             return isFolder;
             return isFolder;
         } catch (e) {
         } catch (e) {
             log.error("error while checking if folder exists", e);
             log.error("error while checking if folder exists", e);

+ 5 - 6
web/apps/photos/src/utils/billing/index.ts

@@ -1,9 +1,8 @@
-import { t } from "i18next";
-
+import log from "@/next/log";
 import { SetDialogBoxAttributes } from "@ente/shared/components/DialogBox/types";
 import { SetDialogBoxAttributes } from "@ente/shared/components/DialogBox/types";
-import { logError } from "@ente/shared/sentry";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import { REDIRECTS, getRedirectURL } from "constants/redirects";
 import { REDIRECTS, getRedirectURL } from "constants/redirects";
+import { t } from "i18next";
 import { NextRouter } from "next/router";
 import { NextRouter } from "next/router";
 import billingService from "services/billingService";
 import billingService from "services/billingService";
 import { Plan, Subscription } from "types/billing";
 import { Plan, Subscription } from "types/billing";
@@ -261,8 +260,8 @@ export async function manageFamilyMethod(
         setLoading(true);
         setLoading(true);
         const familyPortalRedirectURL = getRedirectURL(REDIRECTS.FAMILIES);
         const familyPortalRedirectURL = getRedirectURL(REDIRECTS.FAMILIES);
         openLink(familyPortalRedirectURL, true);
         openLink(familyPortalRedirectURL, true);
-    } catch (error) {
-        logError(error, "failed to redirect to family portal");
+    } catch (e) {
+        log.error("failed to redirect to family portal", e);
         setDialogMessage({
         setDialogMessage({
             title: t("ERROR"),
             title: t("ERROR"),
             content: t("UNKNOWN_ERROR"),
             content: t("UNKNOWN_ERROR"),
@@ -308,7 +307,7 @@ function handleFailureReason(
     setDialogMessage: SetDialogBoxAttributes,
     setDialogMessage: SetDialogBoxAttributes,
     setLoading: SetLoading,
     setLoading: SetLoading,
 ): void {
 ): void {
-    logError(Error(reason), "subscription purchase failed");
+    log.error(`subscription purchase failed: ${reason}`);
     switch (reason) {
     switch (reason) {
         case FAILURE_REASON.CANCELED:
         case FAILURE_REASON.CANCELED:
             setDialogMessage({
             setDialogMessage({

+ 12 - 14
web/apps/photos/src/utils/collection/index.ts

@@ -1,8 +1,6 @@
-import ElectronAPIs from "@/next/electron";
+import log from "@/next/log";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
-import { addLogLine } from "@ente/shared/logging";
 import { getAlbumsURL } from "@ente/shared/network/api";
 import { getAlbumsURL } from "@ente/shared/network/api";
-import { logError } from "@ente/shared/sentry";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
 import { getUnixTimeInMicroSecondsWithDelta } from "@ente/shared/time";
 import { getUnixTimeInMicroSecondsWithDelta } from "@ente/shared/time";
 import { User } from "@ente/shared/user/types";
 import { User } from "@ente/shared/user/types";
@@ -18,7 +16,6 @@ import {
     SYSTEM_COLLECTION_TYPES,
     SYSTEM_COLLECTION_TYPES,
 } from "constants/collection";
 } from "constants/collection";
 import { t } from "i18next";
 import { t } from "i18next";
-import isElectron from "is-electron";
 import {
 import {
     addToCollection,
     addToCollection,
     createAlbum,
     createAlbum,
@@ -119,7 +116,7 @@ export async function downloadCollectionHelper(
             setFilesDownloadProgressAttributes,
             setFilesDownloadProgressAttributes,
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "download collection failed ");
+        log.error("download collection failed ", e);
     }
     }
 }
 }
 
 
@@ -140,7 +137,7 @@ export async function downloadDefaultHiddenCollectionHelper(
             setFilesDownloadProgressAttributes,
             setFilesDownloadProgressAttributes,
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "download hidden files failed ");
+        log.error("download hidden files failed ", e);
     }
     }
 }
 }
 
 
@@ -153,8 +150,9 @@ export async function downloadCollectionFiles(
         return;
         return;
     }
     }
     let downloadDirPath: string;
     let downloadDirPath: string;
-    if (isElectron()) {
-        const selectedDir = await ElectronAPIs.selectDirectory();
+    const electron = globalThis.electron;
+    if (electron) {
+        const selectedDir = await electron.selectDirectory();
         if (!selectedDir) {
         if (!selectedDir) {
             return;
             return;
         }
         }
@@ -272,7 +270,7 @@ export const changeCollectionVisibility = async (
             );
             );
         }
         }
     } catch (e) {
     } catch (e) {
-        logError(e, "change collection visibility failed");
+        log.error("change collection visibility failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -298,7 +296,7 @@ export const changeCollectionSortOrder = async (
             updatedPubMagicMetadata,
             updatedPubMagicMetadata,
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, "change collection sort order failed");
+        log.error("change collection sort order failed", e);
     }
     }
 };
 };
 
 
@@ -319,7 +317,7 @@ export const changeCollectionOrder = async (
 
 
         await updateCollectionMagicMetadata(collection, updatedMagicMetadata);
         await updateCollectionMagicMetadata(collection, updatedMagicMetadata);
     } catch (e) {
     } catch (e) {
-        logError(e, "change collection order failed");
+        log.error("change collection order failed", e);
     }
     }
 };
 };
 
 
@@ -339,7 +337,7 @@ export const changeCollectionSubType = async (
         );
         );
         await updateCollectionMagicMetadata(collection, updatedMagicMetadata);
         await updateCollectionMagicMetadata(collection, updatedMagicMetadata);
     } catch (e) {
     } catch (e) {
-        logError(e, "change collection subType failed");
+        log.error("change collection subType failed", e);
         throw e;
         throw e;
     }
     }
 };
 };
@@ -568,13 +566,13 @@ export const getOrCreateAlbum = async (
     }
     }
     for (const collection of existingCollections) {
     for (const collection of existingCollections) {
         if (isValidReplacementAlbum(collection, user, albumName)) {
         if (isValidReplacementAlbum(collection, user, albumName)) {
-            addLogLine(
+            log.info(
                 `Found existing album ${albumName} with id ${collection.id}`,
                 `Found existing album ${albumName} with id ${collection.id}`,
             );
             );
             return collection;
             return collection;
         }
         }
     }
     }
     const album = await createAlbum(albumName);
     const album = await createAlbum(albumName);
-    addLogLine(`Created new album ${albumName} with id ${album.id}`);
+    log.info(`Created new album ${albumName} with id ${album.id}`);
     return album;
     return album;
 };
 };

+ 5 - 5
web/apps/photos/src/utils/common/job.ts

@@ -1,4 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
+import log from "@/next/log";
 import { JobConfig, JobResult, JobState } from "types/common/job";
 import { JobConfig, JobResult, JobState } from "types/common/job";
 
 
 export class SimpleJob<R extends JobResult> {
 export class SimpleJob<R extends JobResult> {
@@ -27,7 +27,7 @@ export class SimpleJob<R extends JobResult> {
         if (this.state !== "Running") {
         if (this.state !== "Running") {
             this.scheduleNext();
             this.scheduleNext();
         } else {
         } else {
-            addLogLine("Job already running, not scheduling");
+            log.info("Job already running, not scheduling");
         }
         }
     }
     }
 
 
@@ -41,7 +41,7 @@ export class SimpleJob<R extends JobResult> {
             this.intervalSec * 1000,
             this.intervalSec * 1000,
         );
         );
         this.state = "Scheduled";
         this.state = "Scheduled";
-        addLogLine("Scheduled next job after: ", this.intervalSec);
+        log.info("Scheduled next job after: ", this.intervalSec);
     }
     }
 
 
     async run() {
     async run() {
@@ -58,7 +58,7 @@ export class SimpleJob<R extends JobResult> {
             } else {
             } else {
                 this.resetInterval();
                 this.resetInterval();
             }
             }
-            addLogLine("Job completed");
+            log.info("Job completed");
         } catch (e) {
         } catch (e) {
             console.error("Error while running Job: ", e);
             console.error("Error while running Job: ", e);
         } finally {
         } finally {
@@ -77,6 +77,6 @@ export class SimpleJob<R extends JobResult> {
         clearTimeout(this.nextTimeoutId);
         clearTimeout(this.nextTimeoutId);
         this.nextTimeoutId = undefined;
         this.nextTimeoutId = undefined;
         this.state = "NotScheduled";
         this.state = "NotScheduled";
-        addLogLine("Cleared next job");
+        log.info("Cleared next job");
     }
     }
 }
 }

+ 22 - 15
web/apps/photos/src/utils/file/index.ts

@@ -1,6 +1,6 @@
-import ElectronAPIs from "@/next/electron";
 import { convertBytesToHumanReadable } from "@/next/file";
 import { convertBytesToHumanReadable } from "@/next/file";
 import log from "@/next/log";
 import log from "@/next/log";
+import type { Electron } from "@/next/types/ipc";
 import { workerBridge } from "@/next/worker/worker-bridge";
 import { workerBridge } from "@/next/worker/worker-bridge";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import ComlinkCryptoWorker from "@ente/shared/crypto";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
@@ -489,8 +489,9 @@ const convertToJPEGInElectron = async (
     try {
     try {
         const startTime = Date.now();
         const startTime = Date.now();
         const inputFileData = new Uint8Array(await fileBlob.arrayBuffer());
         const inputFileData = new Uint8Array(await fileBlob.arrayBuffer());
-        const convertedFileData = isElectron()
-            ? await ElectronAPIs.convertToJPEG(inputFileData, filename)
+        const electron = globalThis.electron;
+        const convertedFileData = electron
+            ? await electron.convertToJPEG(inputFileData, filename)
             : await workerBridge.convertToJPEG(inputFileData, filename);
             : await workerBridge.convertToJPEG(inputFileData, filename);
         log.info(
         log.info(
             `originalFileSize:${convertBytesToHumanReadable(
             `originalFileSize:${convertBytesToHumanReadable(
@@ -688,8 +689,10 @@ export async function downloadFilesWithProgress(
         canceller,
         canceller,
     });
     });
 
 
-    if (isElectron()) {
+    const electron = globalThis.electron;
+    if (electron) {
         await downloadFilesDesktop(
         await downloadFilesDesktop(
+            electron,
             files,
             files,
             { increaseSuccess, increaseFailed, isCancelled },
             { increaseSuccess, increaseFailed, isCancelled },
             downloadDirPath,
             downloadDirPath,
@@ -711,8 +714,9 @@ export async function downloadSelectedFiles(
         return;
         return;
     }
     }
     let downloadDirPath: string;
     let downloadDirPath: string;
-    if (isElectron()) {
-        downloadDirPath = await ElectronAPIs.selectDirectory();
+    const electron = globalThis.electron;
+    if (electron) {
+        downloadDirPath = await electron.selectDirectory();
         if (!downloadDirPath) {
         if (!downloadDirPath) {
             return;
             return;
         }
         }
@@ -729,8 +733,9 @@ export async function downloadSingleFile(
     setFilesDownloadProgressAttributes: SetFilesDownloadProgressAttributes,
     setFilesDownloadProgressAttributes: SetFilesDownloadProgressAttributes,
 ) {
 ) {
     let downloadDirPath: string;
     let downloadDirPath: string;
-    if (isElectron()) {
-        downloadDirPath = await ElectronAPIs.selectDirectory();
+    const electron = globalThis.electron;
+    if (electron) {
+        downloadDirPath = await electron.selectDirectory();
         if (!downloadDirPath) {
         if (!downloadDirPath) {
             return;
             return;
         }
         }
@@ -764,7 +769,8 @@ export async function downloadFiles(
     }
     }
 }
 }
 
 
-export async function downloadFilesDesktop(
+async function downloadFilesDesktop(
+    electron: Electron,
     files: EnteFile[],
     files: EnteFile[],
     progressBarUpdater: {
     progressBarUpdater: {
         increaseSuccess: () => void;
         increaseSuccess: () => void;
@@ -779,7 +785,7 @@ export async function downloadFilesDesktop(
             if (progressBarUpdater?.isCancelled()) {
             if (progressBarUpdater?.isCancelled()) {
                 return;
                 return;
             }
             }
-            await downloadFileDesktop(fileReader, file, downloadPath);
+            await downloadFileDesktop(electron, fileReader, file, downloadPath);
             progressBarUpdater?.increaseSuccess();
             progressBarUpdater?.increaseSuccess();
         } catch (e) {
         } catch (e) {
             log.error("download fail for file", e);
             log.error("download fail for file", e);
@@ -788,7 +794,8 @@ export async function downloadFilesDesktop(
     }
     }
 }
 }
 
 
-export async function downloadFileDesktop(
+async function downloadFileDesktop(
+    electron: Electron,
     fileReader: FileReader,
     fileReader: FileReader,
     file: EnteFile,
     file: EnteFile,
     downloadPath: string,
     downloadPath: string,
@@ -810,7 +817,7 @@ export async function downloadFileDesktop(
             livePhoto.imageNameTitle,
             livePhoto.imageNameTitle,
         );
         );
         const imageStream = generateStreamFromArrayBuffer(livePhoto.image);
         const imageStream = generateStreamFromArrayBuffer(livePhoto.image);
-        await ElectronAPIs.saveStreamToDisk(
+        await electron.saveStreamToDisk(
             getFileExportPath(downloadPath, imageExportName),
             getFileExportPath(downloadPath, imageExportName),
             imageStream,
             imageStream,
         );
         );
@@ -820,12 +827,12 @@ export async function downloadFileDesktop(
                 livePhoto.videoNameTitle,
                 livePhoto.videoNameTitle,
             );
             );
             const videoStream = generateStreamFromArrayBuffer(livePhoto.video);
             const videoStream = generateStreamFromArrayBuffer(livePhoto.video);
-            await ElectronAPIs.saveStreamToDisk(
+            await electron.saveStreamToDisk(
                 getFileExportPath(downloadPath, videoExportName),
                 getFileExportPath(downloadPath, videoExportName),
                 videoStream,
                 videoStream,
             );
             );
         } catch (e) {
         } catch (e) {
-            await ElectronAPIs.deleteFile(
+            await electron.deleteFile(
                 getFileExportPath(downloadPath, imageExportName),
                 getFileExportPath(downloadPath, imageExportName),
             );
             );
             throw e;
             throw e;
@@ -835,7 +842,7 @@ export async function downloadFileDesktop(
             downloadPath,
             downloadPath,
             file.metadata.title,
             file.metadata.title,
         );
         );
-        await ElectronAPIs.saveStreamToDisk(
+        await electron.saveStreamToDisk(
             getFileExportPath(downloadPath, fileExportName),
             getFileExportPath(downloadPath, fileExportName),
             updatedFileStream,
             updatedFileStream,
         );
         );

+ 1 - 1
web/apps/photos/src/utils/image/index.ts

@@ -80,7 +80,7 @@ export function cropWithRotation(
         }
         }
     }
     }
 
 
-    // addLogLine({ imageBitmap, box, outputSize });
+    // log.info({ imageBitmap, box, outputSize });
 
 
     const offscreen = new OffscreenCanvas(outputSize.width, outputSize.height);
     const offscreen = new OffscreenCanvas(outputSize.width, outputSize.height);
     const offscreenCtx = offscreen.getContext("2d");
     const offscreenCtx = offscreen.getContext("2d");

+ 6 - 6
web/apps/photos/src/utils/machineLearning/faceAlign.ts

@@ -61,7 +61,7 @@ export function getFaceAlignmentUsingSimilarityTransform(
         simTransform.rotation.get(0, 1),
         simTransform.rotation.get(0, 1),
         simTransform.rotation.get(0, 0),
         simTransform.rotation.get(0, 0),
     );
     );
-    // addLogLine({ affineMatrix, meanTranslation, centerMat, center, toMean: simTransform.toMean, fromMean: simTransform.fromMean, size });
+    // log.info({ affineMatrix, meanTranslation, centerMat, center, toMean: simTransform.toMean, fromMean: simTransform.fromMean, size });
 
 
     return {
     return {
         affineMatrix,
         affineMatrix,
@@ -169,7 +169,7 @@ export function ibExtractFaceImageUsingTransform(
     const scaledMatrix = new Matrix(alignment.affineMatrix)
     const scaledMatrix = new Matrix(alignment.affineMatrix)
         .mul(faceSize)
         .mul(faceSize)
         .to2DArray();
         .to2DArray();
-    // addLogLine("scaledMatrix: ", scaledMatrix);
+    // log.info("scaledMatrix: ", scaledMatrix);
     return transform(image, scaledMatrix, faceSize, faceSize);
     return transform(image, scaledMatrix, faceSize, faceSize);
 }
 }
 
 
@@ -230,7 +230,7 @@ export function getRotatedFaceImage(
     padding: number = 1.5,
     padding: number = 1.5,
 ): tf.Tensor4D {
 ): tf.Tensor4D {
     const paddedBox = enlargeBox(faceDetection.box, padding);
     const paddedBox = enlargeBox(faceDetection.box, padding);
-    // addLogLine("paddedBox", paddedBox);
+    // log.info("paddedBox", paddedBox);
     const landmarkPoints = faceDetection.landmarks;
     const landmarkPoints = faceDetection.landmarks;
 
 
     return tf.tidy(() => {
     return tf.tidy(() => {
@@ -245,15 +245,15 @@ export function getRotatedFaceImage(
             foreheadCenter,
             foreheadCenter,
         ); // landmarkPoints[BLAZEFACE_NOSE_INDEX]
         ); // landmarkPoints[BLAZEFACE_NOSE_INDEX]
         // angle = computeRotation(leftEye, rightEye);
         // angle = computeRotation(leftEye, rightEye);
-        // addLogLine('angle: ', angle);
+        // log.info('angle: ', angle);
 
 
         const faceCenter = getBoxCenter(faceDetection.box);
         const faceCenter = getBoxCenter(faceDetection.box);
-        // addLogLine('faceCenter: ', faceCenter);
+        // log.info('faceCenter: ', faceCenter);
         const faceCenterNormalized: [number, number] = [
         const faceCenterNormalized: [number, number] = [
             faceCenter.x / tf4dFloat32Image.shape[2],
             faceCenter.x / tf4dFloat32Image.shape[2],
             faceCenter.y / tf4dFloat32Image.shape[1],
             faceCenter.y / tf4dFloat32Image.shape[1],
         ];
         ];
-        // addLogLine('faceCenterNormalized: ', faceCenterNormalized);
+        // log.info('faceCenterNormalized: ', faceCenterNormalized);
 
 
         let rotatedImage = tf4dFloat32Image;
         let rotatedImage = tf4dFloat32Image;
         if (angle !== 0) {
         if (angle !== 0) {

+ 3 - 3
web/apps/photos/src/utils/machineLearning/faceCrop.ts

@@ -1,4 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
+import log from "@/next/log";
 import { CacheStorageService } from "@ente/shared/storage/cacheStorage";
 import { CacheStorageService } from "@ente/shared/storage/cacheStorage";
 import { CACHES } from "@ente/shared/storage/cacheStorage/constants";
 import { CACHES } from "@ente/shared/storage/cacheStorage/constants";
 import { getBlobFromCache } from "@ente/shared/storage/cacheStorage/helpers";
 import { getBlobFromCache } from "@ente/shared/storage/cacheStorage/helpers";
@@ -105,7 +105,7 @@ export async function removeOldFaceCrops(
 }
 }
 
 
 export async function removeFaceCropUrls(faceCropUrls: Array<string>) {
 export async function removeFaceCropUrls(faceCropUrls: Array<string>) {
-    addLogLine("Removing face crop urls: ", JSON.stringify(faceCropUrls));
+    log.info("Removing face crop urls: ", JSON.stringify(faceCropUrls));
     const faceCropCache = await CacheStorageService.open(CACHES.FACE_CROPS);
     const faceCropCache = await CacheStorageService.open(CACHES.FACE_CROPS);
     const urlRemovalPromises = faceCropUrls?.map((url) =>
     const urlRemovalPromises = faceCropUrls?.map((url) =>
         faceCropCache.delete(url),
         faceCropCache.delete(url),
@@ -132,7 +132,7 @@ export function extractFaceImageFromCrop(
         .shift(-imageBox.x, -imageBox.y)
         .shift(-imageBox.x, -imageBox.y)
         .rescale(scale)
         .rescale(scale)
         .round();
         .round();
-    // addLogLine({ box, imageBox, faceCropImage, scale, scaledBox, scaledImageBox, shiftedBox });
+    // log.info({ box, imageBox, faceCropImage, scale, scaledBox, scaledImageBox, shiftedBox });
 
 
     const faceSizeDimentions: Dimensions = {
     const faceSizeDimentions: Dimensions = {
         width: faceSize,
         width: faceSize,

+ 11 - 11
web/apps/photos/src/utils/machineLearning/index.ts

@@ -1,4 +1,4 @@
-import { addLogLine } from "@ente/shared/logging";
+import log from "@/next/log";
 import { CACHES } from "@ente/shared/storage/cacheStorage/constants";
 import { CACHES } from "@ente/shared/storage/cacheStorage/constants";
 import { cached } from "@ente/shared/storage/cacheStorage/helpers";
 import { cached } from "@ente/shared/storage/cacheStorage/helpers";
 import * as tf from "@tensorflow/tfjs-core";
 import * as tf from "@tensorflow/tfjs-core";
@@ -130,7 +130,7 @@ export function extractFaces(
             ];
             ];
         });
         });
 
 
-        // addLogLine('boxes: ', boxes[0]);
+        // log.info('boxes: ', boxes[0]);
 
 
         const faceImagesTensor = tf.image.cropAndResize(
         const faceImagesTensor = tf.image.cropAndResize(
             reshapedImage,
             reshapedImage,
@@ -356,14 +356,14 @@ export async function getOriginalImageBitmap(
     } else {
     } else {
         fileBlob = await getOriginalConvertedFile(file, queue);
         fileBlob = await getOriginalConvertedFile(file, queue);
     }
     }
-    addLogLine("[MLService] Got file: ", file.id.toString());
+    log.info("[MLService] Got file: ", file.id.toString());
 
 
     return getImageBlobBitmap(fileBlob);
     return getImageBlobBitmap(fileBlob);
 }
 }
 
 
 export async function getThumbnailImageBitmap(file: EnteFile) {
 export async function getThumbnailImageBitmap(file: EnteFile) {
     const thumb = await DownloadManager.getThumbnail(file);
     const thumb = await DownloadManager.getThumbnail(file);
-    addLogLine("[MLService] Got thumbnail: ", file.id.toString());
+    log.info("[MLService] Got thumbnail: ", file.id.toString());
 
 
     return getImageBlobBitmap(new Blob([thumb]));
     return getImageBlobBitmap(new Blob([thumb]));
 }
 }
@@ -380,7 +380,7 @@ export async function getLocalFileImageBitmap(
 export async function getPeopleList(file: EnteFile): Promise<Array<Person>> {
 export async function getPeopleList(file: EnteFile): Promise<Array<Person>> {
     let startTime = Date.now();
     let startTime = Date.now();
     const mlFileData: MlFileData = await mlIDbStorage.getFile(file.id);
     const mlFileData: MlFileData = await mlIDbStorage.getFile(file.id);
-    addLogLine(
+    log.info(
         "getPeopleList:mlFilesStore:getItem",
         "getPeopleList:mlFilesStore:getItem",
         Date.now() - startTime,
         Date.now() - startTime,
         "ms",
         "ms",
@@ -395,18 +395,18 @@ export async function getPeopleList(file: EnteFile): Promise<Array<Person>> {
     if (!peopleIds || peopleIds.length < 1) {
     if (!peopleIds || peopleIds.length < 1) {
         return [];
         return [];
     }
     }
-    // addLogLine("peopleIds: ", peopleIds);
+    // log.info("peopleIds: ", peopleIds);
     startTime = Date.now();
     startTime = Date.now();
     const peoplePromises = peopleIds.map(
     const peoplePromises = peopleIds.map(
         (p) => mlIDbStorage.getPerson(p) as Promise<Person>,
         (p) => mlIDbStorage.getPerson(p) as Promise<Person>,
     );
     );
     const peopleList = await Promise.all(peoplePromises);
     const peopleList = await Promise.all(peoplePromises);
-    addLogLine(
+    log.info(
         "getPeopleList:mlPeopleStore:getItems",
         "getPeopleList:mlPeopleStore:getItems",
         Date.now() - startTime,
         Date.now() - startTime,
         "ms",
         "ms",
     );
     );
-    // addLogLine("peopleList: ", peopleList);
+    // log.info("peopleList: ", peopleList);
 
 
     return peopleList;
     return peopleList;
 }
 }
@@ -514,7 +514,7 @@ export function getNearestPointIndex(
         (a, b) => Math.abs(a.distance) - Math.abs(b.distance),
         (a, b) => Math.abs(a.distance) - Math.abs(b.distance),
     );
     );
 
 
-    // addLogLine('Nearest dist: ', nearest.distance, maxDistance);
+    // log.info('Nearest dist: ', nearest.distance, maxDistance);
     if (!maxDistance || nearest.distance <= maxDistance) {
     if (!maxDistance || nearest.distance <= maxDistance) {
         return nearest.index;
         return nearest.index;
     }
     }
@@ -522,11 +522,11 @@ export function getNearestPointIndex(
 
 
 export function logQueueStats(queue: PQueue, name: string) {
 export function logQueueStats(queue: PQueue, name: string) {
     queue.on("active", () =>
     queue.on("active", () =>
-        addLogLine(
+        log.info(
             `queuestats: ${name}: Active, Size: ${queue.size} Pending: ${queue.pending}`,
             `queuestats: ${name}: Active, Size: ${queue.size} Pending: ${queue.pending}`,
         ),
         ),
     );
     );
-    queue.on("idle", () => addLogLine(`queuestats: ${name}: Idle`));
+    queue.on("idle", () => log.info(`queuestats: ${name}: Idle`));
     queue.on("error", (error) =>
     queue.on("error", (error) =>
         console.error(`queuestats: ${name}: Error, `, error),
         console.error(`queuestats: ${name}: Error, `, error),
     );
     );

+ 2 - 5
web/apps/photos/src/utils/photoFrame/index.ts

@@ -1,4 +1,4 @@
-import { logError } from "@ente/shared/sentry";
+import log from "@/next/log";
 import { FILE_TYPE } from "constants/file";
 import { FILE_TYPE } from "constants/file";
 import { LivePhotoSourceURL, SourceURLs } from "services/download";
 import { LivePhotoSourceURL, SourceURLs } from "services/download";
 import { EnteFile } from "types/file";
 import { EnteFile } from "types/file";
@@ -94,10 +94,7 @@ export async function updateFileSrcProps(
     } else if (file.metadata.fileType === FILE_TYPE.IMAGE) {
     } else if (file.metadata.fileType === FILE_TYPE.IMAGE) {
         file.src = url as string;
         file.src = url as string;
     } else {
     } else {
-        logError(
-            Error(`unknown file type - ${file.metadata.fileType}`),
-            "Unknown file type",
-        );
+        log.error(`unknown file type - ${file.metadata.fileType}`);
         file.src = url as string;
         file.src = url as string;
     }
     }
 }
 }

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.