Send data from JavaScript app to Axiom
To send data from a JavaScript app to Axiom, use one of the following libraries of the Axiom JavaScript SDK:
The choice between these options depends on your individual requirements:
| Capabilities | @axiomhq/js | @axiomhq/logging |
|---|---|---|
| Send data to Axiom | Yes | Yes |
| Query data | Yes | No |
| Capture errors | Yes | No |
| Create annotations | Yes | No |
| Transports | No | Yes |
| Structured logging by default | No | Yes |
| Send data to multiple places from a single function | No | Yes |
The @axiomhq/logging library is a logging solution that also serves as the base for other libraries like @axiomhq/react and @axiomhq/nextjs.
The @axiomhq/js and the @axiomhq/logging libraries are part of the Axiom JavaScript SDK, an open-source project and welcomes your contributions. For more information, see the GitHub repository.
Prerequisites#
- Create an Axiom account.
- Create a dataset in Axiom where you send your data.
- Create an API token in Axiom with permissions to ingest data to the dataset you have created.
Use @axiomhq/js#
Install @axiomhq/js#
In your terminal, go to the root folder of your JavaScript app and run the following command:
```shell
npm install @axiomhq/js
```
Configure environment variables#
Configure the environment variables in one of the following ways:
-
Export the API token as
AXIOM_TOKEN. -
Pass the API token to the constructor of the client:
import { Axiom } from '@axiomhq/js'; const axiom = new Axiom({ token: process.env.AXIOM_TOKEN, }); -
Install the Axiom CLI, and then run the following command:
eval $(axiom config export -f)
Configure region#
By default, the client sends data to api.axiom.co. To target a specific edge region, set the edge option to the edge domain that matches the region your dataset lives in:
import { Axiom } from '@axiomhq/js';
const axiom = new Axiom({
token: process.env.AXIOM_TOKEN,
edge: 'eu-central-1.aws.edge.axiom.co',
});import { Axiom } from '@axiomhq/js';
const axiom = new Axiom({
token: process.env.AXIOM_TOKEN,
edge: 'us-east-1.aws.edge.axiom.co',
});The following edge domains are available:
| Edge deployment | Base domain for ingest and query |
|---|---|
| US East 1 (AWS) | us-east-1.aws.edge.axiom.co |
| EU Central 1 (AWS) | eu-central-1.aws.edge.axiom.co |
For more information about edge deployments, see Edge deployments.
Always use the edge option to target a region. Don't put a regional hostname in url — url is reserved for non-ingest API operations and won't route ingest correctly.
Edge endpoints require an API token (xaat-). Personal tokens (xapt-) are deprecated and aren't supported for edge routing.
Client options#
| Option | Required | Description |
|---|---|---|
token |
yes | An Axiom API token with ingest permission for the dataset. |
orgId |
no | Organization ID. Required when using a personal token. |
edge |
no | Edge domain for ingest and query, without scheme. Example: eu-central-1.aws.edge.axiom.co. Use this to target a region. |
edgeUrl |
no | Full edge URL with scheme. Takes precedence over edge if both are set. Useful for self-hosted or proxy setups. |
url |
no | Base URL for non-ingest API operations. Only needed if you call other Axiom APIs from the same client. |
onError |
no | Callback invoked when sending data fails. Defaults to console.error. |
Send data to Axiom#
The following example sends data to Axiom:
axiom.ingest('DATASET_NAME', [{ foo: 'bar' }]);
await axiom.flush();Replace DATASET_NAME with the name of the Axiom dataset where you send your data.
The client automatically batches events in the background. In most cases, call flush() only before your app exits.
Query data#
The following example queries data from Axiom:
const res = await axiom.query(`['DATASET_NAME'] | where foo == 'bar' | limit 100`);
console.log(res);Replace DATASET_NAME with the name of the Axiom dataset where you send your data.
For more examples, see the examples in GitHub.
Capture errors#
To capture errors, pass a method onError to the client:
let client = new Axiom({
token: '',
...,
onError: (err) => {
console.error('ERROR:', err);
}
});By default, onError is set to console.error.
Create annotations#
The following example creates an annotation:
import { annotations } from '@axiomhq/js';
const client = new annotations.Service({ token: process.env.AXIOM_TOKEN });
await annotations.create({
type: 'deployment',
datasets: ['DATASET_NAME'],
title: 'New deployment',
description: 'Deployed version 1.0.0',
})Use @axiomhq/logging#
Install @axiomhq/logging#
In your terminal, go to the root folder of your JavaScript app and run the following command:
npm install @axiomhq/loggingSend data to Axiom#
The following example sends data to Axiom:
import { Logger, AxiomJSTransport, ConsoleTransport } from "@axiomhq/logging";
import { Axiom } from "@axiomhq/js";
const axiom = new Axiom({
token: process.env.AXIOM_TOKEN,
});
const logger = new Logger(
{
transports: [
new AxiomJSTransport({
axiom,
dataset: process.env.AXIOM_DATASET,
}),
new ConsoleTransport(),
],
}
);
logger.info("Hello, world!");Because AxiomJSTransport sends data through the @axiomhq/js client, set the region by passing the edge option to the Axiom constructor. For the full list of edge domains, see Configure region.
Transports#
The @axiomhq/logging library includes the following transports:
-
ConsoleTransport: Logs to the console.import { ConsoleTransport } from "@axiomhq/logging"; const transport = new ConsoleTransport({ logLevel: "warn", prettyPrint: true, }); -
AxiomJSTransport: Sends logs to Axiom using the @axiomhq/js library.import { Axiom } from "@axiomhq/js"; import { AxiomJSTransport } from "@axiomhq/logging"; const axiom = new Axiom({ token: process.env.AXIOM_TOKEN, }); const transport = new AxiomJSTransport({ axiom, dataset: process.env.AXIOM_DATASET, logLevel: "warn", }); -
ProxyTransport: Sends logs the proxy server function that acts as a proxy between your app and Axiom. It’s particularly useful when your app runs on top of a server-enabled framework like Next.js or Remix.import { ProxyTransport } from "@axiomhq/logging"; const transport = new ProxyTransport({ url: "/proxy", logLevel: "warn", autoFlush: { durationMs: 1000 }, });
Alternatively, create your own transports by implementing the Transport interface:
import { Transport } from "@axiomhq/logging";
class MyTransport implements Transport {
log(log: Transport['log']) {
console.log(log);
}
flush() {
console.log("Flushing logs");
}
}Logging levels#
The @axiomhq/logging library includes the following logging levels:
debug: Debug-level logs.info: Informational logs.warn: Warning logs.error: Error logs.
Formatters#
Formatters are used to change the content of a log before sending it to a transport. For example:
import { Logger, LogEvent } from "@axiomhq/logging";
const myCustomFormatter = (event: LogEvent) => {
const upperCaseKeys = {
...event,
fields: Object.fromEntries(
Object.entries(event.fields).map(([key, value]) => [key.toUpperCase(), value])
),
};
return upperCaseKeys;
};
const logger = new Logger({
formatters: [myCustomFormatter],
});
logger.info("Hello, world!");Related logging options#
Send data from JavaScript libraries and frameworks#
To send data to Axiom from JavaScript libraries and frameworks, see the following:
Send data from Node.js#
While the Axiom JavaScript SDK works on both the backend and the browsers, Axiom provides transports for some of the popular loggers: