diff --git a/.env.dist b/.env.dist index cc7ed71256..524d5f1eff 100644 --- a/.env.dist +++ b/.env.dist @@ -47,6 +47,8 @@ COOPCYCLE_JWT_TTL=3600 COOPCYCLE_OSRM_HOST=osrm:5000 COOPCYCLE_DEMO=0 COOPCYCLE_SENTRY_DSN=https://@sentry.io/******** +COOPCYCLE_DATADOG_CLIENT_TOKEN= +COOPCYCLE_DATADOG_APPLICATION_ID= APNS_PRIVATE_KEY_FILE=/dev/null APNS_CERTIFICATE_PASS_PHRASE= APNS_KEY_ID= diff --git a/app/config/config.yml b/app/config/config.yml index c34d713372..8a593522d3 100755 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -239,7 +239,10 @@ twig: - '@VichUploader/Form/fields.html.twig' globals: is_demo: "%is_demo%" + instance_name: "%env(COOPCYCLE_APP_NAME)%" sentry_public_dsn: "%sentry_public_dsn%" + datadog_client_token: "%env(COOPCYCLE_DATADOG_CLIENT_TOKEN)%" + datadog_application_id: "%env(COOPCYCLE_DATADOG_APPLICATION_ID)%" country_iso: "%country_iso%" region_iso: "%region_iso%" cart_provider: '@AppBundle\Service\CartProviderService' diff --git a/js/app/components/order/timeRange/TimeRangeChangedModal.js b/js/app/components/order/timeRange/TimeRangeChangedModal.js index 2f7170aa5f..1c7b5c0b40 100644 --- a/js/app/components/order/timeRange/TimeRangeChangedModal.js +++ b/js/app/components/order/timeRange/TimeRangeChangedModal.js @@ -24,6 +24,7 @@ import TimeSlotPicker from '../TimeSlotPicker' import DatePicker from '../DatePicker' import Button from '../../core/Button' import Alert from '../../core/Alert' +import { useDatadog } from '../../../hooks/useDatadog' import { useMatomo } from '../../../hooks/useMatomo' function useChooseRestaurant() { @@ -183,12 +184,14 @@ export default function TimeRangeChangedModal() { const isModalOpen = useSelector(selectIsTimeRangeChangedModalOpen) const { t } = useTranslation() + const { logger } = useDatadog() const { trackEvent } = useMatomo() return ( { + logger.info('TimeRangeChangedModal opened') trackEvent('Checkout', 'openTimeRangeChangedModal') }} contentLabel={t('CART_CHANGE_TIME_MODAL_LABEL')} diff --git a/js/app/datadog.js b/js/app/datadog.js new file mode 100644 index 0000000000..f46ad0b2b6 --- /dev/null +++ b/js/app/datadog.js @@ -0,0 +1,95 @@ +import { datadogLogs } from '@datadog/browser-logs' +import { datadogRum } from '@datadog/browser-rum' + +const el = document.getElementById('datadog') +const datadogEnabled = Boolean(el) + +if (datadogEnabled) { + datadogLogs.init({ + clientToken: el.dataset.clientToken, + site: 'datadoghq.com', + service: el.dataset.service, + forwardErrorsToLogs: true, + // Only tracked sessions send logs; from 0 to 100 + sessionSampleRate: 100, + telemetrySampleRate: 0, + }) + + datadogRum.init({ + applicationId: el.dataset.applicationId, + clientToken: el.dataset.clientToken, + site: 'datadoghq.com', + service: el.dataset.service, + // Specify a version number to identify the deployed version of your application in Datadog + // version: '1.0.0', + // 'Browser RUM' session sample rate; from 0 to 100 + sessionSampleRate: 1, + // 'Browser RUM & Session Replay' sample rate (% from sessions tracked by RUM/sessionSampleRate); from 0 to 100 + sessionReplaySampleRate: 10, + telemetrySampleRate: 0, + trackUserInteractions: true, + trackResources: true, + trackLongTasks: true, + defaultPrivacyLevel: 'mask-user-input', + }) +} + +const DatadogLogger = { + /** + * Send a log with debug level. + * @param message: The message to send. + * @param context: The additional context to send. + */ + debug(message, context) { + if (!datadogEnabled) { + console.debug(message, context) + return + } + + datadogLogs.logger.debug(message, context) + }, + + /** + * Send a log with info level. + * @param message: The message to send. + * @param context: The additional context to send. + */ + info(message, context) { + if (!datadogEnabled) { + console.info(message, context) + return + } + + datadogLogs.logger.info(message, context) + }, + + /** + * Send a log with warn level. + * @param message: The message to send. + * @param context: The additional context to send. + */ + warn(message, context) { + if (!datadogEnabled) { + console.warn(message, context) + return + } + + datadogLogs.logger.warn(message, context) + }, + + /** + * Send a log with error level. + * @param message: The message to send. + * @param context: The additional context to send. + */ + error(message, context) { + if (!datadogEnabled) { + console.error(message, context) + return + } + + datadogLogs.logger.error(message, context) + }, +} + +window.DatadogLogger = DatadogLogger diff --git a/js/app/hooks/useDatadog.js b/js/app/hooks/useDatadog.js new file mode 100644 index 0000000000..0e8e11f3c3 --- /dev/null +++ b/js/app/hooks/useDatadog.js @@ -0,0 +1,5 @@ +export const useDatadog = () => { + return { + logger: window.DatadogLogger, + } +} diff --git a/package-lock.json b/package-lock.json index b2708454e3..1d45d82663 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,8 @@ "@cubejs-client/core": "^0.34.0", "@cubejs-client/playground": "^0.34.0", "@cubejs-client/react": "^0.34.0", + "@datadog/browser-logs": "^5.29.1", + "@datadog/browser-rum": "^5.29.1", "@hotwired/stimulus": "^3.2.2", "@mapbox/polyline": "^1.1.0", "@nivo/core": "^0.87.0", @@ -2397,6 +2399,56 @@ "ms": "^2.1.1" } }, + "node_modules/@datadog/browser-core": { + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/@datadog/browser-core/-/browser-core-5.29.1.tgz", + "integrity": "sha512-7GLo2A94XBgnIEc9wQe6aT69e5+s15hg2p+24gczYvnr9xVXV2dLzJkhMMM3iwJTErJuOpC8A1e8s/evgj63KA==", + "dev": true + }, + "node_modules/@datadog/browser-logs": { + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/@datadog/browser-logs/-/browser-logs-5.29.1.tgz", + "integrity": "sha512-HsWjF8gn3IJnjOsWl9SRHAFvY5JwfN5p9+MqS+ISHSCbx73WqewGz7VFi8EuPorQqzXPl0xljxKRwl695uNSYw==", + "dev": true, + "dependencies": { + "@datadog/browser-core": "5.29.1" + }, + "peerDependencies": { + "@datadog/browser-rum": "5.29.1" + }, + "peerDependenciesMeta": { + "@datadog/browser-rum": { + "optional": true + } + } + }, + "node_modules/@datadog/browser-rum": { + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/@datadog/browser-rum/-/browser-rum-5.29.1.tgz", + "integrity": "sha512-tqEUaClFNv2Ka/e34pSZ7E9rROz9aK9Y88hCaCRKFpd1DanaNRREtpmmDUqPR6v8Hry48NQ0m9l3PcbjEuVS9g==", + "dev": true, + "dependencies": { + "@datadog/browser-core": "5.29.1", + "@datadog/browser-rum-core": "5.29.1" + }, + "peerDependencies": { + "@datadog/browser-logs": "5.29.1" + }, + "peerDependenciesMeta": { + "@datadog/browser-logs": { + "optional": true + } + } + }, + "node_modules/@datadog/browser-rum-core": { + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/@datadog/browser-rum-core/-/browser-rum-core-5.29.1.tgz", + "integrity": "sha512-AOK52YpK6Hf+Lj3wINDk3LHNEzTO/g6zshnkdWE/3iJBDzmPGFWzcm/Y+uf55VFeU3V1GWujV5YFPuLnCsQwkA==", + "dev": true, + "dependencies": { + "@datadog/browser-core": "5.29.1" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -36109,6 +36161,40 @@ } } }, + "@datadog/browser-core": { + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/@datadog/browser-core/-/browser-core-5.29.1.tgz", + "integrity": "sha512-7GLo2A94XBgnIEc9wQe6aT69e5+s15hg2p+24gczYvnr9xVXV2dLzJkhMMM3iwJTErJuOpC8A1e8s/evgj63KA==", + "dev": true + }, + "@datadog/browser-logs": { + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/@datadog/browser-logs/-/browser-logs-5.29.1.tgz", + "integrity": "sha512-HsWjF8gn3IJnjOsWl9SRHAFvY5JwfN5p9+MqS+ISHSCbx73WqewGz7VFi8EuPorQqzXPl0xljxKRwl695uNSYw==", + "dev": true, + "requires": { + "@datadog/browser-core": "5.29.1" + } + }, + "@datadog/browser-rum": { + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/@datadog/browser-rum/-/browser-rum-5.29.1.tgz", + "integrity": "sha512-tqEUaClFNv2Ka/e34pSZ7E9rROz9aK9Y88hCaCRKFpd1DanaNRREtpmmDUqPR6v8Hry48NQ0m9l3PcbjEuVS9g==", + "dev": true, + "requires": { + "@datadog/browser-core": "5.29.1", + "@datadog/browser-rum-core": "5.29.1" + } + }, + "@datadog/browser-rum-core": { + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/@datadog/browser-rum-core/-/browser-rum-core-5.29.1.tgz", + "integrity": "sha512-AOK52YpK6Hf+Lj3wINDk3LHNEzTO/g6zshnkdWE/3iJBDzmPGFWzcm/Y+uf55VFeU3V1GWujV5YFPuLnCsQwkA==", + "dev": true, + "requires": { + "@datadog/browser-core": "5.29.1" + } + }, "@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", diff --git a/package.json b/package.json index ee992ac5d7..0add81695b 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "@cubejs-client/core": "^0.34.0", "@cubejs-client/playground": "^0.34.0", "@cubejs-client/react": "^0.34.0", + "@datadog/browser-logs": "^5.29.1", + "@datadog/browser-rum": "^5.29.1", "@hotwired/stimulus": "^3.2.2", "@mapbox/polyline": "^1.1.0", "@nivo/core": "^0.87.0", diff --git a/templates/_partials/monitoring.html.twig b/templates/_partials/monitoring.html.twig new file mode 100644 index 0000000000..94ef0ade55 --- /dev/null +++ b/templates/_partials/monitoring.html.twig @@ -0,0 +1,15 @@ +{% if app.environment == "prod" %} +
+ {{ encore_entry_script_tags('sentry') }} +{% endif %} + +{% if app.environment == "prod" %} +
+{% endif %} + +{# inject on all environments (on dev: logs to console) #} +{{ encore_entry_script_tags('datadog') }} diff --git a/templates/base.html.twig b/templates/base.html.twig index bf87c22e33..73365b6669 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -89,10 +89,8 @@ {% include "footer.html.twig" %} {% endif %} {% endblock %} - {% if app.environment == "prod" %} -
- {{ encore_entry_script_tags('sentry') }} - {% endif %} + + {% include '_partials/monitoring.html.twig' %}
diff --git a/templates/delivery/tracking.html.twig b/templates/delivery/tracking.html.twig index d5321cdc1d..89d4528599 100644 --- a/templates/delivery/tracking.html.twig +++ b/templates/delivery/tracking.html.twig @@ -44,10 +44,7 @@
- {% if app.environment == "prod" %} -
- {{ encore_entry_script_tags('sentry') }} - {% endif %} + {% include '_partials/monitoring.html.twig' %} diff --git a/templates/error.html.twig b/templates/error.html.twig index 1dbb9b9dc5..f3247f4610 100644 --- a/templates/error.html.twig +++ b/templates/error.html.twig @@ -14,6 +14,7 @@

{{ ('error.' ~ exception.statusCode)|trans }}

{{ 'error.return_to_homepage'|trans }} + {% include '_partials/monitoring.html.twig' %} {% include "_partials/analytics.html.twig" %} diff --git a/templates/maintenance.html.twig b/templates/maintenance.html.twig index d58aa00606..fa677b6407 100644 --- a/templates/maintenance.html.twig +++ b/templates/maintenance.html.twig @@ -19,6 +19,7 @@ {% endif %} + {% include '_partials/monitoring.html.twig' %} {% include "_partials/analytics.html.twig" %} diff --git a/webpack.config.js b/webpack.config.js index ee567df371..5e3b4891d0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -27,6 +27,7 @@ Encore .addEntry('common', './js/app/common.js') .addEntry('customize-form', './js/app/customize/form.js') .addEntry('dashboard', './js/app/dashboard/index.js') + .addEntry('datadog', './js/app/datadog.js') .addEntry('delivery-form', './js/app/delivery/form.js') .addEntry('delivery-homepage', './js/app/delivery/homepage.js') .addEntry('delivery-list', './js/app/delivery/list.js')