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

BatchSpanProcessor error when running on Next.js instrumentation #1383

Open
lapa182 opened this issue Sep 12, 2024 · 6 comments
Open

BatchSpanProcessor error when running on Next.js instrumentation #1383

lapa182 opened this issue Sep 12, 2024 · 6 comments

Comments

@lapa182
Copy link

lapa182 commented Sep 12, 2024

Hello, we are seeing a number of errors on the console (please see below):

2024-09-12T15:39:59.766848450Z {"stack":"Error: BatchSpanProcessor: span export failed\n    at /app/node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@opentelemetry/sdk-trace-base/build/src/export/BatchSpanProcessorBase.js:154:85\n    at AzureMonitorTraceExporter.export (/app/node_modules/.pnpm/@[email protected]/node_modules/@azure/monitor-opentelemetry-exporter/dist/index.js:3639:13)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)","message":"BatchSpanProcessor: span export failed","name":"Error"} []

This is the latest applicationinsights package version (3.2.2) with Next.js 14.2.9 loaded in the instrumentation.

@hectorhdzg
Copy link
Member

@lapa182 please follow instructions on how to create debug logs for this library here, we need the actual exporter error to determine the issue here.

@lapa182
Copy link
Author

lapa182 commented Sep 24, 2024

Thanks @hectorhdzg, I passed this to the team and asked them to enable the debug logs. Once we have the information me or someone from the team will post it here!

@lapa182
Copy link
Author

lapa182 commented Oct 1, 2024

Hi @hectorhdzg, sorry for taking too long, I'm attaching the CSV with the logs where the issue is happening (if you search for BatchSpanprocessor you can find it). From what I saw briefly, it's related to ContextTagKeys being too long.

query_data_v2_without_II.csv

Also, not sure if it's related to this, but when we did some load testing with the AppInsights turned on, our application memory usage sky-rocketed and it crashed after some time due to memory heap. We even bumped the memory to 28GB thinking it was because of the memory we needed and still continued to rump it up and it crashed, but as soon we turned AppInsights off the memory usage didn't go up at all.

@hectorhdzg
Copy link
Member

@lapa182 error will be fixed next release, for performance issue, can you add more details about your app and initialization of the SDK?, @JacksonWeber we may need to add the scenario in our perf tests

@lapa182
Copy link
Author

lapa182 commented Oct 2, 2024

Sure.

We are using:

Node.js: 22.9.0
Next.js 14.2.3
applicationinsights: 3.3.0
Azure as host with App Service and Docker

Here's a screenshot of the memory usage example, which we run using Load Testing from Azure with 50 users accessing simultaneously 22 pages:

image

Example of the log of heap memory:

Memory Error

This was the pattern which triggered our investigation to do the load testing:

Memory Leak

The way we currently load AppInsights is using the instrumentation.ts file following this link:

export async function register() {
	if (process.env.NEXT_RUNTIME === 'nodejs') {
		await import('./utils/appInsights/azure-monitor');
	}
}

And the azure-monitor.ts:

import * as appInsights from 'applicationinsights';

const connectionString = process.env.APPLICATIONINSIGHTS_CONNECTION_STRING;

if (connectionString) {
	appInsights
		.setup(connectionString)
		.setAutoCollectRequests(true)
		.setAutoCollectPerformance(true, false)
		.setAutoCollectExceptions(true)
		.setAutoCollectDependencies(true)
		.setAutoCollectConsole(true, true)
		.setAutoCollectPreAggregatedMetrics(true)
		.setSendLiveMetrics(false)
		.setInternalLogging(false, true)
		.enableWebInstrumentation(false)
		.start();
}

We then load inside AppInsightsProvider as the following:

import type { PropsWithChildren, ReactNode } from 'react';

'use client';

import { AppInsightsContext, ReactPlugin } from '@microsoft/applicationinsights-react-js';
import { ApplicationInsights } from '@microsoft/applicationinsights-web';
import type { PropsWithChildren } from 'react';

interface StateProps {
	appInsights: ApplicationInsights;
	reactPlugin: ReactPlugin;
}

// Store the AI state on `window` so we aren't constantly re-initializing it on every hot-reload during `npm run dev` (we can't use a `Symbol` for this, as we'd get a new symbol on every hot-reload)
const getState = (): StateProps | undefined =>
	typeof window !== 'undefined' ? (window.__AI_STATE__ as StateProps | undefined) : undefined;

const setState = (state: StateProps): void => {
	if (typeof window !== 'undefined') {
		window.__AI_STATE__ = state;
	}
};

function getOrInit(connectionString: string): StateProps {
	let state = getState();
	if (state) {
		return state;
	}

	const reactPlugin = new ReactPlugin();
	const appInsights = new ApplicationInsights({
		config: {
			connectionString,
			disableAjaxTracking: true,
			disableFetchTracking: true,
			extensions: [reactPlugin],
			extensionConfig: {
				[reactPlugin.identifier]: {},
			},
		},
	});

	appInsights.loadAppInsights();

	state = {
		appInsights,
		reactPlugin,
	};

	setState(state);

	return state;
}

interface AppInsightsContextProviderProps extends PropsWithChildren {
	connectionString: string;
}

function AppInsightsContextProvider({ connectionString, children }: AppInsightsContextProviderProps): JSX.Element {
	return (
		<AppInsightsContext.Provider value={getOrInit(connectionString).reactPlugin}>
			{children}
		</AppInsightsContext.Provider>
	);
}

export { AppInsightsContextProvider };

export type { AppInsightsContextProviderProps };


function AppInsightsProvider({ children }: PropsWithChildren): JSX.Element | ReactNode {
	const connectionString = process.env.APPLICATIONINSIGHTS_CONNECTION_STRING;

	if (!connectionString) {
		return children;
	}

	return <AppInsightsContextProvider connectionString={connectionString}>{children}</AppInsightsContextProvider>;
}

export { AppInsightsProvider };

And load in the layout.tsx:

export default function RootLayout({ children }: RootLayoutProps): JSX.Element {
	return (
		<html lang="en">
			<body>
				<AppInsightsProvider>
					{children}
				</AppInsightsProvider>
			</body>
		</html>
	);
}

For context, we were following this implementation: https://github.com/CMeeg/nextjs-aca

cc @Adonas-B

hectorhdzg added a commit to Azure/azure-sdk-for-js that referenced this issue Dec 6, 2024
…31283)

### Packages impacted by this PR
@azure/monitor-opentelemetry-exporter

### Issues associated with this PR

microsoft/ApplicationInsights-node.js#1383 (comment)
@ricardasjak
Copy link

Hello, same issue here. Any plans to release a fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants