applicationinsights
Version:
Microsoft Application Insights module for Node.js
286 lines • 12.6 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TelemetryClient = void 0;
const api_1 = require("@opentelemetry/api");
const api_logs_1 = require("@opentelemetry/api-logs");
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
const context_1 = require("./context");
const util_1 = require("../shared/util");
const Config = require("./shim-config");
const attributeSpanProcessor_1 = require("../shared/util/attributeSpanProcessor");
const attributeLogRecordProcessor_1 = require("../shared/util/attributeLogRecordProcessor");
const logsApi_1 = require("./logsApi");
const main_1 = require("../main");
const types_1 = require("./types");
/**
* Application Insights telemetry client provides interface to track telemetry items, register telemetry initializers and
* and manually trigger immediate sending (flushing)
*/
class TelemetryClient {
/**
* Constructs a new instance of TelemetryClient
* @param setupString the Connection String or Instrumentation Key to use (read from environment variable if not specified)
*/
constructor(input) {
this._configWarnings = [];
const config = new Config(input, this._configWarnings);
this.config = config;
this.commonProperties = {};
this.context = new context_1.Context();
this._isInitialized = false;
}
initialize() {
this._isInitialized = true;
// Parse shim config to Azure Monitor options
this._options = this.config.parseConfig();
(0, main_1.useAzureMonitor)(this._options);
try {
// LoggerProvider would be initialized when client is instantiated
// Get Logger from global provider
this._logApi = new logsApi_1.LogApi(api_logs_1.logs.getLogger("ApplicationInsightsLogger"));
this._attributeSpanProcessor = new attributeSpanProcessor_1.AttributeSpanProcessor(Object.assign(Object.assign({}, this.context.tags), this.commonProperties));
api_1.trace.getTracerProvider().getDelegate().addSpanProcessor(this._attributeSpanProcessor);
this._attributeLogProcessor = new attributeLogRecordProcessor_1.AttributeLogProcessor(Object.assign(Object.assign({}, this.context.tags), this.commonProperties));
api_logs_1.logs.getLoggerProvider().addLogRecordProcessor(this._attributeLogProcessor);
// Warn if any config warnings were generated during parsing
for (let i = 0; i < this._configWarnings.length; i++) {
api_1.diag.warn(this._configWarnings[i]);
}
}
catch (error) {
api_1.diag.error(`Failed to initialize TelemetryClient ${error}`);
}
}
/**
* Log information about availability of an application
* @param telemetry Object encapsulating tracking options
*/
trackAvailability(telemetry) {
if (!this._isInitialized) {
this.initialize();
}
this._logApi.trackAvailability(telemetry);
}
/**
* Log a page view
* @param telemetry Object encapsulating tracking options
*/
trackPageView(telemetry) {
if (!this._isInitialized) {
this.initialize();
}
this._logApi.trackPageView(telemetry);
}
/**
* Log a trace message
* @param telemetry Object encapsulating tracking options
*/
trackTrace(telemetry) {
if (!this._isInitialized) {
this.initialize();
}
this._logApi.trackTrace(telemetry);
}
/**
* Log an exception
* @param telemetry Object encapsulating tracking options
*/
trackException(telemetry) {
if (!this._isInitialized) {
this.initialize();
}
this._logApi.trackException(telemetry);
}
/**
* Log a user action or other occurrence.
* @param telemetry Object encapsulating tracking options
*/
trackEvent(telemetry) {
if (!this._isInitialized) {
this.initialize();
}
this._logApi.trackEvent(telemetry);
}
/**
* Log a numeric value that is not associated with a specific event. Typically used to send regular reports of performance indicators.
* To send a single measurement, use just the first two parameters. If you take measurements very frequently, you can reduce the
* telemetry bandwidth by aggregating multiple measurements and sending the resulting average at intervals.
* @param telemetry Object encapsulating tracking options
*/
trackMetric(telemetry) {
if (!this._isInitialized) {
this.initialize();
}
// Create custom metric
try {
const meter = api_1.metrics.getMeterProvider().getMeter("ApplicationInsightsMetrics");
const histogram = meter.createHistogram(telemetry.name);
histogram.record(telemetry.value, Object.assign(Object.assign(Object.assign({}, telemetry.properties), this.commonProperties), this.context.tags));
}
catch (error) {
api_1.diag.error(`Failed to record metric: ${error}`);
}
}
/**
* Log a request. Note that the default client will attempt to collect HTTP requests automatically so only use this for requests
* that aren't automatically captured or if you've disabled automatic request collection.
*
* @param telemetry Object encapsulating tracking options
*/
trackRequest(telemetry) {
if (!this._isInitialized) {
this.initialize();
}
const startTime = telemetry.time || new Date();
const endTime = startTime.getTime() + telemetry.duration;
const ctx = api_1.context.active();
const attributes = Object.assign({}, telemetry.properties);
attributes[semantic_conventions_1.SEMATTRS_HTTP_METHOD] = "HTTP";
attributes[semantic_conventions_1.SEMATTRS_HTTP_URL] = telemetry.url;
attributes[semantic_conventions_1.SEMATTRS_HTTP_STATUS_CODE] = telemetry.resultCode;
const options = {
kind: api_1.SpanKind.SERVER,
attributes: attributes,
startTime: startTime,
};
const span = api_1.trace.getTracer("ApplicationInsightsTracer")
.startSpan(telemetry.name, options, ctx);
span.setStatus({
code: telemetry.success ? api_1.SpanStatusCode.OK : api_1.SpanStatusCode.ERROR,
});
span.end(endTime);
}
/**
* Log a dependency. Note that the default client will attempt to collect dependencies automatically so only use this for dependencies
* that aren't automatically captured or if you've disabled automatic dependency collection.
*
* @param telemetry Object encapsulating tracking option
* */
trackDependency(telemetry) {
if (!this._isInitialized) {
this.initialize();
}
const startTime = telemetry.time || new Date();
const endTime = startTime.getTime() + telemetry.duration;
if (telemetry && !telemetry.target && telemetry.data) {
// url.parse().host returns null for non-urls,
// making this essentially a no-op in those cases
// If this logic is moved, update jsdoc in DependencyTelemetry.target
// url.parse() is deprecated, update to use WHATWG URL API instead
try {
telemetry.target = new URL(telemetry.data).host;
}
catch (error) {
// set target as null to be compliant with previous behavior
telemetry.target = null;
api_1.diag.warn(this.constructor.name, "Failed to create URL.", error);
}
}
const ctx = api_1.context.active();
const attributes = Object.assign({}, telemetry.properties);
if (telemetry.dependencyTypeName) {
if (telemetry.dependencyTypeName.toLowerCase().indexOf("http") > -1) {
attributes[semantic_conventions_1.SEMATTRS_HTTP_METHOD] = "HTTP";
attributes[semantic_conventions_1.SEMATTRS_HTTP_URL] = telemetry.data;
attributes[semantic_conventions_1.SEMATTRS_HTTP_STATUS_CODE] = telemetry.resultCode;
}
else if (util_1.Util.getInstance().isDbDependency(telemetry.dependencyTypeName)) {
attributes[semantic_conventions_1.SEMATTRS_DB_SYSTEM] = telemetry.dependencyTypeName;
attributes[semantic_conventions_1.SEMATTRS_DB_STATEMENT] = telemetry.data;
}
else if (telemetry.dependencyTypeName.toLowerCase().indexOf("rpc") > -1) {
attributes[semantic_conventions_1.SEMATTRS_RPC_SYSTEM] = telemetry.dependencyTypeName;
attributes[semantic_conventions_1.SEMATTRS_RPC_METHOD] = telemetry.data;
attributes[semantic_conventions_1.SEMATTRS_RPC_GRPC_STATUS_CODE] = telemetry.resultCode;
}
}
if (telemetry.target) {
attributes[semantic_conventions_1.SEMATTRS_PEER_SERVICE] = telemetry.target;
}
const options = {
kind: api_1.SpanKind.CLIENT,
attributes: attributes,
startTime: startTime,
};
const span = api_1.trace.getTracer("ApplicationInsightsTracer")
.startSpan(telemetry.name, options, ctx);
span.setStatus({
code: telemetry.success ? api_1.SpanStatusCode.OK : api_1.SpanStatusCode.ERROR,
});
span.end(endTime);
}
/**
* Generic track method for all telemetry types
* @param data the telemetry to send
* @param telemetryType specify the type of telemetry you are tracking from the list of Contracts.DataTypes
*/
track(telemetry, telemetryType) {
throw new Error(`Not implemented. Please use the specific track method for the type of telemetry you are tracking. ${types_1.UNSUPPORTED_MSG}`);
}
/**
* Automatically populate telemetry properties like RoleName when running in Azure
*
* @param value if true properties will be populated
*/
setAutoPopulateAzureProperties() {
// NO-OP
}
/**
* Get Authorization handler
*/
getAuthorizationHandler(config) {
api_1.diag.warn(`getAuthorizationHandler is not supported in ApplicationInsights any longer. ${types_1.UNSUPPORTED_MSG}`);
}
/*
* Get Statsbeat instance
*/
getStatsbeat() {
return null;
}
setUseDiskRetryCaching(value, resendInterval, maxBytesOnDisk) {
throw new Error("Not implemented");
}
/**
* Adds telemetry processor to the collection. Telemetry processors will be called one by one
* before telemetry item is pushed for sending and in the order they were added.
*
* @param telemetryProcessor function, takes Envelope, and optional context object and returns boolean
*/
addTelemetryProcessor(telemetryProcessor) {
api_1.diag.warn(`addTelemetryProcessor is not supported in ApplicationInsights any longer. ${types_1.UNSUPPORTED_MSG}`);
}
/*
* Removes all telemetry processors
*/
clearTelemetryProcessors() {
throw new Error("Not implemented");
}
trackNodeHttpRequestSync(telemetry) {
api_1.diag.warn("trackNodeHttpRequestSync is not implemented and is a no-op. Please use trackRequest instead.");
}
trackNodeHttpRequest(telemetry) {
api_1.diag.warn("trackNodeHttpRequest is not implemented and is a no-op. Please use trackRequest instead.");
}
trackNodeHttpDependency(telemetry) {
api_1.diag.warn("trackNodeHttpDependency is not implemented and is a no-op. Please use trackDependency instead.");
}
/**
* Immediately send all queued telemetry.
*/
async flush() {
return (0, main_1.flushAzureMonitor)();
}
/**
* Shutdown client
*/
async shutdown() {
return (0, main_1.shutdownAzureMonitor)();
}
pushWarningToLog(warning) {
this._configWarnings.push(warning);
}
}
exports.TelemetryClient = TelemetryClient;
//# sourceMappingURL=telemetryClient.js.map
;