UNPKG

@inst/vscode-bin-darwin

Version:

BINARY ONLY - VSCode binary deployment for macOS

249 lines (248 loc) 11.6 kB
///<reference path="..\typings\globals\node\index.d.ts" /> "use strict"; var url = require("url"); var os = require("os"); var Config = require("./Config"); var Context = require("./Context"); var ExceptionTracking = require("../AutoCollection/Exceptions"); var ContractsModule = require("../Library/Contracts"); var Channel = require("./Channel"); var ServerRequestTracking = require("../AutoCollection/ServerRequests"); var ClientRequestTracking = require("../AutoCollection/ClientRequests"); var Sender = require("./Sender"); var Util = require("./Util"); var Logging = require("./Logging"); var Client = (function () { /** * Constructs a new client of the client * @param iKey the instrumentation key to use (read from environment variable if not specified) */ function Client(iKey) { this._sequencePrefix = Util.int32ArrayToBase64([ Util.random32(), Util.random32(), Util.random32(), Util.random32() ]) + ":"; this._sequenceNumber = 0; this._telemetryProcessors = []; var config = new Config(iKey); this.config = config; this.context = new Context(); this.commonProperties = {}; var sender = new Sender(function () { return config.endpointUrl; }); this.channel = new Channel(function () { return config.disableAppInsights; }, function () { return config.maxBatchSize; }, function () { return config.maxBatchIntervalMs; }, sender); } /** * Log a user action or other occurrence. * @param name A string to identify this event in the portal. * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. * @param measurements map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. */ Client.prototype.trackEvent = function (name, properties, measurements) { var event = new ContractsModule.Contracts.EventData(); event.name = name; event.properties = properties; event.measurements = measurements; var data = new ContractsModule.Contracts.Data(); data.baseType = "EventData"; data.baseData = event; this.track(data); }; /** * Log a trace message * @param message A string to identify this event in the portal. * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. */ Client.prototype.trackTrace = function (message, severityLevel, properties) { var trace = new ContractsModule.Contracts.MessageData(); trace.message = message; trace.properties = properties; if (!isNaN(severityLevel)) { trace.severityLevel = severityLevel; } else { trace.severityLevel = ContractsModule.Contracts.SeverityLevel.Information; } var data = new ContractsModule.Contracts.Data(); data.baseType = "MessageData"; data.baseData = trace; this.track(data); }; /** * Log an exception you have caught. * @param exception An Error from a catch clause, or the string error message. * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. * @param measurements map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. */ Client.prototype.trackException = function (exception, properties, measurements) { if (!Util.isError(exception)) { exception = new Error(exception); } var data = ExceptionTracking.getExceptionData(exception, true, properties, measurements); this.track(data); }; /** * * 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 name A string that identifies the metric. * @param value The value of the metric * @param count the number of samples used to get this value * @param min the min sample for this set * @param max the max sample for this set * @param stdDev the standard deviation of the set */ Client.prototype.trackMetric = function (name, value, count, min, max, stdDev, properties) { var metrics = new ContractsModule.Contracts.MetricData(); // todo: enable client-batching of these metrics.metrics = []; var metric = new ContractsModule.Contracts.DataPoint(); metric.count = !isNaN(count) ? count : 1; metric.kind = ContractsModule.Contracts.DataPointType.Aggregation; metric.max = !isNaN(max) ? max : value; metric.min = !isNaN(min) ? min : value; metric.name = name; metric.stdDev = !isNaN(stdDev) ? stdDev : 0; metric.value = value; metrics.metrics.push(metric); metrics.properties = properties; var data = new ContractsModule.Contracts.Data(); data.baseType = "MetricData"; data.baseData = metrics; this.track(data); }; Client.prototype.trackRequestSync = function (request, response, ellapsedMilliseconds, properties, error) { ServerRequestTracking.trackRequestSync(this, request, response, ellapsedMilliseconds, properties, error); }; Client.prototype.trackRequest = function (request, response, properties) { ServerRequestTracking.trackRequest(this, request, response, properties); }; Client.prototype.trackDependencyRequest = function (requestOptions, request, properties) { ClientRequestTracking.trackRequest(this, requestOptions, request, properties); }; Client.prototype.trackDependency = function (name, commandName, elapsedTimeMs, success, dependencyTypeName, properties, async, target) { if (properties === void 0) { properties = {}; } if (async === void 0) { async = false; } if (target === void 0) { target = null; } if (!target && commandName) { target = url.parse(commandName).host; } var remoteDependency = new ContractsModule.Contracts.RemoteDependencyData(); remoteDependency.name = name; remoteDependency.data = commandName; remoteDependency.target = target; remoteDependency.duration = Util.msToTimeSpan(elapsedTimeMs); remoteDependency.success = success; remoteDependency.type = dependencyTypeName; remoteDependency.properties = properties; var data = new ContractsModule.Contracts.Data(); data.baseType = "RemoteDependencyData"; data.baseData = remoteDependency; this.track(data); }; /** * Immediately send all queued telemetry. */ Client.prototype.sendPendingData = function (callback) { this.channel.triggerSend(false, callback); }; Client.prototype.getEnvelope = function (data, tagOverrides) { if (data && data.baseData) { data.baseData.ver = 2; // if no properties are specified just add the common ones if (!data.baseData.properties) { data.baseData.properties = this.commonProperties; } else { // otherwise, check each of the common ones for (var name in this.commonProperties) { // only override if the property `name` has not been set on this item if (!data.baseData.properties[name]) { data.baseData.properties[name] = this.commonProperties[name]; } } } } // sanitize properties data.baseData.properties = Util.validateStringMap(data.baseData.properties); var iKey = this.config.instrumentationKey; var envelope = new ContractsModule.Contracts.Envelope(); envelope.data = data; envelope.appVer = this.context.tags[this.context.keys.applicationVersion]; envelope.iKey = iKey; // this is kind of a hack, but the envelope name is always the same as the data name sans the chars "data" envelope.name = "Microsoft.ApplicationInsights." + iKey.replace(/-/g, "") + "." + data.baseType.substr(0, data.baseType.length - 4); envelope.os = os && os.type(); envelope.osVer = os && os.release(); envelope.seq = this._sequencePrefix + (this._sequenceNumber++).toString(); envelope.tags = tagOverrides || this.context.tags; envelope.time = (new Date()).toISOString(); envelope.ver = 1; return envelope; }; /** * Generic track method for all telemetry types * @param data the telemetry to send * @param tagOverrides the context tags to use for this telemetry which overwrite default context values */ Client.prototype.track = function (data, tagOverrides, contextObjects) { var envelope = this.getEnvelope(data, tagOverrides); var accepted = this.runTelemetryProcessors(envelope, contextObjects); if (accepted) { this.channel.send(envelope); } }; /** * 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 */ Client.prototype.addTelemetryProcessor = function (telemetryProcessor) { this._telemetryProcessors.push(telemetryProcessor); }; /* * Removes all telemetry processors */ Client.prototype.clearTelemetryProcessors = function () { this._telemetryProcessors = []; }; /** * Parse an envelope sequence. */ Client.parseSeq = function (seq) { var array = seq.split(":"); return [array[0], parseInt(array[1])]; }; Client.prototype.runTelemetryProcessors = function (envelope, contextObjects) { var accepted = true; var telemetryProcessorsCount = this._telemetryProcessors.length; if (telemetryProcessorsCount === 0) { return accepted; } for (var i = 0; i < telemetryProcessorsCount; ++i) { try { var processor = this._telemetryProcessors[i]; if (processor) { if (processor.apply(null, [envelope, contextObjects]) === false) { accepted = false; break; } } } catch (error) { accepted = false; Logging.warn("One of telemetry processors failed, telemetry item will not be sent.", error, envelope); } } return accepted; }; return Client; }()); module.exports = Client;