UNPKG

@instana/core

Version:
84 lines (76 loc) 2.48 kB
/* * (c) Copyright IBM Corp. 2024 */ 'use strict'; /** * @typedef {Object<string, string>} FieldMapping * @typedef {Object<string, FieldMapping>} FieldMappings */ /** * Field mappings for different span types. * * This FieldMappings defines how internal span fields are mapped to backend fields * for various span types (e.g., dynamodb, redis). * * As new span types needs to add, simply add their respective mappings * following the same format (e.g., 'internal-field': 'backend-field'). * * @type {FieldMappings} */ const fieldMappings = { dynamodb: { /// Maps internal field 'operation' to backend field 'op' operation: 'op' }, redis: { operation: 'command' // connection: connection # already normalized }, kafka: { operation: 'access', endpoints: 'service' }, http: { operation: 'method', endpoints: 'url', connection: 'host' } }; /** * Transforms span data fields to match the backend format. * * @param {import('../../core').InstanaBaseSpan} span * @returns {import('../../core').InstanaBaseSpan} The transformed span. */ module.exports.transform = span => { // In most cases, `span.n` matches the key inside `span.data` (e.g., `span.n === 'redis'` → `span.data.redis`). // However, there are exceptions where `span.n` represents a higher-level concept or protocol, // while `span.data` contains one or more lower-level components. // For example: // For `span.n === 'node.http.server'` or 'node.http.client', the actual data is under `span.data.http`. // In the case of `span.n === 'graphql.server'`, the span includes both GraphQL-specific and HTTP data, // so `span.data` may contain both `graphql` and `http` keys simultaneously. Object.keys(span.data).forEach(key => { const mappings = fieldMappings[key]; if (!mappings) return; applyMappings(span.data[key], mappings); }); return span; }; /** * Applies field mappings to a specific data section. * * @param {Record<string, any>} dataSection - The span data object to transform. * @param {FieldMapping} mappings - The field mapping rules to apply. */ function applyMappings(dataSection, mappings) { Object.keys(dataSection).forEach(internalField => { if (internalField in mappings) { const backendField = mappings[internalField]; if (backendField) { dataSection[backendField] = dataSection[internalField]; } delete dataSection[internalField]; } }); }