Rum integration on NextJS with ELK-stack on k8s

Kibana version: Newest version available

Elasticsearch version: Newest version available

APM Server version: Newest version available

APM Agent language and version: RumJS

Browser version: N/A

Original install method (e.g. download page, yum, deb, from source, etc.) and version: Fleet integration

Fresh install or upgraded from other version?: Fresh install

Is there anything special in your setup?

  • Using Fleet integration to host the APM server
  • All requests are rerouted through SSL by our ingress

Description of the problem including expected versus actual behavior. Please include screenshots (if relevant):

  • When adding RumJS to our Next.js

application, we keep getting an authentication error regarding a secret_token.

  • RumJS should not expose the secret token, so it is unclear why this error is appearing.
  • Our APM server works fine, but whenever we add RumJS to Next.js, it requests a secret_token or api_key which we cannot provide.

Steps to reproduce:

  1. Add RumJS to the Next.js application.
  2. Configure the APM server with Fleet integration.
  3. Observe the authentication error regarding secret_token.

Errors in browser console (if relevant):

  • Authentication error regarding secret_token.

Provide logs and/or server output (if relevant):

  • N/A
---
eck-elasticsearch:
  enabled: true

  # Name of the Elasticsearch instance.
  #
  fullnameOverride: elasticsearch

  nodeSets:
  - name: default
    count: 3
    podTemplate:
      spec:
        # This init container ensures that the max_map_count setting has been applied before starting Elasticsearch.
        # This is not required, but is encouraged when using the previous Daemonset to set max_map_count.
        # Do not use this if setting config.node.store.allow_mmap: false
        initContainers:
        - name: max-map-count-check
          command: ['sh', '-c', "while true; do mmc=$(cat /proc/sys/vm/max_map_count); if [ ${mmc} -eq 262144 ]; then exit 0; fi; sleep 1; done"]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 50Gi

eck-kibana:
  enabled: true

  # Name of the Kibana instance.
  #
  fullnameOverride: kibana

  spec:
    # Reference to ECK-managed Elasticsearch instance, ideally from {{ "elasticsearch.fullname" }}
    #
    elasticsearchRef:
      name: elasticsearch

    config:
      # Note that these are specific to the namespace into which this example is installed, and are
      # using `elastic-stack` as configured here and detailed in the README when installing:
      #
      # `helm install es-kb-quickstart elastic/eck-stack -n elastic-stack`
      #
      # If installed outside of the `elastic-stack` namespace, the following 2 lines need modification.
      xpack.fleet.agents.elasticsearch.hosts: ["https://elasticsearch-es-http.elastic-stack.svc:9200"]
      xpack.fleet.agents.fleet_server.hosts: ["https://fleet-server-agent-http.elastic-stack.svc:8220"]
      xpack.fleet.packages:
      - name: system
        version: latest
      - name: elastic_agent
        version: latest
      - name: fleet_server
        version: latest
      - name: kubernetes
        version: latest
      - name: apm
        version: latest
      xpack.fleet.agentPolicies:
      - name: Fleet Server on ECK policy
        id: eck-fleet-server
        namespace: default
        monitoring_enabled:
        - logs
        - metrics
        package_policies:
        - name: fleet_server-1
          id: fleet_server-1
          package:
            name: fleet_server
      - name: Elastic Agent on ECK policy
        id: eck-agent
        namespace: default
        monitoring_enabled:
        - logs
        - metrics
        unenroll_timeout: 900
        package_policies:
        - package:
            name: system
          name: system-1
        - package:
            name: kubernetes
          name: kubernetes-1

eck-agent:
  enabled: true

  spec:
    # Agent policy to be used.
    policyID: eck-agent
    # Reference to ECK-managed Kibana instance.
    #
    kibanaRef:
      name: kibana

    elasticsearchRefs: []

    # Reference to ECK-managed Fleet instance.
    #
    fleetServerRef:
      name: fleet-server

    mode: fleet

    daemonSet:
      podTemplate:
        spec:
          serviceAccountName: elastic-agent
          hostNetwork: true
          dnsPolicy: ClusterFirstWithHostNet
          automountServiceAccountToken: true
          securityContext:
            runAsUser: 0

eck-fleet-server:
  enabled: true

  fullnameOverride: "fleet-server"

  spec:
    # Agent policy to be used.
    policyID: eck-fleet-server
    kibanaRef:
      name: kibana
    elasticsearchRefs:
    - name: elasticsearch

eck-apm-server:
  enabled: true

  # Count of APM Server replicas to create.
  #
  count: 1

  # Reference to ECK-managed Elasticsearch resource.
  #
  elasticsearchRef:
    name: elasticsearch
  kibanaRef:
    name: kibana
  http:
    service:
      spec:
        ports:
        - name: http
          port: 8200
          targetPort: 8200

Hi @Alex_Thoger_Holmberg,

Welcome! Thanks for sharing your config. Can you also share the code snippet for initializing the RUM agent, along with the full error text you see in the browser console?

