From 0d8c67b95cd03d492b507c2d434573037827f759 Mon Sep 17 00:00:00 2001
From: Bastien DUMONT <bdumont@grandlyon.com>
Date: Thu, 1 Dec 2022 13:05:36 +0000
Subject: [PATCH] feat: add sentry

---
 .vscode/settings.json                         |   6 +-
 app.config.environment.alpha.js               |   3 +
 app.config.environment.dev.js                 |   3 +
 app.config.environment.prod.js                |   3 +
 package.json                                  |   4 +-
 src/components/Connection/FormLogin.tsx       |   4 +-
 src/components/Hooks/useKonnectorAuth.tsx     |  23 +-
 src/components/Options/OptionsView.tsx        |   1 +
 .../ProfileType/ProfileTypeFinished.tsx       |  32 +--
 src/components/Splash/SplashRoot.tsx          | 100 +++----
 src/migrations/migration.service.ts           |  30 ++-
 src/migrations/migration.ts                   |  32 +--
 src/services/account.service.ts               |  56 ++--
 src/services/challenge.service.ts             |  94 ++++---
 src/services/connection.service.ts            |  23 +-
 src/services/customPopup.service.ts           |  23 +-
 src/services/dateChart.service.ts             |   3 +-
 src/services/duel.service.ts                  |  34 ++-
 src/services/ecogesture.service.ts            |  26 +-
 .../enedisMonthlyAnalysisData.service.ts      |  14 +-
 src/services/environement.service.spec.ts     |  50 +++-
 src/services/environment.service.ts           |  23 +-
 src/services/fluidsPrices.service.ts          |  18 +-
 src/services/initialization.service.ts        | 248 ++++++++++++------
 src/services/mail.service.ts                  |  12 +-
 src/services/partnersInfo.service.ts          |  22 +-
 src/services/profileType.service.ts           |  39 +--
 src/services/profileTypeEntity.service.ts     |  21 +-
 src/services/queryRunner.service.ts           |  21 +-
 src/services/quiz.service.ts                  |   4 +-
 src/services/terms.service.ts                 |  11 +-
 src/services/triggers.service.ts              |  16 +-
 src/services/usageEvent.service.ts            |  29 +-
 src/store/index.ts                            |  10 +-
 src/targets/browser/index.tsx                 |  48 +++-
 src/targets/services/aggregatorUsageEvents.ts |  47 ++--
 src/targets/services/consumptionAlert.ts      |  16 +-
 .../services/enedisHalfHourMonthlyAnalysis.ts |  51 ++--
 src/targets/services/fluidsPrices.ts          |  86 +++---
 .../services/monthlyReportNotification.ts     |  26 +-
 src/targets/vendor/assets/serviceWorker.js    |   6 +-
 src/utils/logger.js                           |   4 +-
 yarn.lock                                     |  53 ++++
 43 files changed, 918 insertions(+), 457 deletions(-)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index 6c8a184c1..a6d1b84a1 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -22,12 +22,14 @@
     "javascript",
     "javascriptreact",
     "typescript",
