diff --git a/CHANGELOG.md b/CHANGELOG.md index 7be466da..8f00ad98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Added + +- Logging functionality to track domains missing `publisherId` configuration in VTEXAdsProvider + ## [2.145.0] - 2025-12-04 ### Added diff --git a/react/components/VTEXAdsProvider.tsx b/react/components/VTEXAdsProvider.tsx index 5ce8b69e..ef2d843a 100644 --- a/react/components/VTEXAdsProvider.tsx +++ b/react/components/VTEXAdsProvider.tsx @@ -10,6 +10,7 @@ import { getUserData, SessionResponse, } from '../hooks/getUserData' +import { sendErrorLog } from '../utils/sendErrorLog' interface VTEXAdsProviderProps { children?: React.ReactNode @@ -93,6 +94,11 @@ export const VTEXAdsProvider = ({ children }: VTEXAdsProviderProps) => { } if (!publisherId) { + sendErrorLog({ + message: 'PublisherId não encontrado no VTEXAdsProvider', + body: `PublisherId ausente para a conta: ${account}`, + searchIndex: 'ads_pai', + }).catch(() => {}) return children } diff --git a/react/utils/sendErrorLog.ts b/react/utils/sendErrorLog.ts new file mode 100644 index 00000000..daa2a7a0 --- /dev/null +++ b/react/utils/sendErrorLog.ts @@ -0,0 +1,138 @@ +interface SendLogOptions { + message: string + searchIndex?: string + environment?: string + body?: string +} + +export async function sendErrorLog( + options: SendLogOptions +): Promise { + if (!options?.searchIndex) { + return null + } + + const { message, searchIndex, environment = 'production', body } = options + + const severityText = 'ERROR' + const severityNumber = 17 + const timeUnixNano = (Date.now() * 1000000).toString() + const observedTimeUnixNano = timeUnixNano + + const traceId = [...crypto.getRandomValues(new Uint8Array(16))] + .map(b => b.toString(16).padStart(2, '0')) + .join('') + + const spanId = [...crypto.getRandomValues(new Uint8Array(8))] + .map(b => b.toString(16).padStart(2, '0')) + .join('') + + let hostname = '' + let path = '' + let url = '' + + if (typeof window !== 'undefined' && window.location) { + hostname = window.location.hostname + path = window.location.pathname + url = window.location.href + } + + const payload = { + resourceLogs: [ + { + resource: { + attributes: [ + { + key: '_msg', + value: { + stringValue: message ?? 'Log message', + }, + }, + { + key: 'hostname', + value: { + stringValue: hostname, + }, + }, + { + key: 'path', + value: { + stringValue: path, + }, + }, + { + key: 'environment', + value: { + stringValue: environment, + }, + }, + { + key: 'browserInfos', + value: { + stringValue: JSON.stringify({ + url, + hostname, + path, + }), + }, + }, + { + key: 'searchParams', + value: { + stringValue: + typeof window !== 'undefined' && window.location + ? window.location.search + : '', + }, + }, + ], + }, + scopeLogs: [ + { + scope: {}, + logRecords: [ + { + timeUnixNano, + observedTimeUnixNano, + severityText, + severityNumber, + attributes: [ + { + key: 'vtex.search_index', + value: { + stringValue: searchIndex, + }, + }, + { + key: 'body', + value: { + stringValue: body ?? message ?? 'Log message', + }, + }, + ], + traceId, + spanId, + }, + ], + }, + ], + }, + ], + } + + try { + const response = await fetch( + 'https://stable.vtexobservability.com/v1/logs', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(payload), + } + ) + return response + } catch (error) { + console.error('Erro ao enviar log:', error) + } +}