我如何在 Service Worker 中使用 ApplicationInsights-JS?
How can I utilise ApplicationInsights-JS in a service worker?
我目前正在我的渐进式 Web 应用程序中使用 ApplicationInsights-JS。它在我的反应组件中工作,因为我可以从相关的 npm 包中导入我需要的东西。
然而,在我的 service worker 中,我只能使用 importScripts 导入逻辑。
我确实设法在他们的 Github 页面上找到了 ApplicationInsights-JS 的 CDN,但是似乎要使用此库初始化应用程序洞察,您需要访问 window 以便存储 appinsights,这是 service worker 做不到的。
我尝试使用网页代码段方法,因为 CDN 似乎是
与那个特定的库相关,但我不能使用 window 并且我不确定如何实现这个解决方案。
这是用于初始化应用洞察对象的建议代码段的复制粘贴:https://github.com/Microsoft/ApplicationInsights-JS
importScripts('https://az416426.vo.msecnd.net/beta/ai.2.min.js');
const sdkInstance = 'appInsightsSDK';
window[sdkInstance] = 'appInsights';
const aiName = window[sdkInstance];
const aisdk =
window[aiName] ||
(function(e) {
function n(e) {
i[e] = function() {
const n = arguments;
i.queue.push(function() {
i[e](...n);
});
};
}
let i = { config: e };
i.initialize = !0;
const a = document;
const t = window;
setTimeout(function() {
const n = a.createElement('script');
(n.src = e.url || 'https://az416426.vo.msecnd.net/next/ai.2.min.js'),
a.getElementsByTagName('script')[0].parentNode.appendChild(n);
});
try {
i.cookie = a.cookie;
} catch (e) {}
(i.queue = []), (i.version = 2);
for (
const r = [
'Event',
'PageView',
'Exception',
'Trace',
'DependencyData',
'Metric',
'PageViewPerformance'
];
r.length;
)
n(`track${r.pop()}`);
n('startTrackPage'), n('stopTrackPage');
const o = `Track${r[0]}`;
if (
(n(`start${o}`),
n(`stop${o}`),
!(
!0 === e.disableExceptionTracking ||
(e.extensionConfig &&
e.extensionConfig.ApplicationInsightsAnalytics &&
!0 ===
e.extensionConfig.ApplicationInsightsAnalytics
.disableExceptionTracking)
))
) {
n(`_${(r = 'onerror')}`);
const s = t[r];
(t[r] = function(e, n, a, t, o) {
const c = s && s(e, n, a, t, o);
return (
!0 !== c &&
i[`_${r}`]({
message: e,
url: n,
lineNumber: a,
columnNumber: t,
error: o
}),
c
);
}),
(e.autoExceptionInstrumented = !0);
}
return i;
})({ instrumentationKey: 'xxx-xxx-xxx-xxx-xxx' });
(window[aiName] = aisdk),
aisdk.queue && aisdk.queue.length === 0 && aisdk.trackPageView({});
我得到 window is not defined 这是预期的,但我不确定我还能如何从 service worker 使用这个库。
有没有其他人有类似的实现,他们使用 Service Worker 的 ApplicationInsights 成功记录了遥测数据?
我意识到我把这个复杂化了。
因为我只需要跟踪一个自定义事件,而不需要 appInsights 做的所有自动页面跟踪等,所以我最终从我的服务工作者那里获取数据。
我刚刚从使用我的 React 页面发出的请求中复制了 header 和 body 格式。
以下成功地将遥测记录到我的应用洞察信息中心:
fetch(url, {
method: 'post',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify([
{
time: '2019-05-02T15:56:37.589Z',
iKey: 'INSTRUMENTATION_KEY',
name:
'Microsoft.ApplicationInsights.INSTRUMENTATION_KEY.Event',
tags: {
'ai.user.id': 'l6Tey',
'ai.session.id': 'TL+Ry',
'ai.device.id': 'browser',
'ai.device.type': 'Browser',
'ai.operation.id': 'HUfNE',
SampleRate: '100',
// eslint-disable-next-line no-script-url
'ai.internal.sdkVersion': 'javascript:2.0.0-rc4'
},
data: {
baseType: 'EventData',
baseData: {
ver: 2,
name: 'Testing manual event',
properties: {},
measurements: {}
}
}
}
])
})
.then(json)
.then(function(data) {
})
.catch(function(error) {
});
我几乎 设法在我们应用程序的服务工作者中使用 Microsoft Application Insights。
关键部分是:
- 将 appInsights 的轻量级版本(参见 this small remark at 4th step)与
importScripts('https://az416426.vo.msecnd.net/next/aib.2.min.js')
结合使用。
- 初始化 appInsights 对象:
appInsights = new Microsoft.AppInsights.AppInsights({ instrumentationKey: "[replace with your own key]" });
- 当需要跟踪时(在
onpush
事件或 onnotificationclick
期间),去 appInsight.track({ eventItemFields })
然后 appInsights.flush()
。
我说过 "almost" 因为刷新部分似乎不起作用,我得到:"Sender was not initialized" 启用调试后出现内部错误。
如果我成功解决了这个问题,我会在这里发布一个有效的示例代码。
参考文献:
在service worker中使用Web SDK比较麻烦。完整版依赖于 window 对象,而基本 SDK 依赖于 Beacon 或 XmlHttpRequest 来发送消息(在文件 https://github.com/microsoft/ApplicationInsights-JS/blob/master/channels/applicationinsights-channel-js/src/Sender.ts 中):
if (!_self._senderConfig.isBeaconApiDisabled() && Util.IsBeaconApiSupported()) {
_self._sender = _beaconSender;
} else {
if (typeof XMLHttpRequest !== undefined) {
const xhr:any = getGlobalInst("XMLHttpRequest");
if(xhr) {
const testXhr = new xhr();
if ("withCredentials" in testXhr) {
_self._sender = _xhrSender;
_self._XMLHttpRequestSupported = true;
} else if (typeof XDomainRequest !== undefined) {
_self._sender = _xdrSender; // IE 8 and 9
}
}
}
}
目前 Application Insights SDK 似乎不支持服务工作者。 Rajars 解决方案似乎是目前最好的选择。
更新:Github 回购中存在关于此的问题:https://github.com/microsoft/ApplicationInsights-JS/issues/1436
一个可行的建议是在初始化 Application Insights 之前使用 basic/lightweight 版本的 Application Insights(如 Rajar 所述)并添加 XMLHttpRequest polyfill(使用提取 api)。之后就可以使用轻量版了
可在此处找到示例:https://github.com/Pkiri/pwa-ai
我试图在 E2E 测试环境 (pupeteer) 中使用 AppInsightsSDK,当我尝试记录事件或指标时,出现“发件人未初始化”错误。
正如@Pkiri 提到的那样,需要 XMLHttpRequest polyfill 来解决这个问题。虽然我的场景与 Service worker 没有直接关系,但我想提一下@Pkiri 的回答并不完全正确,因为也可以使用 globalThis, self, window或global根据SDK源码函数得到相同的结果getGlobalInst("XMLHttpRequest");
解析为
function getGlobal() {
if (typeof globalThis !== strShimUndefined && globalThis) {
return globalThis;
}
if (typeof self !== strShimUndefined && self) {
return self;
}
if (typeof window !== strShimUndefined && window) {
return window;
}
if (typeof global !== strShimUndefined && global) {
return global;
}
return null;
}
对于我的场景,这是一个有效的解决方案
const appInsights = new ApplicationInsights({
config: {
instrumentationKey: 'AppInsights_InstrumentationKey',
},
});
global.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
global.appInsights = appInsights.loadAppInsights();
我目前正在我的渐进式 Web 应用程序中使用 ApplicationInsights-JS。它在我的反应组件中工作,因为我可以从相关的 npm 包中导入我需要的东西。
然而,在我的 service worker 中,我只能使用 importScripts 导入逻辑。
我确实设法在他们的 Github 页面上找到了 ApplicationInsights-JS 的 CDN,但是似乎要使用此库初始化应用程序洞察,您需要访问 window 以便存储 appinsights,这是 service worker 做不到的。
我尝试使用网页代码段方法,因为 CDN 似乎是 与那个特定的库相关,但我不能使用 window 并且我不确定如何实现这个解决方案。
这是用于初始化应用洞察对象的建议代码段的复制粘贴:https://github.com/Microsoft/ApplicationInsights-JS
importScripts('https://az416426.vo.msecnd.net/beta/ai.2.min.js');
const sdkInstance = 'appInsightsSDK';
window[sdkInstance] = 'appInsights';
const aiName = window[sdkInstance];
const aisdk =
window[aiName] ||
(function(e) {
function n(e) {
i[e] = function() {
const n = arguments;
i.queue.push(function() {
i[e](...n);
});
};
}
let i = { config: e };
i.initialize = !0;
const a = document;
const t = window;
setTimeout(function() {
const n = a.createElement('script');
(n.src = e.url || 'https://az416426.vo.msecnd.net/next/ai.2.min.js'),
a.getElementsByTagName('script')[0].parentNode.appendChild(n);
});
try {
i.cookie = a.cookie;
} catch (e) {}
(i.queue = []), (i.version = 2);
for (
const r = [
'Event',
'PageView',
'Exception',
'Trace',
'DependencyData',
'Metric',
'PageViewPerformance'
];
r.length;
)
n(`track${r.pop()}`);
n('startTrackPage'), n('stopTrackPage');
const o = `Track${r[0]}`;
if (
(n(`start${o}`),
n(`stop${o}`),
!(
!0 === e.disableExceptionTracking ||
(e.extensionConfig &&
e.extensionConfig.ApplicationInsightsAnalytics &&
!0 ===
e.extensionConfig.ApplicationInsightsAnalytics
.disableExceptionTracking)
))
) {
n(`_${(r = 'onerror')}`);
const s = t[r];
(t[r] = function(e, n, a, t, o) {
const c = s && s(e, n, a, t, o);
return (
!0 !== c &&
i[`_${r}`]({
message: e,
url: n,
lineNumber: a,
columnNumber: t,
error: o
}),
c
);
}),
(e.autoExceptionInstrumented = !0);
}
return i;
})({ instrumentationKey: 'xxx-xxx-xxx-xxx-xxx' });
(window[aiName] = aisdk),
aisdk.queue && aisdk.queue.length === 0 && aisdk.trackPageView({});
我得到 window is not defined 这是预期的,但我不确定我还能如何从 service worker 使用这个库。
有没有其他人有类似的实现,他们使用 Service Worker 的 ApplicationInsights 成功记录了遥测数据?
我意识到我把这个复杂化了。
因为我只需要跟踪一个自定义事件,而不需要 appInsights 做的所有自动页面跟踪等,所以我最终从我的服务工作者那里获取数据。
我刚刚从使用我的 React 页面发出的请求中复制了 header 和 body 格式。
以下成功地将遥测记录到我的应用洞察信息中心:
fetch(url, {
method: 'post',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify([
{
time: '2019-05-02T15:56:37.589Z',
iKey: 'INSTRUMENTATION_KEY',
name:
'Microsoft.ApplicationInsights.INSTRUMENTATION_KEY.Event',
tags: {
'ai.user.id': 'l6Tey',
'ai.session.id': 'TL+Ry',
'ai.device.id': 'browser',
'ai.device.type': 'Browser',
'ai.operation.id': 'HUfNE',
SampleRate: '100',
// eslint-disable-next-line no-script-url
'ai.internal.sdkVersion': 'javascript:2.0.0-rc4'
},
data: {
baseType: 'EventData',
baseData: {
ver: 2,
name: 'Testing manual event',
properties: {},
measurements: {}
}
}
}
])
})
.then(json)
.then(function(data) {
})
.catch(function(error) {
});
我几乎 设法在我们应用程序的服务工作者中使用 Microsoft Application Insights。
关键部分是:
- 将 appInsights 的轻量级版本(参见 this small remark at 4th step)与
importScripts('https://az416426.vo.msecnd.net/next/aib.2.min.js')
结合使用。 - 初始化 appInsights 对象:
appInsights = new Microsoft.AppInsights.AppInsights({ instrumentationKey: "[replace with your own key]" });
- 当需要跟踪时(在
onpush
事件或onnotificationclick
期间),去appInsight.track({ eventItemFields })
然后appInsights.flush()
。
我说过 "almost" 因为刷新部分似乎不起作用,我得到:"Sender was not initialized" 启用调试后出现内部错误。 如果我成功解决了这个问题,我会在这里发布一个有效的示例代码。
参考文献:
在service worker中使用Web SDK比较麻烦。完整版依赖于 window 对象,而基本 SDK 依赖于 Beacon 或 XmlHttpRequest 来发送消息(在文件 https://github.com/microsoft/ApplicationInsights-JS/blob/master/channels/applicationinsights-channel-js/src/Sender.ts 中):
if (!_self._senderConfig.isBeaconApiDisabled() && Util.IsBeaconApiSupported()) {
_self._sender = _beaconSender;
} else {
if (typeof XMLHttpRequest !== undefined) {
const xhr:any = getGlobalInst("XMLHttpRequest");
if(xhr) {
const testXhr = new xhr();
if ("withCredentials" in testXhr) {
_self._sender = _xhrSender;
_self._XMLHttpRequestSupported = true;
} else if (typeof XDomainRequest !== undefined) {
_self._sender = _xdrSender; // IE 8 and 9
}
}
}
}
目前 Application Insights SDK 似乎不支持服务工作者。 Rajars 解决方案似乎是目前最好的选择。
更新:Github 回购中存在关于此的问题:https://github.com/microsoft/ApplicationInsights-JS/issues/1436
一个可行的建议是在初始化 Application Insights 之前使用 basic/lightweight 版本的 Application Insights(如 Rajar 所述)并添加 XMLHttpRequest polyfill(使用提取 api)。之后就可以使用轻量版了
可在此处找到示例:https://github.com/Pkiri/pwa-ai
我试图在 E2E 测试环境 (pupeteer) 中使用 AppInsightsSDK,当我尝试记录事件或指标时,出现“发件人未初始化”错误。
正如@Pkiri 提到的那样,需要 XMLHttpRequest polyfill 来解决这个问题。虽然我的场景与 Service worker 没有直接关系,但我想提一下@Pkiri 的回答并不完全正确,因为也可以使用 globalThis, self, window或global根据SDK源码函数得到相同的结果getGlobalInst("XMLHttpRequest");
解析为
function getGlobal() {
if (typeof globalThis !== strShimUndefined && globalThis) {
return globalThis;
}
if (typeof self !== strShimUndefined && self) {
return self;
}
if (typeof window !== strShimUndefined && window) {
return window;
}
if (typeof global !== strShimUndefined && global) {
return global;
}
return null;
}
对于我的场景,这是一个有效的解决方案
const appInsights = new ApplicationInsights({
config: {
instrumentationKey: 'AppInsights_InstrumentationKey',
},
});
global.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
global.appInsights = appInsights.loadAppInsights();