-    "typescriptreact",
+    "typescriptreact"
   ],
   "gitlab.instanceUrl": "https://forge.grandlyon.com/web-et-numerique/llle_project/ecolyo",
   "gitlab.ignoreCertificateErrors": true,
   "editor.codeActionsOnSave": {
-    "source.fixAll.eslint": true
+    "source.fixAll.eslint": true,
+    "source.fixAll": true,
+    "source.organizeImports": true
   },
   "gitlab.showPipelineUpdateNotifications": true,
   "sonarlint.connectedMode.project": {
diff --git a/app.config.environment.alpha.js b/app.config.environment.alpha.js
index e680fd5fe..346a1c982 100644
--- a/app.config.environment.alpha.js
+++ b/app.config.environment.alpha.js
@@ -19,6 +19,9 @@ module.exports = {
       __STACK_ASSETS__: target !== 'mobile',
       __PIWIK_TRACKER_URL__: JSON.stringify('https://statweb.grandlyon.com/'),
       __PIWIK_SITEID__: 117,
+      __SENTRY_DSN__: JSON.stringify(
+        'https://c868f6010f3f431d95be8f70d7f37666@grandlyon.errors.cozycloud.cc/6'
+      ),
       __SAU_LINK__: JSON.stringify(
         'https://portail-citoyen-sau.guichet-recette.grandlyon.com/ecolyo/'
       ),
diff --git a/app.config.environment.dev.js b/app.config.environment.dev.js
index 8895164f7..8cb780426 100644
--- a/app.config.environment.dev.js
+++ b/app.config.environment.dev.js
@@ -29,6 +29,9 @@ const stackProvidedLibsConfig = {
       __SAU_IDEA_DIRECT_LINK__: JSON.stringify(
         'https://demarches-sau.guichet-recette.grandlyon.com/retour-ecolyo/ecolyo-une-idee/'
       ),
+      __SENTRY_DSN__: JSON.stringify(
+        'https://c868f6010f3f431d95be8f70d7f37666@grandlyon.errors.cozycloud.cc/6'
+      ),
     }),
   ],
   module: {
diff --git a/app.config.environment.prod.js b/app.config.environment.prod.js
index b09cab9e8..6688983f2 100644
--- a/app.config.environment.prod.js
+++ b/app.config.environment.prod.js
@@ -23,6 +23,9 @@ module.exports = {
       __SAU_IDEA_DIRECT_LINK__: JSON.stringify(
         'https://demarches-support.grandlyon.com/retour-ecolyo/ecolyo-une-idee/'
       ),
+      __SENTRY_DSN__: JSON.stringify(
+        'https://c868f6010f3f431d95be8f70d7f37666@grandlyon.errors.cozycloud.cc/6'
+      ),
     }),
   ],
   optimization: {
diff --git a/package.json b/package.json
index e83952341..f9c0be248 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,8 @@
     "@cozy/minilog": "^1.0.0",
     "@material-ui/core": "~4.12.0",
     "@material-ui/styles": "^4.11.3",
+    "@sentry/react": "^7.21.1",
+    "@sentry/tracing": "^7.21.1",
     "@simbathesailor/use-what-changed": "^2.0.0",
     "axios": "^0.27.0",
     "cozy-bar": "8.9.2",
@@ -56,8 +58,8 @@
     "cozy-intent": ">=1.14.1",
     "cozy-keys-lib": ">=4.1.9",
     "cozy-logger": ">1.7.0",
-    "cozy-scripts": "6.3.10",
     "cozy-realtime": "4.2.8",
+    "cozy-scripts": "6.3.10",
     "cozy-ui": "75.4.1",
     "d3": "^6.0.0",
     "detect-browser": "^5.1.1",
diff --git a/src/components/Connection/FormLogin.tsx b/src/components/Connection/FormLogin.tsx
index e8c01d752..ba3f0171d 100644
--- a/src/components/Connection/FormLogin.tsx
+++ b/src/components/Connection/FormLogin.tsx
@@ -9,6 +9,7 @@ import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
 import { FluidType } from 'enum/fluid.enum'
 import { getPartnerPicto } from 'utils/picto'
 import useKonnectorAuth from 'components/Hooks/useKonnectorAuth'
+import * as Sentry from '@sentry/react'
 
 interface FormLoginProps {
   fluidStatus: FluidStatus
@@ -77,7 +78,8 @@ const FormLogin: React.FC<FormLoginProps> = ({
       } else {
         await update()
       }
-    } catch (err) {
+    } catch (error) {
+      Sentry.captureException(JSON.stringify({ error }))
       setLoading(false)
     }
   }
diff --git a/src/components/Hooks/useKonnectorAuth.tsx b/src/components/Hooks/useKonnectorAuth.tsx
index 96e568bf0..2feceda08 100644
--- a/src/components/Hooks/useKonnectorAuth.tsx
+++ b/src/components/Hooks/useKonnectorAuth.tsx
@@ -1,6 +1,8 @@
-import { useState, useCallback } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
+import * as Sentry from '@sentry/react'
 import { Client, useClient } from 'cozy-client'
+import { useI18n } from 'cozy-ui/transpiled/react/I18n'
+import { FluidSlugType } from 'enum/fluidSlug.enum'
+import { UsageEventType } from 'enum/usageEvent.enum'
 import {
   AccountAuthData,
   AccountSgeData,
@@ -8,15 +10,15 @@ import {
   FluidStatus,
   UsageEvent,
 } from 'models'
-import { AppStore } from 'store'
-import { UsageEventType } from 'enum/usageEvent.enum'
+import { useCallback, useState } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
 import AccountService from 'services/account.service'
-import UsageEventService from 'services/usageEvent.service'
-import { updatedFluidConnection } from 'store/global/global.actions'
 import ConnectionService from 'services/connection.service'
+import UsageEventService from 'services/usageEvent.service'
+import { AppStore } from 'store'
 import { setLoading } from 'store/chart/chart.actions'
-import { useI18n } from 'cozy-ui/transpiled/react/I18n'
-import { FluidSlugType } from 'enum/fluidSlug.enum'
+import { updatedFluidConnection } from 'store/global/global.actions'
+import logApp from 'utils/logger'
 
 const useKonnectorAuth = (
   fluidStatus: FluidStatus,
@@ -81,10 +83,11 @@ const useKonnectorAuth = (
       setLoading(false)
       dispatch(updatedFluidConnection(fluidStatus.fluidType, updatedConnection))
       onSuccess()
-    } catch (err) {
+    } catch (error) {
       setLoading(false)
       sendUsageEventError(konnectorSlug)
-      console.log(err)
+      logApp.error(error)
+      Sentry.captureException(JSON.stringify({ error }))
     }
   }
 
diff --git a/src/components/Options/OptionsView.tsx b/src/components/Options/OptionsView.tsx
index b6e54afdc..d63b05610 100644
--- a/src/components/Options/OptionsView.tsx
+++ b/src/components/Options/OptionsView.tsx
@@ -17,6 +17,7 @@ const OptionsView: React.FC = () => {
   const defineHeaderHeight = (height: number) => {
     setHeaderHeight(height)
   }
+
   return (
     <>
       <CozyBar titleKey={'common.title_options'} />
diff --git a/src/components/ProfileType/ProfileTypeFinished.tsx b/src/components/ProfileType/ProfileTypeFinished.tsx
index 24be38a59..9149ff48d 100644
--- a/src/components/ProfileType/ProfileTypeFinished.tsx
+++ b/src/components/ProfileType/ProfileTypeFinished.tsx
@@ -1,24 +1,25 @@
-import React, { useEffect, useState } from 'react'
+import Button from '@material-ui/core/Button'
+import * as Sentry from '@sentry/react'
+import finishIcon from 'assets/icons/visu/profileType/finish.svg'
+import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
+import useExploration from 'components/Hooks/useExploration'
 import 'components/ProfileType/profileTypeFinished.scss'
+import { useClient } from 'cozy-client'
 import { useI18n } from 'cozy-ui/transpiled/react/I18n'
+import { UsageEventType } from 'enum/usageEvent.enum'
+import { UserExplorationID } from 'enum/userExploration.enum'
+import { DateTime } from 'luxon'
+import { TimePeriod } from 'models'
+import { ProfileType } from 'models/profileType.model'
+import React, { useEffect, useState } from 'react'
 import { useDispatch, useSelector } from 'react-redux'
 import { useHistory, useLocation } from 'react-router-dom'
-import { updateProfile } from 'store/profile/profile.actions'
-import { newProfileTypeEntry } from 'store/profileType/profileType.actions'
-import { ProfileType } from 'models/profileType.model'
-import Button from '@material-ui/core/Button'
-import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
-import finishIcon from 'assets/icons/visu/profileType/finish.svg'
 import ProfileTypeService from 'services/profileType.service'
-import useExploration from 'components/Hooks/useExploration'
-import { AppStore } from 'store'
-import { TimePeriod } from 'models'
-import { UserExplorationID } from 'enum/userExploration.enum'
-import { UsageEventType } from 'enum/usageEvent.enum'
-import { useClient } from 'cozy-client'
-import UsageEventService from 'services/usageEvent.service'
 import ProfileTypeEntityService from 'services/profileTypeEntity.service'
-import { DateTime } from 'luxon'
+import UsageEventService from 'services/usageEvent.service'
+import { AppStore } from 'store'
+import { updateProfile } from 'store/profile/profile.actions'
+import { newProfileTypeEntry } from 'store/profileType/profileType.actions'
 
 interface ProfileTypeFinishedProps {
   profileType: ProfileType
@@ -77,6 +78,7 @@ const ProfileTypeFinished: React.FC<ProfileTypeFinishedProps> = ({
           )
         } else {
           console.log('ERROR')
+          Sentry.captureException('error in profileTypeFinished')
         }
       } else {
         dispatch(newProfileTypeEntry(consistentProfileType))
diff --git a/src/components/Splash/SplashRoot.tsx b/src/components/Splash/SplashRoot.tsx
index db60f3bac..2da350a56 100644
--- a/src/components/Splash/SplashRoot.tsx
+++ b/src/components/Splash/SplashRoot.tsx
@@ -1,68 +1,69 @@
-import React, { useState, useEffect, ReactNode, Dispatch } from 'react'
-import { useClient } from 'cozy-client'
 import classNames from 'classnames'
+import { useClient } from 'cozy-client'
+import React, { Dispatch, ReactNode, useEffect, useState } from 'react'
 import { useDispatch } from 'react-redux'
-import { FluidState } from 'enum/fluid.enum'
 
+import useExploration from 'components/Hooks/useExploration'
+import { FluidState } from 'enum/fluid.enum'
+import { UsageEventType } from 'enum/usageEvent.enum'
+import { UserActionState } from 'enum/userAction.enum'
+import { UserChallengeState } from 'enum/userChallenge.enum'
+import { UserDuelState } from 'enum/userDuel.enum'
 import {
+  UserExplorationID,
+  UserExplorationState,
+} from 'enum/userExploration.enum'
+import { DateTime } from 'luxon'
+import { migrations } from 'migrations/migration.data'
+import { MigrationService } from 'migrations/migration.service'
+import { FluidStatus, TermsStatus, UserChallenge } from 'models'
+import { InitSteps, InitStepsErrors } from 'models/initialisationSteps.model'
+import { PartnersInfo } from 'models/partnersInfo.model'
+import { ReleaseNotes } from 'models/releaseNotes.model'
+import ActionService from 'services/action.service'
+import ChallengeService from 'services/challenge.service'
+import CustomPupopService from 'services/customPopup.service'
+import FluidService from 'services/fluid.service'
+import InitializationService from 'services/initialization.service'
+import PartnersInfoService from 'services/partnersInfo.service'
+import UsageEventService from 'services/usageEvent.service'
+import {
+  ChallengeActionTypes,
+  setChallengeConsumption,
+  setUserChallengeList,
+  updateUserChallengeList,
+} from 'store/challenge/challenge.actions'
+import { ChartActionTypes, setSelectedDate } from 'store/chart/chart.actions'
+import {
+  GlobalActionTypes,
+  setCustomPopup,
+  setFluidStatus,
+  setPartnersIssue,
+  showReleaseNotes,
   toggleAnalysisNotification,
-  toggleChallengeExplorationNotification,
   toggleChallengeActionNotification,
   toggleChallengeDuelNotification,
-  setFluidStatus,
-  GlobalActionTypes,
+  toggleChallengeExplorationNotification,
   updateTermValidation,
-  showReleaseNotes,
-  setPartnersIssue,
-  setCustomPopup,
 } from 'store/global/global.actions'
 import {
   ProfileActionTypes,
   updateProfile,
 } from 'store/profile/profile.actions'
+import {
+  ProfileEcogestureActionTypes,
+  updateProfileEcogestureSuccess,
+} from 'store/profileEcogesture/profileEcogesture.actions'
 import {
   ProfileTypeActionTypes,
   updateProfileType,
 } from 'store/profileType/profileType.actions'
-import {
-  setUserChallengeList,
-  setChallengeConsumption,
-  updateUserChallengeList,
-  ChallengeActionTypes,
-} from 'store/challenge/challenge.actions'
-import { ChartActionTypes, setSelectedDate } from 'store/chart/chart.actions'
-import InitializationService from 'services/initialization.service'
+import logApp from 'utils/logger'
+import { getTodayDate } from 'utils/utils'
 import './splashRoot.scss'
-import { UserChallengeState } from 'enum/userChallenge.enum'
-import { UserDuelState } from 'enum/userDuel.enum'
-import ChallengeService from 'services/challenge.service'
-import useExploration from 'components/Hooks/useExploration'
-import {
-  UserExplorationID,
-  UserExplorationState,
-} from 'enum/userExploration.enum'
-import { DateTime } from 'luxon'
-import { UserActionState } from 'enum/userAction.enum'
-import ActionService from 'services/action.service'
-import { FluidStatus, TermsStatus, UserChallenge } from 'models'
-import UsageEventService from 'services/usageEvent.service'
-import { UsageEventType } from 'enum/usageEvent.enum'
-import { MigrationService } from 'migrations/migration.service'
-import { migrations } from 'migrations/migration.data'
-import { ReleaseNotes } from 'models/releaseNotes.model'
-import PartnersInfoService from 'services/partnersInfo.service'
-import FluidService from 'services/fluid.service'
-import { PartnersInfo } from 'models/partnersInfo.model'
-import {
-  ProfileEcogestureActionTypes,
-  updateProfileEcogestureSuccess,
-} from 'store/profileEcogesture/profileEcogesture.actions'
-import { InitSteps, InitStepsErrors } from 'models/initialisationSteps.model'
-import log from 'utils/logger'
 import SplashScreen from './SplashScreen'
 import SplashScreenError from './SplashScreenError'
-import CustomPupopService from 'services/customPopup.service'
-import { getTodayDate } from 'utils/utils'
+import * as Sentry from '@sentry/react'
 
 interface SplashRootProps {
   fadeTimer?: number
@@ -312,17 +313,18 @@ const SplashRoot = ({ fadeTimer = 1000, children }: SplashRootProps) => {
         }
 
         if (subscribed) {
-          log.info('Initialization finished successfully !')
+          logApp.info('[Initialization] Finished successfully !')
           setState(prev => ({
             ...prev,
             splashStart: true,
           }))
         }
-      } catch (err: any) {
-        if (err.message === 'Failed to fetch' && !initStepErrors) {
+      } catch (error: any) {
+        if (error.message === 'Failed to fetch' && !initStepErrors) {
           setinitStepErrors(InitStepsErrors.UNKNOWN_ERROR)
         }
-        log.error(`[Initialization] Error : ${err}`)
+        logApp.error(`[Initialization] Error : ${error}`)
+        Sentry.captureException(JSON.stringify({ error }))
       }
     }
     if (!initStepErrors) loadData()
diff --git a/src/migrations/migration.service.ts b/src/migrations/migration.service.ts
index 0ede26eff..32a7ca9ae 100644
--- a/src/migrations/migration.service.ts
+++ b/src/migrations/migration.service.ts
@@ -1,15 +1,16 @@
-import { Client, QueryDefinition, QueryResult, Q } from 'cozy-client'
-import { Migration, MigrationResult } from './migration.type'
-import { migrationLog, migrate } from './migration'
+import * as Sentry from '@sentry/react'
+import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
+import { SCHEMAS_DOCTYPE } from 'doctypes/com-grandlyon-ecolyo-schemas'
+import { InitStepsErrors } from 'models/initialisationSteps.model'
+import { ReleaseNotes } from 'models/releaseNotes.model'
+import { Schema } from 'models/schema.models'
+import logApp from 'utils/logger'
+import { migrate, migrationLog } from './migration'
 import {
   MIGRATION_RESULT_COMPLETE,
   MIGRATION_RESULT_FAILED,
 } from './migration.data'
-import log from 'utils/logger'
-import { ReleaseNotes } from 'models/releaseNotes.model'
-import { InitStepsErrors } from 'models/initialisationSteps.model'
-import { Schema } from 'models/schema.models'
-import { SCHEMAS_DOCTYPE } from 'doctypes/com-grandlyon-ecolyo-schemas'
+import { Migration, MigrationResult } from './migration.type'
 
 export class MigrationService {
   private readonly _client: Client
@@ -37,7 +38,7 @@ export class MigrationService {
   }
 
   public async runMigrations(migrations: Migration[]): Promise<ReleaseNotes> {
-    log.info('[Migration] Running migrations...')
+    logApp.info('[Migration] Running migrations...')
     let releaseStatus = false
     const releaseNotes: ReleaseNotes = {
       show: releaseStatus,
@@ -63,7 +64,7 @@ export class MigrationService {
           migration,
           this._client
         )
-        log.info(migrationLog(migration, migrationResult))
+        logApp.info(migrationLog(migration, migrationResult))
 
         if (migrationResult.type === MIGRATION_RESULT_FAILED) {
           // Retry in case of failure
@@ -71,10 +72,11 @@ export class MigrationService {
           if (result.type === MIGRATION_RESULT_FAILED) {
             // Error in case of second failure
             this._setinitStepError(InitStepsErrors.MIGRATION_ERROR)
-            log.error(migrationLog(migration, result))
+            logApp.error(migrationLog(migration, result))
+            Sentry.captureException(migrationLog(migration, result))
             throw new Error()
           } else {
-            log.info(migrationLog(migration, result))
+            logApp.info(migrationLog(migration, result))
           }
         }
 
@@ -89,10 +91,10 @@ export class MigrationService {
       releaseNotes.show = releaseStatus
       // In case of first instance, don't show release notes
       if (startMigrationIndex === 0) releaseNotes.show = false
-      log.info('[Migration] Done')
+      logApp.info('[Migration] Done')
       return releaseNotes
     } else {
-      log.info('[Migration] Skipped Migration Process, already up-to-date')
+      logApp.info('[Migration] Skipped Migration Process, already up-to-date')
       return releaseNotes
     }
   }
diff --git a/src/migrations/migration.ts b/src/migrations/migration.ts
index 402db8290..5e278a579 100644
--- a/src/migrations/migration.ts
+++ b/src/migrations/migration.ts
@@ -1,18 +1,19 @@
-import {
-  Migration,
-  MigrationQueryOptions,
-  MigrationResult,
-} from './migration.type'
+import * as Sentry from '@sentry/react'
 import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
 import { SCHEMAS_DOCTYPE } from 'doctypes/com-grandlyon-ecolyo-schemas'
-import log from 'utils/logger'
+import { Schema } from 'models/schema.models'
+import logApp from 'utils/logger'
 import {
   MIGRATION_RESULT_COMPLETE,
   MIGRATION_RESULT_FAILED,
   MIGRATION_RESULT_NOOP,
   SCHEMA_INITIAL_VERSION,
 } from './migration.data'
-import { Schema } from 'models/schema.models'
+import {
+  Migration,
+  MigrationQueryOptions,
+  MigrationResult,
+} from './migration.type'
 
 function migrationNoop(): MigrationResult {
   return { type: MIGRATION_RESULT_NOOP, errors: [] }
@@ -64,7 +65,7 @@ async function updateSchemaVersion(
   _client: Client,
   targetSchemaVersion: number
 ): Promise<void> {
-  log.info('[Migration] Update schema version')
+  logApp.info('[Migration] Update schema version')
   const query: QueryDefinition = Q(SCHEMAS_DOCTYPE)
   const data: QueryResult<Schema[]> = await _client.query(query.limitBy(1))
   const doc = data.data[0]
@@ -79,11 +80,11 @@ async function updateSchemaVersion(
  * @returns Promise<MigrationResult>
  */
 async function save(_client: Client, docs: any[]): Promise<MigrationResult> {
-  log.info('[Migration] Saving docs...')
+  logApp.info('[Migration] Saving docs...')
   const migrationResult: MigrationResult = migrationNoop()
 
   if (docs.length) {
-    log.info('[Migration] Saving docs...')
+    logApp.info('[Migration] Saving docs...')
     docs.forEach(async doc => {
       if (doc.deleteAction) {
         await _client.destroy(doc)
@@ -93,7 +94,7 @@ async function save(_client: Client, docs: any[]): Promise<MigrationResult> {
         await _client.save(doc)
       }
     })
-    log.info('[Migration] Docs saved')
+    logApp.info('[Migration] Docs saved')
     migrationResult.type = migrationResult.errors.length
       ? MIGRATION_RESULT_FAILED
       : MIGRATION_RESULT_COMPLETE
@@ -114,7 +115,7 @@ const schemaExist = async (_client: Client): Promise<boolean> => {
 }
 
 const initSchemaDoctype = async (_client: Client) => {
-  log.info('[Migration] Init doctype')
+  logApp.info('[Migration] Init doctype')
   await _client.create(SCHEMAS_DOCTYPE, {
     version: SCHEMA_INITIAL_VERSION,
   })
@@ -175,11 +176,12 @@ export async function migrate(
           await updateSchemaVersion(_client, migration.targetSchemaVersion)
           break
       }
-    } catch (err: any) {
-      console.error(err)
+    } catch (error: any) {
+      console.error(error)
+      Sentry.captureException(JSON.stringify({ error }))
       result = {
         type: MIGRATION_RESULT_FAILED,
-        errors: [err.toString()],
+        errors: [error.toString()],
       }
     }
 
diff --git a/src/services/account.service.ts b/src/services/account.service.ts
index 4535ba52f..4c79724e0 100644
--- a/src/services/account.service.ts
+++ b/src/services/account.service.ts
@@ -1,4 +1,15 @@
-import { Client, QueryDefinition, Q, QueryResult } from 'cozy-client'
+import * as Sentry from '@sentry/react'
+import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
+import {
+  createAccount,
+  deleteAccount,
+  fetchAccount,
+  updateAccount,
+} from 'cozy-harvest-lib/dist/connections/accounts'
+import { build } from 'cozy-harvest-lib/dist/helpers/accounts'
+import logger from 'cozy-logger'
+import { ACCOUNTS_DOCTYPE } from 'doctypes'
+import { DateTime } from 'luxon'
 import {
   Account,
   AccountAttributes,
@@ -7,16 +18,10 @@ import {
   Konnector,
   Trigger,
 } from 'models'
-import { ACCOUNTS_DOCTYPE } from 'doctypes'
-import { build } from 'cozy-harvest-lib/dist/helpers/accounts'
-import {
-  createAccount,
-  fetchAccount,
-  deleteAccount,
-  updateAccount,
-} from 'cozy-harvest-lib/dist/connections/accounts'
+import logApp from 'utils/logger'
 import TriggerService from './triggers.service'
-import { DateTime } from 'luxon'
+
+const logStack = logger.namespace('accountService')
 
 export default class AccountService {
   private _client: Client
@@ -48,7 +53,10 @@ export default class AccountService {
       const account: Account = await fetchAccount(this._client, id)
       return account
     } catch (error) {
-      console.log(error)
+      const errorMessage = `Get account failed :${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw new Error('Get account failed')
     }
   }
@@ -93,8 +101,11 @@ export default class AccountService {
       } else {
         return accounts[0] ? accounts[0] : null
       }
-    } catch (err) {
-      console.error(`Error GetAccountByType: ${err}`)
+    } catch (error) {
+      const errorMessage = `Error GetAccountByType: ${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       return null
     }
   }
@@ -108,8 +119,11 @@ export default class AccountService {
       const { data: accounts }: QueryResult<Account[]> =
         await this._client.query(query)
       return accounts
-    } catch (err) {
-      console.error(`Error: GetAccountsByType: ${err}`)
+    } catch (error) {
+      const errorMessage = `Error: GetAccountsByType: ${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       return []
     }
   }
@@ -119,7 +133,10 @@ export default class AccountService {
       const updatedAccount: Account = await updateAccount(this._client, account)
       return updatedAccount
     } catch (error) {
-      console.log(error)
+      const errorMessage = `Update account failed: ${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw new Error('Update account failed')
     }
   }
@@ -129,8 +146,11 @@ export default class AccountService {
       await deleteAccount(this._client, account)
       return true
     } catch (error) {
-      console.log(error)
-      throw new Error('Delete account failed')
+      const errorMessage = `Delete account failed`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
+      throw new Error(errorMessage)
     }
   }
 
diff --git a/src/services/challenge.service.ts b/src/services/challenge.service.ts
index f08afb593..fb7c042a7 100644
--- a/src/services/challenge.service.ts
+++ b/src/services/challenge.service.ts
@@ -1,43 +1,48 @@
-import { Client, QueryDefinition, QueryResult, Q } from 'cozy-client'
-import { DateTime } from 'luxon'
+import * as Sentry from '@sentry/react'
+import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
+import logger from 'cozy-logger'
 import { CHALLENGE_DOCTYPE, USERCHALLENGE_DOCTYPE } from 'doctypes'
+import { FluidState, FluidType } from 'enum/fluid.enum'
+import { TimeStep } from 'enum/timeStep.enum'
+import { UserActionState } from 'enum/userAction.enum'
+import {
+  UserChallengeState,
+  UserChallengeSuccess,
+  UserChallengeUpdateFlag,
+} from 'enum/userChallenge.enum'
+import { UserDuelState } from 'enum/userDuel.enum'
+import { UserExplorationState } from 'enum/userExploration.enum'
+import { DateTime } from 'luxon'
 import {
   ChallengeEntity,
-  UserChallenge,
-  UserChallengeEntity,
-  DuelEntity,
-  UserDuel,
   Datachart,
   Dataload,
+  DuelEntity,
+  Ecogesture,
+  ExplorationEntity,
+  FluidStatus,
   QuizEntity,
   Relation,
-  TimePeriod,
-  UserQuiz,
-  UserExploration,
-  ExplorationEntity,
   RelationEntitiesObject,
-  FluidStatus,
-  Ecogesture,
+  TimePeriod,
   UserAction,
+  UserChallenge,
+  UserChallengeEntity,
+  UserDuel,
+  UserExploration,
+  UserQuiz,
 } from 'models'
-import {
-  UserChallengeState,
-  UserChallengeSuccess,
-  UserChallengeUpdateFlag,
-} from 'enum/userChallenge.enum'
-import { TimeStep } from 'enum/timeStep.enum'
-import { UserDuelState } from 'enum/userDuel.enum'
+import ConsumptionDataManager from 'services/consumption.service'
 import DuelService from 'services/duel.service'
 import QuizService from 'services/quiz.service'
-import ConsumptionDataManager from 'services/consumption.service'
-import { getRelationship, getRelationshipHasMany } from 'utils/utils'
 import { getLagDays } from 'utils/date'
-import ExplorationService from './exploration.service'
-import { FluidState, FluidType } from 'enum/fluid.enum'
-import { UserExplorationState } from 'enum/userExploration.enum'
-import { UserActionState } from 'enum/userAction.enum'
-import ActionService from './action.service'
+import logApp from 'utils/logger'
 import { getRoundFloat } from 'utils/math'
+import { getRelationship, getRelationshipHasMany } from 'utils/utils'
+import ActionService from './action.service'
+import ExplorationService from './exploration.service'
+
+const logStack = logger.namespace('challengeService')
 
 export default class ChallengeService {
   private readonly _client: Client
@@ -473,9 +478,14 @@ export default class ChallengeService {
         await this._client.destroy(challengeEntity[index])
       }
       return true
-    } catch (err) {
-      console.log(err)
-      throw err
+    } catch (error) {
+      const errorMessage = `deleteAllChallengeEntities :${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
+      throw error
     }
   }
 
@@ -494,9 +504,9 @@ export default class ChallengeService {
     return userChallenges
   }
 
-  /*
+  /**
    * Retrieve dataloads for ongoing duel
-   * sucess return: UserChallenge, Dataload[]
+   * success return: UserChallenge, Dataload[]
    * failure throw error
    */
   public async initChallengeDuelProgress(
@@ -527,10 +537,12 @@ export default class ChallengeService {
         )
       return { updatedUserChallenge, dataloads }
     } catch (error) {
-      console.log(
-        'Challenge service error on initChallengeDuelProgress : ',
+      const errorMessage = `Challenge service error on initChallengeDuelProgress: ${JSON.stringify(
         error
-      )
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
@@ -564,7 +576,12 @@ export default class ChallengeService {
         this.parseUserChallengeEntityToUserChallenge(updatedUserChallengeEntity)
       return updatedUserChallenge
     } catch (error) {
-      console.log('Challenge service error on startUserChallenge : ', error)
+      const errorMessage = `Challenge service error on startUserChallenge: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
@@ -770,7 +787,12 @@ export default class ChallengeService {
         this.parseUserChallengeEntityToUserChallenge(userChallengeEntity)
       return result
     } catch (error) {
-      console.log('Update user challenge error : ', error)
+      const errorMessage = `Update user challenge error: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
diff --git a/src/services/connection.service.ts b/src/services/connection.service.ts
index fb8563366..0a1f855ba 100644
--- a/src/services/connection.service.ts
+++ b/src/services/connection.service.ts
@@ -10,6 +10,11 @@ import AccountService from 'services/account.service'
 import TriggerService from 'services/triggers.service'
 import KonnectorService from 'services/konnector.service'
 import { SgeStore } from 'models/sgeStore.model'
+import logger from 'cozy-logger'
+import * as Sentry from '@sentry/react'
+import logApp from 'utils/logger'
+
+const logStack = logger.namespace('connectionService')
 
 export default class ConnectionService {
   private _client: Client
@@ -29,7 +34,11 @@ export default class ConnectionService {
       konnectorId
     )
     if (!konnector || !konnector.slug) {
-      throw new Error(`Could not find konnector for ${konnectorId}`)
+      const errorMessage = `Could not find konnector for ${konnectorId}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
+      throw new Error(errorMessage)
     }
     // Creation of the account linked to the konnector retrieved
     let accountAuthData: AccountAuthData | AccountSgeData
@@ -55,7 +64,11 @@ export default class ConnectionService {
       accountAuthData
     )
     if (!account || !account._id) {
-      throw new Error(`Error during account creation`)
+      const errorMessage = `Error during account creation`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
+      throw new Error(errorMessage)
     }
     // creation of the trigger for the konnector retrieve and the created account
     const triggersServices = new TriggerService(this._client)
@@ -64,7 +77,11 @@ export default class ConnectionService {
       konnector
     )
     if (!trigger) {
-      throw new Error(`Error during trigger creation`)
+      const errorMessage = `Error during trigger creation`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
+      throw new Error(errorMessage)
     }
     return {
       account: account,
diff --git a/src/services/customPopup.service.ts b/src/services/customPopup.service.ts
index c838c8778..1eee45690 100644
--- a/src/services/customPopup.service.ts
+++ b/src/services/customPopup.service.ts
@@ -1,19 +1,23 @@
+import * as Sentry from '@sentry/react'
 import { Client } from 'cozy-client'
-import { CustomPopup } from 'models/customPopup.model'
-import EnvironmentService from './environment.service'
 import logger from 'cozy-logger'
 import {
   REMOTE_ORG_ECOLYO_AGENT_CUSTOM_POPUP,
   REMOTE_ORG_ECOLYO_AGENT_CUSTOM_POPUP_REC,
 } from 'doctypes/remote/org.ecolyo.agent.custom.popup'
-const log = logger.namespace('customPupopService')
+import { CustomPopup } from 'models/customPopup.model'
+import logApp from 'utils/logger'
+import EnvironmentService from './environment.service'
+
+const logStack = logger.namespace('customPopupService')
+
 export default class CustomPupopService {
   private readonly _client: Client
   constructor(_client: Client) {
     this._client = _client
   }
 
-  /*
+  /**
    * Get information from backoffice about the status of custom popup
    * On success, respond the customPopup
    * Else, throw an error
@@ -24,15 +28,18 @@ export default class CustomPupopService {
       ? REMOTE_ORG_ECOLYO_AGENT_CUSTOM_POPUP
       : REMOTE_ORG_ECOLYO_AGENT_CUSTOM_POPUP_REC
     try {
+      logApp.info('[Initialization] Getting CustomPopup')
       const result = await this._client
         .getStackClient()
         .fetchJSON('GET', remoteUrl)
       return result as CustomPopup
     } catch (error) {
-      log(
-        'error',
-        `getCustomPopup: Failed to get custom popup:${JSON.stringify(error)}`
-      )
+      const errorMessage = `getCustomPopup: Failed to get custom popup:${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
     }
   }
 }
diff --git a/src/services/dateChart.service.ts b/src/services/dateChart.service.ts
index 5e4e5f739..7f7ecc150 100644
--- a/src/services/dateChart.service.ts
+++ b/src/services/dateChart.service.ts
@@ -1,7 +1,6 @@
-import { DateTime, Interval } from 'luxon'
-
 import { FluidType } from 'enum/fluid.enum'
 import { TimeStep } from 'enum/timeStep.enum'
+import { DateTime, Interval } from 'luxon'
 import { FluidConfig, TimePeriod } from 'models'
 import ConfigService from './fluidConfig.service'
 
diff --git a/src/services/duel.service.ts b/src/services/duel.service.ts
index 867b53c8e..be3409ffb 100644
--- a/src/services/duel.service.ts
+++ b/src/services/duel.service.ts
@@ -1,21 +1,26 @@
-import { Client, QueryDefinition, QueryResult, Q } from 'cozy-client'
+import * as Sentry from '@sentry/react'
+import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
+import logger from 'cozy-logger'
 import { DUEL_DOCTYPE } from 'doctypes/com-grandlyon-ecolyo-duel'
-import { UserDuelState } from 'enum/userDuel.enum'
-import { DateTime, Duration } from 'luxon'
-import ConsumptionService from './consumption.service'
-import PerformanceService from './performanceIndicator.service'
 import { FluidState, FluidType } from 'enum/fluid.enum'
 import { TimeStep } from 'enum/timeStep.enum'
+import { UserDuelState } from 'enum/userDuel.enum'
+import { DateTime, Duration } from 'luxon'
 import {
-  UserDuel,
-  DuelEntity,
-  TimePeriod,
-  PerformanceIndicator,
   Datachart,
   Dataload,
+  DuelEntity,
+  FluidStatus,
+  PerformanceIndicator,
+  TimePeriod,
+  UserDuel,
 } from 'models'
-import { FluidStatus } from 'models'
+import logApp from 'utils/logger'
 import { getRoundFloat } from 'utils/math'
+import ConsumptionService from './consumption.service'
+import PerformanceService from './performanceIndicator.service'
+
+const logStack = logger.namespace('duelService')
 
 export default class DuelService {
   private readonly _client: Client
@@ -149,9 +154,12 @@ export default class DuelService {
         await this._client.destroy(dueles[index])
       }
       return true
-    } catch (err) {
-      console.log(err)
-      throw err
+    } catch (error) {
+      const errorMessage = `deleteAllDuelEntities:${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
+      throw error
     }
   }
 
diff --git a/src/services/ecogesture.service.ts b/src/services/ecogesture.service.ts
index 393699d1b..d3bc02cfc 100644
--- a/src/services/ecogesture.service.ts
+++ b/src/services/ecogesture.service.ts
@@ -1,12 +1,16 @@
-import { Client, QueryDefinition, QueryResult, Q } from 'cozy-client'
+import * as Sentry from '@sentry/react'
+import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
 import { ECOGESTURE_DOCTYPE } from 'doctypes'
-import { Usage } from 'enum/ecogesture.enum'
+import { Season, Usage } from 'enum/ecogesture.enum'
 import { FluidType } from 'enum/fluid.enum'
 import { IndividualOrCollective, WarmingType } from 'enum/profileType.enum'
-import { Season } from 'enum/ecogesture.enum'
+import { orderBy } from 'lodash'
 import { Ecogesture } from 'models'
 import { ProfileEcogesture } from 'models/profileEcogesture.model'
-import { orderBy } from 'lodash'
+import logApp from 'utils/logger'
+import logger from 'cozy-logger'
+
+const logStack = logger.namespace('ecogestureService')
 
 export default class EcogestureService {
   private readonly _client: Client
@@ -65,7 +69,12 @@ export default class EcogestureService {
       }
       return true
     } catch (error) {
-      console.log('Error deleteAllEcogestures: ', error)
+      const errorMessage = `Error deleteAllEcogestures: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
@@ -83,7 +92,12 @@ export default class EcogestureService {
       }
       return true
     } catch (error) {
-      console.log('Error reinitAllEcogestures: ', error)
+      const errorMessage = `Error reinitAllEcogestures: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
diff --git a/src/services/enedisMonthlyAnalysisData.service.ts b/src/services/enedisMonthlyAnalysisData.service.ts
index ce18173c4..f8a2af627 100644
--- a/src/services/enedisMonthlyAnalysisData.service.ts
+++ b/src/services/enedisMonthlyAnalysisData.service.ts
@@ -1,5 +1,6 @@
-import { Client, QueryDefinition, QueryResult, Q } from 'cozy-client'
-
+import * as Sentry from '@sentry/react'
+import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
+import logger from 'cozy-logger'
 import {
   ENEDIS_MAXPOWER_DOCTYPE,
   ENEDIS_MONTHLY_ANALYSIS_DATA_DOCTYPE,
@@ -12,7 +13,9 @@ import {
   EnedisMonthlyAnalysisData,
 } from 'models/enedisMonthlyAnalysis'
 import { MaxPowerEntity } from 'models/maxPower.model'
+import logApp from 'utils/logger'
 
+const logStack = logger.namespace('enedisMonthlyAnalysisDataService')
 export default class EnedisMonthlyAnalysisDataService {
   private readonly _client: Client
 
@@ -136,7 +139,12 @@ export default class EnedisMonthlyAnalysisDataService {
       )
       return EnedisMonthlyAnalysis
     } catch (error) {
-      console.log('Error creating new EnedisMonthlyAnalysis: ', error)
+      const errorMessage = `Error creating new EnedisMonthlyAnalysis: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
diff --git a/src/services/environement.service.spec.ts b/src/services/environement.service.spec.ts
index 1720cee30..02799398b 100644
--- a/src/services/environement.service.spec.ts
+++ b/src/services/environement.service.spec.ts
@@ -1,9 +1,14 @@
 import EnvironmentService from './environment.service'
 
+declare const global: {
+  __IS_ALPHA__: boolean
+  __DEVELOPMENT__: boolean
+}
+
 describe('Environement service', () => {
   const environmentService = new EnvironmentService()
 
-  describe('isProduction method', () => {
+  describe('isProduction()', () => {
     it('should return true and prod url', async () => {
       global.__IS_ALPHA__ = false
       const result = environmentService.isProduction()
@@ -20,4 +25,47 @@ describe('Environement service', () => {
       expect(url).toEqual('https://ecolyo-agent-rec.grandlyon.com')
     })
   })
+
+  describe('isAlpha()', () => {
+    it('should return false', () => {
+      global.__IS_ALPHA__ = false
+      expect(environmentService.isAlpha()).toBe(false)
+    })
+    it('should return true', () => {
+      global.__IS_ALPHA__ = true
+      expect(environmentService.isAlpha()).toBe(true)
+    })
+  })
+
+  describe('isLocal()', () => {
+    it('should return false', () => {
+      global.__DEVELOPMENT__ = false
+      expect(environmentService.isLocal()).toBe(false)
+    })
+    it('should return true', () => {
+      global.__DEVELOPMENT__ = true
+      expect(environmentService.isLocal()).toBe(true)
+    })
+  })
+
+  describe('isDev()', () => {
+    it('should return false', () => {
+      global.__DEVELOPMENT__ = false
+      global.__IS_ALPHA__ = false
+      expect(environmentService.isDev()).toBe(false)
+    })
+    it('should return true', () => {
+      global.__DEVELOPMENT__ = true
+      global.__IS_ALPHA__ = false
+      expect(environmentService.isDev()).toBe(true)
+
+      global.__DEVELOPMENT__ = false
+      global.__IS_ALPHA__ = true
+      expect(environmentService.isDev()).toBe(true)
+
+      global.__DEVELOPMENT__ = true
+      global.__IS_ALPHA__ = true
+      expect(environmentService.isDev()).toBe(true)
+    })
+  })
 })
diff --git a/src/services/environment.service.ts b/src/services/environment.service.ts
index 62768a1b9..ab969e750 100644
--- a/src/services/environment.service.ts
+++ b/src/services/environment.service.ts
@@ -2,11 +2,19 @@ declare const __IS_ALPHA__: boolean
 declare const __DEVELOPMENT__: boolean
 
 export default class EnvironmentService {
-  private isAlpha() {
-    if (__IS_ALPHA__) {
-      return __IS_ALPHA__
-    }
-    return false
+  public isAlpha() {
+    return __IS_ALPHA__
+  }
+
+  public isLocal() {
+    return __DEVELOPMENT__
+  }
+
+  /**
+   * Returns true for local OR alpha
+   */
+  public isDev() {
+    return __IS_ALPHA__ || __DEVELOPMENT__
   }
 
   public isProduction() {
@@ -15,6 +23,7 @@ export default class EnvironmentService {
     }
     return false
   }
+
   public getPublicURL() {
     if (!this.isAlpha()) {
       return 'https://ecolyo-agent.apps.grandlyon.com'
@@ -22,8 +31,4 @@ export default class EnvironmentService {
       return 'https://ecolyo-agent-rec.grandlyon.com'
     }
   }
-
-  public isLocal() {
-    return __DEVELOPMENT__
-  }
 }
diff --git a/src/services/fluidsPrices.service.ts b/src/services/fluidsPrices.service.ts
index c4c4c3615..91dea0698 100644
--- a/src/services/fluidsPrices.service.ts
+++ b/src/services/fluidsPrices.service.ts
@@ -1,10 +1,15 @@
-import { Q, Client, QueryDefinition, QueryResult } from 'cozy-client'
+import * as Sentry from '@sentry/react'
+import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
+import logger from 'cozy-logger'
 import { FLUIDPRICES_DOCTYPE } from 'doctypes'
 import { FluidType } from 'enum/fluid.enum'
 import { DateTime } from 'luxon'
 import { FluidPrice } from 'models'
+import logApp from 'utils/logger'
 import ConfigService from './fluidConfig.service'
 
+const logStack = logger.namespace('fluidPricesService')
+
 export default class FluidPricesService {
   private readonly _client: Client
 
@@ -105,6 +110,10 @@ export default class FluidPricesService {
       }
       return true
     } catch (error) {
+      const errorMessage = `deleteAllFluidsPrices: ${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       return false
     }
   }
@@ -139,7 +148,12 @@ export default class FluidPricesService {
         await this._client.create(FLUIDPRICES_DOCTYPE, newPrice)
       return createdPrice
     } catch (error) {
-      console.log('Error creating new createdPrice: ', error)
+      const errorMessage = `'Error creating new createdPrice: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
diff --git a/src/services/initialization.service.ts b/src/services/initialization.service.ts
index d23da462d..2ff22d6ed 100644
--- a/src/services/initialization.service.ts
+++ b/src/services/initialization.service.ts
@@ -1,4 +1,6 @@
+import * as Sentry from '@sentry/react'
 import { Client } from 'cozy-client'
+import logger from 'cozy-logger'
 import challengeEntityData from 'db/challengeEntity.json'
 import duelEntityData from 'db/duelEntity.json'
 import ecogestureData from 'db/ecogestureData.json'
@@ -13,6 +15,10 @@ import {
   PROFILE_DOCTYPE,
   QUIZ_DOCTYPE,
 } from 'doctypes'
+import {
+  REMOTE_ORG_ECOLYO_AGENT_PRICES,
+  REMOTE_ORG_ECOLYO_AGENT_PRICES_REC,
+} from 'doctypes/remote/org.ecolyo.agent.prices'
 import { FluidType } from 'enum/fluid.enum'
 import { DateTime } from 'luxon'
 import {
@@ -37,18 +43,15 @@ import ProfileService from 'services/profile.service'
 import QuizService from 'services/quiz.service'
 import { getActualAnalysisDate } from 'utils/date'
 import { hashFile } from 'utils/hash'
-import log from 'utils/logger'
+import logApp from 'utils/logger'
 import EnvironmentService from './environment.service'
 import FluidPricesService from './fluidsPrices.service'
 import ProfileEcogestureService from './profileEcogesture.service'
 import ProfileTypeEntityService from './profileTypeEntity.service'
 import TermsService from './terms.service'
-import logger from 'cozy-logger'
-import {
-  REMOTE_ORG_ECOLYO_AGENT_PRICES,
-  REMOTE_ORG_ECOLYO_AGENT_PRICES_REC,
-} from 'doctypes/remote/org.ecolyo.agent.prices'
-const cozyLog = logger.namespace('initializationService')
+
+const logStack = logger.namespace('initializationService')
+
 export default class InitializationService {
   private readonly _client: Client
   private readonly _setinitStep: React.Dispatch<React.SetStateAction<InitSteps>>
@@ -68,10 +71,10 @@ export default class InitializationService {
     this._setinitStepError = _setinitStepError
   }
 
-  /*
+  /**
    * Check if profil exist
    * If not, the profil is created
-   * sucess return: profil
+   * success return: profil
    * failure return: null
    */
   public async initProfile(): Promise<Profile | null> {
@@ -86,13 +89,13 @@ export default class InitializationService {
           profileData[0]
         )
         if (newProfile) {
-          log.info('[Initialization] Profile created')
+          logApp.info('[Initialization] Profile created')
         } else {
           this._setinitStepError(InitStepsErrors.PROFILE_ERROR)
           throw new Error('initProfile: Profile not created')
         }
       } else {
-        log.info('[Initialization] Profile loaded')
+        logApp.info('[Initialization] Profile loaded')
       }
       const updatedProfile = await profileService.updateProfile({
         lastConnectionDate: DateTime.local().setZone('utc', {
@@ -102,26 +105,37 @@ export default class InitializationService {
       return updatedProfile
     } catch (error) {
       this._setinitStepError(InitStepsErrors.PROFILE_ERROR)
-      log.error('Initialization error - initProfile: ', error)
+
+      const errorMessage = `Initialization error - initProfile: :${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
 
-  /*
+  /**
    * Check if profileType exist
    * If not, the profileType is created
-   * sucess return: profileType
+   * success return: profileType
    * failure return: null
    */
   public async initProfileType(): Promise<ProfileType | null> {
     const profileTypeEntityService = new ProfileTypeEntityService(this._client)
     try {
       const loadedProfileType = await profileTypeEntityService.getProfileType()
-      log.info('[Initialization] ProfileType loaded')
+      logApp.info('[Initialization] ProfileType loaded')
       return loadedProfileType
     } catch (error) {
       this._setinitStepError(InitStepsErrors.PROFILETYPE_ERROR)
-      log.error('Initialization error - initProfileType: ', error)
+      const errorMessage = `Initialization error - initProfileType: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
@@ -130,11 +144,16 @@ export default class InitializationService {
     try {
       const loadedProfileEcogesture =
         await profileEcogestureService.getProfileEcogesture()
-      log.info('[Initialization] ProfileEcogesture loaded')
+      logApp.info('[Initialization] ProfileEcogesture loaded')
       return loadedProfileEcogesture
     } catch (error) {
       this._setinitStepError(InitStepsErrors.PROFILETYPE_ERROR)
-      log.error('Initialization error - initProfileEcogesture: ', error)
+      const errorMessage = `Initialization error - initProfileEcogesture: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
@@ -162,11 +181,16 @@ export default class InitializationService {
             'initEcogesture: Created ecogesture type entities does not match'
           )
         }
-        log.info('[Initialization] Ecogesture list created')
+        logApp.info('[Initialization] Ecogesture list created')
         return hashEcogestureType
       } catch (error) {
         this._setinitStepError(InitStepsErrors.ECOGESTURE_ERROR)
-        log.error('Initialization error - initEcogesture: ', error)
+        const errorMessage = `Initialization error - initEcogesture: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     }
@@ -198,16 +222,21 @@ export default class InitializationService {
             'initEcogesture: Created ecogesture type entities does not match'
           )
         }
-        log.info('[Initialization] Ecogesture updated')
+        logApp.info('[Initialization] Ecogesture updated')
         return hashEcogestureType
       } catch (error) {
         this._setinitStepError(InitStepsErrors.ECOGESTURE_ERROR)
-        log.error('Initialization error - initEcogesture: ', error)
+        const errorMessage = `Initialization error - initEcogesture: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     } else {
       // Doctype already up to date
-      log.info('[Initialization]  Ecogesture already up-to-date')
+      logApp.info('[Initialization] Ecogesture already up-to-date')
       return hashEcogestureType
     }
   }
@@ -217,7 +246,7 @@ export default class InitializationService {
     // Populate data if none ecogesture exists
     const loadedPrices = await fpService.getAllPrices()
     if (loadedPrices?.length) {
-      log.info('[Initialization] FluidPrices db already created')
+      logApp.info('[Initialization] FluidPrices db already created')
       return true
     } else {
       try {
@@ -241,12 +270,14 @@ export default class InitializationService {
         for (const price of allPrices) {
           await fpService.createPrice(price)
         }
-
-        log.info('[Initialization] FluidPrices db created successfully')
-        return true
-      } catch (err) {
-        log.error('Initialization error - initFluidPrices: ', err)
-        cozyLog('error', `Initialization error - initFluidPrices: ${err}`)
+        throw new Error('test')
+      } catch (error) {
+        const errorMessage = `Initialization error - initFluidPrices: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         return false
       }
     }
@@ -273,11 +304,16 @@ export default class InitializationService {
             'initChallengeEntity: Created challenge entities does not match'
           )
         }
-        log.info('[Initialization] Challenge entities created')
+        logApp.info('[Initialization] Challenge entities created')
         return challengeHash
       } catch (error) {
         this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-        log.error('Initialization error - initChallengeEntity: ', error)
+        const errorMessage = `Initialization error - initChallengeEntity: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     }
@@ -299,16 +335,21 @@ export default class InitializationService {
             'initChallengeEntity: Created challenge entities does not match'
           )
         }
-        log.info('[Initialization] Challenge entities updated')
+        logApp.info('[Initialization] Challenge entities updated')
         return challengeHash
       } catch (error) {
         this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-        log.error('Initialization error - initChallengeEntity: ', error)
+        const errorMessage = `Initialization error - initChallengeEntity: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     } else {
       // Doctype already up to date
-      log.info('[Initialization] Challenge Entity loaded')
+      logApp.info('[Initialization] Challenge Entity loaded')
       return challengeHash
     }
   }
@@ -332,11 +373,16 @@ export default class InitializationService {
             'initDuelEntity: Created duel entities does not match'
           )
         }
-        log.info('[Initialization] UserDuel entities created')
+        logApp.info('[Initialization] UserDuel entities created')
         return hashDuelEntity
       } catch (error) {
         this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-        log.error('Initialization error - initDuelEntity: ', error)
+        const errorMessage = `Initialization error - initDuelEntity: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     }
@@ -358,16 +404,21 @@ export default class InitializationService {
             'initDuelEntity: Created duel entities does not match'
           )
         }
-        log.info('[Initialization] UserDuel entities updated')
+        logApp.info('[Initialization] UserDuel entities updated')
         return hashDuelEntity
       } catch (error) {
         this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-        log.error('Initialization error - initDuelEntity: ', error)
+        const errorMessage = `Initialization error - initDuelEntity: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     } else {
       // Doctype already up to date
-      log.info('[Initialization] Duel Entity loaded')
+      logApp.info('[Initialization] Duel Entity loaded')
       return hashDuelEntity
     }
   }
@@ -392,11 +443,16 @@ export default class InitializationService {
           )
         }
 
-        log.info('[Initialization] Quiz entities created')
+        logApp.info('[Initialization] Quiz entities created')
         return quizHash
       } catch (error) {
         this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-        log.error('Initialization error - initQuizEntity: ', error)
+        const errorMessage = `Initialization error - initQuizEntity: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     }
@@ -418,16 +474,21 @@ export default class InitializationService {
             'initQuizEntity: Created quiz entities does not match'
           )
         }
-        log.info('[Initialization] Quiz entities updated')
+        logApp.info('[Initialization] Quiz entities updated')
         return quizHash
       } catch (error) {
         this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-        log.error('Initialization error - initQuizEntity: ', error)
+        const errorMessage = `Initialization error - initQuizEntity: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     } else {
       // Doctype already up to date
-      log.info('[Initialization] Quiz Entity loaded')
+      logApp.info('[Initialization] Quiz Entity loaded')
       return quizHash
     }
   }
@@ -455,11 +516,16 @@ export default class InitializationService {
             'initExplorationEntity: Created exploration entities does not match'
           )
         }
-        log.info('[Initialization] Exploration entities created')
+        logApp.info('[Initialization] Exploration entities created')
         return explorationHash
       } catch (error) {
         this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-        log.error('Initialization error - initExplorationEntity: ', error)
+        const errorMessage = `Initialization error - initExplorationEntity: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     }
@@ -484,16 +550,21 @@ export default class InitializationService {
             'initExplorationEntity: Created exploration entities does not match'
           )
         }
-        log.info('[Initialization] Exploration entities updated')
+        logApp.info('[Initialization] Exploration entities updated')
         return explorationHash
       } catch (error) {
         this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-        log.error('Initialization error - initExplorationEntity: ', error)
+        const errorMessage = `Initialization error - initExplorationEntity: ${JSON.stringify(
+          error
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
         throw error
       }
     } else {
       // Doctype already up to date
-      log.info('[Initialization] Exploration Entity loaded')
+      logApp.info('[Initialization] Exploration Entity loaded')
       return explorationHash
     }
   }
@@ -513,7 +584,9 @@ export default class InitializationService {
           haveSeenLastAnalysis: profile.haveSeenLastAnalysis,
         }
       } else {
-        log.info('[Initialization] Analysis information from profile updated')
+        logApp.info(
+          '[Initialization] Analysis information from profile updated'
+        )
         return {
           monthlyAnalysisDate: actualAnalysisDate,
           haveSeenLastAnalysis: profile.isFirstConnection ? true : false,
@@ -521,14 +594,19 @@ export default class InitializationService {
       }
     } catch (error) {
       this._setinitStepError(InitStepsErrors.ANALYSIS_ERROR)
-      log.error('Initialization error - initAnalysis: ', error)
+      const errorMessage = `Initialization error - initAnalysis: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
 
-  /*
+  /**
    * Check if FluidTypes exist
-   * sucess return: FluidType[]
+   * success return: FluidType[]
    * failure throw error
    */
   public async initFluidTypes(): Promise<FluidType[]> {
@@ -536,7 +614,7 @@ export default class InitializationService {
     try {
       const fluidtypes = await kss.getKonnectorAccountStatus()
       if (fluidtypes) {
-        log.info('[Initialization] Fluid Types loaded')
+        logApp.info('[Initialization] Fluid Types loaded')
         return fluidtypes
       } else {
         this._setinitStepError(InitStepsErrors.CONSOS_ERROR)
@@ -544,14 +622,20 @@ export default class InitializationService {
       }
     } catch (error) {
       this._setinitStepError(InitStepsErrors.CONSOS_ERROR)
-      log.error('Initialization error - initFluidTypes: ', error)
+      logApp.error('Initialization error - : ', error)
+      const errorMessage = `Initialization error - initFluidTypes: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
 
-  /*
+  /**
    * For each fluid get the trigger status and the last data date
-   * sucess return: FluidStatus[]
+   * success return: FluidStatus[]
    * failure throw error
    */
   public async initFluidStatus(): Promise<FluidStatus[]> {
@@ -560,7 +644,7 @@ export default class InitializationService {
       this._setinitStep(InitSteps.CONSOS)
       const fluidStatus = await fs.getFluidStatus()
       if (fluidStatus) {
-        log.info('[Initialization] Fluid Status loaded')
+        logApp.info('[Initialization] Fluid Status loaded')
         return fluidStatus
       } else {
         this._setinitStepError(InitStepsErrors.CONSOS_ERROR)
@@ -568,14 +652,19 @@ export default class InitializationService {
       }
     } catch (error) {
       this._setinitStepError(InitStepsErrors.CONSOS_ERROR)
-      log.error('Initialization error - initFluidStatus: ', error)
+      const errorMessage = `Initialization error - initFluidStatus: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
 
-  /*
+  /**
    * Build the userChallengeList
-   * sucess return: UserChallenge[]
+   * success return: UserChallenge[]
    * failure throw error
    */
   public async initUserChallenges(
@@ -587,7 +676,7 @@ export default class InitializationService {
         fluidStatus
       )
       if (userChallengeList) {
-        log.info('[Initialization] Challenges loaded')
+        logApp.info('[Initialization] Challenges loaded')
         return userChallengeList
       } else {
         this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
@@ -595,14 +684,19 @@ export default class InitializationService {
       }
     } catch (error) {
       this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-      log.error('Initialization error - initUserChallenges: ', error)
+      const errorMessage = `Initialization error - initUserChallenges: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
 
-  /*
+  /**
    * Retrieve dataloads for ongoing duel
-   * sucess return: UserChallenge, Dataload[]
+   * success return: UserChallenge, Dataload[]
    * failure throw error
    */
   public async initDuelProgress(userChallenge: UserChallenge): Promise<{
@@ -616,7 +710,10 @@ export default class InitializationService {
       return { updatedUserChallenge, dataloads }
     } catch (error) {
       this._setinitStepError(InitStepsErrors.CHALLENGES_ERROR)
-      log.error('Initialization error: ', error)
+      const errorMessage = `Initialization error - : ${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
@@ -638,36 +735,41 @@ export default class InitializationService {
           if (isLastConsentValidated) {
             termsStatus.accepted = true
             termsStatus.versionType = 'init'
-            log.info(
+            logApp.info(
               '[Initialization] Last Consent successfully loaded and valid'
             )
           } else {
             termsStatus.versionType = 'init'
             termsStatus.accepted = false
-            log.info('[Initialization] Consent not up-to-date')
+            logApp.info('[Initialization] Consent not up-to-date')
           }
         } else {
           const versionType = await termService.getTermsVersionType()
           if (versionType === 'minor') {
             termsStatus.accepted = false
             termsStatus.versionType = 'minor'
-            log.info('[Initialization] Minor Terms update detected')
+            logApp.info('[Initialization] Minor Terms update detected')
           } else {
             termsStatus.accepted = false
             termsStatus.versionType = 'major'
-            log.info('[Initialization] Major Terms update detected')
+            logApp.info('[Initialization] Major Terms update detected')
           }
         }
       } else {
         termsStatus.accepted = false
         termsStatus.versionType = 'init'
-        log.info('[Initialization] Init first terms')
+        logApp.info('[Initialization] Init first terms')
       }
 
       return termsStatus
     } catch (error) {
       this._setinitStepError(InitStepsErrors.CONSENT_ERROR)
-      log.error('Initialization error - initConsent: ', error)
+      const errorMessage = `Initialization error - initConsent: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
diff --git a/src/services/mail.service.ts b/src/services/mail.service.ts
index 762b53661..9528efdfd 100644
--- a/src/services/mail.service.ts
+++ b/src/services/mail.service.ts
@@ -1,5 +1,9 @@
+import * as Sentry from '@sentry/react'
 import { Client } from 'cozy-client'
+import logger from 'cozy-logger'
+import logApp from 'utils/logger'
 
+const logStack = logger.namespace('mailService')
 export default class MailService {
   public async SendMail(
     client: Client,
@@ -9,9 +13,11 @@ export default class MailService {
       const jobCollection = client.collection('io.cozy.jobs')
       jobCollection.create('sendmail', mailInfo)
     } catch (error) {
-      // eslint-disable-next-line no-console
-      console.log(error)
-      throw new Error('Failed to send mail')
+      const errorMessage = `Failed to send mail`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
+      throw new Error(errorMessage)
     }
   }
 }
diff --git a/src/services/partnersInfo.service.ts b/src/services/partnersInfo.service.ts
index dee233ed2..867f42f41 100644
--- a/src/services/partnersInfo.service.ts
+++ b/src/services/partnersInfo.service.ts
@@ -1,12 +1,15 @@
+import * as Sentry from '@sentry/react'
 import { Client } from 'cozy-client'
-import { PartnersInfo } from 'models/partnersInfo.model'
-import EnvironmentService from './environment.service'
 import logger from 'cozy-logger'
 import {
   REMOTE_ORG_ECOLYO_AGENT_PARTERS_INFO,
   REMOTE_ORG_ECOLYO_AGENT_PARTERS_INFO_REC,
 } from 'doctypes/remote/org.ecolyo.agent.partners.info'
-const log = logger.namespace('partnersInfoService')
+import { PartnersInfo } from 'models/partnersInfo.model'
+import logApp from 'utils/logger'
+import EnvironmentService from './environment.service'
+
+const logStack = logger.namespace('partnersInfoService')
 
 export default class PartnersInfoService {
   private readonly _client: Client
@@ -14,7 +17,7 @@ export default class PartnersInfoService {
     this._client = _client
   }
 
-  /*
+  /**
    * Get information from backoffice about the status of partners' service
    * On success, respond the partnersInfo
    * Else, throw an error
@@ -25,15 +28,18 @@ export default class PartnersInfoService {
       ? REMOTE_ORG_ECOLYO_AGENT_PARTERS_INFO
       : REMOTE_ORG_ECOLYO_AGENT_PARTERS_INFO_REC
     try {
+      logApp.info('[Initialization] Getting PartnersInfo')
       const result = await this._client
         .getStackClient()
         .fetchJSON('GET', remoteUrl)
       return result as PartnersInfo
     } catch (error) {
-      log(
-        'error',
-        `getPartnersInfo: Failed to get partners info: ${JSON.stringify(error)}`
-      )
+      const errorMessage = `getPartnersInfo: Failed to get partners info: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
     }
   }
 }
diff --git a/src/services/profileType.service.ts b/src/services/profileType.service.ts
index 23a52afcc..3aab00466 100644
--- a/src/services/profileType.service.ts
+++ b/src/services/profileType.service.ts
@@ -1,29 +1,33 @@
-import {
-  DetailsMonthlyForecast,
-  FluidForecast,
-  MonthlyForecast,
-  ProfileType,
-} from 'models/profileType.model'
-import { DateTime } from 'luxon'
-import heatingData from 'constants/consumptionConstants/heating.json'
-import cookingData from 'constants/consumptionConstants/cooking.json'
-import elecSpeData from 'constants/consumptionConstants/electricSpecific.json'
+import * as Sentry from '@sentry/react'
 import coldWaterData from 'constants/consumptionConstants/coldWater.json'
+import cookingData from 'constants/consumptionConstants/cooking.json'
 import EcsData from 'constants/consumptionConstants/ecs.json'
+import elecSpeData from 'constants/consumptionConstants/electricSpecific.json'
+import heatingData from 'constants/consumptionConstants/heating.json'
+import { Client } from 'cozy-client'
+import logger from 'cozy-logger'
+import { FluidType } from 'enum/fluid.enum'
 import {
   ConstructionYear,
   Floor,
-  IndividualOrCollective,
   HotWaterEquipment,
   HousingType,
   IndividualInsulationWork,
+  IndividualOrCollective,
   OutsideFacingWalls,
   ThreeChoicesAnswer,
 } from 'enum/profileType.enum'
-import { FluidType } from 'enum/fluid.enum'
+import { DateTime } from 'luxon'
+import {
+  DetailsMonthlyForecast,
+  FluidForecast,
+  MonthlyForecast,
+  ProfileType,
+} from 'models/profileType.model'
+import logApp from 'utils/logger'
 import ConverterService from './converter.service'
-import { Client } from 'cozy-client'
-import log from 'utils/logger'
+
+const logStack = logger.namespace('profileTypeService')
 
 export default class ProfileTypeService {
   private readonly profileType: ProfileType
@@ -31,7 +35,7 @@ export default class ProfileTypeService {
   private readonly year: number
 
   constructor(profileType: ProfileType, _client: Client, year: number) {
-    log.info(
+    logApp.info(
       '[ProfileType] Analysis loaded profileType related to: ',
       profileType.updateDate
         ? profileType.updateDate.toString()
@@ -514,7 +518,10 @@ export default class ProfileTypeService {
         return monthDju
       }
     } catch (error) {
-      console.log('errFetch', error)
+      const errorMessage = `fetchDju error : ${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       return heatingData.dju_average_by_month[month - 1]
     }
   }
diff --git a/src/services/profileTypeEntity.service.ts b/src/services/profileTypeEntity.service.ts
index d05966216..361d60fa0 100644
--- a/src/services/profileTypeEntity.service.ts
+++ b/src/services/profileTypeEntity.service.ts
@@ -1,10 +1,13 @@
+import * as Sentry from '@sentry/react'
 import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
-import { ProfileType, TimePeriod } from 'models'
+import logger from 'cozy-logger'
+import profileTypeData from 'db/profileTypeData.json'
 import { PROFILETYPE_DOCTYPE } from 'doctypes'
 import { DateTime } from 'luxon'
-import profileTypeData from 'db/profileTypeData.json'
-import log from 'utils/logger'
+import { ProfileType, TimePeriod } from 'models'
+import logApp from 'utils/logger'
 
+const logStack = logger.namespace('profileTypeEntityService')
 export default class ProfileTypeEntityService {
   private readonly _client: Client
 
@@ -34,15 +37,15 @@ export default class ProfileTypeEntityService {
       if (result) {
         return this.parseProfileTypeEntityToProfileType(profileType)
       } else {
-        log.debug('No profileType found for: ', date.toString())
-        log.debug(
+        logApp.debug('No profileType found for: ', date.toString())
+        logApp.debug(
           'Checking if user has already filled a profileType and uses it as default'
         )
         const query: QueryDefinition = Q(PROFILETYPE_DOCTYPE)
         const data: QueryResult<ProfileType[]> = await this._client.query(query)
         if (data.data.length) {
           const loadedProfileType: ProfileType = data.data[0]
-          log.debug(
+          logApp.debug(
             'found oldest profileType filled by user : ',
             loadedProfileType
           )
@@ -53,7 +56,7 @@ export default class ProfileTypeEntityService {
             ...profileTypeData[0].profileType,
             updateDate: date,
           }
-          log.debug('No profileType were found, loading default profileType')
+          logApp.debug('No profileType were found, loading default profileType')
           return loadedProfileType
         }
       }
@@ -159,6 +162,10 @@ export default class ProfileTypeEntityService {
       }
       return true
     } catch (error) {
+      const errorMessage = `deleteProfileTypes: ${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       return false
     }
   }
diff --git a/src/services/queryRunner.service.ts b/src/services/queryRunner.service.ts
index 25437e189..fdc6c671e 100644
--- a/src/services/queryRunner.service.ts
+++ b/src/services/queryRunner.service.ts
@@ -1,24 +1,23 @@
-import { Client, QueryDefinition, Q } from 'cozy-client'
-import { DateTime, Interval } from 'luxon'
+import { Client, Q, QueryDefinition } from 'cozy-client'
+import { QueryResult } from 'cozy-client/types/types'
 import {
+  EGL_DAY_DOCTYPE,
+  EGL_MONTH_DOCTYPE,
+  EGL_YEAR_DOCTYPE,
   ENEDIS_DAY_DOCTYPE,
+  ENEDIS_MINUTE_DOCTYPE,
   ENEDIS_MONTH_DOCTYPE,
   ENEDIS_YEAR_DOCTYPE,
   GRDF_DAY_DOCTYPE,
   GRDF_MONTH_DOCTYPE,
   GRDF_YEAR_DOCTYPE,
-  EGL_DAY_DOCTYPE,
-  EGL_MONTH_DOCTYPE,
-  EGL_YEAR_DOCTYPE,
-  ENEDIS_MINUTE_DOCTYPE,
 } from 'doctypes'
-
+import { DataloadState } from 'enum/dataload.enum'
 import { FluidType } from 'enum/fluid.enum'
 import { TimeStep } from 'enum/timeStep.enum'
+import { DateTime, Interval } from 'luxon'
 import { Dataload, TimePeriod } from 'models'
-import { QueryResult } from 'cozy-client/types/types'
-import log from 'utils/logger'
-import { DataloadState } from 'enum/dataload.enum'
+import logApp from 'utils/logger'
 
 export default class QueryRunner {
   // TODO to be clean up
@@ -103,7 +102,7 @@ export default class QueryRunner {
     } catch (error) {
       // log stuff
       // throw new Error('Fetch data failed in query runner')
-      log.error('QueryRunner error: ', error)
+      logApp.error('QueryRunner error: ', error)
     }
     return result
   }
diff --git a/src/services/quiz.service.ts b/src/services/quiz.service.ts
index a44dd35fa..8f6aa656e 100644
--- a/src/services/quiz.service.ts
+++ b/src/services/quiz.service.ts
@@ -23,7 +23,7 @@ import {
 } from 'enum/userQuiz.enum'
 import { shuffle } from 'lodash'
 import { formatNumberValues } from 'utils/utils'
-import log from 'utils/logger'
+import logApp from 'utils/logger'
 
 export default class QuizService {
   private readonly _client: Client
@@ -509,7 +509,7 @@ export default class QuizService {
     singleFluid: boolean
   ): Promise<number> {
     const consumptionService = new ConsumptionDataManager(this._client)
-    log.info('GetAverageOnGivenPeriod is about to call getgraphdata')
+    logApp.info('GetAverageOnGivenPeriod is about to call getgraphdata')
     const graphData = await consumptionService.getGraphData(
       interval,
       timeStep,
diff --git a/src/services/terms.service.ts b/src/services/terms.service.ts
index d4cfd9539..bb063f147 100644
--- a/src/services/terms.service.ts
+++ b/src/services/terms.service.ts
@@ -1,9 +1,13 @@
+import * as Sentry from '@sentry/react'
 import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
-
+import logger from 'cozy-logger'
 import { TERMS_DOCTYPE } from 'doctypes'
 import { DateTime } from 'luxon'
 import { Term, VersionType } from 'models'
+import logApp from 'utils/logger'
 import config from '../constants/config.json'
+
+const logStack = logger.namespace('termsService')
 export default class TermsService {
   private _client: Client
 
@@ -83,7 +87,10 @@ export default class TermsService {
         await this._client.create(TERMS_DOCTYPE, newTerm)
       return createdTerm
     } catch (error) {
-      console.log('Error creating new term: ', error)
+      const errorMessage = `Error creating new term: ${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw error
     }
   }
diff --git a/src/services/triggers.service.ts b/src/services/triggers.service.ts
index 12327b1cb..830b22746 100644
--- a/src/services/triggers.service.ts
+++ b/src/services/triggers.service.ts
@@ -1,4 +1,9 @@
+import * as Sentry from '@sentry/react'
 import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client'
+import triggersMutations from 'cozy-harvest-lib/dist/connections/triggers'
+import { buildAttributes } from 'cozy-harvest-lib/dist/helpers/triggers'
+import logger from 'cozy-logger'
+import { TRIGGERS_DOCTYPE } from 'doctypes'
 import {
   Account,
   Konnector,
@@ -6,10 +11,10 @@ import {
   TriggerAttributes,
   TriggerState,
 } from 'models'
-import { buildAttributes } from 'cozy-harvest-lib/dist/helpers/triggers'
-import triggersMutations from 'cozy-harvest-lib/dist/connections/triggers'
 import ConfigService from 'services/fluidConfig.service'
-import { TRIGGERS_DOCTYPE } from 'doctypes'
+import logApp from 'utils/logger'
+
+const logStack = logger.namespace('triggersService')
 
 export default class TriggerService {
   private _client: Client
@@ -95,7 +100,10 @@ export default class TriggerService {
       await this._client.destroy(trigger)
       return true
     } catch (error) {
-      console.log(error)
+      const errorMessage = `Delete trigger failed: ${JSON.stringify(error)}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
       throw new Error('Delete trigger failed')
     }
   }
diff --git a/src/services/usageEvent.service.ts b/src/services/usageEvent.service.ts
index 429718650..6ab397ddd 100644
--- a/src/services/usageEvent.service.ts
+++ b/src/services/usageEvent.service.ts
@@ -1,10 +1,12 @@
+import * as Sentry from '@sentry/react'
 import {
   Client,
+  MongoSelector,
+  Q,
   QueryDefinition,
   QueryResult,
-  Q,
-  MongoSelector,
 } from 'cozy-client'
+import logger from 'cozy-logger'
 import { USAGEEVENT_DOCTYPE } from 'doctypes'
 import { UsageEventType } from 'enum/usageEvent.enum'
 import { DateTime } from 'luxon'
@@ -14,6 +16,9 @@ import {
   UsageEventCreationEntity,
   UsageEventEntity,
 } from 'models'
+import logApp from 'utils/logger'
+
+const logStack = logger.namespace('usageEventService')
 
 export default class UsageEventService {
   /**
@@ -92,11 +97,13 @@ export default class UsageEventService {
         const { data: savedEvent } = await client.save(updatedEvent)
         return savedEvent
       }
-    } catch (err) {
-      console.log(
-        'UsageEvent service error on udpateConnectionAttemptEvent : ',
-        err
-      )
+    } catch (error) {
+      const errorMessage = `UsageEvent service error on udpateConnectionAttemptEvent: ${JSON.stringify(
+        error
+      )}`
+      logStack('error', errorMessage)
+      logApp.error(errorMessage)
+      Sentry.captureException(errorMessage)
     }
   }
 
@@ -117,10 +124,12 @@ export default class UsageEventService {
           aggregated: true,
         })
       } catch (error) {
-        console.log(
-          'UsageEvent service error on updateUsageEventsAggregated : ',
+        const errorMessage = `UsageEvent service error on updateUsageEventsAggregated: ${JSON.stringify(
           error
-        )
+        )}`
+        logStack('error', errorMessage)
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
       }
     }
     return true
diff --git a/src/store/index.ts b/src/store/index.ts
index b8b4b1e9b..c7e28758b 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -24,6 +24,7 @@ import { ChartState } from 'models/chart.model'
 import { Client } from 'cozy-client'
 import { ProfileEcogesture } from 'models/profileEcogesture.model'
 import { profileEcogestureReducer } from './profileEcogesture/profileEcogesture.reducer'
+import * as Sentry from '@sentry/react'
 
 export interface EcolyoState {
   global: GlobalState
@@ -50,6 +51,8 @@ export interface AppStore {
   cozy: never
 }
 
+const sentryReduxEnhancer = Sentry.createReduxEnhancer({})
+
 const configureStore = (
   client: Client,
   persistedState: any
@@ -63,8 +66,11 @@ const configureStore = (
       cozy: client.reducer(),
       persistedState,
     }),
-    // eslint-disable-next-line prefer-spread
-    composeEnhancers(applyMiddleware.apply(null, middlewares))
+    composeEnhancers(
+      // eslint-disable-next-line prefer-spread
+      applyMiddleware.apply(null, middlewares),
+      sentryReduxEnhancer
+    )
   )
   return store
 }
diff --git a/src/targets/browser/index.tsx b/src/targets/browser/index.tsx
index 92e2c8fec..f6ae85303 100644
--- a/src/targets/browser/index.tsx
+++ b/src/targets/browser/index.tsx
@@ -3,23 +3,27 @@
 declare let cozy: any
 declare let __PIWIK_TRACKER_URL__: string
 declare let __PIWIK_SITEID__: number
+declare let __SENTRY_DSN__: string
 declare let Piwik: any
 
-import '../../styles/index.scss'
-
-import React from 'react'
-import { render } from 'react-dom'
+import * as Sentry from '@sentry/react'
+import { BrowserTracing } from '@sentry/tracing'
 import CozyClient, { Client, CozyProvider } from 'cozy-client'
-import { Provider } from 'react-redux'
-import configureStore from 'store'
-import { I18n, initTranslation } from 'cozy-ui/transpiled/react/I18n'
 import { handleOAuthResponse } from 'cozy-harvest-lib/dist/helpers/oauth'
-import { memoize } from 'lodash'
-import manifest from '../../../manifest.webapp'
+import { I18n, initTranslation } from 'cozy-ui/transpiled/react/I18n'
 import schema from 'doctypes'
 import { createBrowserHistory, History } from 'history'
+import { memoize } from 'lodash'
+import React from 'react'
+import { render } from 'react-dom'
+import { Provider } from 'react-redux'
 import { HashRouter } from 'react-router-dom'
+import EnvironmentService from 'services/environment.service'
+import configureStore from 'store'
+import logApp from 'utils/logger'
 import MatomoTracker from 'utils/matomoTracker'
+import manifest from '../../../manifest.webapp'
+import '../../styles/index.scss'
 
 const setupApp = memoize(() => {
   const history: History = createBrowserHistory()
@@ -46,6 +50,9 @@ const setupApp = memoize(() => {
 
   const persistedState: any = {}
   const store: any = configureStore(client, persistedState)
+  const envService = new EnvironmentService()
+  const isLocal = envService.isLocal()
+  const development = envService.isDev()
 
   cozy.bar.init({
     appName: data.app.name,
@@ -70,6 +77,21 @@ const setupApp = memoize(() => {
     })
   }
 
+  Sentry.init({
+    dsn: __SENTRY_DSN__,
+    integrations: [new BrowserTracing()],
+    // Set tracesSampleRate to 1.0 to capture 100%
+    // of transactions for performance monitoring.
+    // We recommend adjusting this value in production
+    // Set to 0 for local development
+    tracesSampleRate: isLocal ? 0 : 1.0,
+
+    // Custom settings below
+    release: client.appMetadata.version,
+    environment: development ? 'development' : 'production',
+    // cast because init is somehow missing dsn property
+  } as Sentry.BrowserOptions)
+
   return { root, store, client, locale, polyglot, history, tracker }
 })
 
@@ -101,7 +123,13 @@ if (!isSafari && 'serviceWorker' in navigator) {
     navigator.serviceWorker
       .register('/serviceWorker.js')
       .then(reg => console.log('service worker registered', reg.scope))
-      .catch(err => console.log('service worker not registered', err))
+      .catch(error => {
+        const errorMessage = `service worker not registered: ${JSON.stringify(
+          error
+        )}`
+        logApp.error(errorMessage)
+        Sentry.captureException(errorMessage)
+      })
   })
 }
 
diff --git a/src/targets/services/aggregatorUsageEvents.ts b/src/targets/services/aggregatorUsageEvents.ts
index 2599c3015..fbdbf208f 100644
--- a/src/targets/services/aggregatorUsageEvents.ts
+++ b/src/targets/services/aggregatorUsageEvents.ts
@@ -21,8 +21,9 @@ import ProfileTypeEntityService from 'services/profileTypeEntity.service'
 import TermsService from 'services/terms.service'
 import { WarmingType } from 'enum/profileType.enum'
 import { FluidSlugType } from 'enum/fluidSlug.enum'
+import * as Sentry from '@sentry/react'
 
-const log = logger.namespace('aggregatorUsageEvents')
+const logStack = logger.namespace('aggregatorUsageEvents')
 
 interface AggregatorUsageEventsProps {
   client: Client
@@ -50,7 +51,7 @@ const sendIndicator = async (
 ): Promise<boolean> => {
   try {
     const environmentService = new EnvironmentService()
-    log(
+    logStack(
       'info',
       environmentService.isProduction()
         ? 'Sending data to dacc'
@@ -72,10 +73,11 @@ const sendIndicator = async (
       )
     return true
   } catch (error) {
-    log(
+    logStack(
       'error',
       `Error while sending indicator ${indicator.measureName} to remote doctype: ${error.message}`
     )
+    Sentry.captureException(JSON.stringify({ error }))
     throw error
   }
 }
@@ -353,7 +355,7 @@ const calculateConnectedKonnectorPerDay = async (client: Client) => {
   const connectedKonnectors = fluidStatus.filter(
     fluid => fluid.status === FluidState.DONE
   )
-  log('info', 'calculateConnectedKonnectorPerDay')
+  logStack('info', 'calculateConnectedKonnectorPerDay')
   if (connectedKonnectors.length > 0) {
     const konnectorfluidTypes: FluidType[] = []
     for (const konnector of connectedKonnectors) {
@@ -485,7 +487,7 @@ const getConsumptionValue = async (
  * @group [{ slug }, { seniority (in month) }, { profile (ECS, chauffage, etc...) }],
  */
 const calculateConsumptionVariation = async (client: Client) => {
-  log('info', `calculateConsumptionVariation`)
+  logStack('info', `calculateConsumptionVariation`)
   const consumptionData = await getConsumptionValue(client, [
     FluidType.ELECTRICITY,
     FluidType.GAS,
@@ -561,7 +563,7 @@ const calculateConsumptionVariation = async (client: Client) => {
         })
 
         if (events.length > 0 && consumptionVariationIndicator.value !== 0) {
-          log(
+          logStack(
             'info',
             `Send variation indicator : ${JSON.stringify(
               consumptionVariationIndicator
@@ -575,7 +577,7 @@ const calculateConsumptionVariation = async (client: Client) => {
 }
 
 const sendConnectionCount = async (client: Client) => {
-  log('info', `sendConnectionCount`)
+  logStack('info', `sendConnectionCount`)
   // Get daily connexion
   const events: UsageEvent[] = await UsageEventService.getEvents(client, {
     type: UsageEventType.CONNECTION_EVENT,
@@ -616,7 +618,7 @@ const sendConnectionCount = async (client: Client) => {
       .toISODate(),
     value: uniqueDates,
   }
-  log(
+  logStack(
     'info',
     `Send connectionMonthly indicator : ${JSON.stringify(connectionMonthly)}`
   )
@@ -624,7 +626,7 @@ const sendConnectionCount = async (client: Client) => {
 }
 
 const sendProfileCount = async (client: Client) => {
-  log('info', `sendProfileCount`)
+  logStack('info', `sendProfileCount`)
   // Get profile setEvents
   const events: UsageEvent[] = await UsageEventService.getEvents(client, {
     type: UsageEventType.PROFILE_SET_EVENT,
@@ -648,7 +650,7 @@ const sendProfileCount = async (client: Client) => {
 }
 
 const sendEmailSubscription = async (client: Client) => {
-  log('info', `sendEmailSubscription`)
+  logStack('info', `sendEmailSubscription`)
   const profile = await new ProfileService(client).getProfile()
   if (profile?.sendAnalysisNotification) {
     const cameBackFromEmail: Indicator = {
@@ -673,7 +675,7 @@ const sendEmailSubscription = async (client: Client) => {
  * @param client CozyClient
  */
 const sendHalfHourConsumption = async (client: Client) => {
-  log('info', `sendHalfHourConsumption`)
+  logStack('info', `sendHalfHourConsumption`)
   const consumptionService = new ConsumptionService(client)
 
   const data = await consumptionService.getLastHourData(
@@ -704,7 +706,7 @@ const sendHalfHourConsumption = async (client: Client) => {
  * @param client CozyClient
  */
 const sendKonnectorEvents = async (client: Client) => {
-  log('info', `sendKonnectorEvents`)
+  logStack('info', `sendKonnectorEvents`)
   const slugs = Object.values(FluidSlugType)
   const today = DateTime.local().setZone('utc', {
     keepLocalTime: true,
@@ -796,7 +798,7 @@ const sendKonnectorEvents = async (client: Client) => {
  * @param client CozyClient
  */
 const sendKonnectorAttemptsMonthly = async (client: Client) => {
-  log('info', `sendkonnectorAttemptsMonthly`)
+  logStack('info', `sendkonnectorAttemptsMonthly`)
   const slugs = Object.values(FluidSlugType)
   const today = DateTime.local().setZone('utc', {
     keepLocalTime: true,
@@ -815,7 +817,7 @@ const sendKonnectorAttemptsMonthly = async (client: Client) => {
       },
       true
     )
-    log('info', ` : ${JSON.stringify(konnectorEvents)}`)
+    logStack('info', ` : ${JSON.stringify(konnectorEvents)}`)
 
     // Check if there is a success (will be false or true since the event is triggered only for the first connexion)
     const success: boolean =
@@ -1153,11 +1155,11 @@ const aggregateEvents = async (
 const AggregatorUsageEvents = async ({
   client,
 }: AggregatorUsageEventsProps) => {
-  log('info', 'Launch service')
-  log('info', 'Dacc consent validation...')
+  logStack('info', 'Launch service')
+  logStack('info', 'Dacc consent validation...')
   const termService = new TermsService(client)
   if (!(await termService.getLastTerm())) {
-    log('info', 'Exit: no consent available')
+    logStack('info', 'Exit: no consent available')
     return
   }
 
@@ -1176,10 +1178,10 @@ const AggregatorUsageEvents = async ({
     result: 'firstConnection',
   })
   if (events.length > 0) {
-    log('info', `Fetching Sessions`)
+    logStack('info', `Fetching Sessions`)
     calculSessionTime(events, client)
     for (const eventType of Object.values(UsageEventType)) {
-      log('info', `Fetching ${eventType}`)
+      logStack('info', `Fetching ${eventType}`)
       const filteredEvents: UsageEvent[] = events.filter(
         event => event.type === eventType
       )
@@ -1215,7 +1217,7 @@ const AggregatorUsageEvents = async ({
   }
 
   const uniqueReadUsageEvents: UsageEvent[] = uniq(readUsageEvents)
-  log(
+  logStack(
     'info',
     `Tag aggregated usage: total of ${uniqueReadUsageEvents.length} events`
   )
@@ -1230,11 +1232,12 @@ const AggregatorUsageEvents = async ({
     errorEvent.forEach(el => {
       error += `${el.doctype}, `
     })
-    log('error', error)
+    logStack('error', error)
+    Sentry.captureException(JSON.stringify({ error }))
     throw error
   }
 
-  log('info', 'End of service')
+  logStack('info', 'End of service')
 }
 
 runService(AggregatorUsageEvents)
diff --git a/src/targets/services/consumptionAlert.ts b/src/targets/services/consumptionAlert.ts
index f00a19b92..668306c10 100644
--- a/src/targets/services/consumptionAlert.ts
+++ b/src/targets/services/consumptionAlert.ts
@@ -12,7 +12,7 @@ import ConsumptionService from 'services/consumption.service'
 import { getPreviousMonthName } from 'utils/utils'
 import EnvironmentService from 'services/environment.service'
 
-const log = logger.namespace('alert')
+const logStack = logger.namespace('alert')
 
 interface ConsumptionAlertProps {
   client: Client
@@ -20,7 +20,7 @@ interface ConsumptionAlertProps {
 
 //  Only monitoring WATER fluid for now
 const consumptionAlert = async ({ client }: ConsumptionAlertProps) => {
-  log('info', 'Fetching user profile...')
+  logStack('info', 'Fetching user profile...')
   const upm = new ProfileService(client)
   const consumptionService = new ConsumptionService(client)
   const userProfil = await upm.getProfile()
@@ -29,7 +29,7 @@ const consumptionAlert = async ({ client }: ConsumptionAlertProps) => {
     !userProfil.sendConsumptionAlert ||
     userProfil.waterDailyConsumptionLimit === 0
   ) {
-    log(
+    logStack(
       'info',
       'End of process - Alert report notification is disabled or lack informations from user profile to run'
     )
@@ -38,9 +38,9 @@ const consumptionAlert = async ({ client }: ConsumptionAlertProps) => {
 
   let username = ''
 
-  log('info', 'water limit is :' + userProfil.waterDailyConsumptionLimit)
+  logStack('info', 'water limit is :' + userProfil.waterDailyConsumptionLimit)
 
-  log('info', 'Fetching fluid data...')
+  logStack('info', 'Fetching fluid data...')
   // Retrieve public name from the stack
   const settings = await client
     .getStackClient()
@@ -69,14 +69,14 @@ const consumptionAlert = async ({ client }: ConsumptionAlertProps) => {
     })
   }
   if (lastDayValue <= userProfil.waterDailyConsumptionLimit) {
-    log(
+    logStack(
       'info',
       'End of process - Limit consumption set by the user has not been passed.'
     )
     return
   }
 
-  log('info', 'Creation of mail...')
+  logStack('info', 'Creation of mail...')
   const mailService = new MailService()
 
   const environmentService = new EnvironmentService()
@@ -102,7 +102,7 @@ const consumptionAlert = async ({ client }: ConsumptionAlertProps) => {
     ],
   }
 
-  log('info', 'Sending mail...')
+  logStack('info', 'Sending mail...')
   mailService.SendMail(client, mailData)
 }
 
diff --git a/src/targets/services/enedisHalfHourMonthlyAnalysis.ts b/src/targets/services/enedisHalfHourMonthlyAnalysis.ts
index e512b63d2..3f9a56f50 100644
--- a/src/targets/services/enedisHalfHourMonthlyAnalysis.ts
+++ b/src/targets/services/enedisHalfHourMonthlyAnalysis.ts
@@ -1,20 +1,21 @@
-import logger from 'cozy-logger'
+import * as Sentry from '@sentry/react'
 import { Client } from 'cozy-client'
-import { DateTime } from 'luxon'
-import { Datachart, DataloadEntity, TimePeriod } from 'models'
-import { runService } from './service'
-import { FluidType } from 'enum/fluid.enum'
-import { TimeStep } from 'enum/timeStep.enum'
-import ConsumptionService from 'services/consumption.service'
-import { EnedisMonthlyAnalysisData } from 'models/enedisMonthlyAnalysis'
-import EnedisMonthlyAnalysisDataService from 'services/enedisMonthlyAnalysisData.service'
+import logger from 'cozy-logger'
 import {
   ENEDIS_MINUTE_DOCTYPE,
   ENEDIS_MONTHLY_ANALYSIS_DATA_DOCTYPE,
 } from 'doctypes'
+import { FluidType } from 'enum/fluid.enum'
+import { TimeStep } from 'enum/timeStep.enum'
 import { union } from 'lodash'
+import { DateTime } from 'luxon'
+import { Datachart, DataloadEntity, TimePeriod } from 'models'
+import { EnedisMonthlyAnalysisData } from 'models/enedisMonthlyAnalysis'
+import ConsumptionService from 'services/consumption.service'
+import EnedisMonthlyAnalysisDataService from 'services/enedisMonthlyAnalysisData.service'
+import { runService } from './service'
 
-const log = logger.namespace('report')
+const logStack = logger.namespace('report')
 
 interface EnedisMonthlyProps {
   client: Client
@@ -35,7 +36,7 @@ const getMinMonthlyLoad = (
   const filteredTotal = totalArray.filter(val => val !== -1 && val !== 0)
   const talonCons = Math.min(...filteredTotal)
   const minCons = talonCons * 48 * numberofDaysInMonth
-  log('info', `Minimum value is ${minCons} `)
+  logStack('info', `Minimum value is ${minCons} `)
   return minCons
 }
 
@@ -87,7 +88,7 @@ const getMonthMaxPower = async (
   client: Client
 ) => {
   const emas = new EnedisMonthlyAnalysisDataService(client)
-  log('info', `Fetching max power for month ${month} of year ${year}`)
+  logStack('info', `Fetching max power for month ${month} of year ${year}`)
   const data = await emas.getMaxPowerByDate(year, month)
   const maxPowerArray: number[] = []
   if (data?.length) {
@@ -109,7 +110,10 @@ const getEnedisMonthAnalysisData = async (
   month: number,
   year: number
 ): Promise<EnedisMonthlyAnalysisData | undefined> => {
-  log('info', `Getting enedis analysis data for month ${month} of year ${year}`)
+  logStack(
+    'info',
+    `Getting enedis analysis data for month ${month} of year ${year}`
+  )
 
   const timePeriod = {
     startDate: DateTime.fromObject({ month: month, year: year }).startOf(
@@ -197,7 +201,7 @@ const syncEnedisMonthlyAnalysisDataDoctype = async ({
   const lastEnedisMonthlyAnalysis = await emas.getLastEnedisMonthlyAnalysis()
   if (firstMinuteData && firstMinuteData[0]) {
     //First creates the analysis of the month - 1
-    log('info', 'Fetching last Enedis monthly Analysis...')
+    logStack('info', 'Fetching last Enedis monthly Analysis...')
     const firstMinuteDate = DateTime.fromObject({
       year: firstMinuteData[0].year,
       month: firstMinuteData[0].month,
@@ -217,12 +221,17 @@ const syncEnedisMonthlyAnalysisDataDoctype = async ({
     if (data) {
       const created = await emas.createEnedisMonthlyAnalysisData(data)
       if (created) {
-        log('success', 'Created successfully ! ')
+        logStack('success', 'Created successfully ! ')
       } else {
-        log('error', 'Failed to create last Enedis monthly Analysis ')
+        logStack('error', 'Failed to create last Enedis monthly Analysis')
+        Sentry.captureException(
+          JSON.stringify({
+            error: 'Failed to create last Enedis monthly Analysis ',
+          })
+        )
       }
     }
-    log('info', 'Getting first endis half hour data date')
+    logStack('info', 'Getting first endis half hour data date')
 
     if (lastEnedisMonthlyAnalysis.length > 0) {
       //If user has more than one entry (already synced), fetch the full history
@@ -233,10 +242,10 @@ const syncEnedisMonthlyAnalysisDataDoctype = async ({
         firstEnedisMonthlyAnalysis[0]?.month === firstMinuteData[0].month &&
         firstEnedisMonthlyAnalysis[0]?.year === firstMinuteData[0].year
       ) {
-        log('info', 'Every Enedis Anlysis already synchronized')
+        logStack('info', 'Every Enedis Anlysis already synchronized')
         return
       } else if (firstEnedisMonthlyAnalysis) {
-        log(
+        logStack(
           'info',
           'Doctype is partially completed, fetiching all available history'
         )
@@ -263,7 +272,7 @@ const syncEnedisMonthlyAnalysisDataDoctype = async ({
       }
     } else {
       //If user only have the last analysis available, fetch one year history
-      log(
+      logStack(
         'info',
         'Doctype is empty, fetching history for one year maximum or until first enedis minute date'
       )
@@ -288,7 +297,7 @@ const syncEnedisMonthlyAnalysisDataDoctype = async ({
       }
     }
   } else {
-    log(
+    logStack(
       'info',
       'Enedis Minute is not activated or there is no data yet in this doctype'
     )
diff --git a/src/targets/services/fluidsPrices.ts b/src/targets/services/fluidsPrices.ts
index 0a423e180..4f4c1137c 100644
--- a/src/targets/services/fluidsPrices.ts
+++ b/src/targets/services/fluidsPrices.ts
@@ -1,20 +1,22 @@
-import logger from 'cozy-logger'
+import * as Sentry from '@sentry/react'
 import { Client } from 'cozy-client'
-import { runService } from './service'
-import { DateTime } from 'luxon'
-import FluidPricesService from 'services/fluidsPrices.service'
-import { DataloadEntity, FluidPrice, TimePeriod } from 'models'
-import ConsumptionDataManager from 'services/consumption.service'
-import { TimeStep } from 'enum/timeStep.enum'
-import { ENEDIS_DAY_DOCTYPE, GRDF_DAY_DOCTYPE, EGL_DAY_DOCTYPE } from 'doctypes'
-import { FluidType } from 'enum/fluid.enum'
-import QueryRunner from 'services/queryRunner.service'
-import EnvironmentService from 'services/environment.service'
+import logger from 'cozy-logger'
+import { EGL_DAY_DOCTYPE, ENEDIS_DAY_DOCTYPE, GRDF_DAY_DOCTYPE } from 'doctypes'
 import {
   REMOTE_ORG_ECOLYO_AGENT_PRICES,
   REMOTE_ORG_ECOLYO_AGENT_PRICES_REC,
 } from 'doctypes/remote/org.ecolyo.agent.prices'
-const log = logger.namespace('fluidPrices')
+import { FluidType } from 'enum/fluid.enum'
+import { TimeStep } from 'enum/timeStep.enum'
+import { DateTime } from 'luxon'
+import { DataloadEntity, FluidPrice, TimePeriod } from 'models'
+import ConsumptionDataManager from 'services/consumption.service'
+import EnvironmentService from 'services/environment.service'
+import FluidPricesService from 'services/fluidsPrices.service'
+import QueryRunner from 'services/queryRunner.service'
+import { runService } from './service'
+
+const logStack = logger.namespace('fluidPrices')
 
 interface PricesProps {
   client: Client
@@ -61,7 +63,10 @@ const synchroPricesToUpdate = async (
               remotePrice.UpdatedAt &&
               existingPrice.UpdatedAt < remotePrice.UpdatedAt
             ) {
-              log('debug', `Price exist in db but not up to date, updating it`)
+              logStack(
+                'debug',
+                `Price exist in db but not up to date, updating it`
+              )
               //If a price has been updated, set the oldest startDate of the edited price so we can redo aggregation
               if (firstEditedPrice === null) {
                 firstEditedPrice = remotePrice.startDate
@@ -83,10 +88,10 @@ const synchroPricesToUpdate = async (
                 UpdatedAt: remotePrice.UpdatedAt,
               })
             } else {
-              log('debug', `Price up to date`)
+              logStack('debug', `Price up to date`)
             }
           } else {
-            log('debug', `Price doesn't exist in db, creating new price`)
+            logStack('debug', `Price doesn't exist in db, creating new price`)
             //If a price has been updated, set the oldest startDate of the edited price so we can redo aggregation
             if (firstEditedPrice === null) {
               firstEditedPrice = remotePrice.startDate
@@ -97,8 +102,9 @@ const synchroPricesToUpdate = async (
             //create price in db
             await fps.createPrice(remotePrice)
           }
-        } catch (err) {
-          log('error', `Error: ${err}`)
+        } catch (error) {
+          logStack('error', `Error: ${error}`)
+          Sentry.captureException(JSON.stringify({ error }))
         } finally {
           resolve()
         }
@@ -138,7 +144,10 @@ const getTimePeriod = async (
         endDate: date.endOf('year'),
       }
     default:
-      log('error', 'Unhandled time period')
+      logStack('error', 'Unhandled time period')
+      Sentry.captureException(
+        JSON.stringify({ error: 'Unhandled time period' })
+      )
       throw Error('Unhandled time period')
   }
 }
@@ -151,7 +160,7 @@ const aggregatePrices = async (
   fluidType: FluidType
 ) => {
   const tsa = [TimeStep.MONTH, TimeStep.YEAR]
-  log(
+  logStack(
     'debug',
     `Aggregation started for fluid: ${fluidType}, from ${firstDate}  `
   )
@@ -185,15 +194,16 @@ const aggregatePrices = async (
               date = date.plus({ month: 1 }).startOf('month')
             }
           } while (date < today)
-        } catch (err) {
-          log('info', `Error : ${err}`)
+        } catch (error) {
+          logStack('info', `Error : ${error}`)
+          Sentry.captureException(JSON.stringify({ error }))
         } finally {
           resolve()
         }
       })
     })
   )
-  log('debug', `Aggregation done`)
+  logStack('debug', `Aggregation done`)
 }
 
 const getDoctypeTypeByFluid = (fluidType: FluidType): string => {
@@ -206,7 +216,8 @@ const getDoctypeTypeByFluid = (fluidType: FluidType): string => {
   if (fluidType === FluidType.WATER) {
     return EGL_DAY_DOCTYPE
   }
-  log('error', 'Unkown FluidType')
+  logStack('error', 'Unkown FluidType')
+  Sentry.captureException({ error: 'Unkown FluidType Doctype' })
   throw new Error()
 }
 
@@ -217,8 +228,8 @@ const getTimeSetByFluid = (fluidType: FluidType): TimeStep[] => {
   if (fluidType === FluidType.GAS || fluidType === FluidType.WATER) {
     return [TimeStep.DAY]
   }
-
-  log('error', 'Unkown FluidType')
+  logStack('error', 'Unkown FluidType')
+  Sentry.captureException({ error: 'Unkown FluidType' })
   throw new Error()
 }
 
@@ -234,7 +245,7 @@ const applyPrices = async (client: Client, fluidType: FluidType) => {
   const prices = await fluidsPricesService.getAllPrices()
   // Prices data exsit
   if (prices.length > 0) {
-    log('debug', 'fluidPrices data found')
+    logStack('debug', 'fluidPrices data found')
     const firstMinuteData = await cdm.getFirstDataDateFromDoctypeWithPrice(
       getDoctypeTypeByFluid(fluidType)
     )
@@ -330,8 +341,9 @@ const applyPrices = async (client: Client, fluidType: FluidType) => {
                   date = date.plus({ month: 1 }).startOf('month')
                 }
               } while (date < today)
-            } catch (err) {
-              log('error', `ERROR : ${err} `)
+            } catch (error) {
+              logStack('error', `ERROR : ${error} `)
+              Sentry.captureException(JSON.stringify({ error }))
             } finally {
               resolve()
             }
@@ -341,22 +353,22 @@ const applyPrices = async (client: Client, fluidType: FluidType) => {
 
       // Call aggregation method
       await aggregatePrices(qr, cdm, firstDate, today, fluidType)
-    } else log('info', `No data found for fluid ${fluidType}`)
-  } else log('info', 'No fluidesPrices data')
+    } else logStack('info', `No data found for fluid ${fluidType}`)
+  } else logStack('info', 'No fluidesPrices data')
 }
 
 const processPrices = async ({ client }: PricesProps) => {
-  log('info', `Processing electricity data...`)
+  logStack('info', `Processing electricity data...`)
   const elec = applyPrices(client, FluidType.ELECTRICITY)
-  log('info', `Electricity data done`)
-  log('info', `Processing gas data...`)
+  logStack('info', `Electricity data done`)
+  logStack('info', `Processing gas data...`)
   const gas = applyPrices(client, FluidType.GAS)
-  log('info', `Gas data done`)
-  log('info', `Processing water data...`)
+  logStack('info', `Gas data done`)
+  logStack('info', `Processing water data...`)
   const water = applyPrices(client, FluidType.WATER)
-  log('info', `Water data done`)
+  logStack('info', `Water data done`)
   await Promise.all([elec, gas, water])
-  log('info', `processPrices done`)
+  logStack('info', `processPrices done`)
 }
 
 runService(processPrices)
diff --git a/src/targets/services/monthlyReportNotification.ts b/src/targets/services/monthlyReportNotification.ts
index cc925a0a6..33bca041b 100644
--- a/src/targets/services/monthlyReportNotification.ts
+++ b/src/targets/services/monthlyReportNotification.ts
@@ -1,3 +1,4 @@
+import * as Sentry from '@sentry/react'
 import { Client } from 'cozy-client'
 import logger from 'cozy-logger'
 import {
@@ -19,7 +20,7 @@ import { getMonthNameWithPrep } from 'utils/utils'
 import { runService } from './service'
 const monthlyReportTemplate = require('notifications/monthlyReport.hbs')
 
-const log = logger.namespace('report')
+const logStack = logger.namespace('report')
 
 interface MonthlyReportNotificationProps {
   client: Client
@@ -60,7 +61,7 @@ const getConsumptionValue = async (
  * @returns string
  */
 const buildConsumptionText = async (client: Client) => {
-  log('info', 'Building consumption text...')
+  logStack('info', 'Building consumption text...')
   const consumption = await getConsumptionValue(client, [
     FluidType.ELECTRICITY,
     FluidType.GAS,
@@ -136,7 +137,7 @@ const getMonthlyReport = async (
 ): Promise<MonthlyReport> => {
   try {
     const environmentService = new EnvironmentService()
-    log(
+    logStack(
       'info',
       environmentService.isProduction()
         ? 'Fetching data from BO prod'
@@ -153,7 +154,8 @@ const getMonthlyReport = async (
       )
     return result
   } catch (error) {
-    log('error', error)
+    logStack('error', JSON.stringify(error))
+    Sentry.captureException(JSON.stringify({ error }))
     return {
       year: parseInt(year),
       month: parseInt(month),
@@ -171,11 +173,14 @@ const getMonthlyReport = async (
 const monthlyReportNotification = async ({
   client,
 }: MonthlyReportNotificationProps) => {
-  log('info', 'Fetching user profile...')
+  logStack('info', 'Fetching user profile...')
   const upm = new ProfileService(client)
   let userProfil = await upm.getProfile()
   if (!userProfil || !userProfil.sendAnalysisNotification) {
-    log('info', 'End of process - Report Notification disabled in user profile')
+    logStack(
+      'info',
+      'End of process - Report Notification disabled in user profile'
+    )
     return
   }
 
@@ -188,7 +193,8 @@ const monthlyReportNotification = async ({
         mailToken: token,
       })
     } catch (error) {
-      log('error', 'Update mailToken user profile error : ' + error)
+      logStack('error', 'Update mailToken user profile error : ' + error)
+      Sentry.captureException(JSON.stringify({ error }))
       throw error
     }
   }
@@ -196,7 +202,7 @@ const monthlyReportNotification = async ({
   let username = ''
   let url = ''
 
-  log('info', 'Fetching data for mail...')
+  logStack('info', 'Fetching data for mail...')
   // Retrieve public name from the stack
   const settings = await client
     .getStackClient()
@@ -213,7 +219,7 @@ const monthlyReportNotification = async ({
     url = appLink
   }
 
-  log('info', 'Creation of mail...')
+  logStack('info', 'Creation of mail...')
   const mailService = new MailService()
 
   const today = DateTime.local().setZone('utc', {
@@ -302,7 +308,7 @@ const monthlyReportNotification = async ({
       },
     ],
   }
-  log('info', 'Sending mail...')
+  logStack('info', 'Sending mail...')
   mailService.SendMail(client, mailData)
 }
 
diff --git a/src/targets/vendor/assets/serviceWorker.js b/src/targets/vendor/assets/serviceWorker.js
index 15a90d79b..51dc9b97b 100644
--- a/src/targets/vendor/assets/serviceWorker.js
+++ b/src/targets/vendor/assets/serviceWorker.js
@@ -13,7 +13,11 @@ self.addEventListener('install', event => {
 
 // Listen for requests
 self.addEventListener('fetch', event => {
-  if (event.request.url.indexOf('statweb') !== -1) {
+  // Exception for Matomo & Sentry
+  if (
+    event.request.url.includes('statweb') ||
+    event.request.url.includes('grandlyon.errors')
+  ) {
     return false
   }
 
diff --git a/src/utils/logger.js b/src/utils/logger.js
index ee502e362..af75208f6 100644
--- a/src/utils/logger.js
+++ b/src/utils/logger.js
@@ -5,6 +5,6 @@ const inBrowser = typeof window !== 'undefined'
 // eslint-disable-next-line no-undef
 const minilog = (inBrowser && window.minilog) || minilog_
 
-const log = minilog('ecolyo')
+const logApp = minilog('ecolyo')
 
-export default log
+export default logApp
diff --git a/yarn.lock b/yarn.lock
index c2f66af57..063c3def2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2319,6 +2319,16 @@
     "@react-spring/core" "9.0.0-rc.3"
     "@react-spring/shared" "9.0.0-rc.3"
 
+"@sentry/browser@7.21.1":
+  version "7.21.1"
+  resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.21.1.tgz#bffa3ea19050c06400107d2297b9802f9719f98b"
+  integrity sha512-cS2Jz2+fs9+4pJqLJPtYqGyY97ywJDWAWIR1Yla3hs1QQuH6m0Nz3ojZD1gE2eKH9mHwkGbnNAh+hHcrYrfGzw==
+  dependencies:
+    "@sentry/core" "7.21.1"
+    "@sentry/types" "7.21.1"
+    "@sentry/utils" "7.21.1"
+    tslib "^1.9.3"
+
 "@sentry/browser@^6.0.1":
   version "6.19.7"
   resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.19.7.tgz#a40b6b72d911b5f1ed70ed3b4e7d4d4e625c0b5f"
@@ -2340,6 +2350,15 @@
     "@sentry/utils" "6.19.7"
     tslib "^1.9.3"
 
+"@sentry/core@7.21.1":
+  version "7.21.1"
+  resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.21.1.tgz#d0423282d90875625802dfe380f9657e9242b72b"
+  integrity sha512-Og5wEEsy24fNvT/T7IKjcV4EvVK5ryY2kxbJzKY6GU2eX+i+aBl+n/vp7U0Es351C/AlTkS+0NOUsp2TQQFxZA==
+  dependencies:
+    "@sentry/types" "7.21.1"
+    "@sentry/utils" "7.21.1"
+    tslib "^1.9.3"
+
 "@sentry/hub@6.19.7":
   version "6.19.7"
   resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.19.7.tgz#58ad7776bbd31e9596a8ec46365b45cd8b9cfd11"
@@ -2358,11 +2377,37 @@
     "@sentry/types" "6.19.7"
     tslib "^1.9.3"
 
+"@sentry/react@^7.21.1":
+  version "7.21.1"
+  resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.21.1.tgz#275e6fd46212f608f382c7dde46d21e748f93491"
+  integrity sha512-w91PIUyX07mErKgrBQA+7ID8zFKrYDUYSOrFSHufg5DdPq4EpHiNDe/Yngg3e9ELhtr1AbCnEvx9wlvqLi3nZQ==
+  dependencies:
+    "@sentry/browser" "7.21.1"
+    "@sentry/types" "7.21.1"
+    "@sentry/utils" "7.21.1"
+    hoist-non-react-statics "^3.3.2"
+    tslib "^1.9.3"
+
+"@sentry/tracing@^7.21.1":
+  version "7.21.1"
+  resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.21.1.tgz#db02643e84960f1ea14b35fe75a93fc0bbca1fcb"
+  integrity sha512-b1BTPsRaNQpohzegoz59KGuBl+To651vEq0vMS4tCzSyIdxkYso3JCrjDdEqW/2MliQYANNVrUai2bmwmU9h1g==
+  dependencies:
+    "@sentry/core" "7.21.1"
+    "@sentry/types" "7.21.1"
+    "@sentry/utils" "7.21.1"
+    tslib "^1.9.3"
+
 "@sentry/types@6.19.7":
   version "6.19.7"
   resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.19.7.tgz#c6b337912e588083fc2896eb012526cf7cfec7c7"
   integrity sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==
 
+"@sentry/types@7.21.1":
+  version "7.21.1"
+  resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.21.1.tgz#408a7b95a66ddc30c4359979594e03bee8f9fbdc"
+  integrity sha512-3/IKnd52Ol21amQvI+kz+WB76s8/LR5YvFJzMgIoI2S8d82smIr253zGijRXxHPEif8kMLX4Yt+36VzrLxg6+A==
+
 "@sentry/utils@6.19.7":
   version "6.19.7"
   resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.19.7.tgz#6edd739f8185fd71afe49cbe351c1bbf5e7b7c79"
@@ -2371,6 +2416,14 @@
     "@sentry/types" "6.19.7"
     tslib "^1.9.3"
 
+"@sentry/utils@7.21.1":
+  version "7.21.1"
+  resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.21.1.tgz#96582345178015fd32fe9159c25c44ccf2f99d2a"
+  integrity sha512-F0W0AAi8tgtTx6ApZRI2S9HbXEA9ENX1phTZgdNNWcMFm1BNbc21XEwLqwXBNjub5nlA6CE8xnjXRgdZKx4kzQ==
+  dependencies:
+    "@sentry/types" "7.21.1"
+    tslib "^1.9.3"
+
 "@simbathesailor/use-what-changed@^2.0.0":
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/@simbathesailor/use-what-changed/-/use-what-changed-2.0.0.tgz#7f82d78f92c8588b5fadd702065dde93bd781403"
-- 
GitLab