aws-observability / aws-rum-web Goto Github PK
View Code? Open in Web Editor NEWAmazon CloudWatch RUM Web Client
License: Apache License 2.0
Amazon CloudWatch RUM Web Client
License: Apache License 2.0
Hi, I'm getting the following error when importing AwsRum and AwsRumConfig on v1.13.2:
Type error: Cannot find module 'aws-rum-web' or its corresponding type declarations.
Workaround has been to downgrade to v1.12.0.
Very weird because I can see them being exported in the index.d.ts in node_modules. :/
Anyone else have this problem?
We've found that recordError
is a useful replacement for custom client error logging. However to completely replace what we have now we'd need support for other log levels, e.g. info, warn.
This could be provided by a recordLog
or recordEvent
command that supports arbitrary logging. Is this something that would be considered in scope for the rum client?
Expecting:
{
sessionSampleRate: 1,
guestRoleArn:
'arn:aws:iam::xxxxxxxx',
identityPoolId: 'us-west-xxxxxxxxx',
endpoint: 'https://dataplane.rum.us-west-2.amazonaws.com',
telemetries: ['performance', 'errors', 'http'],
allowCookies: true,
enableXRay: true,
pageIdFormat: 'PATH_AND_HASH',
/////// if the following configuration matches an error then ignore it.
ignoreErrors: [
/ResizeObserver loop limit exceeded/g, // <---------- Focus here please.
/Script error\./g, // <---------- Focus here please.
]
},
The RUM web client uses TSLint as its linter (in pre-commit and continuous integration). However, TSLint is deprecated and does not support modern ECMAScript.
Onboard typescript-eslint by following the instructions in tslint-to-eslint-config.
Choose an opinionated ESLint config (see this helpful list).
See the Visual Studio Code migration guide for re-configuring VS Code.
It is used in src/dispatch/BeaconHttpHandler.ts
, which causes errors when using Plug-n-Play build tooling:
Module not found: Error: Can't resolve '@aws-sdk/querystring-builder' in '/home/runner/work/.../.../.yarn/cache/aws-rum-web-npm-1.12.0-d1cba678f0-d2387b42c7.zip/node_modules/aws-rum-web/dist/es/dispatch'
I believe this can be solved as simply as adding "@aws-sdk/querystring-builder": "^3.0.0"
to package.json
's dependencies
list.
Hi folks,
Thanks for developing aws-rum-web
. It is a great library with a promising roadmap.
When I install aws-rum-web
via yarn
in a Vue application that uses Typescript 4.4 I get the following errors in dev server (yarn run serve
which also results in a build failure via yarn run build
.
ERROR in /cw_rum/node_modules/aws-rum-web/dist/cjs/plugins/event-plugins/XhrPlugin.d.ts(61,19):
61:19 Property 'patches' in type 'XhrPlugin' is not assignable to the same property in base type 'MonkeyPatched<XMLHttpRequest, "open" | "send">'.
Type '(MonkeyPatch<XMLHttpRequest, "open"> | { nodule: XMLHttpRequest; name: "send"; wrapper: () => (original: any) => (this: XMLHttpRequest) => void; })[]' is not assignable to type 'MonkeyPatch<XMLHttpRequest, "open" | "send">[]'.
Type 'MonkeyPatch<XMLHttpRequest, "open"> | { nodule: XMLHttpRequest; name: "send"; wrapper: () => (original: any) => (this: XMLHttpRequest) => void; }' is not assignable to type 'MonkeyPatch<XMLHttpRequest, "open" | "send">'.
Type 'MonkeyPatch<XMLHttpRequest, "open">' is not assignable to type 'MonkeyPatch<XMLHttpRequest, "open" | "send">'.
Type '"open" | "send"' is not assignable to type '"open"'.
Type '"send"' is not assignable to type '"open"'.
59 | constructor(config?: PartialHttpPluginConfig);
60 | protected onload(): void;
> 61 | protected get patches(): (MonkeyPatch<XMLHttpRequest, "open"> | {
| ^
62 | nodule: XMLHttpRequest;
63 | name: "send";
64 | wrapper: () => (original: any) => (this: XMLHttpRequest) => void;
Version: typescript 4.4.4
I believe it is due to an incorrect type being inferred from this line.
I think updating the patches method in XhrPlugin to what's shown below should fix the issue. I was able to fix the issue by directly editing the type definition file to match the type used below.
protected get patches() {
return [
{
nodule: XMLHttpRequest.prototype,
name: 'send' as const,
wrapper: this.sendWrapper
},
{
nodule: XMLHttpRequest.prototype,
name: 'open' as const,
wrapper: this.openWrapper
}
] as MonkeyPatch<XMLHttpRequest, 'send' | 'open'>[];
}
This issue currently blocks the usage of aws-rum-web
in Vue/Typescript applications. Let me know if that isn't the case and if it is due to something in my setup.
Packages of importance in my setup:
Thanks!
When recording an error, is there a maximum length of the message
from the Error
that can successfully be recorded?
For example:
try {
throw new Error("A message that might be very long...");
} catch (e)
awsRum.recordError(e);
}
The reason I'm asking is that I have encountered errors recorded to CloudWatch RUM simply as Empty or no message. One reason could have been that the error message was too long, but I can't find any relevant documentation around this.
Hello,
Are there any plans to support sourcemaps in CloudWatch RUM? In short I'd like to be able to understand the root cause of errors similar to this:
I'm looking for something similar to https://docs.datadoghq.com/real_user_monitoring/guide/upload-javascript-source-maps/
The LCP measure uses a PerformanceObserver. As PerformanceObservers don't run in the background, if a user visits a page and minimizes / changes browser tab before the LCP is measured then the LCP value will be the time the browser tab is brought back to the foreground
While browsing this repo I've noticed this section on interaction
telemetry:
https://github.com/aws-observability/aws-rum-web/blob/main/docs/configuration.md#interaction
As far as I can tell this is not documented anywhere else (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-RUM.html) and it's unclear to me whether I can try to use it to record DOM events.
Thank you in advance ๐
I'm currently trying out the CloudWatch RUM product. One thing I noticed today is that the https://client.rum.us-east-1.amazonaws.com/1.0.2/cwr.js file is served without any Cache-Control headers:
๎ฐ curl -v https://client.rum.us-east-1.amazonaws.com/1.0.2/cwr.js
* Trying 65.8.233.80:443...
* Connected to client.rum.us-east-1.amazonaws.com (65.8.233.80) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
* CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=client.rum.us-east-1.amazonaws.com
* start date: Nov 12 00:00:00 2021 GMT
* expire date: Dec 11 23:59:59 2022 GMT
* subjectAltName: host "client.rum.us-east-1.amazonaws.com" matched cert's "client.rum.us-east-1.amazonaws.com"
* issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f98b6811000)
> GET /1.0.2/cwr.js HTTP/2
> Host: client.rum.us-east-1.amazonaws.com
> user-agent: curl/7.77.0
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< content-type: application/javascript
< content-length: 114311
< last-modified: Tue, 23 Nov 2021 00:51:47 GMT
< x-amz-version-id: mQ3VEzOswAhdeQEPxFrH_CGxedkxk4zn
< accept-ranges: bytes
< server: AmazonS3
< date: Sat, 18 Dec 2021 12:39:43 GMT
< etag: "0dfa77fbb42f338ac9955897e9f55641"
< vary: Accept-Encoding
< x-cache: Hit from cloudfront
< via: 1.1 30ea845097208edbc19305c535a5be99.cloudfront.net (CloudFront)
< x-amz-cf-pop: DEN52-C1
< x-amz-cf-id: Vo5ZG0zegHb7QUxU2Iu4PwiIXRBZv3_ibZd5Ack_ZENrsWNgB2kHJQ==
< age: 38372
This (rightfully) triggers warnings from Lighthouse:
As you can see from the screenshot, Google Analytics caches for 2 hours but is still flagged. Since the URL for the CloudWatch asset has a version embedded (1.0.2), it seems like this should be safe to cache for at least 24 hours, if not more.
We need to know what versions of which browsers does it works/doesn't work.
Especially old browsers.
Error ignore feature doesn't filter out errors caused by browser extensions. such as @moz-extension
and chrome-extension
.
Using the error handler function like this:
export const rumErrorHandler = (
errorEvent: ErrorEvent | PromiseRejectionEvent
): boolean => {
if (!(errorEvent instanceof ErrorEvent)) {
return false;
}
const errorPatterns = [
/chrome-extension/,
/moz-extension/,
/ResizeObserver loop/,
];
return errorPatterns.some(
(errorPattern) =>
errorPattern.test(errorEvent.error?.stack) ||
errorPattern.test(errorEvent.filename) ||
errorPattern.test(errorEvent.message)
);
};
In addition to this issue, that would be also great to be able to filter out 4XX errors.
Thank you.
n.context.getSession().record
fails since if getSession()
returns undefined.
Strict type checks in TypeScript gives stronger guarantees about types, but are not currently enforced.
This task is to (1) update tsconfig.json to include "strict": true
in compilerOptions
and (2) fix any TypeScript compiler errors with the new configuration.
Hello,
First of all - thank you for building CloudWatch RUM, looking forward to seeing how this project will evolve.
We just noticed a following issue in our DataDog (occurred only once so far):
Are there any actions we could take in order to avoid this error? Moreover, would it be possible to include the actual exception being thrown along with the Failed to retrieve Cognito identity
error message?
I'm trying to use RUM in an iFrame which has no access to the window.localStorage value.
Environment:
Angular 10.21 in an iFrame (on the same domain)
RUM 1.2.1
I'm injecting the script into head dynamically with the following code,
loadRum() {
(window as any).AwsRumClient = {
q: [],
n: 'cwr',
i: environment.rum.cwrId,
v: '1.0.0',
r: 'us-west-2',
c: {
sessionSampleRate: 1,
guestRoleArn: environment.rum.guestRoleArn,
identityPoolId: environment.rum.identityPoolId,
endpoint: 'https://dataplane.rum.us-west-2.amazonaws.com',
telemetries: ['performance', 'errors', 'http'],
allowCookies: true,
enableXRay: false,
cookieAttributes: {
domain: window.location.hostname,
path: '/',
sameSite: 'None',
secure: true,
},
},
};
const x = (window as any).AwsRumClient;
(window as any).cwr = (a, p) => {
x.q.push({ a, p });
};
const z = document.createElement('script');
z.async = true;
z.src = 'https://client.rum.us-east-1.amazonaws.com/1.2.1/cwr.js';
document.head.insertBefore(z, document.getElementsByTagName('script')[0]);
}
Is it possible to add support for storing authentication tokens in cookies when localStorage is not supported (ie in an iFrame)? This doesn't affect usability of RUM, but it does lead to a series of console errors, since the reject in https://github.com/aws-observability/aws-rum-web/blob/main/src/dispatch/Authentication.ts#L71 is not caught.
The affected lines are
polyfills.cf07b70d8bd3c7d2eb81.js:1 Error: Uncaught (in promise): [object Undefined]
at Z (polyfills.cf07b70d8bd3c7d2eb81.js:1:12260)
at polyfills.cf07b70d8bd3c7d2eb81.js:1:11343
at cwr.js:formatted:1941:44
at new O (polyfills.cf07b70d8bd3c7d2eb81.js:1:14095)
at e.<anonymous> (cwr.js:formatted:1939:40)
at cwr.js:formatted:1905:39
at Object.next (cwr.js:formatted:1918:22)
at cwr.js:formatted:1823:45
at new O (polyfills.cf07b70d8bd3c7d2eb81.js:1:14095)
at _ (cwr.js:formatted:1800:20)
n.onUnhandledError @ polyfills.cf07b70d8bd3c7d2eb81.js:1
polyfills.cf07b70d8bd3c7d2eb81.js:1 Error: Uncaught (in promise): [object Undefined]
at Z (polyfills.cf07b70d8bd3c7d2eb81.js:1:12260)
at Z (polyfills.cf07b70d8bd3c7d2eb81.js:1:11791)
at polyfills.cf07b70d8bd3c7d2eb81.js:1:11343
at c (cwr.js:formatted:1817:30)
at cwr.js:formatted:1823:17
at new O (polyfills.cf07b70d8bd3c7d2eb81.js:1:14095)
at _ (cwr.js:formatted:1800:20)
at e.AnonymousCredentialsProvider (cwr.js:formatted:1936:28)
at e.<anonymous> (cwr.js:formatted:1928:45)
at cwr.js:formatted:1905:39
n.onUnhandledError @ polyfills.cf07b70d8bd3c7d2eb81.js:1
2polyfills.cf07b70d8bd3c7d2eb81.js:1 Uncaught (in promise) undefined
invoke @ polyfills.cf07b70d8bd3c7d2eb81.js:1
run @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
invokeTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
runTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
m @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Promise.then (async)
k @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Z @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Z @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
c @ cwr.js:formatted:1817
(anonymous) @ cwr.js:formatted:1823
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
_ @ cwr.js:formatted:1800
AnonymousCredentialsProvider @ cwr.js:formatted:1936
(anonymous) @ cwr.js:formatted:1928
(anonymous) @ cwr.js:formatted:1905
(anonymous) @ cwr.js:formatted:1918
(anonymous) @ cwr.js:formatted:1823
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
_ @ cwr.js:formatted:1800
ChainAnonymousCredentialsProvider @ cwr.js:formatted:1926
e.setAwsCredentials @ cwr.js:formatted:4231
e.initDispatch @ cwr.js:formatted:5485
e @ cwr.js:formatted:5432
e.initCwr @ cwr.js:formatted:5927
(anonymous) @ cwr.js:formatted:5900
(anonymous) @ cwr.js:formatted:5838
(anonymous) @ cwr.js:formatted:5851
(anonymous) @ cwr.js:formatted:5756
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Rn @ cwr.js:formatted:5733
e.init @ cwr.js:formatted:5888
(anonymous) @ cwr.js:formatted:5945
(anonymous) @ cwr.js:formatted:5946
(anonymous) @ cwr.js:formatted:5947
2polyfills.cf07b70d8bd3c7d2eb81.js:1 Uncaught (in promise) undefined
invoke @ polyfills.cf07b70d8bd3c7d2eb81.js:1
run @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
invokeTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
runTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
m @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Promise.then (async)
k @ polyfills.cf07b70d8bd3c7d2eb81.js:1
scheduleTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
scheduleTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
scheduleMicroTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
P @ polyfills.cf07b70d8bd3c7d2eb81.js:1
then @ polyfills.cf07b70d8bd3c7d2eb81.js:1
catch @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ cwr.js:formatted:1928
(anonymous) @ cwr.js:formatted:1905
(anonymous) @ cwr.js:formatted:1918
(anonymous) @ cwr.js:formatted:1823
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
_ @ cwr.js:formatted:1800
ChainAnonymousCredentialsProvider @ cwr.js:formatted:1926
e.setAwsCredentials @ cwr.js:formatted:4231
e.initDispatch @ cwr.js:formatted:5485
e @ cwr.js:formatted:5432
e.initCwr @ cwr.js:formatted:5927
(anonymous) @ cwr.js:formatted:5900
(anonymous) @ cwr.js:formatted:5838
(anonymous) @ cwr.js:formatted:5851
(anonymous) @ cwr.js:formatted:5756
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Rn @ cwr.js:formatted:5733
e.init @ cwr.js:formatted:5888
(anonymous) @ cwr.js:formatted:5945
(anonymous) @ cwr.js:formatted:5946
(anonymous) @ cwr.js:formatted:5947
polyfills.cf07b70d8bd3c7d2eb81.js:1 Uncaught (in promise) undefined
invoke @ polyfills.cf07b70d8bd3c7d2eb81.js:1
run @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
invokeTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
runTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
m @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Promise.then (async)
k @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Z @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Z @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
c @ cwr.js:formatted:1817
(anonymous) @ cwr.js:formatted:1823
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
_ @ cwr.js:formatted:1800
AnonymousStorageCredentialsProvider @ cwr.js:formatted:1952
invoke @ polyfills.cf07b70d8bd3c7d2eb81.js:1
run @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
invokeTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
runTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
m @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Promise.then (async)
k @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Z @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ cwr.js:formatted:1941
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ cwr.js:formatted:1939
(anonymous) @ cwr.js:formatted:1905
(anonymous) @ cwr.js:formatted:1918
(anonymous) @ cwr.js:formatted:1823
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
_ @ cwr.js:formatted:1800
AnonymousCredentialsProvider @ cwr.js:formatted:1936
(anonymous) @ cwr.js:formatted:1928
(anonymous) @ cwr.js:formatted:1905
(anonymous) @ cwr.js:formatted:1918
(anonymous) @ cwr.js:formatted:1823
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
_ @ cwr.js:formatted:1800
ChainAnonymousCredentialsProvider @ cwr.js:formatted:1926
e.setAwsCredentials @ cwr.js:formatted:4231
e.initDispatch @ cwr.js:formatted:5485
e @ cwr.js:formatted:5432
e.initCwr @ cwr.js:formatted:5927
(anonymous) @ cwr.js:formatted:5900
(anonymous) @ cwr.js:formatted:5838
(anonymous) @ cwr.js:formatted:5851
(anonymous) @ cwr.js:formatted:5756
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Rn @ cwr.js:formatted:5733
e.init @ cwr.js:formatted:5888
(anonymous) @ cwr.js:formatted:5945
(anonymous) @ cwr.js:formatted:5946
(anonymous) @ cwr.js:formatted:5947
Show 24 more frames
polyfills.cf07b70d8bd3c7d2eb81.js:1 Uncaught (in promise) undefined
invoke @ polyfills.cf07b70d8bd3c7d2eb81.js:1
run @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
invokeTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
runTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
m @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Promise.then (async)
k @ polyfills.cf07b70d8bd3c7d2eb81.js:1
scheduleTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
scheduleTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
scheduleMicroTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
P @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Z @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Z @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
invokeTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
runTask @ polyfills.cf07b70d8bd3c7d2eb81.js:1
m @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Promise.then (async)
k @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Z @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ cwr.js:formatted:1941
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
(anonymous) @ cwr.js:formatted:1939
(anonymous) @ cwr.js:formatted:1905
(anonymous) @ cwr.js:formatted:1918
(anonymous) @ cwr.js:formatted:1823
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
_ @ cwr.js:formatted:1800
AnonymousCredentialsProvider @ cwr.js:formatted:1936
(anonymous) @ cwr.js:formatted:1928
(anonymous) @ cwr.js:formatted:1905
(anonymous) @ cwr.js:formatted:1918
(anonymous) @ cwr.js:formatted:1823
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
_ @ cwr.js:formatted:1800
ChainAnonymousCredentialsProvider @ cwr.js:formatted:1926
e.setAwsCredentials @ cwr.js:formatted:4231
e.initDispatch @ cwr.js:formatted:5485
e @ cwr.js:formatted:5432
e.initCwr @ cwr.js:formatted:5927
(anonymous) @ cwr.js:formatted:5900
(anonymous) @ cwr.js:formatted:5838
(anonymous) @ cwr.js:formatted:5851
(anonymous) @ cwr.js:formatted:5756
O @ polyfills.cf07b70d8bd3c7d2eb81.js:1
Rn @ cwr.js:formatted:5733
e.init @ cwr.js:formatted:5888
(anonymous) @ cwr.js:formatted:5945
(anonymous) @ cwr.js:formatted:5946
(anonymous) @ cwr.js:formatted:5947
Show 20 more frames
4polyfills.cf07b70d8bd3c7d2eb81.js:1 Uncaught (in promise) undefined
Hello! I am trying to implement AWS RUM in my react application and it works really fine on Chrome but it does not work properly on Internet Explorer. Comparing to the Chrome I see that the application on IE does not fire any calls to the AWS. My suspicious is that IE does not support fetch which cwr script uses to communicate with AWS I believe. I use React 16.3.1 and IE 21H2. I pasted my snippet into public/index.html. Is there any possibility to use AWS RUM in Internet Explorer? Does AWS RUM support IE at all?
Used aws-sdk packages are old. Can be updated to latest version
"@aws-sdk/client-rum": "^3.202.0"
"@aws-sdk/fetch-http-handler": "^3.201.0"
"@aws-sdk/protocol-http": "^3.201.0"
"@aws-sdk/signature-v4": "^3.201.0"
"@aws-sdk/util-hex-encoding": "^3.201.0",
Hi,
I'm setting up aws-rum-web
via npm
into a React Typescript project that has an existing Cognito user pool.
Steps so far:
npm i aws-rum-web
rum:PutRumEvents
When I run the app, I get this error:
Uncaught (in promise) Error: CWR: Failed to retrieve credentials from STS: TypeError: Cannot read properties of undefined (reading 'split')
at StsClient.eval (StsClient.js?0019:98:1)
at step (StsClient.js?0019:43:1)
at Object.eval [as next] (StsClient.js?0019:24:46)
at fulfilled (StsClient.js?0019:15:43)
This is caused by not properly handling an STS error payload, with the root cause to this being at Cognito with something-something basic auth flow. What I see happening is this:
cognito-identity
is called and returns an error such as "Basic flow not enabled" (there are two variants, see below)sts
is called next with a payload containing WebIdentityToken: undefined
, so it returns "The ID Token provided is not a valid JWT."StsClient.eval()
doesn't correctly parse this response and generates the above error, and suppresses the actual errorThe root error to this is about basic auth flow, which I see is part of Cognito Identity Pools.
I've read the troubleshooting guide which talks to this, and I've also read open issue 172 where that user is in a similar position. I've also read of people using proxies, and that'd be great if there's an example I can run with.
However, while open issue 172 is asking you to implement the enhanced flow, all I'm after is for the out-of-box experience to work. I figure it works on your machine, so I'm wondering what I've done wrong, or what I need to do in Cognito in order to get this all working?
Many thanks, Scott
Adding labels/tags is essential in order to analyze the page performance.
For example - account_id, page_name and more
Is it possible to send a label/tag?
Other tools support it:
https://support.speedcurve.com/docs/rum-page-labels
https://docs.sentry.io/platforms/python/enriching-events/tags/
What does the second argument allow
Could we get the domain, host or hostname added as a dimension to the HttpStatusCodeCount metric. Most pages only make requests to a fixed number of domains, so the cardinality of this dimension should reasonable. This would let us filter the metric based on the domain the request go to.
We could do this with a metricFilter on the logs, but that is a pain. Wanting to see your failures broken down by domain seems like a pretty common use case.
I see status and file.type as dimensions already. Those can conceivably have a cardinality in the hundreds, so the domain should be less than that.
See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-RUM-metrics.html
Hello,
We've noticed an error thrown by aws-rum-web client itself in our AWS RUM monitoring (occurred only once so far):
The error itself is thrown here:
aws-rum-web/src/dispatch/StsClient.ts
Line 77 in 1d461c9
Are there any actions we could take in order to avoid this error? Moreover, would it be possible to include the actual exception being thrown along with the Failed to retrieve credentials from STS
error message?
In the VirtualPageLoadTimer
plugin on line 81 it has a keydown event, which if a user holds down a key it will get hit every ms until they list their finger from the keyboard.
I think there are two options to fix this issue:
aws/aws-cdk#17939 adds support for the AppMonitor
Cfn resource within CDK. Is there any way to use that or will there be any future way to output the CW RUM JS snippet (or the properties needed for the snippet) to inject into webapps during deployments?
Today, the text of cwr.js
is not compressed:
Since this is served via CloudFront (I'm assuming with an S3 backend), you should be able to simply enable automatic compression on the distribution, which should clear this error.
Certain chrome extensions inject script tags in document
outside and above head
tags. While this doesn't feel like something RUM should concern itself with it has caused issues sending metrics while using the JS snippet in Chrome.
Extension example: this extension injects a script via document.createElement('script')
which inserts outside and above the head tag.
This results in:
when attempting to send metrics to RUM.
Running document.getElementsByTagName('script')[0];
during a debug session in the middle of the RUM script results in:
The easiest way to get around this happening to other customers (even if other chrome extensions don't behave this way) is to have the rum script injected as the first script in head
rather than document
. Not sure if this change would have any other implications.
Version: 1.12.0.
We use RUM to track # of unique users that visit our website. We add a custom session attribute of a SHA-256 hash of the user alias at run time after their identity has been verified.
We notice that for some users, either
This behaviour seems to exist for all browser types, and there doesn't seem to be a specific pattern to when these issues occur.
In our service:
const addUserAliasHash = async (alias: string) => {
if (cwrClient !== null) {
const textAsBuffer = new TextEncoder().encode(alias);
const hashBuffer = await window.crypto.subtle.digest('SHA-256', textAsBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const userAliasHash = hashArray.map((b) => b.toString(16)
.padStart(2, '0'))
.join('');
cwrClient.addSessionAttributes({ userAliasHash });
}
};
In our bootstrap:
useEffect(() => {
const { alias } = getUserIdentityState;
CloudWatchRumService.addUserAliasHash(alias)
}, [ getUserIdentityState ]);
The web client HTTP plugins use the hostname of the callee as the subsegment name. For example, the subsegment name of fetch(https://dataplane.rum.us-east-1.amazonaws.com/appmonitors/abc123)
would be dataplane.rum.us-east-1.amazonaws.com
. When there is no hostname (e.g., if the URL is specified using a relative path like /appmonitors/abc123
), or if the hostname cannot be read, then the empty string ""
is used.
This is problematic because the empty string is an invalid subsegment name in X-Ray. When the subsegment name is an empty string, X-Ray will not ingest the trace segment.
This task is to ensure the subsegment name is never empty. If the URL is a relative path, then window.location.hostname
should be used.
Hello - I seem to still get approval requests for deployments in this repo even though I'm not at AWS anymore. I couldn't find a reference to my user in this repo, so not sure why but would be good if that could be sorted. Thanks.
/cc @Aneurysm9
v1.13.3
TypeScript v5.0.2, Webpack v4.46.0, ECMAScript modules (ESM) and React v18.2.0
None
{
allowCookies: true,
endpoint: "https://dataplane.rum.us-west-2.amazonaws.com",
guestRoleArn: "arn:aws:iam::000000000000:role/RUM-Monitor-us-west-2-000000000000-00xx-Unauth",
identityPoolId: "us-west-2:00000000-0000-0000-0000-000000000000",
sessionSampleRate: 1,
telemetries: ['errors', 'performance', 'http']
}
Wrt #328, the issue still exist in latest version. kindly release tag a new version so the fix is available.
Raising this issue here because I don't know how else I would reach the RUM team.
When I try to create a RUM monitor via an L1 CDK construct, CloudFormation outputs the following error.
Resource handler returned message: "null (Service: Rum, Status Code: 403, Request ID: 25882675-8906-45e6-8494-2bb0d62bdb28)" (RequestToken: 4aab9635-1c07-613e-52ae-34085dd4f896, HandlerErrorCode: AccessDenied)
I have admin permission when executing cdk deploy
.
Is there more info to this than just "null
that I can find anywhere? Also checked if there are any CW logs, but without success.
The CloudFormation stack is afterwards in ROLLBACK_COMPLETE
, but I can see that the Cogito identity pool and the CW RUM app have been created. I have tried this multiple times, and every time made sure that there is no existing identity pool and no CW RUM app. The same code seems to work in the account of another team, but not in ours. I'm running out of ideas what to try.
Below is the CDK code we use, with [email protected], [email protected], and [email protected]:
import { Stack } from "aws-cdk-lib";
import { CfnIdentityPool, CfnIdentityPoolRoleAttachment } from "aws-cdk-lib/aws-cognito";
import { FederatedPrincipal, PolicyDocument, PolicyStatement, Role } from "aws-cdk-lib/aws-iam";
import { CfnAppMonitor } from "aws-cdk-lib/aws-rum";
import { Construct } from "constructs";
export interface RumProps {
/**
* Provide a domain that will be allowed to send telemetry data to the Real
* User Monitoring agent
*/
readonly topLevelDomain: string;
/**
* The name for the App Monitor that will be created
*
* @unique
*/
readonly appMonitorName: string;
}
/**
* The RUM custom resource can be used to setup Real User Monitoring using AWS
*
* The resource itself creates all the required infrastructure.
* Adapted from https://blog.simonireilly.com/posts/cloudwatch-rum-end-to-end-monitoring
*
* @example
* const rum = new Rum(this, "SiteRum", {
* topLevelDomain: "*.s3-website-eu-west-1.amazonaws.com",
* appMonitorName: "canary-stack-rum",
* });
*
*/
export class Rum extends Construct {
protected unauthenticatedRumRole: Role;
readonly appMonitor: CfnAppMonitor;
readonly topLevelDomain: string;
readonly appMonitorName: string;
readonly identityPool: CfnIdentityPool;
constructor(scope: Construct, id: string, props: RumProps) {
super(scope, id);
this.topLevelDomain = props.topLevelDomain;
this.appMonitorName = props.appMonitorName;
this.identityPool = this.createIdentityPool();
this.unauthenticatedRumRole = this.createRumRole();
this.appMonitor = this.initializeRum();
}
private initializeRum() {
this.createRoleAttachment();
return this.createApplicationMonitor();
}
private createIdentityPool() {
return new CfnIdentityPool(this, "RumAppIdentityPool", {
allowUnauthenticatedIdentities: true,
});
}
private createRumRole() {
// See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-RUM-get-started-authorization.html
return new Role(this, "UnauthenticatedRumRole", {
assumedBy: new FederatedPrincipal(
"cognito-identity.amazonaws.com",
{
StringEquals: {
"cognito-identity.amazonaws.com:aud": this.identityPool.ref,
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "unauthenticated",
},
},
"sts:AssumeRoleWithWebIdentity",
),
inlinePolicies: {
RUMPutBatchMetrics: new PolicyDocument({
statements: [
new PolicyStatement({
actions: ["rum:PutRumEvents"],
resources: [
Stack.of(this).formatArn({
service: "rum",
resource: "appmonitor",
resourceName: this.appMonitorName,
}),
],
}),
],
}),
},
});
}
private createRoleAttachment() {
new CfnIdentityPoolRoleAttachment(this, "RumAppRoleAttachment", {
identityPoolId: this.identityPool.ref,
roles: {
unauthenticated: this.unauthenticatedRumRole.roleArn,
},
});
}
private createApplicationMonitor() {
return new CfnAppMonitor(this, "RumAppMonitor", {
name: this.appMonitorName,
domain: this.topLevelDomain,
appMonitorConfiguration: {
allowCookies: true,
enableXRay: false,
sessionSampleRate: 1,
telemetries: ["errors", "performance", "http"],
identityPoolId: this.identityPool.ref,
guestRoleArn: this.unauthenticatedRumRole.roleArn,
},
});
}
}
The current retention period is currently 30 days, can that be configured where the users can specify "x" days?
Hey, really appreciate the efforts to simplify the initial setup experience but I'm having a couple of issues with the current implementation.
In my case I would like to instrument an application with http
telemetry enabled but I'm faced with a couple of different challenges.
AwsRum
instance.It's not clear if you are accepting contributions, particularly those extending the public API of the web client. If you are I'd be happy to implement some of these features myself.
Currently, rum uses the basic (classic) authflow. Would it be possible to switch (maybe with a config option) to the Enhanced (simplified) authflow?
Both are documented here:
https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow.html
Reason for the request is that the basic authflow does not work with RoleMappings.
Error message is Basic (classic) flow is not supported with RoleMappings, please use enhanced flow.
`
We are aplanning to use rum in eu-central-1 and for a complete GDPR compatble usage I need to get the js file eiter:
from a domain that is under our control (and in eu-central-1)
or
*** or a AWS source in eu-central-1***
I did try to change the url from 'https://client.rum.us-east-1.amazonaws.com/1.0.2/cwr.js' to 'https://client.rum.eu-central-1.amazonaws.com/1.0.2/cwr.js' and got a 404
any ideas?
GitHub is updating Node.js to version 16 in all OS images.
Several unit test suites and unit tests fail when run with Node.js 16:
Jest worker encountered 4 child process exceptions, exceeding retry limit
when a TypeError is thrown then the plugin records the name, message and stack
To reproduce, run npm run test
with Node.js 16.
Hi all!
I wanted to ask if it's possible to scope the awsSigV4
object w/in the DataPlaneClient
to something other than rum
. The service attribute only allows rum
.
I've noticed in the documentation it's possible to set an endpoint to an API gateway proxy. However the permissions won't quite work with the client to only give the client the ability to call the API because this signature is scoped to rum.
We wanted to set the guest role arn to have execute-api
permissions to our API. Then from there we can forward it along to RUM.
Thank you!
Hello ๐
I'm implementing RUM monitoring for a library that's deployed on a number of websites. For this use-case, the final bundle size is of critical importance. I noticed that RUM is bundling ua-parser-js
(approx 6kb gzipped) to obtain information about the navigator. Unfortunately this adds too much weight for me to include within the performance budget for my library.
Could the RUM dataplane API accept the raw user agent string as a metadata property, instead of parsing this information into separate fields on the client-side?
When a new user visits my site, CW RUM kicks off a series of steps before sending metrics: the browser obtains an anonymous identity from the Identity Pool, fetches a token for the identity, assumes role via STS, and stashes the credentials in localstorage.
Once an identity is obtained, the client then performs cryptography (sigv4) on every metrics payload before sending it over the wire.
Initially I thought that the credentials obtained from Cognito were used to establish a tracking session, but looking at the code, the generated user ID in the cwr_u
cookie, and the session ID in the session cookie are locally generated UUIDs, separate to the Cognito Identity.
Typically RUM solutions are fire-and-forget, not requiring coordination between the collector endpoint and the client. Instead of credentials, the origin URL, device fingerprint (user agent etc) and the monitor ID are sent to the endpoint.
Could you consider an architecture where the collector endpoints are unauthenticated, and take care of any required AWS service authorisation internally?
Client side libraries should aim to do the least amount of work possible, in the fewest bytes.
v1.13.6
Remix v1.14.3, Typescript v5.0.4, ECMAScript modules (ESM) and React v18.2.0, aws-rum-web installed as JavaScript Module
SPA
{
"allowCookies":true,
"enableXRay":true,
"endpoint":"https://dataplane.rum.eu-north-1.amazonaws.com",
"guestRoleArn":"arn:aws:iam::account:role/stage-stack-App-AppMonitorUnauthentic1O1WJSN77WOS0",
"identityPoolId":"eu-north-1:4447b5b0-ebdd-4a73-ace3-ede974be41c3",
"sessionSampleRate":1,
"telemetries":[
"errors",
"performance",
["http", { "addXRayTraceIdHeader": true }]
]
}
There seems to be some kind of race condition, if the application is installed as a JS module, whereby multiple identities are loaded when starting up the application. I believe this should happen only once. If the script is injected via the script tag, it works as expected with the same config.
I am working on adding CloudWatch RUM to a web app. Our users will authenticate with AWS Identity Center (IDC) which assigns each user a UUID already. I'd like to use that same UUID as the userId
RUM instead of letting RUM generate a new UUID for me. Having consistent userIds will make it easier to connect RUM data with our backend events. We could pass in the IDC user ID as event metadata but it makes sifting through data more confusing and error prone.
Passing in user and session IDs could look like:
const config: AwsRumConfig = {
userId: 'bd33b2a2-4b14-4ea6-aaeb-ee85c2062f5d',
sessionId: '40af9b9a-6fa2-45f8-a437-67d2566380d9'
};
This request is to use Webhooks to send notifications when certain events occur in this repository.
recordPageView
accepts a PageAttributes
parameter, but the PageAttributes
type is not exported by aws-rum-web
.
In order to either (1) wrap this function or (2) initialize the payload ahead of time, the PageAttributes
type needs to be exposed.
Example 1: wrapping the function
function myRecordPageView(payload: PageAttributes | string): void {
myCustomHandler(payload);
cwr.recordPageView(payload);
}
Example 2: Initializing the payload ahead of time.
const payload: PageAttributes = {
pageId: 'test-page-id',
pageAttributes: {},
};
for (const [key, value] of Object.entries(window.location)) {
if (typeof value !== 'string') {
continue;
}
payload.pageAttributes[key] = value;
}
cwr.recordPageView(payload);
Both scenarios would be unblocked by allowing:
import type { PageAttributes } from 'aws-rum-web';
Is it possible to obtain the Endpoint URL programmatically or does it need to be computed?
For example I have Terraform deploying a Cloudwatch RUM and I want to output the data the user needs to configure the Client code with and I can easily obtain the parameters for guestRoleARN and identityPoolID but it appears endpoint needs to be computed. Is this really the case?
Would it make sense just to use one of them?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.