ApplicationInsights-JS icon indicating copy to clipboard operation
ApplicationInsights-JS copied to clipboard

[BUG] Offline Channel silently discards all messages received prior to configuration

Open peitschie opened this issue 1 month ago • 2 comments

Description/Screenshot

If I follow the exact setup in https://github.com/microsoft/ApplicationInsights-JS/tree/main/channels/offline-channel-js#npm-setup, the first messages are discarded due to the async nature of the channel configuration.

Specifically, the offline channel is configured via a scheduledTimeout: https://github.com/microsoft/ApplicationInsights-JS/blob/223d8c2381e53cf11ee114bfa894ce8bce14cfbd/channels/offline-channel-js/src/OfflineChannel.ts#L131

Any calls to process items are discarded until this configuration is performed: https://github.com/microsoft/ApplicationInsights-JS/blob/223d8c2381e53cf11ee114bfa894ce8bce14cfbd/channels/offline-channel-js/src/OfflineChannel.ts#L169

Steps to Reproduce

Run the exact setup code, and see that even when the persistence level is correctly set, the immediately messages sent are not stored by the channel.

Expected behavior

All logs should be recorded by the offline channel immediately.

peitschie avatar Nov 24 '25 22:11 peitschie

Yeah, the example should be updated now that (I believe) we addressed (a loooong time ago now) needing to wait for the sender channel to be initialized before adding the offline channel. You "should" (need to check) now be able to pass the offline channel as an "extension" in the config blob to avoid this so that it is initialized as part of the full SDK initialization.

let offlineChannel = new OfflineChannel();
let coreConfig = {
    connectionString: "YOUR_CONNECTION_STRING",
    extensionConfig: {
        [offlineChannel.identifier]: {
            providers: [eStorageProviders.LocalStorage, eStorageProviders.IndexedDb],
            minPersistenceLevel:  2, // only events with PersistenceLevel >=2 will be saved/sent
        } // Add config for offline support channel
    },
    extensions: [ offlineChannel]
};

If this "still" doesn't work (I don't remember for sure), then we need to fix that so that it does, as that will be the only way to address this problem...

Why? Well it's because the term "Silently discarding all messages", is not "quite" accurate....

This occurs because the "offlineChannel" is not even in the processing pipeline when those events are processed (with the result being that they are not included) and as with most of the other extensions if an extension is not "loaded" (which doesn't happen until appInsights.addPlugin(offlineChannel);) then they never see the previous events.

Hence they are not discarded, its that they are not even seen.

MSNev avatar Nov 24 '25 23:11 MSNev

Thanks for the clarification @MSNev

The short answer is: this still doesn't work 🙁

I'm dropping breakpoints specifically in processTelemetry hook of the offline channel plugin specifically to confirm that it is definitely being called and asked to process an event prior to being fully configured.

I'm doing the full construction and then immediately using the instance:

offlineChannel = new OfflineChannel();
appInsights = new ApplicationInsights({
  config: {
    connectionString: "...",
    loggingLevelConsole: config.loggingLevel,
    loggingLevelTelemetry: config.loggingLevel,
    disableAjaxTracking: true,
    disableFetchTracking: true,
    extensionConfig: {
      [offlineChannel.identifier]: {
        providers: [eStorageProviders.IndexedDb],
      },
    },
    extensions: [offlineChannel],
  },
});
appInsights.addTelemetryInitializer(axiosErrorsInitializer);
appInsights.loadAppInsights();
appInsights.trackTrace({ message: "Application started" });

In this case, I can see the message is making it through to the processTelemetry method of the offline channel, but it's doing it before the channel has configured.

If I put a very short delay, the initialization completes.

peitschie avatar Nov 25 '25 05:11 peitschie