Skip to content

Commit

Permalink
[Beta] Add prefix to Agent (#1117)
Browse files Browse the repository at this point in the history
* Add prefix to Agent

* Lint
  • Loading branch information
hectorhdzg committed Apr 17, 2023
1 parent 0bbe5aa commit 4c31023
Show file tree
Hide file tree
Showing 15 changed files with 131 additions and 80 deletions.
27 changes: 25 additions & 2 deletions src/agent/agentLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ import { Util } from "../shared/util";
import { ConsoleWriter } from "./diagnostics/writers/consoleWriter";
import { DiagnosticLogger } from "./diagnostics/diagnosticLogger";
import { StatusLogger } from "./diagnostics/statusLogger";
import { DiagnosticMessageId, IDiagnosticLog, IDiagnosticLogger, NODE_JS_RUNTIME_MAJOR_VERSION } from "./types";
import { AgentResourceProviderType, DiagnosticMessageId, IDiagnosticLog, IDiagnosticLogger, NODE_JS_RUNTIME_MAJOR_VERSION } from "./types";


const forceStart = process.env.APPLICATIONINSIGHTS_FORCE_START === "true";

export class AgentLoader {
private _canLoad: boolean;
protected _canLoad: boolean;
protected _config: ApplicationInsightsConfig;
protected _instrumentationKey: string;
protected _diagnosticLogger: IDiagnosticLogger;
protected _statusLogger: StatusLogger;
protected _isWindows: boolean;
private _aadCredential: any; // Types not available as library should not be loaded in older versions of Node.js runtime

constructor() {
Expand Down Expand Up @@ -49,6 +50,7 @@ export class AgentLoader {
//Default diagnostic using console
this._diagnosticLogger = new DiagnosticLogger(this._instrumentationKey, new ConsoleWriter());
this._statusLogger = new StatusLogger(this._instrumentationKey, new ConsoleWriter());
this._isWindows = process.platform === 'win32';
}
}

Expand Down Expand Up @@ -214,4 +216,25 @@ export class AgentLoader {
}
}

protected _getVersionPrefix(rpType: AgentResourceProviderType): string {
let rp = "u"; // Default unknown
let os = "u"; // Default unknown
if (rpType === AgentResourceProviderType.aks) {
rp = "k";
}
else if (rpType === AgentResourceProviderType.appServices) {
rp = "a";
}
else if (rpType === AgentResourceProviderType.azureFunctions) {
rp = "f";
}
if (process.platform === 'win32') {
os = "w";
}
else if (process.platform === 'linux') {
os = "l";
}
return `${rp}${os}_`;
}

}
60 changes: 31 additions & 29 deletions src/agent/aksLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,43 @@ import { DiagnosticLogger } from './diagnostics/diagnosticLogger';
import { FileWriter } from "./diagnostics/writers/fileWriter";
import { StatusLogger } from "./diagnostics/statusLogger";
import { AgentLoader } from "./agentLoader";
import { AgentResourceProviderType, AZURE_MONITOR_AGENT_PREFIX } from './types';


