├── .gitignore ├── LICENSE ├── cs-http ├── MatrixMultiply.csx ├── function.json ├── project.json └── run.csx ├── host.json ├── item ├── function.json └── index.js ├── lib └── items.js ├── package.json ├── process-item ├── function.json └── index.js └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | secrets 3 | data 4 | **/project.lock.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Microsoft Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /cs-http/MatrixMultiply.csx: -------------------------------------------------------------------------------- 1 | public static int[][] CreateRandomMatrix(int size, int seed, int valueMin, int valueMax) 2 | { 3 | Random rng = new Random(seed); 4 | var matrix = new int[size][]; 5 | for (var i = 0; i < size; i++) 6 | { 7 | var row = new int[size]; 8 | for (var j = 0; j < size; j++) 9 | { 10 | row[j] = rng.Next(valueMin, valueMax); 11 | } 12 | 13 | matrix[i] = row; 14 | } 15 | return matrix; 16 | } 17 | 18 | public static int[][] MultiplyMatrix(int[][] matrixA, int[][] matrixB) 19 | { 20 | int[][] result = new int[matrixA.GetLength(0)][]; 21 | int elements = matrixB.GetLength(0); 22 | for (var i = 0; i < matrixA.GetLength(0); i++) 23 | { 24 | result[i] = new int[elements]; 25 | for (var j = 0; j < matrixA.GetLength(0); j++) 26 | { 27 | var row = matrixA[i]; 28 | var col = GetColumn(matrixB, j); 29 | 30 | result[i][j] = MultiplyRowAndColumn(row, col); 31 | } 32 | } 33 | return result; 34 | } 35 | 36 | private static int MultiplyRowAndColumn(int[] row, int[] col) 37 | { 38 | int sum = 0; 39 | for (int b = 0; b < row.Length; b++) 40 | { 41 | sum += row[b] * col[b]; 42 | } 43 | 44 | return sum; 45 | } 46 | 47 | private static int[] GetColumn(int[][] matrixB, int j) 48 | { 49 | var result = new int[matrixB.Length]; 50 | for (int i = 0; i < matrixB.Length; i++) 51 | { 52 | result[i] = matrixB[i][j]; 53 | } 54 | 55 | return result; 56 | } 57 | 58 | public static void PrintMatrix(int[][] matrix) 59 | { 60 | for (var i = 0; i < matrix.Length; i++) 61 | { 62 | var row = ""; 63 | for (var j = 0; j < matrix.Length; j++) 64 | { 65 | row += " " + matrix[i][j]; 66 | } 67 | 68 | Console.WriteLine(row); 69 | } 70 | } -------------------------------------------------------------------------------- /cs-http/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "disabled": false, 3 | "bindings": [ 4 | { 5 | "authLevel": "function", 6 | "name": "req", 7 | "type": "httpTrigger", 8 | "direction": "in" 9 | }, 10 | { 11 | "name": "res", 12 | "type": "http", 13 | "direction": "out" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /cs-http/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "frameworks": { 3 | "net46":{ 4 | "dependencies": { 5 | "Microsoft.ApplicationInsights": "2.1.0" 6 | } 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /cs-http/run.csx: -------------------------------------------------------------------------------- 1 | #load "./MatrixMultiply.csx" 2 | 3 | using System.Net; 4 | using Microsoft.ApplicationInsights; 5 | using Microsoft.ApplicationInsights.DataContracts; 6 | using Microsoft.ApplicationInsights.Extensibility; 7 | 8 | private static TelemetryClient telemetry = new TelemetryClient(); 9 | private static string key = TelemetryConfiguration.Active.InstrumentationKey = System.Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", EnvironmentVariableTarget.Process); 10 | 11 | public static async Task Run(HttpRequestMessage req, TraceWriter log) 12 | { 13 | log.Info($"C# HTTP trigger function processed a request. RequestUri={req.RequestUri}"); 14 | 15 | telemetry.TrackEvent("Function Started"); 16 | // Establish an operation context and associated telemetry item: 17 | using (var operation = telemetry.StartOperation("CS-MatrixMultiply")) 18 | { 19 | // parse query parameter 20 | string val = req.GetQueryNameValuePairs() 21 | .FirstOrDefault(q => string.Compare(q.Key, "size", true) == 0) 22 | .Value; 23 | 24 | // Set size to query string or body data 25 | int size = Int32.Parse(val ?? "5"); 26 | int seed = 124; 27 | int valueMin = 0; 28 | int valueMax = 101; 29 | 30 | telemetry.TrackEvent("MatrixMultiplyStarted", null, new Dictionary{{"size", size}}); 31 | 32 | int[][] matrix = CreateRandomMatrix(size, seed, valueMin, valueMax); 33 | seed = 2 * seed; 34 | int[][] matrix2 = CreateRandomMatrix(size, seed, valueMin, valueMax); 35 | int[][] result = MultiplyMatrix(matrix, matrix2); 36 | 37 | // Set properties of containing telemetry item - for example: 38 | operation.Telemetry.ResponseCode = "200"; 39 | 40 | //optional 41 | telemetry.StopOperation(operation); 42 | 43 | } // When operation is disposed, telemetry item is sent. 44 | return req.CreateResponse(HttpStatusCode.OK); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /host.json: -------------------------------------------------------------------------------- 1 | {"id":"541af1347e0449de97c39b72a50b959f"} -------------------------------------------------------------------------------- /item/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "disabled": false, 3 | "bindings": [ 4 | { 5 | "authLevel": "function", 6 | "type": "httpTrigger", 7 | "direction": "in", 8 | "name": "req" 9 | }, 10 | { 11 | "type": "http", 12 | "direction": "out", 13 | "name": "res" 14 | }, 15 | { 16 | "type": "queue", 17 | "name": "output", 18 | "queueName": "item-queue", 19 | "connection": "AzureWebJobsStorage", 20 | "direction": "out" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /item/index.js: -------------------------------------------------------------------------------- 1 | var uuid = require('node-uuid'); 2 | var appInsights = require("applicationinsights"); 3 | var client = appInsights.getClient(); 4 | 5 | var items = require('../lib/items.js'); 6 | 7 | exports.run = function(context, req) { 8 | var start = new Date(); 9 | context.log('Node.js HTTP trigger function processed a request. RequestUri=%s', req.originalUrl); 10 | req.url = req.originalUrl; 11 | var operation = uuid.v4(); 12 | client.trackEvent("function.item.execution", 13 | { 14 | operation: operation, 15 | query: JSON.stringify(req.query), 16 | body: JSON.stringify(req.body ? req.body : {}) 17 | }); 18 | 19 | if(req.method == 'GET') { 20 | items.get((items) => { 21 | context.res = { 22 | body: { 23 | items: items 24 | } 25 | } 26 | client.trackRequestSync(req, context.res, (new Date() - start)); 27 | context.done(); 28 | }) 29 | } else if (req.method == 'POST') { 30 | if(req.body && req.body.items) { 31 | context.bindings.output = []; 32 | req.body.items.forEach((item) => { 33 | context.bindings.output.push({ 34 | item: item, 35 | operation: operation 36 | }); 37 | }) 38 | } 39 | context.done(); 40 | } else { 41 | context.done(); 42 | } 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /lib/items.js: -------------------------------------------------------------------------------- 1 | var items = []; 2 | 3 | var get = function(cb) { 4 | setTimeout(() => { 5 | cb(items); 6 | }, 1000) 7 | } 8 | 9 | var add = function(item, cb) { 10 | setTimeout(() => { 11 | items.push(item); 12 | cb(); 13 | }, 5000) 14 | } 15 | 16 | module.exports = { 17 | get: get, 18 | add: add 19 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions-app-insights", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "applicationinsights": "^0.16.0", 13 | "node-uuid": "^1.4.7" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /process-item/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "disabled": false, 3 | "bindings": [ 4 | { 5 | "name": "myQueueItem", 6 | "type": "queueTrigger", 7 | "direction": "in", 8 | "queueName": "item-queue", 9 | "connection": "AzureWebJobsStorage" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /process-item/index.js: -------------------------------------------------------------------------------- 1 | var appInsights = require("applicationinsights"); 2 | var client = appInsights.getClient(); 3 | 4 | var items = require('../lib/items.js'); 5 | 6 | module.exports = function (context, item) { 7 | context.log('Node.js queue trigger function processed work item', item.operation); 8 | 9 | client.trackEvent("function.process-item.execution", 10 | { 11 | operation: item.operation, 12 | query: JSON.stringify(item.item), 13 | }); 14 | 15 | items.add(item.item, () => { 16 | context.done(); 17 | }); 18 | }; -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Azure Functions with Application Insights 2 | 3 | This repo has a few examples of using Application Insights in Node.JS and C# 4 | 5 | ## Configuring Application Insights 6 | 7 | To use these samples, you must set an environment variable for `APPINSIGHTS_INSTRUMENTATIONKEY` (via your Function App's app settings). You should avoid including the instrumentation key directly in your code. 8 | 9 | ## Node.JS 10 | 11 | The `item` and `process-item` functions are Node.JS based and have examples of how to use the SDK. 12 | 13 | You must have the package.json at the root of your project and the node_modules installed (either via direct npm install with Kudu, or via a Git Deployment). 14 | 15 | See the Application Insights docs for full usage. https://docs.microsoft.com/en-us/azure/application-insights/app-insights-nodejs 16 | 17 | ## C\# 18 | 19 | The `cs-http` functions are C# based and have examples of how to use the SDK. 20 | 21 | You have to have the project.json at the function level. The host will auto fetch the nuget packages for you on compliation. 22 | 23 | See the Application Insights docs for full usage. https://docs.microsoft.com/en-us/azure/application-insights/app-insights-api-custom-events-metrics 24 | 25 | ## License 26 | 27 | [MIT](LICENSE) 28 | --------------------------------------------------------------------------------