Skip to main content

Instrumentation

FrontHub proxies all events emitted by your microfronted, messages, errors, RUM beacons are scoped per microfronted before sent to the monitoring system.

You may log messages or track events:

import { useInstrumentation } from '@resultadosdigitais/front-hub/react'

function MyComponent() {
const { track, log } = useInstrumentation()

track('myEvent')

log('this is a log message')

return <h1>Instrumentation Example</h1>
}

In the Application Host you can define as many listeners as necessary to listen for these events or messages:

fronthub('instrumentation', {
track: function (event, next) {
AnalyticsService.track(event.name, event.payload)
next()
},
log: function (context, next) {
if (context.level === 'error') {
ErrorService.error(context.message, context)
} else {
LogService.info(context.message, context)
}
next()
},
})

If no listener is defined, all of these information are sent to console.log.

It is important to note that the triggering of these functions does not block the main thread of the browser, it queues the functions to be called during a browser's idle periods. This enables you to send all these events to a server without impacting latency-critical events such as animation and input response.

Logging

To send a log just use the log() function from useInstrumentation hook:

import { useInstrumentation } from '@resultadosdigitais/front-hub/react'

function MyComponent() {
const { log } = useInstrumentation()

log('this is a log message')

return <h1>Instrumentation Example</h1>
}

The log() can be described as:

log(message[, options])

The message is preferably a string with any significant information.

The options can be used to complete the log with extra information, the following values will be set if it is not overwritten:

{
group: 'default',
tracePerformance: false,
}

Logging Levels

Logging levels in FrontHub is ordered from least important to most important. The higher the priority the more important the message is considered to be, and the lower the corresponding integer priority.

The levels are defined as follows:

PriorityNameDescription
1'verbose'Designates finer-grained informational events to be used in very specific cases
2'debug'Designates fine-grained informational events that are most useful to debug an application.
3'info'Designates informational messages that highlight the progress of the application at coarse-grained level.
4'warn'Designates potentially harmful situations.
5'error'Designates error events that might still allow the application to continue running.

Always use the name to configure or handle the level.

Using Logging Levels

You can use functions directly from the hook with the name of the level itself:

import { useInstrumentation } from '@resultadosdigitais/front-hub/react'

function MyComponent() {
const { verbose, debug, info, warn, error } = useInstrumentation()

verbose('The application passed through here :)')
debug("I'll send an S.O.S to the world")
info("Some important flow's information")
warn("It shouldn't have happened")
error('OMG! Something is broken')

return <h1>Instrumentation Example</h1>
}

The log() function is equivalent to the info() function.

Error Handling

The error is the highest level in the logging:

import { useInstrumentation } from '@resultadosdigitais/front-hub/react'

function MyComponent() {
const { error } = useInstrumentation()

error('OMG! Something is broken')

return <h1>Instrumentation Example</h1>
}

However, in addition to the message as a string, it is possible to pass an error instance:

import { useInstrumentation } from '@resultadosdigitais/front-hub/react'

function MyComponent() {
const { error } = useInstrumentation()

// you can create an error from nowhere and send it
error(new Error('My custom error'))

try {
// ...
} catch (e) {
// You can send a captured error as well
error(e)
}

return <h1>Instrumentation Example</h1>
}

The error instance contains the stack trace for where our error was thrown, this is very important in investigating bugs in your microfrontend.

If you want to standardize the errors sent, you can extend the Error class:

import { useInstrumentation } from '@resultadosdigitais/front-hub/react'

class ValidationError extends Error {
constructor(message) {
super(message)
this.name = 'ValidationError'
}
}

function MyComponent({ title }) {
const { error } = useInstrumentation()

if (!title) {
error(new ValidationError('MyComponent: title is not present'))
}

return <h1>Instrumentation Example</h1>
}

Tracking

To track an event just use the track() function from useInstrumentation hook:

import { useInstrumentation } from '@resultadosdigitais/front-hub/react'

function MyComponent() {
const { track } = useInstrumentation()

track('myEvent')

return <h1>Instrumentation Example</h1>
}

The track() can be described as:

track(name[, payload, options])

The name is the name of the event.

The payload can be used to add extra information to event, the default value is an empty plain object.

The options can be used to add extra information for the listener, the following values will be set if it is not overwritten:

{
group: 'default',
tracePerformance: false,
}

Listeners

All listeners must to call next() to be able to move on to the next listener, since it can be called multiple times:

fronthub('instrumentation', {
log: function (context, next) {
next()
},
})
fronthub('instrumentation', {
log: function (context, next) {
// This listener will be used,
// since the previous one called the next()
},
})
fronthub('instrumentation', {
log: function (context, next) {
// This listener will NOT be used because
// the previous listener did not call the next()
},
})

You can define all properties in the same instrumentation, for example:

fronthub('instrumentation', {
track: function (context, next) {
next()
},
log: function (context, next) {
next()
},
error: function (context, next) {
next()
},
})

When defined together the order of the listeners is: track > log > [log levels by priorities].

Logging Listeners

The simplest way to listen to the logs on the Application Host is to use the log property:

fronthub('instrumentation', {
log: function (context, next) {
console.log(context)
next()
},
})

The context has the following properties:

PropertyTypeDescription
typestringFor logging the type is 'log'
levelstringLogging Level name
messagestringString sent in the first parameter or the error message if it is an instance of Error
errorErrorContains the instance of the Error if it is defined in the first parameter, otherwise it is undefined
optionsobjectInformation sent in the second parameter
metadataobjectFrontHub information

You can define an lister using the level name:

fronthub('instrumentation', {
error: function (context, next) {
// only error logs
console.error(context)
next()
},
warn: function (context, next) {
// only warning logs
console.warn(context)
next()
},
info: function (context, next) {
// only information logs
console.log(context)
next()
},
})

When defining a listener using the level name, it will be called exactly the level you are defining, priority is not used here.

The log is called for all logs, but you can filter by level through the context.level parameter.

Tracking Listeners

The simplest way to listen to the events on the Application Host is to use the track property:

fronthub('instrumentation', {
track: function (context, next) {
console.log(context)
next()
},
})

You can use the Front Hub Analytics library as a listener to listen to your events. Front Hub Analytics was developed to accommodate the needs related to recording business metrics (Analytics) in any Microfrontend that uses Front Hub.

fronthub('instrumentation', {
track: function (event, next) {
fronthubAnalytics.track(event.name, event.payload)
next()
},
})

The context has the following properties:

PropertyTypeDescription
typestringFor tracking the type is 'track'
namestringInformation sent in the first parameter
payloadobjectInformation sent in the second parameter
optionsobjectInformation sent in the third parameter
metadataobjectFrontHub information

Configuration

Logging

You can configure the logging in FrontHub configuration with the follow properties:

PropertyDefaultDescription
level'debug'Minimum level that listeners will receive

Example:

front-hub.config.js
module.exports = {
// ...
log: {
level: 'error',
},
}