Skip to content

Commit

Permalink
Merge branch 'main' into add-support-for-server-side-props
Browse files Browse the repository at this point in the history
  • Loading branch information
schehata committed Jan 26, 2023
2 parents 811bb9c + 4355540 commit b7e1249
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 32 deletions.
48 changes: 34 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<div align="center">

[![build](https://img.shields.io/github/workflow/status/axiomhq/next-axiom/CI?ghcache=unused)](https://github.com/axiomhq/next-axiom/actions?query=workflow%3ACI)
[![build](https://img.shields.io/github/actions/workflow/status/axiomhq/next-axiom/ci.yml?branch=main&ghcache=unused)](https://github.com/axiomhq/next-axiom/actions?query=workflow%3ACI)
[![Latest release](https://img.shields.io/github/release/axiomhq/next-axiom.svg)](https://github.com/axiomhq/next-axiom/releases/latest)
[![License](https://img.shields.io/github/license/axiomhq/next-axiom.svg?color=blue)](https://opensource.org/licenses/MIT)

Expand All @@ -13,29 +13,43 @@

- **Ingest with ease, store without limits:** Axiom’s next-generation datastore enables ingesting petabytes of data with ultimate efficiency. Ship logs from Kubernetes, AWS, Azure, Google Cloud, DigitalOcean, Nomad, and others.
- **Query everything, all the time:** Whether DevOps, SecOps, or EverythingOps, query all your data no matter its age. No provisioning, no moving data from cold/archive to “hot”, and no worrying about slow queries. All your data, all. the. time.
- **Powerful dashboards, for continuous observability:** Build dashboards to collect related queries and present information that’s quick and easy to digest for you and your team. Dashboards can be kept private or shared with others, and are the perfect way to bring together data from different sources
- **Powerful dashboards, for continuous observability:** Build dashboards to collect related queries and present information that’s quick and easy to digest for you and your team. Dashboards can be kept private or shared with others, and are the perfect way to bring together data from different sources.

For more information check out the [official documentation](https://axiom.co/docs).
For more information, check out the [official documentation](https://axiom.co/docs).

## Quickstart
## Installation

- If you are using Vercel, make sure you have the [Axiom Vercel integration](https://www.axiom.co/vercel)
installed. On other platforms you must create an API token and set those environment variables:
### Using Vercel Integration

:warning: next-axiom is still experimental for non-Vercel platforms and is subject to change.
Make sure you have the [Axiom Vercel integration](https://www.axiom.co/vercel) installed. Once it is done, perform the steps below:

- In your Next.js project, run install `next-axiom` as follows:

```sh
npm install --save next-axiom
```
AXIOM_DATASET: the dataset the logs will be ingested into
AXIOM_TOKEN: the API token you created for ingestion to the dataset

- In the `next.config.js` file, wrap your Next.js config in `withAxiom` as follows:

```js
const { withAxiom } = require('next-axiom');

module.exports = withAxiom({
// ... your existing config
});
```

- Then in your Next.js project, run install `next-axiom` like this:
### Using Any Other Platform

Create an API token in [Axiom settings](https://cloud.axiom.co/settings/profile) and export it as `AXIOM_TOKEN`, as well as the Axiom dataset name as `AXIOM_DATASET`. Once it is done, perform the steps below:

- In your Next.js project, run install `next-axiom` as follows:

```sh
npm install --save next-axiom
```

- Wrap your Next.js config in `withAxiom` like this in `next.config.js`:
- In the `next.config.js` file, wrap your Next.js config in `withAxiom` as follows:

```js
const { withAxiom } = require('next-axiom');
Expand All @@ -45,7 +59,13 @@ module.exports = withAxiom({
});
```

- Go to `pages/_app.js` or `pages/_app.ts` and add the following line to report web vitals:
:warning: `next-axiom` is still experimental for non-Vercel platforms and is subject to change.

## Usage

### Web Vitals

Go to `pages/_app.js` or `pages/_app.ts` and add the following line to report web vitals:

```js
export { reportWebVitals } from 'next-axiom';
Expand Down Expand Up @@ -85,7 +105,7 @@ function home() {
}
```

## Log Levels
### Log Levels

The log level defines the lowest level of logs sent to Axiom.
The default is debug, resulting in all logs being sent.
Expand All @@ -103,6 +123,6 @@ You can also disable logging completely by setting the log level to `off`:
export AXIOM_LOG_LEVEL=off
```

## License
### License

Distributed under the [MIT License](LICENSE).
12 changes: 12 additions & 0 deletions __tests__/log.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,15 @@ test('flushing child loggers', async () => {
await log.flush();
expect(fetch).toHaveBeenCalledTimes(3);
});

test('throwing exception', async () => {
global.fetch = jest.fn() as jest.Mock;
const err = new Error('test');
log.error('hello, world!', err);
await log.flush();
expect(fetch).toHaveBeenCalledTimes(1);
const payload = JSON.parse((fetch as jest.Mock).mock.calls[0][1].body);
expect(Object.keys(payload[0].fields).length).toEqual(3); // { name, message, stack }
expect(payload[0].fields.message).toEqual(err.message);
expect(payload[0].fields.name).toEqual(err.name);
});
17 changes: 8 additions & 9 deletions examples/logger/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 25 additions & 3 deletions src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@ export class Logger {
const logEvent: LogEvent = { level, message, _time: new Date(Date.now()).toISOString(), fields: this.args || {} };

// check if passed args is an object, if its not an object, add it to fields.args
if (typeof args === 'object' && args !== null && Object.keys(args).length > 0) {
logEvent.fields = { ...logEvent.fields, ...args };
if (args instanceof Error) {
logEvent.fields = { ...logEvent.fields, message: args.message, stack: args.stack, name: args.name };
} else if (typeof args === 'object' && args !== null && Object.keys(args).length > 0) {
const parsedArgs = JSON.parse(JSON.stringify(args, jsonFriendlyErrorReplacer));
logEvent.fields = { ...logEvent.fields, ...parsedArgs };
} else if (args && args.length) {
logEvent.fields = { ...logEvent.fields, args: args };
}
Expand Down Expand Up @@ -153,7 +156,11 @@ export class Logger {
const fetch = await require('whatwg-fetch');
await fetch(url, reqOptions);
} else if (config.isBrowser && isVercel && navigator.sendBeacon) {
navigator.sendBeacon(url, body);
// sendBeacon fails if message size is greater than 64kb, so
// we fall back to fetch.
if (!navigator.sendBeacon(url, body)) {
await fetch(url, reqOptions);
}
} else {
await fetch(url, reqOptions);
}
Expand Down Expand Up @@ -226,3 +233,18 @@ export function prettyPrint(ev: LogEvent) {

console.log.apply(console, [msgString, ...args]);
}

function jsonFriendlyErrorReplacer(key: string, value: any) {
if (value instanceof Error) {
return {
// Pull all enumerable properties, supporting properties on custom Errors
...value,
// Explicitly pull Error's non-enumerable properties
name: value.name,
message: value.message,
stack: value.stack,
};
}

return value;
}

0 comments on commit b7e1249

Please sign in to comment.