All files / app/src/shared/helpers sentry.helpers.ts

26.25% Statements 21/80
71.42% Branches 5/7
25% Functions 1/4
26.25% Lines 21/80

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 1131x               1x   1x                 1x                                 1x   1x 1x 1x 1x   1x   1x 1x 1x 1x             1x                                                                         1x 72x 72x   72x                           72x 72x  
import { BASE_URL, NODE_ENV } from '../config'
import { isProdEnv } from '../config'
import * as Sentry from '@sentry/nextjs'
import { ulid } from 'ulid'
import { AxiosRequestConfig } from 'axios'
import { getActiveSpan, getDynamicSamplingContextFromSpan, getRootSpan, spanToTraceHeader } from '@sentry/core'
import { dynamicSamplingContextToSentryBaggageHeader } from '@sentry/utils'
 
export const FAKE_BASE_URL = 'https://api.tmk.webant.ru'
 
export function formatBreadcrumbsToFakeDomainInProd(breadcrumb: Sentry.Breadcrumb): Sentry.Breadcrumb {
  if (isProdEnv && breadcrumb.category === 'xhr' && breadcrumb?.data?.url) {
    const splittedUrl = breadcrumb.data.url.split(BASE_URL)
    breadcrumb.data.url = FAKE_BASE_URL + splittedUrl[1]
    return breadcrumb
  }
  return breadcrumb
}
 
export function getSentryEnvironment(): string {
  switch (NODE_ENV) {
    case 'test':
      return 'test'
    case 'local':
      return 'local'
    case 'development':
      return 'dev'
    case 'production':
      return 'prod'
  }
  return 'prod'
}
 
//нужно добавить ссылки для двух доменов, поэтому проходим два раза
//пока не изсправится восприятие запросов в сентри
//добавлять нужные и заблокированные префиксы в массивы networkDetailAllowUrlsPrexixes и networkDetailDenyUrlsPrexixes
const networkDetailAllowUrlsPrefixes = ['']
 
export const networkDetailAllowUrls = [
  ...networkDetailAllowUrlsPrefixes.map(urlPrefix => BASE_URL + urlPrefix),
  ...networkDetailAllowUrlsPrefixes.map(urlPrefix => FAKE_BASE_URL + urlPrefix),
]
 
const networkDetailDenyUrlsPrefixes = ['/health']
 
export const networkDetailDenyUrls = [
  ...networkDetailDenyUrlsPrefixes.map(urlPrefix => BASE_URL + urlPrefix),
  ...networkDetailDenyUrlsPrefixes.map(urlPrefix => FAKE_BASE_URL + urlPrefix),
]
 
export type SentryTraceHeaders = {
  'Sentry-Trace': string
  Baggage: string
}
 
export function generateSentryTraceHeaders(config: AxiosRequestConfig): SentryTraceHeaders {
  const sentryTraceIdUid = ulid()
  // Создаем объект события, представляющий транзакцию
  //Здесь пока больше информации, чем надо, если пригодиться
  const transaction = {
    type: 'transaction',
    op: 'http.server',
    name: 'Request',
    startTimestamp: Date.now(),
    tags: {
      'request.path': config.url,
    },
    contexts: {
      trace: {
        data: sentryTraceIdUid,
      },
    },
    data: {
      baggage: {
        //TODO получить почту пользователя
        // user: config.auth?.username,
        date: Date.now(),
        url: config.url,
      },
    },
  }
  // Генерируем заголовки sentry-trace и baggage из объекта транзакции
  const sentryTraceHeader = `trace-id=${transaction.contexts.trace.data}`
  const baggageHeader = Object.entries(transaction.data.baggage)
    .map(([key, value]) => `${key}=${value}`)
    .join(',')
  return {
    'Sentry-Trace': sentryTraceHeader,
    Baggage: baggageHeader,
  }
}
 
export const getTraceAndBaggage = (): SentryTraceHeaders | null => {
  const span = getActiveSpan()
  const rootSpan = span && getRootSpan(span)
 
  if (rootSpan) {
    const dynamicSamplingContext = getDynamicSamplingContextFromSpan(rootSpan)
 
    const sentryBaggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext)
 
    if (!sentryBaggage) {
      return null
    }
    return {
      Baggage: sentryBaggage,
      'Sentry-Trace': spanToTraceHeader(span),
    }
  }
 
  return null
}