UNPKG

@azure/monitor-opentelemetry

Version:
249 lines 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getRequestDimensions = getRequestDimensions; exports.getDependencyDimensions = getDependencyDimensions; exports.getExceptionDimensions = getExceptionDimensions; exports.getTraceDimensions = getTraceDimensions; exports.getBaseDimensions = getBaseDimensions; exports.getDependencyTarget = getDependencyTarget; exports.isSqlDB = isSqlDB; exports.isExceptionTelemetry = isExceptionTelemetry; exports.isTraceTelemetry = isTraceTelemetry; exports.isSyntheticLoad = isSyntheticLoad; exports.convertDimensions = convertDimensions; exports.getPhysicalMemory = getPhysicalMemory; exports.getProcessorTimeNormalized = getProcessorTimeNormalized; exports.getProcessorTime = getProcessorTime; exports.getCloudRole = getCloudRole; exports.getCloudRoleInstance = getCloudRoleInstance; const tslib_1 = require("tslib"); const api_1 = require("@opentelemetry/api"); const semantic_conventions_1 = require("@opentelemetry/semantic-conventions"); const types_js_1 = require("./types.js"); const utils_js_1 = require("./quickpulse/utils.js"); const logger_js_1 = require("../shared/logging/logger.js"); const os = tslib_1.__importStar(require("node:os")); const process = tslib_1.__importStar(require("node:process")); function getRequestDimensions(span) { const dimensions = getBaseDimensions(span.resource); dimensions.metricId = types_js_1.StandardMetricIds.REQUEST_DURATION; const statusCode = String((0, utils_js_1.getHttpStatusCode)(span.attributes)); dimensions.requestResultCode = statusCode; // OTel treats 4xx request responses as UNSET SpanStatusCode, but we should count them as failed dimensions.requestSuccess = span.status.code !== api_1.SpanStatusCode.ERROR && (Number(statusCode) || 0) < 400 ? "True" : "False"; if (isSyntheticLoad(span)) { dimensions.operationSynthetic = "True"; } return convertDimensions(dimensions); } function getDependencyDimensions(span) { const dimensions = getBaseDimensions(span.resource); dimensions.metricId = types_js_1.StandardMetricIds.DEPENDENCIES_DURATION; const statusCode = String((0, utils_js_1.getHttpStatusCode)(span.attributes)); dimensions.dependencyTarget = getDependencyTarget(span.attributes); dimensions.dependencyResultCode = statusCode; dimensions.dependencyType = "http"; dimensions.dependencySuccess = span.status.code !== api_1.SpanStatusCode.ERROR ? "True" : "False"; if (isSyntheticLoad(span)) { dimensions.operationSynthetic = "True"; } return convertDimensions(dimensions); } function getExceptionDimensions(resource) { const dimensions = getBaseDimensions(resource); dimensions.metricId = types_js_1.StandardMetricIds.EXCEPTIONS_COUNT; return dimensions; } function getTraceDimensions(resource) { const dimensions = getBaseDimensions(resource); dimensions.metricId = types_js_1.StandardMetricIds.TRACES_COUNT; return dimensions; } function getBaseDimensions(resource) { const dimensions = {}; dimensions.IsAutocollected = "True"; if (resource) { dimensions.cloudRoleName = getCloudRole(resource); dimensions.cloudRoleInstance = getCloudRoleInstance(resource); } return dimensions; } // Get metric dependency target, avoiding high cardinality. function getDependencyTarget(attributes) { if (!attributes) { return ""; } const peerService = attributes[semantic_conventions_1.SEMATTRS_PEER_SERVICE]; const hostPort = (0, utils_js_1.getNetHostPort)(attributes); const netPeerName = (0, utils_js_1.getNetPeerName)(attributes); if (peerService) { return String(peerService); } else if (hostPort && netPeerName) { return `${netPeerName}:${hostPort}`; } else if (netPeerName) { return String(netPeerName); } return ""; } function isSqlDB(dbSystem) { return (dbSystem === semantic_conventions_1.DBSYSTEMVALUES_DB2 || dbSystem === semantic_conventions_1.DBSYSTEMVALUES_DERBY || dbSystem === semantic_conventions_1.DBSYSTEMVALUES_MARIADB || dbSystem === semantic_conventions_1.DBSYSTEMVALUES_MSSQL || dbSystem === semantic_conventions_1.DBSYSTEMVALUES_ORACLE || dbSystem === semantic_conventions_1.DBSYSTEMVALUES_SQLITE || dbSystem === semantic_conventions_1.DBSYSTEMVALUES_OTHER_SQL || dbSystem === semantic_conventions_1.DBSYSTEMVALUES_HSQLDB || dbSystem === semantic_conventions_1.DBSYSTEMVALUES_H2); } function isExceptionTelemetry(logRecord) { const baseType = logRecord.attributes["_MS.baseType"]; // If Application Insights Legacy logs if (baseType && baseType === "ExceptionData") { return true; } else if (logRecord.attributes[semantic_conventions_1.SEMATTRS_EXCEPTION_MESSAGE] || logRecord.attributes[semantic_conventions_1.SEMATTRS_EXCEPTION_TYPE]) { return true; } return false; } function isTraceTelemetry(logRecord) { const baseType = logRecord.attributes["_MS.baseType"]; // If Application Insights Legacy logs if (baseType && baseType === "MessageData") { return true; } else if (!logRecord.attributes[semantic_conventions_1.SEMATTRS_EXCEPTION_MESSAGE] && !logRecord.attributes[semantic_conventions_1.SEMATTRS_EXCEPTION_TYPE]) { return true; } return false; } function isSyntheticLoad(record) { // eslint-disable-next-line @typescript-eslint/no-base-to-string const userAgent = String((0, utils_js_1.getUserAgent)(record.attributes)); return userAgent !== null && userAgent.includes("AlwaysOn") ? true : false; } function convertDimensions(dimensions) { const convertedDimensions = {}; for (const dim in dimensions) { convertedDimensions[types_js_1.StandardMetricPropertyNames[dim]] = dimensions[dim]; } return convertedDimensions; } // to get physical memory bytes function getPhysicalMemory() { if (process === null || process === void 0 ? void 0 : process.memoryUsage) { return process.memoryUsage.rss(); } else { logger_js_1.Logger.getInstance().debug("process.memoryUsage is not available"); return 0; } } // This function can get the normalized cpu, but it assumes that after this function is called, // that the process.hrtime.bigint() & process.cpuUsage() are called/stored to be used as the // parameters for the next call. function getProcessorTimeNormalized(lastHrTime, lastCpuUsage) { let numCpus = os.cpus().length; const usageDif = process.cpuUsage(lastCpuUsage); const elapsedTimeNs = process.hrtime.bigint() - lastHrTime; const usageDifMs = (usageDif.user + usageDif.system) / 1000.0; const elapsedTimeMs = elapsedTimeNs === BigInt(0) ? 1 : Number(elapsedTimeNs) / 1000000.0; // just for division safety, don't know a case in which this would actually happen numCpus = numCpus === 0 ? 1 : numCpus; return (usageDifMs / elapsedTimeMs / numCpus) * 100; } // This function can get the cpu %, but it assumes that after this function is called, // that the process.hrtime.bigint() & process.cpuUsage() are called/stored to be used as the // parameters for the next call. function getProcessorTime(lastHrTime, lastCpuUsage) { if (process === null || process === void 0 ? void 0 : process.cpuUsage) { const usageDif = process.cpuUsage(lastCpuUsage); const elapsedTimeNs = process.hrtime.bigint() - lastHrTime; const usageDifMs = (usageDif.user + usageDif.system) / 1000.0; const elapsedTimeMs = elapsedTimeNs === BigInt(0) ? 1 : Number(elapsedTimeNs) / 1000000.0; return (usageDifMs / elapsedTimeMs) * 100; } else { logger_js_1.Logger.getInstance().debug("process.cpuUsage is not available"); return 0; } } /** * Gets the cloud role name based on the resource attributes */ function getCloudRole(resource) { let cloudRole = ""; // Service attributes const serviceName = resource.attributes[semantic_conventions_1.SEMRESATTRS_SERVICE_NAME]; const serviceNamespace = resource.attributes[semantic_conventions_1.SEMRESATTRS_SERVICE_NAMESPACE]; if (serviceName) { // Custom Service name provided by customer is highest precedence if (!String(serviceName).startsWith("unknown_service")) { if (serviceNamespace) { return `${serviceNamespace}.${serviceName}`; } else { return String(serviceName); } } else { // Service attributes will be only used if K8S attributes are not present if (serviceNamespace) { cloudRole = `${serviceNamespace}.${serviceName}`; } else { cloudRole = String(serviceName); } } } // Kubernetes attributes should take precedence const kubernetesDeploymentName = resource.attributes[semantic_conventions_1.SEMRESATTRS_K8S_DEPLOYMENT_NAME]; if (kubernetesDeploymentName) { return String(kubernetesDeploymentName); } const kuberneteReplicasetName = resource.attributes[semantic_conventions_1.SEMRESATTRS_K8S_REPLICASET_NAME]; if (kuberneteReplicasetName) { return String(kuberneteReplicasetName); } const kubernetesStatefulSetName = resource.attributes[semantic_conventions_1.SEMRESATTRS_K8S_STATEFULSET_NAME]; if (kubernetesStatefulSetName) { return String(kubernetesStatefulSetName); } const kubernetesJobName = resource.attributes[semantic_conventions_1.SEMRESATTRS_K8S_JOB_NAME]; if (kubernetesJobName) { return String(kubernetesJobName); } const kubernetesCronjobName = resource.attributes[semantic_conventions_1.SEMRESATTRS_K8S_CRONJOB_NAME]; if (kubernetesCronjobName) { return String(kubernetesCronjobName); } const kubernetesDaemonsetName = resource.attributes[semantic_conventions_1.SEMRESATTRS_K8S_DAEMONSET_NAME]; if (kubernetesDaemonsetName) { return String(kubernetesDaemonsetName); } return cloudRole; } /** * Gets the cloud role instance based on the resource attributes */ function getCloudRoleInstance(resource) { // Kubernetes attributes should take precedence const kubernetesPodName = resource.attributes[semantic_conventions_1.SEMRESATTRS_K8S_POD_NAME]; if (kubernetesPodName) { return String(kubernetesPodName); } // Service attributes const serviceInstanceId = resource.attributes[semantic_conventions_1.SEMRESATTRS_SERVICE_INSTANCE_ID]; if (serviceInstanceId) { return String(serviceInstanceId); } // Default return os && os.hostname(); } //# sourceMappingURL=utils.js.map