node.jsazureexpressazure-application-insights

Using Azure AppInsights in a Nodejs Express Azure WebApp Application


How do I configure Azure AppInsights with all routes to log exceptions and console statements?

This is appInsights.js:

const appInsights = require('applicationinsights');

appInsights.setup(process.env.APPLICATIONINSIGHTS_CONNECTION_STRING)
.setAutoCollectConsole(true, true)
.setAutoCollectExceptions(true)
.start();

module.exports = appInsights

routes/index.js:


var express = require('express');
var router = express.Router();
const { appInsights } = require('../services/appInsights');
const { botService } = require('../services/bot');

router.get('/', function (req, res, next) {
  res.render('index', { title: 'Express' });
});

router.post('/api/messages', async function (req, res, next) {
  console.log("--inside /messages--")
  try {
  //call a method from bot.js
    });
  }
  catch (error) {
    console.error('Error in /messages:', error);
    appInsights.defaultClient.trackException({ exception: error });
    res.status(500).send('Internal Server Error');
  }

Currently, everything is being logged as "trace" in App Insights and the exceptions are not shown separately even though I've used

appInsights.defaultClient.trackException({ exception: error });

in index.js and I'm also unsure how to use this in bot.js. I've tried importing appInsights again in Bot.js, but that results in duplication of logs. I'm familiar with AWS where I just create a lambda and it has Cloudwatch logs by default and this is my first time working on Azure.


Solution

  • I'm able to see logs in exceptions and traces separately.

    The exceptions handled in the catch block are displayed in the exception section.

    I've added this try catch block code to index.js file

    try {
        await someMethod();
        res.status(200).send('Message processed successfully');
      } catch (error) {
        console.error('Error in /messages:', error);
        appInsights.defaultClient.trackException({ exception: error });
        res.status(500).send('Internal Server Error');
      }
    

    My index.js file:

    const express = require('express');
    const router = express.Router();
    const appInsights = require('../services/appInsights'); 
    const { someMethod } = require('../services/bot'); 
    router.get('/', function (req, res, next) {
      res.send('API running at: /api/names, /api/error, /api/dependency');
    });
    router.get('/api/names', (req, res, next) => {
      res.json(['Tony', 'Lisa', 'Michael', 'Ginger', 'Food']);
    });
    router.get('/api/error', (req, res, next) => {
      try {
        throw new Error('This is a test error');
      } catch (error) {
    
        appInsights.defaultClient.trackException({ exception: error });  
        res.status(500).json({ error: 'Internal Server Error' });
      }
    });
    router.post('/api/messages', async function (req, res, next) {
      console.log("--inside /messages--");
      try {
        await someMethod();
        res.status(200).send('Message processed successfully');
      } catch (error) {
        console.error('Error in /messages:', error);
        appInsights.defaultClient.trackException({ exception: error });
        res.status(500).send('Internal Server Error');
      }
    });
    module.exports = router;
    

    My bot.js file:

    const appInsights = require('../services/appInsights');
    async function someMethod() {
      try {
            console.log("Simulated successful process in bot service");
        return "Success";
      } catch (error) {
        console.error('Error in bot service:', error);
        appInsights.defaultClient.trackException({ exception: error });
        throw error;
      }
    }
    module.exports = {
      someMethod
    };
    

    I've added few more methods in appInsights.js

    My appInsights.js file

    const  appInsights  =  require('applicationinsights');
    appInsights.setup("
    process.env.APPLICATIONINSIGHTS_CONNECTION_STRING")
    .setAutoDependencyCorrelation(true)
    .setAutoCollectRequests(true)
    .setAutoCollectPerformance(true, true)
    .setAutoCollectExceptions(true)
    .setAutoCollectDependencies(true)
    .setAutoCollectConsole(true, true)
    .setUseDiskRetryCaching(true)
    .setSendLiveMetrics(false)
    .setDistributedTracingMode(appInsights.DistributedTracingModes.AI_AND_W3C)
    .start();
    module.exports  =  appInsights;
    

    My app.js file:

    const express = require('express');
    const app = express();
    const indexRouter = require('./routes/index');
    const appInsights = require('./services/appInsights');
    app.use(express.json());
    app.use((req, res, next) => {
      appInsights.defaultClient.trackRequest({ name: req.method + ' ' + req.url, url: req.url, time: new Date(), duration: 0, resultCode: res.statusCode, success: true });
      next();
    });
    app.use('/', indexRouter);
    app.use((err, req, res, next) => {
      console.error('Unhandled error:', err);
      appInsights.defaultClient.trackException({ exception: err });
      res.status(500).send('Internal Server Error');
    });
    const port = process.env.PORT || 3000;
    app.set('port', port);
    app.listen(port, () => {
      console.log(`Server is running on port ${port}`);
    });
    

    Now, for every route, I have the App Insights log traces.

    enter image description here

    enter image description here

    enter image description here

    enter image description here