diff --git a/src/shared/util/attributeLogRecordProcessor.ts b/src/shared/util/attributeLogRecordProcessor.ts new file mode 100644 index 000000000..273bf4de7 --- /dev/null +++ b/src/shared/util/attributeLogRecordProcessor.ts @@ -0,0 +1,14 @@ +import { BatchLogRecordProcessor, LogRecord, LogRecordExporter } from "@opentelemetry/sdk-logs"; + +export class AttributeLogProcessor extends BatchLogRecordProcessor { + private _attributes: { [key: string]: string }; + constructor(exporter: LogRecordExporter, attributes: { [key: string]: string }) { + super(exporter); + this._attributes = attributes; + } + // Override onStart to apply span attributes before exporting + onEmit(record: LogRecord) { + record.setAttributes(this._attributes); + super.onEmit(record); + } +} diff --git a/src/shim/shim-applicationinsights.ts b/src/shim/shim-applicationinsights.ts index 0de1039cd..6f4f1dddb 100644 --- a/src/shim/shim-applicationinsights.ts +++ b/src/shim/shim-applicationinsights.ts @@ -66,7 +66,7 @@ export function start() { const ignoreIncomingRequestHooks = httpOptions?.ignoreIncomingRequestHook?.toString(); const ignoreOutgoingRequestHooks = httpOptions?.ignoreOutgoingRequestHook?.toString(); - const ignoreFunction = (request: any) => true; + const ignoreFunction = (request: http.IncomingMessage | http.RequestOptions) => true; if ( ignoreIncomingRequestHooks === ignoreFunction.toString() && ignoreOutgoingRequestHooks === ignoreFunction.toString() diff --git a/src/shim/telemetryClient.ts b/src/shim/telemetryClient.ts index 3a81ed7d5..89949e3e4 100644 --- a/src/shim/telemetryClient.ts +++ b/src/shim/telemetryClient.ts @@ -22,9 +22,10 @@ import { dispose, Configuration, _setupCalled } from "./shim-applicationinsights import { HttpInstrumentationConfig } from "@opentelemetry/instrumentation-http"; import { ShimJsonConfig } from "./shim-jsonConfig"; import ConfigHelper = require("../shared/util/configHelper"); -import { AzureMonitorTraceExporter } from "@azure/monitor-opentelemetry-exporter"; +import { AzureMonitorTraceExporter, AzureMonitorLogExporter } from "@azure/monitor-opentelemetry-exporter"; import { AttributeSpanProcessor } from "../shared/util/attributeSpanProcessor"; import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; +import { AttributeLogProcessor } from "../shared/util/attributeLogRecordProcessor"; /** * Application Insights telemetry client provides interface to track telemetry items, register telemetry initializers and @@ -37,7 +38,8 @@ export class TelemetryClient { private _console: AutoCollectConsole; private _exceptions: AutoCollectExceptions; private _idGenerator: IdGenerator; - private _attributeProcessor: AttributeSpanProcessor; + private _attributeSpanProcessor: AttributeSpanProcessor; + private _attributeLogProcessor: AttributeLogProcessor; public context: Context; public commonProperties: { [key: string]: string }; // TODO: Add setter so Resources are updated public config: IConfig; @@ -472,9 +474,12 @@ export class TelemetryClient { // Only support attribute processing in the shim if (_setupCalled) { - this._attributeProcessor = new AttributeSpanProcessor(new AzureMonitorTraceExporter(this._options.azureMonitorExporterConfig), this.context.tags); + this._attributeSpanProcessor = new AttributeSpanProcessor(new AzureMonitorTraceExporter(this._options.azureMonitorExporterConfig), this.context.tags); const tracerProvider = this._client.getTracerProvider() as NodeTracerProvider; - tracerProvider.addSpanProcessor(this._attributeProcessor); + tracerProvider.addSpanProcessor(this._attributeSpanProcessor); + this._attributeLogProcessor = new AttributeLogProcessor(new AzureMonitorLogExporter(this._options.azureMonitorExporterConfig), this.context.tags); + const loggerProvider = this._client.getLoggerProvider(); + loggerProvider.addLogRecordProcessor(this._attributeLogProcessor); } } diff --git a/test/unitTests/shim/config.tests.ts b/test/unitTests/shim/config.tests.ts index a0f00361a..f7de17205 100644 --- a/test/unitTests/shim/config.tests.ts +++ b/test/unitTests/shim/config.tests.ts @@ -103,11 +103,12 @@ describe("shim/configuration/config", () => { assert.equal(JSON.stringify(telemetryClient["_options"].extendedMetrics), JSON.stringify({ gc: false, heap: false, loop: false })); }); - it("should set context tags", () => { + it("should set context tags on logs and spans", () => { const telemetryClient = new TelemetryClient(connectionString); telemetryClient.context.tags = { "ai.cloud.role": "testRole", "ai.cloud.roleInstance": "testRoleInstance" }; telemetryClient.start(); - telemetryClient["_attributeProcessor"]["_attributes"] = { "ai.cloud.role": "testRole", "ai.cloud.roleInstance": "testRoleInstance" }; + telemetryClient["_attributeSpanProcessor"]["_attributes"] = { "ai.cloud.role": "testRole", "ai.cloud.roleInstance": "testRoleInstance" }; + telemetryClient["_attributeLogProcessor"]["_attributes"] = { "ai.cloud.role": "testRole", "ai.cloud.roleInstance": "testRoleInstance" }; }); it("should disableAppInsights", () => {