3.2.0 • Published 4 years ago

@vendasta/heimdall v3.2.0

Weekly downloads
849
License
ISC
Repository
-
Last release
4 years ago

Heimdall

Heimdall is Vendasta's monitoring and error reporting service for our modern frontend applications.

You can think of Heimdall as basically vStore for frontend monitoring. You send your Error Reports, RPC logs, and user events all to one place: Heimdall. Then Heimdall replicates to Sentry/Datadog/Stackdriver or whatever is appropriate.

Error Reporting

For error reporting, Heimdall is currently backed by RavenJS. RavenJS handles many things for us such as User Event breadcrumbing, error capturing and stacktrace parsing. The HeimdallModule wraps RavenJS in a generic way to fire off error reports to the Heimdall µs which will put them in vStore and replicate to Sentry and wherever else we want them in the future.

SessionTraces (Deprecated: Will be removed in the future)

SessionTraces are the newest thing added to Heimdall, however they are the most critical piece to unlocking the functionality of Heimdall in the future. Every time your application is loaded, a new trace_id is generated for the current session, we then create a SessionTrace model with that trace_id and any easy to grab user information that we want to collect such as the referrer, device/browser info, preferred language and user email.

We also add the same trace_id onto the other 3 models in Heimdall. This will allow us to join any UserEvent, RPCLog and ErrorReport together.

RPCLogging (Deprecated: Will be removed in the future)

For RPC logging, Heimdall is backed by an Angular HttpInterceptor. The interceptor will intercept any call made by the HttpClient and will track information about the request(host, path, origin, http method), as well as information about the response(status code, response time, response size). This means that in order for you to get RPC logs for your SDK or endpoint, it needs to be using the HttpClient, not the deprecated Http class.

We've replicated these RPCLogs to DataDog and setup dashboards that teams can look at to see the general health of these applications:

User Events (Deprecated: Will be removed in the future)

Usages of the UserEventsService are discouraged. Use the SnowplowService instead.

UserEvents closely follow the same pattern as Google Analytics Events, being composed of 4 pieces:

  • Category - What group the event belongs to, often Page for page views or loads, or User for user actions.
  • Action - A descriptive term for the action taken such as View or Click.
  • Label - For adding further detail to a specific event. For instance this might describe what the user clicked, like login-button.
  • Value - The numeric value associated to the event, which is 1 by default.

We have finished the first slice of Heimdall User Events, which by default will track Page Views, we have done this by subscribing to all of Angular's RouterEvents and creating UserEvents that look something like:

{
    'event_category': 'Page',
    'event_action': 'View',
    'event_label': '/route/being/viewed',
    'event_value': 1,
    'timestamp': '1993-08-28T08:22:55Z'
}

We also expose the UserEventsService which has a method for tracking any other events you may be interested in created dynamically

export declare class UserEventsService {
  // ... removed code ...
  track(
      category: string,
      action: string,
      label: string,
      value?: number, // defaults to 1
      dimensions?: {[key: string]: string}
  ): void;
}

Dimensions (Deprecated: Will be removed in the future)

Dimensions are properties you would be interested in aggregating or filtering on later on for events or any other Heimdall model(the dimensions are included on the central SessionTrace model). Represented as a map<string, string> you can add basically any key/value pair you are interested in. You should specify any user dimensions that won't change that you want to track on the HeimdallConfigService.initialize() call, like partner_id/market_id. You can also specify additional dimensions on the UserEventsService.track() call for dimensions that may be dynamic like account_group_id.

If you need to update your dimensions (without refreshing the page), use the updateDimensions function in your instance of the HeimdallConfigService. This will update the dimension for any future calls Heimdall makes.

Initialization

To get Heimdall setup in your frontend application now, you'll first need to import the HeimdallModule from '@vendasta/core/heimdall' and add it to the list of imports of your AppModule. Which should look something like:

import { HeimdallModule } from '@vendasta/core/heimdall';

