Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/tracing / src / toTracing.ts
Size: Mime:
import uuid from 'uuid'

/**
 * Trace id to pass SFO has to be in 16 digits with alpha numeric under the name
 * 'x-b3-traceid' along with 'x-b3-spanid' and this 'x-b3-traceid' will pass to
 * all the micro services and return back in response header as 'x-b3-traceid' and 'x-traceid'
 */
const fromUniqueIdentifierToTraceId = (uniqueId = uuid()) => uniqueId.replace(/-/g, '').substr(0, 16)

import { Request as ExpressRequest } from 'express'

export const TRACING_HEADERS = Object.freeze({
  openTraceId: 'x-b3-traceid',
  openTraceSpanId: 'x-b3-spanid',
  requestId: 'x-request-id',
  sessionId: 'x-sk-session-id',
})


import { isObj, isFunction } from 'exotic'

export const fromReqToTraceIdOnly = (req?: ExpressRequest) => isObj(req) === true
  ? req.get(TRACING_HEADERS.openTraceId) || req.get(TRACING_HEADERS.requestId) || req.get('openTraceId')
  : undefined

export const toTraceId = (req?: ExpressRequest): string => {
  const openTraceIdHeader = fromReqToTraceIdOnly(req)

  // @note - falsy
  if (openTraceIdHeader) {
    return openTraceIdHeader
  } else {
    return fromUniqueIdentifierToTraceId()
  }
}

export const toSpanId = (req?: ExpressRequest): number => {
  const spanIHeader = isObj(req) === true && req.get(TRACING_HEADERS.openTraceSpanId)
  const traceIdHeader = fromReqToTraceIdOnly(req)

  // exists, came from browser or ssr
  if (spanIHeader) {
    // console.info('[tracing] span id + 1')
    return +(spanIHeader as any || 0) + 1
  } else if (traceIdHeader) {
    // console.info('[tracing] span id + 2')
    // trace id, but no span id, then nginx created it and span  is 2
    return 2
  } else {
    // console.info('[tracing] span id = 1')
    // otherwise, it's 1, which means like, browser, or graphql playground
    return 1
  }
}

export const fromReqToCookie = (request: ExpressRequest) => {
  if (isObj(request) === false) {
    return undefined
  } else if (isObj(request.headers) === true && isFunction(request.headers.get) === true) {
    return (request.headers as any).get('Cookie')
  } else if (isFunction(request.get) === true) {
    return request.get('Cookie')
  } else if (isObj(request.headers) === true && request.headers.Cookie !== undefined) {
    return request.headers.Cookie
  } else {
    return undefined
  }
}

export const fromReqToSessionId = (req: ExpressRequest) => {
  const cookie = fromReqToCookie(req)
  const sessionIdHeader = isObj(req) && req.get(TRACING_HEADERS.sessionId)
  if (sessionIdHeader) {
    return sessionIdHeader
  } else {
    return cookie
  }
}

import { LoggingMetaTracingType } from './typings'

export const toTracing = (req?: ExpressRequest): LoggingMetaTracingType => {
  const openTraceIdHeader = toTraceId(req)
  const spanIdHeader = toSpanId(req)
  const sessionIdHeader = fromReqToSessionId(req)

  return {
    // not enumerable
    get openTraceSpanId() {
      return spanIdHeader
    },
    get openTraceId() {
      return openTraceIdHeader
    },
    get sessionId() {
      return sessionIdHeader
    },

    // same
    [TRACING_HEADERS.requestId]: openTraceIdHeader,
    [TRACING_HEADERS.openTraceId]: openTraceIdHeader,
    [TRACING_HEADERS.openTraceSpanId]: spanIdHeader,
    [TRACING_HEADERS.sessionId]: sessionIdHeader,
  } as LoggingMetaTracingType
}