Welcome to the Quantum Metric Analytics Plugin for Backstage! This plugin aims to provide a quick and robust means to integrate Quantum Metric analytics with your Backstage instance.
This plugin requires an account with Quantum Metric
yarn --cwd packages/app add @quantum-metric/plugin-analytics-module-qm
import {
analyticsApiRef,
configApiRef,
identityApiRef,
} from '@backstage/core-plugin-api';
import { QuantumMetric } from '@quantum-metric/plugin-analytics-module-qm';
createApiFactory({
api: analyticsApiRef,
deps: { configApi: configApiRef, identityApi: identityApiRef },
factory: ({ configApi, identityApi }) =>
QuantumMetric.fromConfig(configApi, {
identityApi,
}),
}),
After installing the plugin, the Quantum Metric Analytics plugin will need to be configured. The options and reference example are detailed below.
The table below lists the available configuration options for the Quantum Metric Analytics plugin:
Field Name | Type | Required | Default | Description |
---|---|---|---|---|
enabled | boolean | Yes | Disables plugin. | |
src | string | Yes | CDN location of Quantum Metric API. The value is qtm.src on your subscriptions Install page. |
|
debug | boolean | No | false |
Turns on console.debug messages. |
test | boolean | No | false |
When enabled, events are logged to console instead of sent to Quantum Metric. |
async | boolean | No | false |
Sets the async attribute of the resulting HTML <script> element. |
events.mappings | list of {name: string, id: integer} | Yes | {} |
Maps Backstage AnalyticsEvent actions to Quantum Metric Event ID's as a list of objects with name and id . |
events.attributes | list of {name: string, value: string} | Yes | {} |
Included on every event sent to Quantum Metric under Event Details as a list of objects with name and value . |
Below is a reference configuration file:
app:
analytics:
qm:
enabled: true
src: https://cdn.quantummetric.com/qscripts/quantum-$SUB_NAME.js
debug: false
test: false
async: false
events:
mappings:
- name: navigate
id: $QUANTUM_NAVIGATE_EVENT_ID
- name: click
id: $QUANTUM_CLICK_EVENT_ID
- name: search
id: $QUANTUM_SEARCH_EVENT_ID
- name: discover
id: $QUANTUM_DISCOVER_EVENT_ID
attributes:
- name: environment
value: development
- name: version
value: 0.0.1
Where the event mappings IDs are the Quantum Metric event IDs you wish to send.
The plugin comes with default Event Transformers for each predefined Backstage key event as described in Default Transformers. However, you can customize or extend these transformers. To override a default transformer or add transformers for new actions, modify the Analytics API configuration as follows:
createApiFactory({
api: analyticsApiRef,
deps: { configApi: configApiRef },
factory: ({ configApi }) =>
QuantumMetric.fromConfig(configApi, {
eventTransforms: {
discover: (event, mapping) => {
return { eventId: mapping[event.action], eventValue: event.attributes.to, attributes: { ...event.attributes, event.subject } };
},
},
}),
})
In the above example, the default transformer for the discover key event is overridden. The value sent to Quantum Metric
is changed to event.attributes.to
instead of the provided event.subject
, and the event.subject
is added as an
attribute.
There is a transformer for every Backstage key
event, and a default transformer when an action is not found
in the eventTransforms
record. The definitions can be found in src/api/util/transforms.ts.
Backstage Analytics Action | Quantum Metric Event ID | Quantum Metric Event Value | Quantum Metric Event Attributes | Quantum Metric Event Conversion |
---|---|---|---|---|
sendEvent |
Set to Backstage event subject | Set to Backstage event value | Event attributes | Set to false |
navigate |
Mapped from configuration event.mappings |
Set to Backstage event subject | Combined attributes from context and event attributes | Set to false |
search |
Mapped from configuration event.mappings |
Set to Backstage event subject | Combined attributes from context, event attributes, and results-found from event value |
Set to false |
discover |
Mapped from configuration event.mappings |
Set to Backstage event subject | Combined attributes from context, event attributes, and search-position from event value |
Set to false |
click |
Mapped from configuration event.mappings |
Set to Backstage event subject | Combined attributes from context and event attributes | Set to false |
defaultEventTransform |
Mapped from configuration event.mappings |
Set to Backstage event value and if not present then subject | Combined attributes from context and event attributes | Set to false |
To configure identity from Backstage to Quantum Metric provide the IdentityAPI
to the plugin like so:
createApiFactory({
api: analyticsApiRef,
deps: { configApi: configApiRef },
factory: ({ configApi, identityApi }) =>
QuantumMetric.fromConfig(configApi, {
identityApi
}),
}),
This will identify users in Quantum Metric by their Backstage profile email.
Global attributes allow you to add attributes to all events sent through the Quantum Metric analytics plugin. When configured, these attributes will be included in the event details in Quantum Metric.
To configure global attributes, use the following format in your configuration file:
app:
analytics:
qm:
events:
attributes:
- name: environment
value: development
- name: version
value: 0.0.1
With the above configuration, the event details in Quantum Metric will include the following attributes:
{
"environment": "development",
"version": "0.0.1"
}
If the event is generated from Backstage events and includes attributes via the event transformers, those attributes will also be included along with the global attributes.
For example, if a search event is triggered with the default event transformer it includes the attribute results-found
and also has the global attributes configured, the event details will look like this:
{
"results-found": 10,
"environment": "development",
"version": "0.0.1"
}
Note: In the case of attribute name collisions between global attributes and event-specific attributes, the global attributes will take precedence and be included in the event details.
With the Quantum Metric plugin fully installed and configured, Backstage key events will be captured without extra effort.
To send events that are defined in the configuration's event mappings or event transformers, you can use the
useAnalytics hook provided by @backstage/core-plugin-api
.
Here's an example of capturing a basic event:
import { useAnalytics } from '@backstage/core-plugin-api';
const analytics = useAnalytics();
analytics.captureEvent('catalog-updated', catalogEntityName);
If you want to add more information sent to Quantum Metric, you can include additional attributes:
analytics.captureEvent('catalog-updated', catalogEntityName {
value: numOfEntitiesUpdated,
attributes: {
entityOwner,
entityType,
userTeam,
},
});
These additional attributes will show up under the events details in Quantum Metric.
The specific configuration for the catalog-updated
event can be defined either in the event mappings or with an event
transformer.
Example event mappings configuration:
app:
analytics:
qm:
events:
mappings:
- name: catalog-updated
id: $QUANTUM_METRIC_CATALOG_UPDATED_EVENT_ID
Alternatively, the default event transformer can be extended to capture more attributes for catalog-updated
:
createApiFactory({
api: analyticsApiRef,
deps: { configApi: configApiRef },
factory: ({ configApi }) =>
QuantumMetric.fromConfig(configApi, {
eventTransforms: {
'catalog-updated': (event, mapping) => {
return {
eventId: mapping[event.action],
eventValue: event.subject,
attributes: { ...event.attributes, ...event.context, numberOfAffectedEntities: event.value }
};
},
},
}),
})
Additional information can also be added to Quantum Metric event details with the context React component.
import { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';
const GreetingComponent = ({ name }) => {
const analytics = useAnalytics();
const handleClick = () => analytics.captureEvent('greeted', name);
return <button onClick={handleClick}>Say Hello to {name}</button>;
};
const GreetingComponentWrapper = () => {
return (
<AnalyticsContext attributes={{ admin: true }}>
<GreetingComponent name={'Alice'} />
</AnalyticsContext>
);
};
When the GreetingComponent
button is clicked, it will send a greeted
event to Quantum Metric with the value of
Alice
, and the event details will include information about Alice
being an admin.
Before submitting your pull request, ensure your title follows the semantic commit format. This not only helps our maintainers but also improves the overall transparency and readability of our project history.
For more detailed contributions guidelines, check our CONTRIBUTING.md file.
yarn install
yarn build
yarn add @quantum-metric/plugin-analytics-module-qm@link:$INSTALL_PATH
Note: If making changes to config.d.ts
against a Backstage instance started with backstage-cli package start
,
changes will not take effect till the next backstage-cli package start
In this project, we enforce the use of semantic commit messages to streamline our release and changelog generation process. This ensures our commit history is readable and understandable.
Semantic commit messages follow a structured format to clearly describe the purpose and intent of each commit. The general format is:
-
<type>
: This denotes the kind of change you're making. Common types includefeat
(new features),fix
(bug fixes),docs
(documentation changes),style
(code styling, no functional changes),refactor
(code changes that neither fix bugs nor add features),perf
(performance improvements),test
(adding missing tests), andchore
(maintenance tasks). -
<scope>
: A scope provides additional contextual information, such as the part of the codebase affected (optional). -
<description>
: A brief, imperative mood description of the change.
Examples:
feat(auth): implement JWT authentication
fix(server): resolve memory leak issue
chore(readme): update installation instructions
This project uses the amannn/action-semantic-pull-request
GitHub Action to ensure all pull requests follow the semantic commit format. The action checks your pull request titles,
not the individual commit messages. Make sure your PR titles follow the semantic format.
If your pull request title does not meet the semantic requirements, the check will fail, and you'll need to update the
title accordingly. You can also add multiple types if your pull request covers more than one scope, separated by commas
(e.g., feat, fix: implement new feature and fix a bug
).
Semantic versioning works by interpreting your semantic commit as described in the previous section and assigning it a
classification based on the level of severity of the work. That classification then translates into a version number
that follows the sequence: Major.Minor.Patch
.
When a major, minor, or patch update is made, the corresponding number is increased.
- Major version changes when incompatible API changes are made.
- Minor version changes when new functionality is added backward-compatible manner.
- Patch version changes when backward-compatible bug fixes are made.
The table below describes the relationship between the semantic commit message and the semantic version sequence:
Commit Message | Inferred Type | Example Sequence Update |
---|---|---|
feat(auth): implement JWT authentication |
Major | 1.0.0 |
fix(server): resolve memory leak issue |
Minor | 0.1.0 |
chore(readme): update installation instructions |
Patch | 0.0.1 |