applicationinsights
Advanced tools
Comparing version 0.15.2 to 0.15.3
@@ -39,2 +39,5 @@ var AutoCollectConsole = require("./AutoCollection/Console"); | ||
} | ||
if (ApplicationInsights.client && ApplicationInsights.client.channel) { | ||
ApplicationInsights.client.channel.setOfflineMode(ApplicationInsights._isOfflineMode); | ||
} | ||
return ApplicationInsights; | ||
@@ -108,2 +111,14 @@ }; | ||
/** | ||
* Enable or disable offline mode to cache events when client is offline (disabled by default) | ||
* @param value if true events that occured while client is offline will be cahced on disk | ||
* @returns {ApplicationInsights} this class | ||
*/ | ||
ApplicationInsights.setOfflineMode = function (value) { | ||
ApplicationInsights._isOfflineMode = value; | ||
if (ApplicationInsights.client && ApplicationInsights.client.channel) { | ||
ApplicationInsights.client.channel.setOfflineMode(value); | ||
} | ||
return ApplicationInsights; | ||
}; | ||
/** | ||
* Enables verbose debug logging | ||
@@ -120,2 +135,3 @@ * @returns {ApplicationInsights} this class | ||
ApplicationInsights._isRequests = true; | ||
ApplicationInsights._isOfflineMode = false; | ||
ApplicationInsights._isStarted = false; | ||
@@ -122,0 +138,0 @@ return ApplicationInsights; |
@@ -48,3 +48,3 @@ ///<reference path="..\Declarations\node\node.d.ts" /> | ||
exception.properties = properties; | ||
exception.severityLevel = 3 /* Error */; | ||
exception.severityLevel = ContractsModule.Contracts.SeverityLevel.Error; | ||
exception.properties = properties; | ||
@@ -51,0 +51,0 @@ exception.exceptions = []; |
@@ -93,24 +93,25 @@ ///<reference path="..\Declarations\node\node.d.ts" /> | ||
var perfmetric = new ContractsModule.Contracts.PerformanceCounterData(); | ||
// semantic descriptions of these can be found here: https://support.microsoft.com/en-us/kb/815159/ | ||
switch (counterType) { | ||
case 0 /* ProcessorTime */: | ||
case PerfCounterType.ProcessorTime: | ||
perfmetric.categoryName = "Process"; | ||
perfmetric.counterName = "% Processor Time"; | ||
break; | ||
case 1 /* AvailableMemory */: | ||
case PerfCounterType.AvailableMemory: | ||
perfmetric.categoryName = "Memory"; | ||
perfmetric.counterName = "Available Bytes"; | ||
break; | ||
case 2 /* RequestsPerSec */: | ||
case PerfCounterType.RequestsPerSec: | ||
perfmetric.categoryName = "ASP.NET Applications"; | ||
perfmetric.counterName = "Requests/Sec"; | ||
break; | ||
case 3 /* PrivateBytes */: | ||
case PerfCounterType.PrivateBytes: | ||
perfmetric.categoryName = "Process"; | ||
perfmetric.counterName = "Private Bytes"; | ||
break; | ||
case 4 /* RequestExecutionTime */: | ||
case PerfCounterType.RequestExecutionTime: | ||
perfmetric.categoryName = "ASP.NET Applications"; | ||
perfmetric.counterName = "Request Execution Time"; | ||
break; | ||
case 5 /* PercentProcessorTime */: | ||
case PerfCounterType.PercentProcessorTime: | ||
perfmetric.categoryName = "Processor"; | ||
@@ -121,3 +122,3 @@ perfmetric.counterName = "% Processor Time"; | ||
perfmetric.count = 1; | ||
perfmetric.kind = 1 /* Aggregation */; | ||
perfmetric.kind = ContractsModule.Contracts.DataPointType.Aggregation; | ||
perfmetric.max = value; | ||
@@ -176,4 +177,4 @@ perfmetric.min = value; | ||
// todo: remove this legacy counter once the UI updates (~june 2015) | ||
this._trackLegacyPerformance(0 /* ProcessorTime */, totalUser / combinedTotal); | ||
this._trackLegacyPerformance(5 /* PercentProcessorTime */, (combinedTotal - totalIdle) / combinedTotal); | ||
this._trackLegacyPerformance(PerfCounterType.ProcessorTime, totalUser / combinedTotal); | ||
this._trackLegacyPerformance(PerfCounterType.PercentProcessorTime, (combinedTotal - totalIdle) / combinedTotal); | ||
} | ||
@@ -194,4 +195,4 @@ this._lastCpus = cpus; | ||
// todo: remove this legacy counter once the UI updates (~june 2015) | ||
this._trackLegacyPerformance(1 /* AvailableMemory */, freeMem); | ||
this._trackLegacyPerformance(3 /* PrivateBytes */, usedMem); | ||
this._trackLegacyPerformance(PerfCounterType.AvailableMemory, freeMem); | ||
this._trackLegacyPerformance(PerfCounterType.PrivateBytes, usedMem); | ||
}; | ||
@@ -219,4 +220,4 @@ AutoCollectPerformance.prototype._trackNetwork = function () { | ||
// todo: remove this legacy counter once the UI updates (~june 2015) | ||
this._trackLegacyPerformance(2 /* RequestsPerSec */, requestsPerSec); | ||
this._trackLegacyPerformance(4 /* RequestExecutionTime */, AutoCollectPerformance._lastRequestExecutionTime); | ||
this._trackLegacyPerformance(PerfCounterType.RequestsPerSec, requestsPerSec); | ||
this._trackLegacyPerformance(PerfCounterType.RequestExecutionTime, AutoCollectPerformance._lastRequestExecutionTime); | ||
} | ||
@@ -223,0 +224,0 @@ this._lastRequests = requests; |
///<reference path="..\Declarations\node\node.d.ts" /> | ||
var http = require("http"); | ||
var url = require("url"); | ||
var ContractsModule = require("../Library/Contracts"); | ||
var Logging = require("../Library/Logging"); | ||
var Util = require("../Library/Util"); | ||
var RequestDataHelper = require("./RequestDataHelper"); | ||
var AutoCollectRequests = (function () { | ||
@@ -85,82 +83,2 @@ function AutoCollectRequests(client) { | ||
})(); | ||
/** | ||
* Helper class to read data from the requst/response objects and convert them into the telemetry contract | ||
*/ | ||
var RequestDataHelper = (function () { | ||
function RequestDataHelper(request) { | ||
if (request) { | ||
this.method = request.method; | ||
this.url = request.url; | ||
this.startTime = +new Date(); | ||
this.rawHeaders = request.headers || request.rawHeaders; | ||
this.socketRemoteAddress = request.socket && request.socket.remoteAddress; | ||
this.userAgent = request.headers && request.headers["user-agent"]; | ||
if (request.connection) { | ||
this.connectionRemoteAddress = request.connection.remoteAddress; | ||
this.legacySocketRemoteAddress = request.connection["socket"] && request.connection["socket"].remoteAddress; | ||
} | ||
} | ||
} | ||
RequestDataHelper.prototype.onResponse = function (response, errorProperties) { | ||
this.endTime = +new Date; | ||
this.statusCode = response.statusCode; | ||
this.errorProperties = errorProperties; | ||
}; | ||
RequestDataHelper.prototype.getRequestData = function () { | ||
var duration = this.endTime - this.startTime; | ||
var requestData = new ContractsModule.Contracts.RequestData(); | ||
requestData.httpMethod = this.method; | ||
requestData.id = Util.newGuid(); | ||
requestData.name = this.method + " " + url.parse(this.url).pathname; | ||
requestData.startTime = (new Date(this.startTime)).toISOString(); | ||
requestData.url = this.url; | ||
requestData.duration = Util.msToTimeSpan(duration); | ||
requestData.responseCode = this.statusCode.toString(); | ||
requestData.success = this._isSuccess(this.statusCode); | ||
requestData.properties = this.errorProperties; | ||
var data = new ContractsModule.Contracts.Data(); | ||
data.baseType = "Microsoft.ApplicationInsights.RequestData"; | ||
data.baseData = requestData; | ||
return data; | ||
}; | ||
RequestDataHelper.prototype.getRequestTags = function (tags) { | ||
// create a copy of the context for requests since client info will be used here | ||
var newTags = {}; | ||
for (var key in tags) { | ||
newTags[key] = tags[key]; | ||
} | ||
newTags[RequestDataHelper.keys.locationIp] = this._getIp(); | ||
newTags[RequestDataHelper.keys.sessionId] = this._getSessionId(); | ||
newTags[RequestDataHelper.keys.userAgent] = this.userAgent; | ||
return newTags; | ||
}; | ||
RequestDataHelper.prototype._isSuccess = function (statusCode) { | ||
return (statusCode < 400) && !this.errorProperties; // todo: this could probably be improved | ||
}; | ||
RequestDataHelper.prototype._getIp = function () { | ||
// regex to match ipv4 without port | ||
// Note: including the port would cause the payload to be rejected by the data collector | ||
var ipMatch = /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/; | ||
var check = function (str) { | ||
var results = ipMatch.exec(str); | ||
if (results) { | ||
return results[0]; | ||
} | ||
}; | ||
var ip = check(this.rawHeaders["x-forwarded-for"]) || check(this.rawHeaders["x-client-ip"]) || check(this.rawHeaders["x-real-ip"]) || check(this.connectionRemoteAddress) || check(this.socketRemoteAddress) || check(this.legacySocketRemoteAddress); | ||
// node v12 returns this if the address is "localhost" | ||
if (!ip && this.connectionRemoteAddress && this.connectionRemoteAddress.substr && this.connectionRemoteAddress.substr(0, 2) === "::") { | ||
ip = "127.0.0.1"; | ||
} | ||
return ip; | ||
}; | ||
RequestDataHelper.prototype._getSessionId = function () { | ||
var name = "ai_session"; | ||
var cookie = (this.rawHeaders && this.rawHeaders["cookie"] && typeof this.rawHeaders["cookie"] === 'string' && this.rawHeaders["cookie"]) || ""; | ||
var value = Util.getCookie(name, cookie); | ||
return value; | ||
}; | ||
RequestDataHelper.keys = new ContractsModule.Contracts.ContextTagKeys(); | ||
return RequestDataHelper; | ||
})(); | ||
module.exports = AutoCollectRequests; |
@@ -12,2 +12,8 @@ var Logging = require("./Logging"); | ||
/** | ||
* Enable or disable offline mode | ||
*/ | ||
Channel.prototype.setOfflineMode = function (value) { | ||
this._sender.setOfflineMode(value); | ||
}; | ||
/** | ||
* Add a telemetry item to the send buffer | ||
@@ -14,0 +20,0 @@ */ |
@@ -52,3 +52,3 @@ ///<reference path="..\Declarations\node\node.d.ts" /> | ||
else { | ||
trace.severityLevel = 1 /* Information */; | ||
trace.severityLevel = ContractsModule.Contracts.SeverityLevel.Information; | ||
} | ||
@@ -90,3 +90,3 @@ var data = new ContractsModule.Contracts.Data(); | ||
metric.count = !isNaN(count) ? count : 1; | ||
metric.kind = 1 /* Aggregation */; | ||
metric.kind = ContractsModule.Contracts.DataPointType.Aggregation; | ||
metric.max = !isNaN(max) ? max : value; | ||
@@ -120,2 +120,3 @@ metric.min = !isNaN(min) ? min : value; | ||
else { | ||
// otherwise, check each of the common ones | ||
for (var name in this.commonProperties) { | ||
@@ -122,0 +123,0 @@ // only override if the property `name` has not been set on this item |
@@ -14,3 +14,6 @@ ///<reference path="..\Declarations\node\node.d.ts" /> | ||
// check for both the documented env variable and the azure-prefixed variable | ||
var iKey = process.env[Config.ENV_iKey] || process.env[Config.ENV_azurePrefix + Config.ENV_iKey] || process.env[Config.legacy_ENV_iKey] || process.env[Config.ENV_azurePrefix + Config.legacy_ENV_iKey]; | ||
var iKey = process.env[Config.ENV_iKey] | ||
|| process.env[Config.ENV_azurePrefix + Config.ENV_iKey] | ||
|| process.env[Config.legacy_ENV_iKey] | ||
|| process.env[Config.ENV_azurePrefix + Config.legacy_ENV_iKey]; | ||
if (!iKey || iKey == "") { | ||
@@ -17,0 +20,0 @@ throw new Error("Instrumentation key not found, pass the key in the config to this method or set the key in the environment variable APPINSIGHTS_INSTRUMENTATIONKEY before starting the server"); |
@@ -1,2 +0,2 @@ | ||
var __extends = this.__extends || function (d, b) { | ||
var __extends = (this && this.__extends) || function (d, b) { | ||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; | ||
@@ -149,3 +149,3 @@ function __() { this.constructor = d; } | ||
function DataPoint() { | ||
this.kind = 0 /* Measurement */; | ||
this.kind = Contracts.DataPointType.Measurement; | ||
} | ||
@@ -192,6 +192,6 @@ return DataPoint; | ||
this.ver = 2; | ||
this.kind = 0 /* Measurement */; | ||
this.dependencyKind = 2 /* Other */; | ||
this.kind = Contracts.DataPointType.Measurement; | ||
this.dependencyKind = Contracts.DependencyKind.Other; | ||
this.success = true; | ||
this.dependencySource = 0 /* Undefined */; | ||
this.dependencySource = Contracts.DependencySourceType.Undefined; | ||
this.properties = {}; | ||
@@ -229,3 +229,3 @@ _super.call(this); | ||
this.ver = 2; | ||
this.state = 0 /* Start */; | ||
this.state = Contracts.SessionState.Start; | ||
_super.call(this); | ||
@@ -240,3 +240,3 @@ } | ||
this.ver = 2; | ||
this.kind = 1 /* Aggregation */; | ||
this.kind = DataPointType.Aggregation; | ||
this.properties = {}; | ||
@@ -243,0 +243,0 @@ _super.call(this); |
@@ -11,10 +11,13 @@ ///<reference path="..\Declarations\node\node.d.ts" /> | ||
function Sender(getUrl, onSuccess, onError) { | ||
var _this = this; | ||
this._getUrl = getUrl; | ||
this._onSuccess = onSuccess; | ||
this._onError = onError; | ||
this._enableCacheOnError = false; | ||
// always begin by trying to send saved data when initialized | ||
setTimeout(function () { return _this._sendFirstFileOnDisk(); }); | ||
this._enableOfflineMode = false; | ||
} | ||
/** | ||
* Enable or disable offline mode | ||
*/ | ||
Sender.prototype.setOfflineMode = function (value) { | ||
this._enableOfflineMode = value; | ||
}; | ||
Sender.prototype.send = function (payload, callback) { | ||
@@ -65,6 +68,6 @@ var _this = this; | ||
} | ||
if (_this._enableCacheOnError) { | ||
if (_this._enableOfflineMode) { | ||
// try to send any cached events if the user is back online | ||
if (res.statusCode === 200) { | ||
_this._sendFirstFileOnDisk(); | ||
setTimeout(function () { return _this._sendFirstFileOnDisk(); }, Sender.WAIT_BETWEEN_RESEND); | ||
} | ||
@@ -89,3 +92,3 @@ else { | ||
} | ||
if (_this._enableCacheOnError) { | ||
if (_this._enableOfflineMode) { | ||
_this._storeToDisk(payload); | ||
@@ -99,46 +102,56 @@ } | ||
Sender.prototype.saveOnCrash = function (payload) { | ||
this._storeToDisk(payload, true); | ||
this._storeToDiskSync(payload); | ||
}; | ||
/** | ||
* enable caching events locally on error | ||
*/ | ||
Sender.prototype.enableCacheOnError = function () { | ||
this._enableCacheOnError = true; | ||
Sender.prototype._confirmDirExists = function (direcotry, callback) { | ||
fs.exists(direcotry, function (exists) { | ||
if (!exists) { | ||
fs.mkdir(direcotry, function (err) { | ||
callback(err); | ||
}); | ||
} | ||
else { | ||
callback(null); | ||
} | ||
}); | ||
}; | ||
/** | ||
* disable caching events locally on error | ||
*/ | ||
Sender.prototype.disableCacheOnError = function () { | ||
this._enableCacheOnError = false; | ||
}; | ||
/** | ||
* Stores the payload as a json file on disk in the temp direcotry | ||
*/ | ||
Sender.prototype._storeToDisk = function (payload, isCrash) { | ||
Sender.prototype._storeToDisk = function (payload) { | ||
var _this = this; | ||
//ensure directory is created | ||
var direcotry = path.join(os.tmpDir(), Sender.TEMPDIR); | ||
if (!fs.existsSync(direcotry)) { | ||
try { | ||
fs.mkdirSync(direcotry); | ||
} | ||
catch (error) { | ||
// failing to create the temp directory | ||
this._onErrorHelper(error); | ||
this._confirmDirExists(direcotry, function (error) { | ||
if (error) { | ||
_this._onErrorHelper(error); | ||
return; | ||
} | ||
} | ||
//create file - file name for now is the timestamp, a better approach would be a UUID but that | ||
//would require an external dependency | ||
var fileName = new Date().getTime() + ".ai.json"; | ||
var fileFullPath = path.join(direcotry, fileName); | ||
// if the file already exist, replace the content | ||
if (isCrash) { | ||
Logging.info(Sender.TAG, "saving crash to disk at: " + fileFullPath); | ||
fs.writeFileSync(fileFullPath, payload); | ||
} | ||
else { | ||
//create file - file name for now is the timestamp, a better approach would be a UUID but that | ||
//would require an external dependency | ||
var fileName = new Date().getTime() + ".ai.json"; | ||
var fileFullPath = path.join(direcotry, fileName); | ||
Logging.info(Sender.TAG, "saving data to disk at: " + fileFullPath); | ||
fs.writeFile(fileFullPath, payload, function (error) { return _this._onErrorHelper(error); }); | ||
}); | ||
}; | ||
/** | ||
* Stores the payload as a json file on disk using sync file operations | ||
* this is used when storing data before crashes | ||
*/ | ||
Sender.prototype._storeToDiskSync = function (payload) { | ||
var direcotry = path.join(os.tmpDir(), Sender.TEMPDIR); | ||
try { | ||
if (!fs.existsSync(direcotry)) { | ||
fs.mkdirSync(direcotry); | ||
} | ||
//create file - file name for now is the timestamp, a better approach would be a UUID but that | ||
//would require an external dependency | ||
var fileName = new Date().getTime() + ".ai.json"; | ||
var fileFullPath = path.join(direcotry, fileName); | ||
Logging.info(Sender.TAG, "saving data before crash to disk at: " + fileFullPath); | ||
fs.writeFileSync(fileFullPath, payload); | ||
} | ||
catch (error) { | ||
this._onErrorHelper(error); | ||
} | ||
}; | ||
@@ -152,17 +165,21 @@ /** | ||
var tempDir = path.join(os.tmpDir(), Sender.TEMPDIR); | ||
if (!fs.existsSync(tempDir)) { | ||
return; | ||
} | ||
fs.readdir(tempDir, function (error, files) { | ||
if (!error) { | ||
files = files.filter(function (f) { return path.basename(f).indexOf(".ai.json") > -1; }); | ||
if (files.length > 0) { | ||
var firstFile = files[0]; | ||
var filePath = path.join(tempDir, firstFile); | ||
fs.readFile(filePath, function (error, payload) { | ||
if (!error) { | ||
// delete the file first to prevent double sending | ||
fs.unlink(filePath, function (error) { | ||
fs.exists(tempDir, function (exists) { | ||
if (exists) { | ||
fs.readdir(tempDir, function (error, files) { | ||
if (!error) { | ||
files = files.filter(function (f) { return path.basename(f).indexOf(".ai.json") > -1; }); | ||
if (files.length > 0) { | ||
var firstFile = files[0]; | ||
var filePath = path.join(tempDir, firstFile); | ||
fs.readFile(filePath, function (error, payload) { | ||
if (!error) { | ||
_this.send(payload); | ||
// delete the file first to prevent double sending | ||
fs.unlink(filePath, function (error) { | ||
if (!error) { | ||
_this.send(payload); | ||
} | ||
else { | ||
_this._onErrorHelper(error); | ||
} | ||
}); | ||
} | ||
@@ -174,11 +191,8 @@ else { | ||
} | ||
else { | ||
_this._onErrorHelper(error); | ||
} | ||
}); | ||
} | ||
} | ||
else { | ||
_this._onErrorHelper(error); | ||
} | ||
}); | ||
} | ||
else { | ||
_this._onErrorHelper(error); | ||
} | ||
}); | ||
@@ -192,2 +206,4 @@ }; | ||
Sender.TAG = "Sender"; | ||
// the amount of time the SDK will wait between resending cached data, this buffer is to avoid any throtelling from the service side | ||
Sender.WAIT_BETWEEN_RESEND = 60 * 1000; | ||
Sender.TEMPDIR = "appInsights-node"; | ||
@@ -194,0 +210,0 @@ return Sender; |
@@ -5,3 +5,3 @@ { | ||
"bugs": "https://github.com/Microsoft/ApplicationInsights-node.js/issues", | ||
"version": "0.15.2", | ||
"version": "0.15.3", | ||
"description": "Microsoft Application Insights module for Node.JS", | ||
@@ -25,3 +25,7 @@ "repository": { | ||
"email": "scsouthw@microsoft.com" | ||
} | ||
}, | ||
{ | ||
"name": "bogdanbe", | ||
"email": "bogdanbe@microsoft.com" | ||
} | ||
], | ||
@@ -28,0 +32,0 @@ "scripts": { |
@@ -6,2 +6,4 @@ # Application Insights for Node.js | ||
This project provides a Node.js SDK for Application Insights. [Application Insights](http://azure.microsoft.com/en-us/services/application-insights/) is a service that allows developers to keep their applications available, performant, and successful. This node module will allow you to send telemetry of various kinds (event, trace, exception, etc.) to the Application Insights service where they can be visualized in the Azure Portal. | ||
@@ -15,3 +17,3 @@ | ||
``` | ||
npm install applicationinsights | ||
npm install applicationinsights | ||
``` | ||
@@ -32,5 +34,10 @@ **Get an instrumentation key** | ||
>The instrumentation key can also be set in the environment variable APPINSIGHTS_INSTRUMENTATIONKEY. If this is done, no argument is required when calling `appInsights.setup()` or `appInsights.getClient()`. | ||
## Customized Usage ## | ||
Disabling auto-collection | ||
#####Disabling auto-collection##### | ||
```javascript | ||
import appInsights = require("applicationinsights"); | ||
appInsights.setup("<instrumentation_key>") | ||
@@ -41,27 +48,43 @@ .setAutoCollectRequests(false) | ||
// no telemetry will be sent until .start() is called | ||
// this prevents any of the auto-collectors from initializing | ||
.start(); | ||
``` | ||
// get a client for another iKey (or if setup is never called) | ||
var otherClient = AppInsights.getClient("<instrumentation_key>"); | ||
#####Using multiple instrumentaion keys##### | ||
```javascript | ||
import appInsights = require("applicationinsights"); | ||
// configure auto-collection with one instrumentation key | ||
appInsights.setup("<instrumentation_key>").start(); | ||
// get a client for another instrumentation key | ||
var otherClient = appInsights.getClient("<other_instrumentation_key>"); | ||
otherClient.trackEvent("custom event"); | ||
``` | ||
Custom monitoring | ||
#####Custom monitoring##### | ||
```javascript | ||
appInsights.client.trackEvent("custom event", {customProperty: "custom property value"}); | ||
appInsights.client.trackException(new Error("handled exceptions can be logged with this method")); | ||
appInsights.client.trackMetric("custom metric", 3); | ||
appInsights.client.trackTrace("trace message"); | ||
import appInsights = require("applicationinsights"); | ||
var client = appInsights.getClient(); | ||
client.trackEvent("custom event", {customProperty: "custom property value"}); | ||
client.trackException(new Error("handled exceptions can be logged with this method")); | ||
client.trackMetric("custom metric", 3); | ||
client.trackTrace("trace message"); | ||
``` | ||
Example with manual request tracking of all "GET" requests | ||
#####Example with manual request tracking of all "GET" requests##### | ||
```javascript | ||
var http = require("http"); | ||
var appInsights = require('applicationinsights'); | ||
var appInsights = require("applicationinsights"); | ||
appInsights.setup("<instrumentation_key>") | ||
.setAutoCollectRequests(false) // disabling auto-collection for this example | ||
.setAutoCollectRequests(false) // disable auto-collection of requests for this example | ||
.start(); | ||
// assign common properties to all telemetry | ||
// assign common properties to all telemetry sent from the default client | ||
appInsights.client.commonProperties = { | ||
@@ -82,4 +105,4 @@ environment: process.env.SOME_ENV_VARIABLE | ||
res.writeHead(200, { 'Content-Type': 'text/plain' }); | ||
res.end('Hello World\n'); | ||
res.writeHead(200, { "Content-Type": "text/plain" }); | ||
res.end("Hello World\n"); | ||
}).listen(port); | ||
@@ -98,2 +121,3 @@ | ||
## Contributing ## | ||
@@ -110,3 +134,3 @@ **Development environment** | ||
``` | ||
set APPINSIGHTS_INSTRUMENTATION_KEY=<insert_your_instrumentation_key_here> | ||
set APPINSIGHTS_INSTRUMENTATIONKEY=<insert_your_instrumentation_key_here> | ||
``` | ||
@@ -113,0 +137,0 @@ * Run tests |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
77744
19
1635
135