UNPKG

dd-trace

Version:

Datadog APM tracing client for JavaScript

96 lines (83 loc) 2.92 kB
'use strict' const rfdc = require('rfdc')({ proto: false, circles: false }) const { PAYLOAD_TAG_REQUEST_PREFIX, PAYLOAD_TAG_RESPONSE_PREFIX } = require('../constants') const jsonpath = require('jsonpath-plus').JSONPath const { tagsFromObject } = require('./tagging') /** * Given an identified value, attempt to parse it as JSON if relevant * * @param {any} value * @returns {any} the parsed object if parsing was successful, the input if not */ function maybeJSONParseValue (value) { if (typeof value !== 'string' || value[0] !== '{') { return value } try { return JSON.parse(value) } catch { return value } } /** * Apply expansion to all expansion JSONPath queries * * @param {Object} object * @param {[String]} expansionRules list of JSONPath queries */ function expand (object, expansionRules) { for (const rule of expansionRules) { jsonpath(rule, object, (value, _type, desc) => { desc.parent[desc.parentProperty] = maybeJSONParseValue(value) }) } } /** * Apply redaction to all redaction JSONPath queries * * @param {Object} object * @param {[String]} redactionRules */ function redact (object, redactionRules) { for (const rule of redactionRules) { jsonpath(rule, object, (_value, _type, desc) => { desc.parent[desc.parentProperty] = 'redacted' }) } } /** * Generate a map of tag names to tag values by performing: * 1. Attempting to parse identified fields as JSON * 2. Redacting fields identified by redaction rules * 3. Flattening the resulting object, producing as many tag name/tag value pairs * as there are leaf values in the object * This function performs side-effects on a _copy_ of the input object. * * @param {Object} config sdk configuration for the service * @param {[String]} config.expand expansion rules for the service * @param {[String]} config.request redaction rules for the request * @param {[String]} config.response redaction rules for the response * @param {Object} object the input object to generate tags from * @param {Object} opts tag generation options * @param {String} opts.prefix prefix for all generated tags * @param {number} opts.maxDepth maximum depth to traverse the object * @returns */ function computeTags (config, object, opts) { const payload = rfdc(object) const redactionRules = opts.prefix === PAYLOAD_TAG_REQUEST_PREFIX ? config.request : config.response const expansionRules = config.expand expand(payload, expansionRules) redact(payload, redactionRules) return tagsFromObject(payload, opts) } function tagsFromRequest (config, object, opts) { return computeTags(config, object, { ...opts, prefix: PAYLOAD_TAG_REQUEST_PREFIX }) } function tagsFromResponse (config, object, opts) { return computeTags(config, object, { ...opts, prefix: PAYLOAD_TAG_RESPONSE_PREFIX }) } module.exports = { computeTags, tagsFromRequest, tagsFromResponse }