export class AKSLoader extends AgentLoader {

constructor() {
super();
const isWindows = process.platform === 'win32';
let statusLogDir = '/var/log/applicationinsights/';
if (isWindows) {
if (process.env.HOME) {
statusLogDir = path.join(process.env.HOME, "LogFiles", "ApplicationInsights", "status");
}
else {
statusLogDir = path.join(os.tmpdir(), "Microsoft", "ApplicationInsights", "StatusMonitor", "LogFiles", "ApplicationInsights", "status");
if (this._canLoad) {
let statusLogDir = '/var/log/applicationinsights/';
if (this._isWindows) {
if (process.env.HOME) {
statusLogDir = path.join(process.env.HOME, "LogFiles", "ApplicationInsights", "status");
}
else {
statusLogDir = path.join(os.tmpdir(), "Microsoft", "ApplicationInsights", "StatusMonitor", "LogFiles", "ApplicationInsights", "status");
}
}
}
this._statusLogger = new StatusLogger(this._instrumentationKey, new FileWriter(statusLogDir, 'status_nodejs.json', {
append: false,
deleteOnExit: false,
renamePolicy: 'overwrite',
sizeLimit: 1024 * 1024,
}));
this._statusLogger = new StatusLogger(this._instrumentationKey, new FileWriter(statusLogDir, 'status_nodejs.json', {
append: false,
deleteOnExit: false,
renamePolicy: 'overwrite',
sizeLimit: 1024 * 1024,
}));

this._diagnosticLogger = new DiagnosticLogger(
this._instrumentationKey,
new FileWriter(
statusLogDir,
'applicationinsights-extension.log',
{
append: true,
deleteOnExit: false,
renamePolicy: 'overwrite',
sizeLimit: 1024 * 1024, // 1 MB
}
)
);
this._diagnosticLogger = new DiagnosticLogger(
this._instrumentationKey,
new FileWriter(
statusLogDir,
'applicationinsights-extension.log',
{
append: true,
deleteOnExit: false,
renamePolicy: 'overwrite',
sizeLimit: 1024 * 1024, // 1 MB
}
)
);
process.env[AZURE_MONITOR_AGENT_PREFIX] = this._getVersionPrefix(AgentResourceProviderType.aks);
}
}
}
59 changes: 31 additions & 28 deletions src/agent/appServicesLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,44 @@ import { DiagnosticLogger } from './diagnostics/diagnosticLogger';
import { FileWriter } from "./diagnostics/writers/fileWriter";
import { StatusLogger } from "./diagnostics/statusLogger";
import { AgentLoader } from "./agentLoader";
import { AgentResourceProviderType, AZURE_MONITOR_AGENT_PREFIX } from './types';


export class AppServicesLoader extends AgentLoader {

constructor() {
super();
const isWindows = process.platform === 'win32';
let statusLogDir = '/var/log/applicationinsights/';
if (isWindows) {
if (process.env.HOME) {
statusLogDir = path.join(process.env.HOME, "LogFiles", "ApplicationInsights", "status");
}
else {
statusLogDir = path.join(os.tmpdir(), "Microsoft", "ApplicationInsights", "StatusMonitor", "LogFiles", "ApplicationInsights", "status");
if (this._canLoad) {
let statusLogDir = '/var/log/applicationinsights/';
if (this._isWindows) {
if (process.env.HOME) {
statusLogDir = path.join(process.env.HOME, "LogFiles", "ApplicationInsights", "status");
}
else {
statusLogDir = path.join(os.tmpdir(), "Microsoft", "ApplicationInsights", "StatusMonitor", "LogFiles", "ApplicationInsights", "status");
}
}
}
this._statusLogger = new StatusLogger(this._instrumentationKey, new FileWriter(statusLogDir, 'status_nodejs.json', {
append: false,
deleteOnExit: false,
renamePolicy: 'overwrite',
sizeLimit: 1024 * 1024,
}));
this._statusLogger = new StatusLogger(this._instrumentationKey, new FileWriter(statusLogDir, 'status_nodejs.json', {
append: false,
deleteOnExit: false,
renamePolicy: 'overwrite',
sizeLimit: 1024 * 1024,
}));

this._diagnosticLogger = new DiagnosticLogger(
this._instrumentationKey,
new FileWriter(
statusLogDir,
'applicationinsights-extension.log',
{
append: true,
deleteOnExit: false,
renamePolicy: 'overwrite',
sizeLimit: 1024 * 1024, // 1 MB
}
)
);
this._diagnosticLogger = new DiagnosticLogger(
this._instrumentationKey,
new FileWriter(
statusLogDir,
'applicationinsights-extension.log',
{
append: true,
deleteOnExit: false,
renamePolicy: 'overwrite',
sizeLimit: 1024 * 1024, // 1 MB
}
)
);
process.env[AZURE_MONITOR_AGENT_PREFIX] = this._getVersionPrefix(AgentResourceProviderType.appServices);
}
}
}
18 changes: 11 additions & 7 deletions src/agent/azureFunctionsLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ import { AgentLoader } from "./agentLoader";
import { DiagnosticLogger } from "./diagnostics/diagnosticLogger";
import { StatusLogger } from "./diagnostics/statusLogger";
import { AzureFunctionsWriter } from "./diagnostics/writers/azureFunctionsWriter";
import { AgentResourceProviderType, AZURE_MONITOR_AGENT_PREFIX } from "./types";


export class AzureFunctionsLoader extends AgentLoader {

constructor() {
super();
// Azure Fn specific configuration
this._config.enableAutoCollectPerformance = false;
this._config.enableAutoCollectStandardMetrics = false;

const writer = new AzureFunctionsWriter(this._instrumentationKey);
this._diagnosticLogger = new DiagnosticLogger(this._instrumentationKey, writer);
this._statusLogger = new StatusLogger(this._instrumentationKey, writer)
if (this._canLoad) {
// Azure Fn specific configuration
this._config.enableAutoCollectPerformance = false;
this._config.enableAutoCollectStandardMetrics = false;

const writer = new AzureFunctionsWriter(this._instrumentationKey);
this._diagnosticLogger = new DiagnosticLogger(this._instrumentationKey, writer);
this._statusLogger = new StatusLogger(this._instrumentationKey, writer);
process.env[AZURE_MONITOR_AGENT_PREFIX] = this._getVersionPrefix(AgentResourceProviderType.azureFunctions);
}
}
}
4 changes: 2 additions & 2 deletions src/agent/diagnostics/baseDiagnosticLogger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IAgentLogger, IDiagnosticLog, IDiagnosticLogger, LOGGER_LANGUAGE, LOGGER_NAME } from "../types";
import { APPLICATION_INSIGHTS_SDK_VERSION } from "../../declarations/constants";
import { AZURE_MONITOR_DISTRO_VERSION } from "../../declarations/constants";


export class BaseDiagnosticLogger implements IDiagnosticLogger {
Expand All @@ -19,7 +19,7 @@ export class BaseDiagnosticLogger implements IDiagnosticLogger {
this._language = LOGGER_LANGUAGE;
this._siteName = process.env.WEBSITE_SITE_NAME;
this._extensionVersion = process.env.ApplicationInsightsAgent_EXTENSION_VERSION;
this._sdkVersion = APPLICATION_INSIGHTS_SDK_VERSION;
this._sdkVersion = AZURE_MONITOR_DISTRO_VERSION;
this._subscriptionId = process.env.WEBSITE_OWNER_NAME ? process.env.WEBSITE_OWNER_NAME.split("+")[0] : null;
}

Expand Down
4 changes: 2 additions & 2 deletions src/agent/diagnostics/statusLogger.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as os from "os";
import { FileWriter } from "./writers/fileWriter";
import { IAgentLogger, IStatusContract, LOGGER_LANGUAGE } from "../types";
import { APPLICATION_INSIGHTS_SDK_VERSION } from "../../declarations/constants";
import { AZURE_MONITOR_DISTRO_VERSION } from "../../declarations/constants";


export class StatusLogger {
Expand All @@ -16,7 +16,7 @@ export class StatusLogger {
this._agentLogger = agentLogger;
this._instrumentationKey = instrumentationKey;
this._language = LOGGER_LANGUAGE;
this._sdkVersion = APPLICATION_INSIGHTS_SDK_VERSION;
this._sdkVersion = AZURE_MONITOR_DISTRO_VERSION;
this._machineName = os.hostname();
this._processId = String(process.pid);
}
Expand Down
6 changes: 3 additions & 3 deletions src/agent/diagnostics/writers/azureFunctionsWriter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { APPLICATION_INSIGHTS_SDK_VERSION } from "../../../declarations/constants";
import { AZURE_MONITOR_DISTRO_VERSION } from "../../../declarations/constants";
import { AZURE_APP_NAME, IAgentLogger } from "../../types";

const AZURE_FUNCTIONS_DIAGNOSTIC_PREFIX = "LanguageWorkerConsoleLogMS_APPLICATION_INSIGHTS_LOGS";
Expand All @@ -11,7 +11,7 @@ export class AzureFunctionsWriter implements IAgentLogger {
constructor(instrumentationKey: string) {
this._instrumentationKey = instrumentationKey;
this._appName = AZURE_APP_NAME;
this._agentVersion = APPLICATION_INSIGHTS_SDK_VERSION;
this._agentVersion = AZURE_MONITOR_DISTRO_VERSION;
}

public log(log: any) {
Expand All @@ -23,7 +23,7 @@ export class AzureFunctionsWriter implements IAgentLogger {
}

private _getAzureFnLog(log: any): string {
let output = `${AZURE_FUNCTIONS_DIAGNOSTIC_PREFIX} ${log.time},${log.level},${log.logger},\"${log.message}\",${this._appName},${this._instrumentationKey},${this._agentVersion},node.js`;
const output = `${AZURE_FUNCTIONS_DIAGNOSTIC_PREFIX} ${log.time},${log.level},${log.logger},\"${log.message}\",${this._appName},${this._instrumentationKey},${this._agentVersion},node.js`;
return output;
}
}
7 changes: 7 additions & 0 deletions src/agent/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ export const LOGGER_NAME = "applicationinsights.extension.diagnostics";
export const LOGGER_LANGUAGE = "nodejs";
export const NODE_JS_RUNTIME_MAJOR_VERSION = parseInt(process.versions.node.split('.')[0], 10);
export const AZURE_APP_NAME = process.env.WEBSITE_SITE_NAME || 'unknown';
export const AZURE_MONITOR_AGENT_PREFIX = "AZURE_MONITOR_AGENT_PREFIX";

export enum AgentResourceProviderType {
appServices,
azureFunctions,
aks
}

export interface IAgentLogger {
log(message: any, ...optional: any[]): void;
Expand Down
3 changes: 2 additions & 1 deletion src/declarations/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const APPLICATION_INSIGHTS_SDK_VERSION = "3.0.0-beta.4";
export const AZURE_MONITOR_DISTRO_VERSION = "3.0.0-beta.4";
process.env["AZURE_MONITOR_DISTRO_VERSION"] = AZURE_MONITOR_DISTRO_VERSION;
export const DEFAULT_BREEZE_ENDPOINT = "https://dc.services.visualstudio.com";
export const DEFAULT_LIVEMETRICS_ENDPOINT = "https://rt.services.visualstudio.com";
export const DEFAULT_LIVEMETRICS_HOST = "rt.services.visualstudio.com";
5 changes: 2 additions & 3 deletions src/metrics/statsbeat/statsbeat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { IVirtualMachineInfo } from "../../shared/azureVirtualMachine";
import { MeterProvider, PeriodicExportingMetricReader, PeriodicExportingMetricReaderOptions } from "@opentelemetry/sdk-metrics";
import { AzureMonitorExporterOptions, AzureMonitorStatsbeatExporter } from "@azure/monitor-opentelemetry-exporter";
import { BatchObservableResult, Meter, ObservableGauge, ObservableResult } from "@opentelemetry/api-metrics";
import { APPLICATION_INSIGHTS_SDK_VERSION } from "../../declarations/constants";
import { AZURE_MONITOR_DISTRO_VERSION } from "../../declarations/constants";

const STATSBEAT_LANGUAGE = "node";
const AZURE_MONITOR_STATSBEAT_FEATURES = "AZURE_MONITOR_STATSBEAT_FEATURES";
Expand All @@ -44,7 +44,7 @@ export class Statsbeat {

// Custom dimensions
private _resourceProvider: string = StatsbeatResourceProvider.unknown;
private _sdkVersion: string = APPLICATION_INSIGHTS_SDK_VERSION;
private _sdkVersion: string = AZURE_MONITOR_DISTRO_VERSION;
private _runtimeVersion: string = process.version;
private _os: string = os.type();
private _language: string = STATSBEAT_LANGUAGE;
Expand Down Expand Up @@ -118,7 +118,6 @@ export class Statsbeat {

this._language = STATSBEAT_LANGUAGE;
this._cikey = this._config.getInstrumentationKey();
this._sdkVersion = APPLICATION_INSIGHTS_SDK_VERSION;
this._os = os.type();
this._runtimeVersion = process.version;

Expand Down
4 changes: 2 additions & 2 deletions src/shared/configuration/applicationInsightsConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export class ApplicationInsightsConfig implements IConfig {
}

private _getDefaultResource(): Resource {
let resource = Resource.EMPTY;
const resource = Resource.EMPTY;
resource.attributes[SemanticResourceAttributes.SERVICE_NAME] = DEFAULT_ROLE_NAME;
if (process.env.WEBSITE_SITE_NAME) {
// Azure Web apps and Functions
Expand All @@ -139,7 +139,7 @@ export class ApplicationInsightsConfig implements IConfig {
resource.attributes[SemanticResourceAttributes.SERVICE_INSTANCE_ID] =
process.env.WEBSITE_INSTANCE_ID;
}
const sdkVersion = Constants.APPLICATION_INSIGHTS_SDK_VERSION;
const sdkVersion = Constants.AZURE_MONITOR_DISTRO_VERSION;
resource.attributes[SemanticResourceAttributes.TELEMETRY_SDK_LANGUAGE] =
TelemetrySdkLanguageValues.NODEJS;
resource.attributes[
Expand Down
2 changes: 1 addition & 1 deletion src/shared/logging/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class Logger implements DiagLogger {
* @param logLevel - The DiagLogLevel used to filter logs sent to the logger.
* @param suppressOverrideMessage - Setting that suppress the warning message normally emitted when registering a logger when another logger is already registered.
*/
public updateLogLevel(logLevel: DiagLogLevel, suppressOverrideMessage: boolean = true) {
public updateLogLevel(logLevel: DiagLogLevel, suppressOverrideMessage = true) {
this._diagLevel = logLevel;

// Set OpenTelemetry Logger
Expand Down
3 changes: 3 additions & 0 deletions test/unitTests/agent/aksLoader.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ describe("agent/AKSLoader", () => {
// Loader is using correct diagnostics
assert.equal(agent["_diagnosticLogger"], diagnosticLogger, "Wrong diagnosticLogger");
assert.equal(agent["_statusLogger"], statusLogger, "Wrong statusLogger");
// Prefix Env variable should be set
assert.equal(process.env["AZURE_MONITOR_AGENT_PREFIX"].length, 3, "Missing prefix");
assert.ok(process.env["AZURE_MONITOR_AGENT_PREFIX"].startsWith, "k");
});

it("initialize", () => {
Expand Down
6 changes: 6 additions & 0 deletions test/unitTests/agent/appServicesLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,23 @@ describe("agent/AppServicesLoader", () => {
assert.ok(statusLogger["_agentLogger"] instanceof FileWriter, "Wrong statusLogger agentLogger");
assert.equal(statusLogger["_agentLogger"]["_filename"], "status_nodejs.json");

// Prefix Env variable should be set
assert.equal(process.env["AZURE_MONITOR_AGENT_PREFIX"].length, 3, "Missing prefix");

if (isWindows) {
assert.equal(diagnosticLogger["_agentLogger"]["_filepath"], "c:\\LogFiles\\ApplicationInsights\\status");
assert.equal(statusLogger["_agentLogger"]["_filepath"], "c:\\LogFiles\\ApplicationInsights\\status");
assert.equal(process.env["AZURE_MONITOR_AGENT_PREFIX"], "aw_");
}
else {
assert.equal(diagnosticLogger["_agentLogger"]["_filepath"], "/var/log/applicationinsights/");
assert.equal(statusLogger["_agentLogger"]["_filepath"], "/var/log/applicationinsights/");
assert.equal(process.env["AZURE_MONITOR_AGENT_PREFIX"], "al_");
}
// Loader is using correct diagnostics
assert.equal(agent["_diagnosticLogger"], diagnosticLogger, "Wrong diagnosticLogger");
assert.equal(agent["_statusLogger"], statusLogger, "Wrong statusLogger");

});

it("initialize", () => {
Expand Down
Loading

0 comments on commit 4c31023

Please sign in to comment.