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

Cloudflare Workers #1264

Closed
vanslly opened this issue May 10, 2020 · 11 comments
Closed

Cloudflare Workers #1264

vanslly opened this issue May 10, 2020 · 11 comments
Labels
service-worker Required to properly support service workers

Comments

@vanslly
Copy link

vanslly commented May 10, 2020

Is your feature request related to a problem? Please describe.
I'm unable to integrate the application insights JavaScript library into my Cloudflare JavaScript Worker. https://workers.cloudflare.com/

Describe the solution you'd like
To use the application insights library to track errors, events and dependencies in my Cloudflare Worker so I can get visibility into any interesting events in the worker. Have also tried @microsoft/applicationinsights-web-basic but not luck.

Describe alternatives you've considered
I've tried the NodeJS library (https://github.com/Microsoft/ApplicationInsights-node.js) as well, however Cloudflare workers are web workers so is not a NodeJS process but a v8 thread instead.

Additional context
Example Worker

import { ApplicationInsights, SeverityLevel } from '@microsoft/applicationinsights-web';
import { v4 as uuidv4 } from 'uuid';

const responseOk: Response = new Response(null, { status: 200, statusText: 'OK' });
const responseMethodNotAllowed: Response = new Response(null, { status: 405, statusText: 'Method Not Allowed' });
const responseInternalServerError: Response = new Response(null, { status: 500, statusText: 'Internal Server Error' });

const appInsights = new ApplicationInsights({
    config: {
        instrumentationKey: '{{ Instrumentation Key Here }}'
    }
});

async function handleGETRequests(request: Request): Promise<Response> {
    try {
        // Do some orchestration fetch calls

        return responseOk;
    } catch (ex) {
        appInsights.trackException({
            id: uuidv4(),
            exception: ex,
            severityLevel: SeverityLevel.Critical
        })
        return responseInternalServerError;
    }
}

function handler(event: FetchEvent) {
    switch (event.request.method) {
        case 'GET':
            event.respondWith(handleGETRequests(event.request).then(response => {
                appInsights.flush();
                return response;
            }));
        default:
            event.respondWith(responseMethodNotAllowed);
    }
}

appInsights.loadAppInsights();
addEventListener('fetch', handler);

Resulting Error
The fetch API is supported, but not XMLHttpRequest.
image

Even if fetch was used, the promise might need to be exposed from application insights to hook into the lifecycle of the request & response.

@MSNev
Copy link
Collaborator

MSNev commented May 11, 2020

This is most likely because CloudFlare runtime doesn't include XMLHttpRequest (because it's a worker) and the default configuration attempts to wrap XMLHttpRequest which when access looks like its throwing the listed exception.

In your configuration that you pass to initialize() add the following
disableAjaxTracking: false,
disableFetchTracking: false

These will disable the wrapping of XMLHttpRequest (disableAjaxTracking -- it default to false) and enable ajax (fetch) tracking (disableFetchTracking - defaults to true). If you don't want any ajax call tracking then just include disableAjaxTracking.

Cheers

@vanslly
Copy link
Author

vanslly commented May 12, 2020

I created a minimal working example (calling fetch myself with near static data in the body of the POST request) on an HTML page and it worked fine and I could see the event in Application Insights.

Taking that over to the Cloudflare Worker I got:

image

Since the code executes remote chrome://net-internals isn't available to me. Trying to explicitly set the fetch options to mode: 'cors' (any value) results in an error that mode is not implemented. I'm not sure why Application Insights is returning HTTP 502 Bad Gateway and without a way to debug it in the context of a Cloudflare Worker I am stuck.

@MSNev
Copy link
Collaborator

MSNev commented May 12, 2020

502 is not an expected response for this.

Can you capture the network traffic for this request using fiddler? Make sure to enabled SSL decryption. To try and identify we we got the 502 we would only need the request to the dc.services.visualstudio.com...
And you also don't not need to set the mode to 'cors'

@vanslly
Copy link
Author

vanslly commented May 13, 2020

Cloudflare wrangler runs the worker on a Cloudflare server, not on your local machine so Fiddler isn't of any help. That's why I mentioned chrome://net-internals as it's a bit better than sticking a proxy in between.

From my worker I was able to make a GET & POST request just fine to Azure hosted services I control (it was over SSL, and my POST endpoint was cors enabled), so it's something App Insights related (or the hosting of it) - and without access I can't debug and since this is not a supported SDK I can't get MS support

@MSNev
Copy link
Collaborator

MSNev commented May 13, 2020

Can you capture the traffic from the server?
Also looking at the response it has a content-length of 1374, can you dump that and see if there is any information that might be useful in tracking down the issue. Note: the backend is owned by another team, but if we can get enough context we can work with them to understand the problem.

The request to the server is effectively a POST with a JSON payload and very few headers.

When testing locally (from a browser) the request is normally sent with a referrer policy of strict-origin-when-cross-origin and therefore there is an OPTIONS request prior to the POST. Perhaps because the request is coming from the Cloudflare server it's not including the origin... Just thinking out aloud.

@MSNev
Copy link
Collaborator

MSNev commented May 13, 2020

Digging to the "sender" it currently only appears to have 3 senders -- there is no fetch sender (will need to check with other team members on why) XMLHttpRequest or XDomainRequest (the defaults) and beacon.

To use beacon (as XMLHttpRequest is not support in web workers) add the following to the config
isBeaconApiDisabled: false

There is the following comment with the beacon sender
// Chrome only allows CORS-safelisted values for the sendBeacon data argument
// see: https://bugs.chromium.org/p/chromium/issues/detail?id=720283

The other issue is that it's fire and forget, so if the browser doesn't send the requests for some reason the SDK doesn't have visibility that the events where dropped.

@MSNev
Copy link
Collaborator

MSNev commented May 13, 2020

I've created a new work item to investigate and implement a fetch sender for the above case, beacon not configured and running in an environment that doesn't support XMLHttpRequest or XDomainRequest (i.e. web worker scenario) #1268

@sazzy4o
Copy link

sazzy4o commented Jun 13, 2020

@vanslly I have recently created an npm package that allows you to use application insights with cloudflare workers: https://www.npmjs.com/package/applicationinsights-cloudflareworkers
Maybe it might help 👍

@vanslly
Copy link
Author

vanslly commented Jun 13, 2020

@sazzy4o Thank you for creating, I am very keen to give this go. I was going to loop back and create something to fill the gap and you beat me to it!

To launch our product I had to switch to logging into Elasticsearch for MVP for the interim, but the latency between my Elasticsearch instance and CF edge locations is huge, and I didn't do any log batching which you can so easily do with the Application Insights endpoint.

Thanks again, look forward to reunifying logging with App Insights.

@vanslly vanslly closed this as completed Jun 13, 2020
@sazzy4o
Copy link

sazzy4o commented Jun 13, 2020

@sazzy4o Thank you for creating, I am very keen to give this go. I was going to loop back and create something to fill the gap and you beat me to it!

To launch our product I had to switch to logging into Elasticsearch for MVP for the interim, but the latency between my Elasticsearch instance and CF edge locations is huge, and I didn't do any log batching which you can so easily do with the Application Insights endpoint.

Thanks again, look forward to reunifying logging with App Insights.

Glad to hear. The package is a little bit low level, so depending on your use case your might want to write a wrapper for it. Let me know if you have any trouble getting it working

@MSNev MSNev added the service-worker Required to properly support service workers label Jan 29, 2021
@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
service-worker Required to properly support service workers
Projects
None yet
Development

No branches or pull requests

3 participants