@NgModule({
    imports: [
        // other imports
        HeimdallModule
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

You will then need to call the initialize method on the HeimdallConfigService to initialize the ALL the services. This takes in a new HeimdallConfig defined as:

interface HeimdallConfig {
  project: string;
  environment: Environment;
  deploymentId: string;
  traceId?: string;
  dimensions?: { [key: string]: string };
}

You should inject the HeimdallConfigService into your application's main component such as AppComponent and in the constructor or ngOnInit call this method with a good identifier for your project like 'business-center-client'. You should have a shared or common EnvironmentService in your application which will provide your environment. The deploymentId should be stamped down by vStatic if you have <!-- vStaticInject:deployment --> in your index.html. To access it in Typescript you have to declare you have it as deployment.

All together this should look like:

import { EnvironmentService } from './common/environment.service';
import { HeimdallConfigService } from '@vendasta/core/heimdall';

declare var deployment: string; // Stamped down by vStatic

@Component({
  // Component details
})
export class AppComponent implements OnInit {

  constructor(
      private environmentService: EnvironmentService,
      private heimdallConfigService: HeimdallConfigService
    ) {}

  ngOnInit(): void {
    // Prevents capturing events on the local environment
    if (typeof deployment !== 'undefined') {
      this.heimdallConfigService.initialize({
        project: 'your-app-client',
        environment: this.environmentService.getEnvironment(),
        deploymentId: deployment,
        dimensions: {
          partnerId: partnerId,  // initialize with dimensions to include them with every event
        },
        sidepanelConfig: { defaultOwner: 'AA' },
        snowplowConfig: { projectUUID: 'my-uuid' }
      });
    }
  }
}

Later, in some other piece of code in AppComponent:

this.partnerId$.subscribe(
  newPartnerId => this.heimdallConfigService.updateDimensions({ partnerId: newPartnerId })
);

This will keep the partnerId dimension up to date for future RPCs.

Snowplow Setup

We are using Snowplow Analytics to track user movement throughout the product.

A quick summary for Snowplow, as seen in their docs:

Snowplow is an enterprise-strength marketing and product analytics platform. It does three things:

  1. Identifies your users, and tracks the way they engage with your website or application
  2. Stores your users' behavioural data in a scalable "event data warehouse" you control: in Amazon S3 and (optionally) Amazon Redshift or Postgres
  3. Lets you leverage the biggest range of tools to analyze that data, including big data tools (e.g. Spark) via EMR or more traditional tools e.g. Looker, Mode, Superset, Re:dash to analyze that behavioural data

How to create a UUID for Snowplow

To create a new snowplow UUID, you can hit the following endpoint:

https://prospect-api-prod.apigateway.co/prospect.v1.MarketingAutomation/CreateTracker

with the following payload:

{
	"name": "Project Name",
	"partner_id": "VMF"
}

You can use VMF as the partner id since that is where alot of automations live. You will use the same id for demo and prod.

How to enable Snowplow in your TS Project

To enable Snowplow in your projects that contain Heimdall, you need to add a snowplowConfig config entry, to the HeimdallConfig, with a projectUUID entry with the unique ID you created above.

You can also tie the tracking to a user by passing in their UID to the userID field. The userID is optional.

this.heimdallConfig.initialize({
    // ...
    snowplowConfig: {
        projectUUID: environment.snowplowId,
        userID: userID
    }
});

Tracking directives

[snowplowTrackLink]: Can be used to track link clicks that within the application.

Status Sidepanel

This sidepanel taps into heimdalls rpc logging service and displays it to the user for the current page. When you navigate between pages, it drops all the logs from the previous page. The status sidepanel is injected into any applications DOM if the user has a Success or Developer persona attached to their email.

The node injected into your DOM is called heimdall-sidepanel-container. It is controlled by the StatusSidepanelService that comes with Heimdall. You can access that service to get access to the following information:

  • sidepanelVisible$: Observable<boolean> - Whether the sidepanel is currently visible to the user
  • sidepanelAvailable$: Observable<boolean> - Whether the sidepanel is available for the current user. This tells you if the sidepanel was injected into the DOM.
  • toggleSidepanel(): void - Toggles the visibility of the sidepanel

You will need to add the heimdall-sidepanel-btn component that is exported by the Heimdall SDK into your application Atlas bar actions sections. This will only appear if the use can access the sidepanel.

app.component.html

<div class="atlas-actions">
  ...
  <heimdall-sidepanel-btn></heimdall-sidepanel-btn>
  ...
</div>

Endpoint Ownership

The sidepanel will try to get the owner of each endpoint. If the owner can not be found for the endpoint, it will use to default owner specified in the HeimdallSidepanelConfig. If nothing is set as the default it will say No Owner Found. If the endpoint is returning the wrong owner for an endpoint, view the troubleshooting section.

Troubleshooting

The cause of this issue typically is because your project has multiple HttpClientModule's throughout its imports. Try the following to troubleshoot your problems:

  • Make sure your @vendasta/* imports are the latest version
  • Make sure you only include the HttpClientModule once, in your app.module.ts
  • Install Augury for your chrome based browser and look through all the ngModules imports for HttpClientModule

The owner of each endpoint is gathered from the sre-reporting service which uses the service-level.yaml file that each github report should contain EXAMPLE.

You can update that file to reflect the correct ownership of the endpoint and then you will have to wait for SRE-Reporting to update. If you experience any issues regarding ownership, please reach out to #sre-team for assistance.

3.2.0

4 years ago

3.1.0

4 years ago

3.0.0

4 years ago

2.2.0

4 years ago

2.1.1

4 years ago

2.1.0

4 years ago

2.0.4

4 years ago

2.0.3

4 years ago

2.0.2

4 years ago

2.0.1

4 years ago

2.0.0

4 years ago

1.28.1

5 years ago

1.28.0

5 years ago

1.27.1

5 years ago

1.27.0

5 years ago

1.26.0

5 years ago

1.25.0

5 years ago

1.24.0

5 years ago

1.23.1

5 years ago

1.23.0

5 years ago

1.22.2

5 years ago

1.22.1

5 years ago

1.22.0

5 years ago

1.21.2

5 years ago

1.21.1

5 years ago

1.21.0

5 years ago

1.20.1

5 years ago

1.20.0

5 years ago

1.19.0

5 years ago

1.18.0

5 years ago

1.17.0

5 years ago

1.16.0

5 years ago

1.15.1

5 years ago

1.15.0

5 years ago

1.14.0

5 years ago

1.13.1

5 years ago

1.13.0

5 years ago

1.12.1

5 years ago

1.12.0

5 years ago

1.11.1

5 years ago

1.11.0

5 years ago

1.10.0

5 years ago

1.9.0

5 years ago

1.8.5

6 years ago

1.8.4

6 years ago

1.8.3

6 years ago

1.8.2

6 years ago

1.8.1

6 years ago

1.8.0

6 years ago

1.7.0

6 years ago

1.6.0

6 years ago

1.5.2

6 years ago

1.5.1

6 years ago

1.5.0

6 years ago

1.4.0

6 years ago

1.3.1

6 years ago

1.3.0

6 years ago

1.2.0

6 years ago

1.2.1

6 years ago

1.1.1

6 years ago

1.1.0

6 years ago

1.0.0

6 years ago

0.10.3

6 years ago

0.10.2

6 years ago

0.10.1

6 years ago

0.10.0

6 years ago