@vendasta/heimdall v3.2.0
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, oftenPage
for page views or loads, orUser
for user actions.Action
- A descriptive term for the action taken such asView
orClick
.Label
- For adding further detail to a specific event. For instance this might describe what the user clicked, likelogin-button
.Value
- The numeric value associated to the event, which is1
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:
- Identifies your users, and tracks the way they engage with your website or application
- Stores your users' behavioural data in a scalable "event data warehouse" you control: in Amazon S3 and (optionally) Amazon Redshift or Postgres
- 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.
- You can add developers at the IAM Developers Page
- To add a Success persona to a user, you will need to manually hit a IAM endpoint
- Endpoint: https://iam-api-prod.vendasta-internal.com/iam.v1.IAM/RegisterSubject
- Use your Vendasta accounts Bearer token
- Payload should be the following:
{ "context": { "typed": { "type": "success" } }, "email": "<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 usersidepanelAvailable$: 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 yourapp.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.
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago