Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

content grouping RUM routes in DD #698

Open
deborahgu opened this issue Jun 24, 2024 · 2 comments
Open

content grouping RUM routes in DD #698

deborahgu opened this issue Jun 24, 2024 · 2 comments
Assignees

Comments

@deborahgu
Copy link
Member

Problem

Datadog's content grouping of RUM routes is based on the presence of any digits in the view name, which does identify course runs but doesn't usefully identify usernames. This results in RUM views that should be getting pattern grouped and grouped but aren't. So, for example, profile.edx.org/u/colin_bridgerton and profile.edx.org/u/penelope_featherington will be considered unique pages).

Details

The existing DD docs on view name calculation are unclear:

A view name is computed from the current page URL, where variable alphanumeric IDs are removed automatically. For example, /dashboard/1234 becomes /dashboard/?.

However, on DD support ticket #1748310, DD clarified that by "alphanumeric" they mean "strings that contain at least one digit not preceded by a v":

You are correct that a path segment is replaced with ? when it contains a number (excluding v1-v99).

Workarounds

On the DD support ticket, they suggest the following:

In terms of how to change this behavior, there are two available approaches here:

  1. Use trackViewsManually to manually assign View names. Here is our documentation on that functionality.
  2. Use the beforeSend callback to alter the View names, when appropriate. Here is our documentation on that functionality.

The beforeSend callback is a simpler approach so I would recommend trying that first. That callback would look something like the following:

      beforeSend: function (event, context) {
          if (<event.view.url_path matches username pattern>) {
                event.view.name = <event.view.url_path with the username replaced by ?>
          }
	  return true
        }

Question

We should probably standardize this in some way; I don't think we want every MFE owner hardcoding this JS if we can avoid doing that. Is there something we can do in DatadogLoggingService so that, in [env]_config.yml or env.[env].config.js, an MFE owner could write some mappings for beforeSend without manually creating JS?

@adamstankiewicz
Copy link
Member

Hm, yeah... so there's currently no way for MFEs like frontend-app-profile to pass custom logic to beforeSend during the datadogRum.init call within DatadogLoggingService at the moment.

Because (most) logic within beforeSend would be MFE-specific based on their routes/views, we'd need some way to have MFEs inject their own logic into that callback function within datadogRum.init. It may be possible to have MFEs that want to provide beforeSend logic do so by extending DatadogLoggingService into a CustomDatadogLoggingService and supplying a custom beforeSend function there, e.g. (pseudo-ish code):

// MFE-specific `env.{stage|prod}.config.js` file in {edx|edge}-internal

class CustomDatadogLoggingService extends DatadogLoggingService {
  constructor(options) {
    super(options);
  }

  beforeSend(event, context) {
    // perform any common/shared logic for `beforeSend` defined within DatadogLoggingService.
    const baseBeforeSendResult = super.beforeSend(event, context);
    if (!baseBeforeSendResult) {
      // base `beforeSend` logic denotes the event should be discarded; no need to do addtl MFE-specific checks
      return false;
    }

    // custom MFE-specific logic...
    if ('<event.view.url matches username pattern>') {
      event.view.name = '<event.view.url with the username replaced by ?>';
    }
    return true;
  }
}

const config = {
  loggingService: CustomDatadogLoggingService,
};
export default config;
// DatadogLoggingService (@edx/frontend-logging)

class DatadogLoggingService extends NewRelicLoggingService {
  constructor(options) {
    super(options);
    this.initialize();
  }

  beforeSend(event, context) {
    // common/shared logic across all MFEs
    return true;
  }

  initialize() {
    datadogRum.init({
      applicationId: process.env.DATADOG_APPLICATION_ID,
      clientToken: process.env.DATADOG_CLIENT_TOKEN,
      // ...
      beforeSend: this.beforeSend,
    });
  }
}

Alternatively, we could also consider exposing a view URL -> view name overrides mapping option that a default beforeSend function implemented in the base DatadogLoggingService could iterate over.


[aside] fwiw, slightly related, we might also want to refactor to rely on beforeSend in the common/base DatadogLoggingService class to implement the IGNORED_ERROR_REGEX stuff to ignore certain error messages but that's slightly more tangential to this specific request 😄

@jristau1984 jristau1984 moved this to Backlog in Arch-BOM Jul 1, 2024
@deborahgu
Copy link
Member Author

Aperture is going to take on this work, and @adamstankiewicz, we can coordinate with you as needed. (ref ticket https://2u-internal.atlassian.net/browse/APER-3534).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

3 participants