@grafana/faro-transport-otlp-http
Version:
Faro transport which converts the Faro data model to the Otlp data model.
176 lines • 10.9 kB
JavaScript
import { ATTR_EXCEPTION_MESSAGE, ATTR_EXCEPTION_TYPE, ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, ATTR_TELEMETRY_SDK_LANGUAGE, ATTR_TELEMETRY_SDK_NAME, ATTR_TELEMETRY_SDK_VERSION, ATTR_URL_FULL, ATTR_USER_AGENT_ORIGINAL, TELEMETRY_SDK_LANGUAGE_VALUE_WEBJS, } from '@opentelemetry/semantic-conventions';
import { LogLevel, TransportItemType, VERSION } from '@grafana/faro-core';
import { ATTR_BROWSER_BRANDS, ATTR_BROWSER_LANGUAGE, ATTR_BROWSER_MOBILE, ATTR_BROWSER_PLATFORM, ATTR_DEPLOYMENT_ENVIRONMENT_NAME, ATTR_SERVICE_NAMESPACE, ATTR_SESSION_ID, ATTR_USER_ATTRIBUTES, ATTR_USER_EMAIL, ATTR_USER_FULL_NAME, ATTR_USER_HASH, ATTR_USER_ID, ATTR_USER_NAME, ATTR_USER_ROLES, } from '../../semconv';
import { isAttribute, toAttribute, toAttributeValue } from '../attribute';
export function getLogTransforms(internalLogger, customOtlpTransform) {
function toResourceLog(transportItem) {
const resource = toResource(transportItem);
return {
resource,
scopeLogs: [toScopeLog(transportItem)],
};
}
function toScopeLog(transportItem) {
return {
scope: {
name: '@grafana/faro-web-sdk',
version: VERSION,
},
logRecords: [toLogRecord(transportItem)],
};
}
function toLogRecord(transportItem) {
const { type } = transportItem;
switch (type) {
case TransportItemType.LOG:
return toLogLogRecord(transportItem);
case TransportItemType.EXCEPTION:
return toErrorLogRecord(transportItem);
case TransportItemType.EVENT:
return toEventLogRecord(transportItem);
case TransportItemType.MEASUREMENT:
return toMeasurementLogRecord(transportItem);
default:
internalLogger === null || internalLogger === void 0 ? void 0 : internalLogger.error(`Unknown TransportItemType: ${type}`);
return {};
}
}
function toLogLogRecord(transportItem) {
var _a, _b;
const { meta, payload } = transportItem;
const timeUnixNano = toTimeUnixNano(payload.timestamp);
const body = toAttributeValue(payload.message);
function getSeverityProperties(logLevel) {
switch (logLevel) {
case LogLevel.TRACE:
return { severityNumber: 1, severityText: 'TRACE' };
case LogLevel.DEBUG:
return { severityNumber: 5, severityText: 'DEBUG' };
case LogLevel.INFO:
return { severityNumber: 9, severityText: 'INFO' };
case LogLevel.LOG:
return { severityNumber: 10, severityText: 'INFO2' };
case LogLevel.WARN:
return { severityNumber: 13, severityText: 'WARN' };
case LogLevel.ERROR:
return { severityNumber: 17, severityText: 'ERROR' };
}
}
return Object.assign(Object.assign({ timeUnixNano }, getSeverityProperties(payload.level)), { body, attributes: [...getCommonLogAttributes(meta), toAttribute('faro.log.context', payload.context)].filter(isAttribute), traceId: (_a = payload.trace) === null || _a === void 0 ? void 0 : _a.trace_id, spanId: (_b = payload.trace) === null || _b === void 0 ? void 0 : _b.span_id });
}
function toEventLogRecord(transportItem) {
var _a, _b;
const { meta, payload } = transportItem;
const timeUnixNano = toTimeUnixNano(payload.timestamp);
const body = toAttributeValue(payload.name);
return {
timeUnixNano,
body,
attributes: [
...getCommonLogAttributes(meta),
toAttribute('event.name', payload.name), // This is a semantic attribute. But event.name constant is currently missing in sematic-conventions npm package
toAttribute('event.domain', payload.domain), // This is a semantic attribute. But event.domain constant is currently missing in sematic-conventions npm package
toAttribute('event.attributes', payload.attributes),
].filter(isAttribute),
traceId: (_a = payload.trace) === null || _a === void 0 ? void 0 : _a.trace_id,
spanId: (_b = payload.trace) === null || _b === void 0 ? void 0 : _b.span_id,
};
}
function toErrorLogRecord(transportItem) {
var _a, _b;
const { meta, payload } = transportItem;
const timeUnixNano = toTimeUnixNano(payload.timestamp);
const body = getCustomLogBody(transportItem, customOtlpTransform === null || customOtlpTransform === void 0 ? void 0 : customOtlpTransform.createErrorLogBody);
return Object.assign(Object.assign({ timeUnixNano }, (body ? { body } : {})), { attributes: [
...getCommonLogAttributes(meta),
toAttribute(ATTR_EXCEPTION_TYPE, payload.type),
toAttribute(ATTR_EXCEPTION_MESSAGE, payload.value),
// toAttribute(SemanticAttributes.EXCEPTION_STACKTRACE, undefined),
toAttribute('faro.error.stacktrace', payload.stacktrace),
toAttribute('faro.error.context', payload.context),
].filter(isAttribute), traceId: (_a = payload.trace) === null || _a === void 0 ? void 0 : _a.trace_id, spanId: (_b = payload.trace) === null || _b === void 0 ? void 0 : _b.span_id });
}
function toMeasurementLogRecord(transportItem) {
var _a, _b;
const { meta, payload } = transportItem;
const timeUnixNano = toTimeUnixNano(payload.timestamp);
const [measurementName, measurementValue] = Object.entries(payload.values).flat();
const body = getCustomLogBody(transportItem, customOtlpTransform === null || customOtlpTransform === void 0 ? void 0 : customOtlpTransform.createMeasurementLogBody);
return Object.assign(Object.assign({ timeUnixNano }, (body ? { body } : {})), { attributes: [
...getCommonLogAttributes(meta),
toAttribute('measurement.type', payload.type),
toAttribute('measurement.name', measurementName),
toAttribute('measurement.value', measurementValue),
toAttribute('faro.measurement.context', payload.context),
].filter(isAttribute), traceId: (_a = payload.trace) === null || _a === void 0 ? void 0 : _a.trace_id, spanId: (_b = payload.trace) === null || _b === void 0 ? void 0 : _b.span_id });
}
function getCommonLogAttributes(meta) {
const { view, page, session, user } = meta;
return [
toAttribute('view.name', view === null || view === void 0 ? void 0 : view.name),
toAttribute(ATTR_URL_FULL, page === null || page === void 0 ? void 0 : page.url),
toAttribute('page.id', page === null || page === void 0 ? void 0 : page.id),
toAttribute('page.attributes', page === null || page === void 0 ? void 0 : page.attributes),
toAttribute(ATTR_SESSION_ID, session === null || session === void 0 ? void 0 : session.id),
toAttribute('session.attributes', session === null || session === void 0 ? void 0 : session.attributes),
toAttribute(ATTR_USER_ID, user === null || user === void 0 ? void 0 : user.id),
toAttribute(ATTR_USER_NAME, user === null || user === void 0 ? void 0 : user.username),
toAttribute(ATTR_USER_EMAIL, user === null || user === void 0 ? void 0 : user.email),
toAttribute(ATTR_USER_FULL_NAME, user === null || user === void 0 ? void 0 : user.fullName),
toAttribute(ATTR_USER_ROLES, user === null || user === void 0 ? void 0 : user.roles),
toAttribute(ATTR_USER_HASH, user === null || user === void 0 ? void 0 : user.hash),
toAttribute(ATTR_USER_ATTRIBUTES, user === null || user === void 0 ? void 0 : user.attributes),
].filter(isAttribute);
}
function toTimeUnixNano(timestamp) {
return Date.parse(timestamp) * 1e6;
}
return {
toResourceLog,
toScopeLog,
toLogRecord,
};
}
export function getTraceTransforms(_internalLogger) {
function toResourceSpan(transportItem) {
var _a, _b;
const resource = toResource(transportItem);
const scopeSpans = (_b = (_a = transportItem.payload.resourceSpans) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.scopeSpans;
return {
resource,
scopeSpans: scopeSpans !== null && scopeSpans !== void 0 ? scopeSpans : [],
};
}
return {
toResourceSpan,
};
}
function toResource(transportItem) {
const { browser, sdk, app } = transportItem.meta;
return {
attributes: [
toAttribute(ATTR_BROWSER_MOBILE, browser === null || browser === void 0 ? void 0 : browser.mobile),
toAttribute(ATTR_USER_AGENT_ORIGINAL, browser === null || browser === void 0 ? void 0 : browser.userAgent),
toAttribute(ATTR_BROWSER_LANGUAGE, browser === null || browser === void 0 ? void 0 : browser.language),
toAttribute(ATTR_BROWSER_BRANDS, browser === null || browser === void 0 ? void 0 : browser.brands),
toAttribute(ATTR_BROWSER_PLATFORM, browser === null || browser === void 0 ? void 0 : browser.os),
toAttribute('browser.name', browser === null || browser === void 0 ? void 0 : browser.name),
toAttribute('browser.version', browser === null || browser === void 0 ? void 0 : browser.version),
toAttribute('browser.screen_width', browser === null || browser === void 0 ? void 0 : browser.viewportWidth),
toAttribute('browser.screen_height', browser === null || browser === void 0 ? void 0 : browser.viewportHeight),
toAttribute(ATTR_TELEMETRY_SDK_NAME, sdk === null || sdk === void 0 ? void 0 : sdk.name),
toAttribute(ATTR_TELEMETRY_SDK_VERSION, sdk === null || sdk === void 0 ? void 0 : sdk.version),
Boolean(sdk) ? toAttribute(ATTR_TELEMETRY_SDK_LANGUAGE, TELEMETRY_SDK_LANGUAGE_VALUE_WEBJS) : undefined,
toAttribute(ATTR_SERVICE_NAME, app === null || app === void 0 ? void 0 : app.name),
toAttribute(ATTR_SERVICE_VERSION, app === null || app === void 0 ? void 0 : app.version),
toAttribute(ATTR_SERVICE_NAMESPACE, app === null || app === void 0 ? void 0 : app.namespace),
toAttribute(ATTR_DEPLOYMENT_ENVIRONMENT_NAME, app === null || app === void 0 ? void 0 : app.environment),
].filter(isAttribute),
};
}
function getCustomLogBody(transportItem, createCustomLogBody) {
return typeof createCustomLogBody === 'function'
? toAttributeValue(createCustomLogBody(transportItem))
: undefined;
}
//# sourceMappingURL=transform.js.map