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

[Shim] Fix JSON Config #1203

Merged
merged 12 commits into from
Sep 15, 2023
72 changes: 44 additions & 28 deletions src/shim/config.ts → src/shim/shim-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import { DiagLogLevel } from "@opentelemetry/api";
import { HttpInstrumentationConfig } from "@opentelemetry/instrumentation-http";
import { DistributedTracingModes, IConfig, IDisabledExtendedMetrics, IWebInstrumentationConfig } from "./types";
import { Logger } from "../shared/logging";
import { ShimJsonConfig } from "./jsonConfig";
import { ApplicationInsightsOptions, ExtendedMetricType } from "../types";

import { ShimJsonConfig } from "./shim-jsonConfig";
import { ApplicationInsightsOptions, ExtendedMetricType, InstrumentationOptionsType } from "../types";

class Config implements IConfig {

Expand Down Expand Up @@ -61,6 +60,7 @@ class Config implements IConfig {
public webInstrumentationSrc: string;
public webInstrumentationConnectionString?: string;
public noPatchModules: string;
public noDiagnosticChannel: boolean;


/**
Expand Down Expand Up @@ -130,6 +130,8 @@ class Config implements IConfig {
this.webInstrumentationConnectionString = jsonConfig.webInstrumentationConnectionString;
this.webInstrumentationConfig = jsonConfig.webInstrumentationConfig;
this.webInstrumentationSrc = jsonConfig.webInstrumentationSrc;
this.noPatchModules = jsonConfig.noPatchModules;
this.noDiagnosticChannel = jsonConfig.noDiagnosticChannel
}

/**
Expand All @@ -147,6 +149,7 @@ class Config implements IConfig {
mySql: { enabled: true },
redis: { enabled: true },
redis4: { enabled: true },
postgreSql: { enabled: true },
},
logInstrumentationOptions: {
console: { enabled: false },
Expand Down Expand Up @@ -288,6 +291,44 @@ class Config implements IConfig {
};
}

if (this.noDiagnosticChannel === true) {
// Disable all instrumentations except http to conform with AppInsights 2.x behavior
for (const mod in options.instrumentationOptions) {
if (mod !== "http") {
(options.instrumentationOptions as InstrumentationOptionsType)[mod] = { enabled: false };
}
}
for (const mod in options.logInstrumentationOptions) {
(options.logInstrumentationOptions as InstrumentationOptionsType)[mod] = { enabled: false };
}
}

if (this.noPatchModules && this.noDiagnosticChannel !== true) {
const unpatchedModules: string[] = this.noPatchModules.split(",");
// Convert module names not supported by new InstrumentationOptions
for (let i = 0; i < unpatchedModules.length; i++) {
if (unpatchedModules[i] === "pg-pool" || unpatchedModules[i] === "pg") {
unpatchedModules[i] = "postgresql";
} else if (unpatchedModules[i] === "mongodb-core") {
unpatchedModules[i] = "mongodb";
} else if (unpatchedModules[i] === "redis") {
unpatchedModules.push("redis4")
}
}

// Disable instrumentation for unpatched modules
for (const mod in options.instrumentationOptions) {
if (unpatchedModules.indexOf(mod.toLowerCase()) !== -1) {
(options.instrumentationOptions as InstrumentationOptionsType)[mod] = { enabled: false };
}
}
for (const mod in options.logInstrumentationOptions) {
if (unpatchedModules.indexOf(mod.toLowerCase()) !== -1) {
(options.logInstrumentationOptions as InstrumentationOptionsType)[mod] = { enabled: false };
}
}
}

// NOT SUPPORTED CONFIGURATION OPTIONS
if (this.disableAppInsights) {
Logger.getInstance().warn("disableAppInsights configuration no longer supported.");
Expand Down Expand Up @@ -338,31 +379,6 @@ class Config implements IConfig {
}
return options;
}

/**
* Validate UUID Format
* Specs taken from breeze repo
* The definition of a VALID instrumentation key is as follows:
* Not none
* Not empty
* Every character is a hex character [0-9a-f]
* 32 characters are separated into 5 sections via 4 dashes
* First section has 8 characters
* Second section has 4 characters
* Third section has 4 characters
* Fourth section has 4 characters
* Fifth section has 12 characters
*/
private static _validateInstrumentationKey(iKey: string): boolean {
if (iKey.startsWith("InstrumentationKey=")) {
const startIndex = iKey.indexOf("InstrumentationKey=") + "InstrumentationKey=".length;
const endIndex = iKey.indexOf(";", startIndex);
iKey = iKey.substring(startIndex, endIndex);
}
const UUID_Regex = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
const regexp = new RegExp(UUID_Regex);
return regexp.test(iKey);
}
}

export = Config;
47 changes: 34 additions & 13 deletions src/shim/jsonConfig.ts → src/shim/shim-jsonConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class ShimJsonConfig implements IJsonConfig {
// JSON file
else {
const configFileName = "applicationinsights.json";
const rootPath = path.join(__dirname, "../../../../"); // Root of folder (__dirname = ../dist-esm/src)
const rootPath = path.join(__dirname, "../../../"); // Root of folder (__dirname = ../dist-esm/src)
let tempDir = path.join(rootPath, configFileName); // default
const configFile = process.env[ENV_CONFIGURATION_FILE];
if (configFile) {
Expand All @@ -119,8 +119,39 @@ export class ShimJsonConfig implements IJsonConfig {
}
try {
const jsonConfig: IJsonConfig = JSON.parse(jsonString);
this.connectionString = jsonConfig.connectionString;
this.enableAutoCollectExceptions = jsonConfig.enableAutoCollectExceptions;
if (jsonConfig.connectionString !== undefined) {
this.connectionString = jsonConfig.connectionString;
}
if (jsonConfig.disableAllExtendedMetrics !== undefined) {
this.disableAllExtendedMetrics = jsonConfig.disableAllExtendedMetrics;
}
if (jsonConfig.extendedMetricDisablers !== undefined) {
this.extendedMetricDisablers = jsonConfig.extendedMetricDisablers;
}
if (jsonConfig.proxyHttpUrl !== undefined) {
this.proxyHttpUrl = jsonConfig.proxyHttpUrl;
}
if (jsonConfig.proxyHttpsUrl !== undefined) {
this.proxyHttpsUrl = jsonConfig.proxyHttpsUrl;
}
if (jsonConfig.noDiagnosticChannel !== undefined) {
this.noDiagnosticChannel = jsonConfig.noDiagnosticChannel;
}
if (jsonConfig.noHttpAgentKeepAlive !== undefined) {
this.noHttpAgentKeepAlive = jsonConfig.noHttpAgentKeepAlive;
}
if (jsonConfig.noPatchModules !== undefined) {
this.noPatchModules = jsonConfig.noPatchModules;
}
if (jsonConfig.enableWebInstrumentation !== undefined) {
this.enableWebInstrumentation = jsonConfig.enableWebInstrumentation;
}
if (jsonConfig.webInstrumentationSrc !== undefined) {
this.webInstrumentationSrc = jsonConfig.webInstrumentationSrc;
}
if (jsonConfig.webInstrumentationConnectionString !== undefined) {
this.webInstrumentationConnectionString = jsonConfig.webInstrumentationConnectionString;
}
this.endpointUrl = jsonConfig.endpointUrl;
this.samplingPercentage = jsonConfig.samplingPercentage;
this.enableAutoCollectExternalLoggers = jsonConfig.enableAutoCollectExternalLoggers;
Expand Down Expand Up @@ -148,18 +179,8 @@ export class ShimJsonConfig implements IJsonConfig {
this.enableInternalDebugLogging = jsonConfig.enableInternalDebugLogging;
this.enableInternalWarningLogging = jsonConfig.enableInternalWarningLogging;
this.enableSendLiveMetrics = jsonConfig.enableSendLiveMetrics;
this.disableAllExtendedMetrics = jsonConfig.disableAllExtendedMetrics;
this.extendedMetricDisablers = jsonConfig.extendedMetricDisablers;
this.noDiagnosticChannel = jsonConfig.noDiagnosticChannel;
this.noPatchModules = jsonConfig.noPatchModules;
this.noHttpAgentKeepAlive = jsonConfig.noHttpAgentKeepAlive;
this.proxyHttpUrl = jsonConfig.proxyHttpUrl;
this.proxyHttpsUrl = jsonConfig.proxyHttpsUrl;
this.webInstrumentationConnectionString = jsonConfig.webInstrumentationConnectionString;
this.webInstrumentationConfig = jsonConfig.webInstrumentationConfig;
this.webInstrumentationSrc = jsonConfig.webInstrumentationSrc;
this.quickPulseHost = jsonConfig.quickPulseHost;
this.enableWebInstrumentation = jsonConfig.enableWebInstrumentation;
} catch (err) {
Logger.getInstance().info("Missing or invalid JSON config file: ", err);
}
Expand Down
2 changes: 1 addition & 1 deletion src/shim/telemetryClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { TelemetryItem as Envelope } from "../declarations/generated";
import { Context } from "./context";
import { Logger } from "../shared/logging";
import { Util } from "../shared/util";
import Config = require("./config");
import Config = require("./shim-config");
import { AttributeSpanProcessor } from "../shared/util/attributeSpanProcessor";
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import { AttributeLogProcessor } from "../shared/util/attributeLogRecordProcessor";
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ export interface LogInstrumentationOptions {
winston?: { enabled: boolean };
}

export interface InstrumentationOptionsType {
[key: string]: { enabled: boolean }
}

export const enum ExtendedMetricType {
gc = "gc",
heap = "heap",
Expand Down
33 changes: 32 additions & 1 deletion test/unitTests/shim/config.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import azureCoreAuth = require("@azure/core-auth");
import { DiagLogLevel } from '@opentelemetry/api';
import { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http';
import { Logger } from "../../../src/shared/logging"
import Config = require('../../../src/shim/config');
import Config = require('../../../src/shim/shim-config');
import { TelemetryClient } from "../../../src/shim/telemetryClient";
import applicationInsights = require("../../../src/index");

Expand All @@ -28,6 +28,7 @@ class TestTokenCredential implements azureCoreAuth.TokenCredential {

describe("shim/configuration/config", () => {
const connectionString = "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333;IngestionEndpoint=https://centralus-0.in.applicationinsights.azure.com/";
const ignoredOutgoingUrls = ["*.core.windows.net","*.core.chinacloudapi.cn","*.core.cloudapi.de","*.core.usgovcloudapi.net","*.core.microsoft.scloud","*.core.eaglex.ic.gov"];

let originalEnv: NodeJS.ProcessEnv;
let sandbox: sinon.SinonSandbox;
Expand Down Expand Up @@ -109,6 +110,36 @@ describe("shim/configuration/config", () => {
telemetryClient["_attributeSpanProcessor"]["_attributes"] = { "ai.cloud.role": "testRole", "ai.cloud.roleInstance": "testRoleInstance" };
telemetryClient["_attributeLogProcessor"]["_attributes"] = { "ai.cloud.role": "testRole", "ai.cloud.roleInstance": "testRoleInstance" };
});

it("should disable instrumentations when noDiagnosticChannel is set", () => {
const config = new Config(connectionString);
config.noDiagnosticChannel = true;
let options = config.parseConfig();
assert.equal(JSON.stringify(options.instrumentationOptions), JSON.stringify({
http: { enabled: true, ignoreOutgoingUrls: ignoredOutgoingUrls },
azureSdk: { enabled: false },
mongoDb: { enabled: false },
mySql: { enabled: false },
redis: { enabled: false },
redis4: { enabled: false },
postgreSql: { enabled: false }
}));
});

it("should disable specific instrumentations when noPatchModules is set", () => {
const config = new Config(connectionString);
config.noPatchModules = "azuresdk,mongodb-core,redis,pg-pool";
let options = config.parseConfig();
assert.equal(JSON.stringify(options.instrumentationOptions), JSON.stringify({
http: { enabled: true, ignoreOutgoingUrls: ignoredOutgoingUrls },
azureSdk: { enabled: false },
mongoDb: { enabled: false },
mySql: { enabled: true },
redis: { enabled: false },
redis4: { enabled: false },
postgreSql: { enabled: false }
}));
});
// TODO: Add test for warning messages
});
});
2 changes: 1 addition & 1 deletion test/unitTests/shim/jsonConfig.tests.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import assert = require("assert");
import path = require("path");
import { ShimJsonConfig } from "../../../src/shim/jsonConfig";
import { ShimJsonConfig } from "../../../src/shim/shim-jsonConfig";


describe("Json Config", () => {
Expand Down
Loading