Enable RUM on Kloudfuse for AWS S3
Create Session Replay
You can store RUM session recordings in an AWS S3 container. Follow these steps to create an S3 bucket:
-
Follow instructions in AWS documentation on Creating a bucket.
-
Save for following tasks this information:
-
S3
accessKey
andsecretKey
; use them to create a secret on the Kloudfuse. -
S3
bucketName
andawsRegion
where the bucket exists
-
Create Secret for Kloudfuse Namespace
Run the following command in the cluster that runs Kloudfuse:
kubectl create secret generic kfuse-rum-s3 --from-literal=accessKey=<accessKey> --from-literal=secretKey='<secretKey>'
Configure the custom-values.yaml File
-
Generate a UUID by running the following command:
uuidgen | tr 'A-Z' 'a-z'
You must reference this UUID in the Kloudfuse frontend SDK initialization call.
-
Add a
global.rum
section to thecustom-values.yaml
file:rum: enabled: true applications: - name: kf-frontend id: 944f6a58-dbc2-45ad-bf93-def505aaff62 sessionReplayStorage: type: s3 useSecret: true secretName: "kfuse-rum-s3" s3: region: us-west-2 (2) bucket: rum-session-replay-playground (3)
yaml1 secretName
: Secret created inCreate Secret for Kloudfuse Namespace.
2 region
: Region specified for session replay storage, inCreate Session Replay.
3 bucket
: AWS bucket created for session replay storage, inCreate Session Replay.
-
List RUM-specific Kafka topics in the
custom-values.yaml
file.Use the configuration for the events stream as a reference for the number of replicas and partitions.
- name: kf_rum_session_replay_topic partitions: 3 replicationFactor: 2 - name: kf_rum_views_topic partitions: 3 replicationFactor: 2 - name: kf_rum_actions_topic partitions: 3 replicationFactor: 2 - name: kf_rum_resources_topic partitions: 3 replicationFactor: 2 - name: kf_rum_longtasks_topic partitions: 3 replicationFactor: 2 - name: kf_rum_errors_topic partitions: 3 replicationFactor: 2
yaml -
Specify the TLS configuration in the
tls
section of thecustom-values.yaml
file, and ensure you use a publichost
.tls: enabled: true (1) host: playground.kloudfuse.io (2) email: admin@kloudfuse.com clusterIssuer: playground-letsencrypt-prod
yaml1 enabled: true
: Enable TLS.2 host: playground.kloudfuse.io
: This host is public. -
Specify the Ingress configuration in the
ingress
section of thecustom-values.yaml
file.RUM must have a public ingest endpoint where the frontend browser posts data.
ingress: controller: service: external: enabled: true (1) externalTrafficPolicy: Local (2)
yaml1 Enable external ingress policy 2 Enable and specify external traffic policy. -
Enable RUM in the
ingester
section of thecustom-values.yaml
file:ingester: config: rum: enabled: true # you can ignore the datadog section below from the PR since # this is the default datadog: proxyToDatadogEnabled: false
yaml -
To ingest frontend logs into Kloudfuse, add parsing rules in the
log-parser
section of thecustom-values.yaml
file.Include these rules verbatim, along with existing rules.
logs-parser: gcpConfig: enabled: true subscriptionId: "logs-perf" pubsubKey: "<Pub Sub Key>" replicaCount: 3 jvmOpts: "<JVM Options>" extraApplicationConfigs: |- agent.properties.fluent-bit.enabled = true kf_parsing_config: config: |- - transform: args: - action: "facet_to_label_map" - sourceLabels: "@eventSource" - targetLabel: "source" conditions: - matcher: "#source" op: "==" value: "aws-cloudtrail-logs-502496443919-709d7802" - transform: tag: "arn_user_info" args: - action: facet_to_label_map sourceLabels: "@userIdentity_arn" # arn:aws:sts::502496443919:assumed-role/DatadogIntegrationRole/DatadogAWSIntegration regex: "^.*:.*:.*:.*:.*:(.*)" replacement: $1 targetLabel: user_info conditions: - matcher: "#agent" op: "==" value: "kinesis" - matcher: "#logGroup" op: "==" value: "aws-cloudtrail-logs-502496443919-709d7802" - transform: args: - action: replace targetLabel: "#user_info" sourceLabels: "#user_info" replacement: "$1/$1" regex: "^(.*)$" conditions: - matcher: "__kf_tags" op: "in" value: "arn_user_info" - matcher: "#user_info" op: "==" value: "root" - transform: args: - action: replace sourceLabels: "#user_info" regex: "^(.*?)/.*?(/.*)?$" replacement: $1 targetLabel: "resource_type" conditions: - matcher: "__kf_tags" op: "in" value: "arn_user_info" - transform: args: - action: replace sourceLabels: "#user_info" regex: "^.*?/(.*?)(/.*)?$" replacement: $1 targetLabel: "role" conditions: - matcher: "__kf_tags" op: "in" value: "arn_user_info" - transform: args: - action: replace sourceLabels: "#user_info" regex: "^.*?/.*?/(.*)$" replacement: $1 targetLabel: "src_user" conditions: - matcher: "__kf_tags" op: "in" value: "arn_user_info" - transform: args: - action: "replace" sourceLabels: "role" targetLabel: "src_user" conditions: - matcher: "__kf_tags" op: "in" value: "arn_user_info" - matcher: "#src_user" op: "==" value: "" - transform: tag: "src_role" args: - action: "replace" sourceLabels: "resource_type" targetLabel: "src_role" conditions: - matcher: "__kf_tags" op: "in" value: "arn_user_info" - matcher: "#role" op: "==" value: "#src_user" - transform: tag: "src_role" args: - action: "replace" sourceLabels: "role" targetLabel: "src_role" conditions: - matcher: "__kf_tags" op: "in" value: "arn_user_info" - matcher: "__kf_tags" op: "not in" value: "src_role" - transform: tag: "severity" args: - action: "replace" targetLabel: "severity_string" replacement: "Info" conditions: - matcher: "#agent" op: "==" value: "kinesis" - matcher: "#source" op: "contains" value: "guardduty" - matcher: "@detail_severity" op: "==" value: "0" - transform: tag: "severity" args: - action: "replace" targetLabel: "severity_string" replacement: "Low" conditions: - matcher: "__kf_tags" op: "not in" value: "severity" - matcher: "#agent" op: "==" value: "kinesis" - matcher: "#source" op: "contains" value: "guardduty" - matcher: "@detail_severity" op: "==" value: "2" - transform: tag: "severity" args: - action: "replace" targetLabel: "severity_string" replacement: "Medium" conditions: - matcher: "__kf_tags" op: "not in" value: "severity" - matcher: "#agent" op: "==" value: "kinesis" - matcher: "#source" op: "contains" value: "guardduty" - matcher: "@detail_severity" op: "==" value: "5" - transform: tag: "severity" args: - action: "replace" targetLabel: "severity_string" replacement: "High" conditions: - matcher: "__kf_tags" op: "not in" value: "severity" - matcher: "#agent" op: "==" value: "kinesis" - matcher: "#source" op: "contains" value: "guardduty" - matcher: "@detail_severity" op: "==" value: "8" - transform: tag: "severity" args: - action: "replace" targetLabel: "severity_string" replacement: "Critical" conditions: - matcher: "__kf_tags" op: "not in" value: "severity" - matcher: "#agent" op: "==" value: "kinesis" - matcher: "#source" op: "contains" value: "guardduty" - matcher: "@detail_severity" op: "==" value: "9.5" - remap: args: kf_additional_tags: - "$.origin" - "$.application_id" - "$.session_id" - "$.view.id" - "$.view.url" - "$.view.referrer" - "$.error.handling" - "$.error.kind" - "$.error.stack" - "$.error.message" - "$.http.method" - "$.http.status_code" - "$.http.url" conditions: - matcher: "__kf_agent" value: "datadog" op: "==" - transform: args: - action: "replace" - sourceLabels: "#ddsource" - targetLabel: "source" conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "error.kind" - facetName: "error_kind" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "error.stack" - facetName: "error_stack" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "error.message" - facetName: "error_message" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "http.method" - facetName: "@http_method" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "http.status_code" - facetName: "http_status_code" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "http.url" - facetName: "http_url" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "session_id" - facetName: "sessionid" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "application_id" - facetName: "applicationid" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "view.url" - facetName: "view_url" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "view.referrer" - facetName: "view_referrer" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "view.id" - facetName: "view_id" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "error.handling" - facetName: "@error_handling" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "==" - moveLabelToFacet: args: - name: "origin" - facetName: "event_origin" - agentFacet: true conditions: - matcher: "#__kf_ddrum" value: "true" op: "=="
yaml -
Enable RUM in the
ui
section of thecustom-values.yaml
file:ui: config: rum: enabled: true
yaml -
Upgrade the cluster using these changes, and ensure that all pods are active.
Instrument the Frontend Application
To set up the Frontend SDK for RUM, see instructions in RUM Setup.
Here is guide to the parameters to configure for SDK initialization:
- applicationId
-
applicationId: '<APPLICATION_ID>'
Must match the application id defined above under the customer yaml global.rum.applications section
- clientToken
-
clientToken: '<CLIENT_TOKEN>'
Use the string dummy as a value if the Kloudfuse installation does not have authenticated ingest enabled. If authenticated ingestion is enabled please follow the additional instructions noted on Step 5: Enable authenticated ingest below.
- site
-
site: '<SITE>'
Use empty string.
- proxy
-
proxy: '<KFUSE_RUM_ENDPOINT>'
Must be of the form
https://<customers-kfuse-hostname>/ddrumproxy
.Example: Kloudfuse Playground cluster has the value of
https://playground.kloudfuse.io/ddrumproxy
.
- service
-
service: '<APPLICATION_NAME>'
Must match the application name, and cannot contain any white space.
Example: kf-frontend
- env
-
env: 'production'
This value depends on the type of deployment:
test
,production
,staging
, and so on.
- version
-
version: '1.0.0'
If the frontend application has an identifier, use a string value that represents the version.
Otherwise, use the default value of
1.0.0
.
- sessionSampleRate
-
sessionSampleRate: 100
We recommend a small number if the site has many users.
- enableSessionRecording
-
enableSessionRecording: true
We recommend a value of
true
to use the session capture and replay feature.
- enableLogCollection
-
enableLogCollection: true
We recommend a value of
true
to get frontend logs into their Kloudfuse cluster.
Enable Authenticated Ingestion
(Optional)
By default, this feature is disabled.
When you enable authenticated ingestion on the Kloudfuse platform, you must enable it globally, and add authentication tokens.
Follow these steps:
-
To enable ingestion authentication, set
global authConfig
totrue
in thecustom-values.yaml
file:Enable Ingestion Authenticationglobal: authConfig: enabled: true (1)
yaml1 authConfig
: enable -
Generate a new authentication token:
Generate tokenuuidgen | tr -d '-' | tr 'A-Z' 'a-z' | sed 's/^/pub/'
-
Configure one or more client tokens in the
ingester config rum
section of thecustom-values.yaml
file:Configure tokensingester: config: rum: enabled: true (1) clientTokens: (2) - rumauthkey1: <unique authtoken value> - rumauthkey2: <unique authtoken value>
yaml1 enabled
: Enable RUM ingestion2 clientTokens
rumauthkey1
andrumauthkey2
: Unique authentication tokens for RUM, generated in Generate token. -
Match the generated auth tokens to the
clientToken
value in the frontend RUM SDK configuration:kfuseRumSDK.init({ config: { applicationId: '<application id>', (1) clientToken: '<unique authtoken value>', (2) ... } })
javascript1 applicationId
: The identifier of the service that provides the RUM stream.2 clientToken
: Unique authentication token for RUM, generated in Generate token, matching the declarations in Configure tokens.