Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-Correlation wrapper in Azure Functions/FaaS - Why and better How? #1051

Closed
iyerusad opened this issue Dec 29, 2022 · 3 comments
Closed

Comments

@iyerusad
Copy link

Scenario

The readme says for Azure Functions I want to put my trigger/etc in a wrapper so that Application Insights can enable more tracking.

Azure Functions

Due to how Azure Functions (and other FaaS services) handle incoming requests, they are not seen as http requests to the Node.js runtime. For this reason, Request -> Dependency correlelation will not work out of the box. To enable tracking here, you simply need to grab the context from your Function request handler, and wrap your Function with that context.


All my functions basically start with this helper and it seems to do basic job:

const appInsights = require("applicationinsights");
if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) {appInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY).start()}

Question 1: What is the additional data I could hope to get?

I don't spend immense time in this ecosystem but a screenshot of what it would be with or without could be helpful. Or a newcomer developer level explanation.

Currently I seem to get following WITHOUT adding Auto-Correlation:

  • Failure logging, hooked up with an email alert (albeit very generic Azure Portal email)
  • Metrics on individual Azure Function performance

Question 2: Is there a better/abstracted way to implement this?

Could the wrapper be abstracted in similar fashion as below? Apologizes if this might be very basic JavaScript concept, I am a little cautious about wrappers around productized services (e.g. Faas). Preferably a 1-2 line addition to keep the Azure Functions/git history as light and easy to read through as they can be.

Possible Idea:

const appInsightsInstance = require("applicationinsights");
if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) {appInsightsInstance.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY).start()}
const appInsightsHelper = require('../libs/appInsightsHelper.js');

module.exports = async function (context, req) {
  //my logic
};

appInsightsHelper(appInsightsInstance,module.exports)

The default example given is somewhat verbose and would prefer to update it in a single file rather than dozens of files whenever a change is made.

readme example provided:

const appInsights = require("applicationinsights");
appInsights.setup("<YOUR_CONNECTION_STRING>")
    .setAutoCollectPerformance(false)
    .start();

const axios = require("axios");

/**
 * No changes required to your existing Function logic
 */
const httpTrigger = async function (context, req) {
    const response = await axios.get("https://httpbin.org/status/200");

    context.res = {
        status: response.status,
        body: response.statusText,
    };
};

// Default export wrapped with Application Insights FaaS context propagation
export default async function contextPropagatingHttpTrigger(context, req) {
    // Start an AI Correlation Context using the provided Function context
    const correlationContext = appInsights.startOperation(context, req);

    // Wrap the Function runtime with correlationContext
    return appInsights.wrapWithCorrelationContext(async () => {
        const startTime = Date.now(); // Start trackRequest timer

        // Run the Function
        const result = await httpTrigger(context, req);

        // Track Request on completion
        appInsights.defaultClient.trackRequest({
            name: context.req.method + " " + context.req.url,
            resultCode: context.res.status,
            success: true,
            url: req.url,
            time: new Date(startTime),
            duration: Date.now() - startTime,
            id: correlationContext.operation.parentId,
        });
        appInsights.defaultClient.flush();

        return result;
    }, correlationContext)();
};
@hectorhdzg
Copy link
Member

@iyerusad the main reason to add custom code mentioned in readme is to maintain correlation context available in Azure Functions call, that is the reason of wrapWithCorrelationContext call in the sample code, as you can see we also generate the incoming request telemetry that will not be automatically generated because of code execution timings, we will automatically handle this for customers and remove the need to add custom code in next release scheduled for next week. Related to link

@iyerusad
Copy link
Author

iyerusad commented Jan 5, 2023

Okay I guess I don't understand what is included with "incoming request telemetry"...

but it sounds like this is going to start magically appearing when pull request #1044 is published. I think thats good enough to close, feel free to add comment on what can expect but otherwise I guess will additional correlation context info in the logs it at some point in the future.

@iyerusad iyerusad closed this as completed Jan 5, 2023
@hectorhdzg
Copy link
Member

More info about Request telemetry here, will update documentation shortly about this, like I mentioned the functionality will be enabled by default in next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants