ApplicationInsights-node.js icon indicating copy to clipboard operation
ApplicationInsights-node.js copied to clipboard

SDK Version loaded from node_modules structure breaks when bundling

Open hanvyj opened this issue 5 years ago • 2 comments

I had the library completely fail to send app insights.

After rooting around in the source code I managed to diagnose the issue by adding some extra logging:

[03/09/2019 11:29:35] ApplicationInsights: {"itemsReceived":1,"itemsAccepte d":0,"errors":[{"index":0,"statusCode":400,"message":"5: SDK version '0.0.0-sema ntic-version' has been deprecated and is no longer supported. Please update to v ersion '0.0.0' or greater."}]} []

For some reason it's sending my application's package.json version as the application insights version! Strange, until you read where it gets this value:

        var packageJsonPath = path.resolve(__dirname, "../../package.json");
        if (!Context.sdkVersion) {
            Context.sdkVersion = "unknown";
            try {
                var packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
                if (packageJson && typeof packageJson.version === "string") {
                    Context.sdkVersion = packageJson.version;
                }
            }
            catch (exception) {
                Logging.info("unable to read app version: ", exception);
            }
        }
        this.tags[this.keys.internalSdkVersion] = "node:" + Context.sdkVersion;

We use webpack to bundle our code into a single Azure Function. So of course, the bundled code isn't running in the node_modules folder.

This seems a very brittle way to get the version.

I cann't even work around it by specifying the version manually:

  client.trackEvent({
    name: "test.event",
    properties: {
      test: "Test!"
    },
    tagOverrides: {
      "ai.internal.sdkVersion": "node:1.4.1"
    }
  });

But there must be a better way!

Edit It seems to work in production. Presumably it's because there's no package.json for it to incorrectly pick up a version from.

I have an idea for a solution. As well as checking the packageJson.version also check the packageJson.name matches the actual package: "applicationinsights" or similar:

        var packageJsonPath = path.resolve(__dirname, "../../package.json");
        if (!Context.sdkVersion) {
            Context.sdkVersion = "unknown";
            try {
                var packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
                if (packageJson &&
                    packageJson.name === "applicationinsights" &&
                    typeof packageJson.version === "string") {
                    Context.sdkVersion = packageJson.version;
                }
            }
            catch (exception) {
                Logging.info("unable to read app version: ", exception);
            }
        }
        this.tags[this.keys.internalSdkVersion] = "node:" + Context.sdkVersion;

hanvyj avatar Sep 03 '19 11:09 hanvyj

Thanks for investigating this, seems good to me. Would you like to submit a PR with this change?

markwolff avatar Sep 03 '19 19:09 markwolff

I'll try to when I get a spare moment!

hanvyj avatar Sep 20 '19 15:09 hanvyj