Hi, thanks - of course, I'll also add the browser logs in an image:

'use client';
import { CacheProvider } from '@chakra-ui/next-js';
import { ChakraProvider } from '@chakra-ui/react';
import { resolveValue, Toaster } from 'react-hot-toast';
import { MantineProvider } from '@mantine/core';
import { ResponsiveProvider } from '@/context/MediaQueryContext';
import { NextUIProvider } from '@nextui-org/react';
import { NavigationEvents } from '@/utilities/NavigationEvents';
import { ActiveTabProvider } from '@/context/ActiveTabContext';
import { MemberProvider } from '@/context/MemberContext';
import { AppInitializationProvider } from '@/utilities/AppInitializationProvider';
import { SignUpProvider } from '@/context/SignUpContext';
import { init as initApm } from '@elastic/apm-rum'

export function Providers({ children }: { children: React.ReactNode }) {

  const apm = initApm({
    serviceName: 'intellichat-app',
    serverUrl: 'https://apm.intellioptima.com',
    serviceVersion: '1',
    sendCredentials: true,
  })
  return (

    <CacheProvider>
      <NextUIProvider>
        <ChakraProvider>
          <ResponsiveProvider>
            <MantineProvider>
              <ActiveTabProvider>
                <AppInitializationProvider>
                  <MemberProvider>
                    <SignUpProvider>
                      {children}
                    </SignUpProvider>
                    <NavigationEvents />
                  </MemberProvider>
                </AppInitializationProvider>
              </ActiveTabProvider>
            </MantineProvider>
          </ResponsiveProvider>
          <Toaster
            containerStyle={{
              bottom: 40,
              left: 20,
              right: 20,
            }}
            position='bottom-center'
            gutter={10}
            toastOptions={{
              duration: 3000,
            }}
          >
            {t => (
              <div
                style={{
                  opacity: t.visible ? 1 : 0,
                  transform: t.visible
                    ? 'translatey(0)'
                    : 'translatey(0.75rem)',
                  transition: 'all .2s',
                }}
              >
                {resolveValue(t.message, t)}
              </div>
            )}
          </Toaster>
        </ChakraProvider>
      </NextUIProvider>
    </CacheProvider>
  );
}

So this is our provider.tsx, which the layout.tsx is applying for rootLayout in our nextjs app.


Here is the browser logs:

Thanks for sharing @Alex_Thoger_Holmberg. Have you enabled RUM explicitly in your APM server configuration as covered in the example here? I don't see RUM explicitly enabled in your configuration.

Hi carly,

No, what I understood from documentation since deployed with fleet it should already be enabled ?

maybe I'm misunderstanding something ?

So how would I explicitly enable this when I've already deployed, would it be possible to be added within the values.yml file through helm ?

---- Thanks a lot for answering by the way! :slight_smile:

Hi @Alex_Thoger_Holmberg

having a quick look at the browser logs it seems that your app and the APM server are in different domains. That would explain the CORS error messages displayed when the RUM agent is trying to use fetch and XMLHttpRequest to send data.

Could you check if CORS configuration is present for the domain app.intellioptima.com?
Reference: Configure CORS | APM Real User Monitoring JavaScript Agent Reference [5.x] | Elastic

Cheers,
David

1 Like

Hi David! - So I'm a little bit confused where I would do this ? In the yaml file where the stack is or would I create a new yml file patching ?

Because it makes a lot of sense, if the cops is blocking us, since the cluster origin doesn't match the browsers :slight_smile:

Not sure if you can configure the agent to send some headers back via config. The APM server seems to be under the subdomain app.intellioptima.com. I guess there is a reverse proxy that redirects traffic to it like NGINX. I think that would be a good place to configure it.

Cheers,
David

Hi David, thanks for the assistance ... so I finally got rid of the cors errors ...
But still hitting some weird behavior ... I now get 401 ... and response says:

{
  "error": "authentication failed: missing or improperly formatted Authorization header: expected 'Authorization: Bearer secret_token' or 'Authorization: ApiKey base64(API key ID:API key)'"
}

@David_Luna_Bistuer please dont forget me! :joy:

Hi @Alex_Thoger_Holmberg

I'm not familiar with ECK and doing some searches I found your conversation in Slack with Jack. In that conversation I do not see the APM server configuration. Maybe you should review that to enable RUM. I'm attaching a couple of references hoping they might help you:

Cheers,
David

Well the elastic documentation states, that with fleet server, then RUM(JS) is enabled automatically - since APM Server is managed by fleet agents..

So Rum IS enabled thats for sure, since now I'm also connecting but the error now suggest there is an authentication error of a kind which doesn't really makes sense, since improperly formatted Authentication seems like a weird response, due to one should never share apiKey, secret key or whatsoever on a client oriented component, which is exposed to every user of the app .... :frowning:

Hi,

I found this issue that I think is what's happening here. Could you have a look?

https://github.com/elastic/apm-agent-rum-js/issues/1505

Cheers,
David