Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added support for bunyan logger with axiom #71

Closed
wants to merge 12 commits into from
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ This is a monorepo, for specific documentation, check out the different projects
* [`@axiomhq/js`](./packages/js): Official API bindings that let you ingest or query your data.
* [`@axiomhq/winston`](./packages/winston): A [winston](https://github.com/winstonjs/winston) transport which sends logs to Axiom.
* [`@axiomhq/pino`](./packages/pino): A [pino](https://github.com/pinojs/pino) transport which sends logs to Axiom.
* [`@axiomhq/bunyan`](./packages/bunyan): A [Bunyan](https://github.com/trentm/node-bunyan) transport which sends logs to Axiom.
Bensigo marked this conversation as resolved.
Show resolved Hide resolved

## License

Expand Down
20 changes: 20 additions & 0 deletions examples/bunyan/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "examples-bunyan",
"version": "1.0.0",
"private": true,
"description": "examples on using axiom with bunyan",
"scripts": {
"build": "tsc",
"format": "eslint ./src --ext .ts --quiet --fix",
"lint": "eslint ./src --ext .ts",
"example": "ts-node"
},
"dependencies": {
"@axiomhq/bunyan": "workspace:*",
"bunyan": "^1.8.15"
},
"devDependencies": {
"@types/bunyan": "^1.8.8",
"@types/node": "^20.4.1"
}
}
27 changes: 27 additions & 0 deletions examples/bunyan/src/bunyan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import bunyan from 'bunyan';
import { AxiomStream } from '@axiomhq/bunyan';

const stream = new AxiomStream({
dataset: process.env.AXIOM_DATASET,
orgId: process.env.AXIOM_ORG_ID,
token: process.env.AXIOM_TOKEN,
onError: (err) => {
console.log({ err });
},
});

const logger = bunyan.createLogger({
name: 'Example app',
streams: [
{
type: 'raw',
stream: stream,
level: 'info',
},
],
});

logger.info('Hello world!!');

// flush axiom event batch
stream.flush();
8 changes: 8 additions & 0 deletions examples/bunyan/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src/**/*"]
}
10 changes: 10 additions & 0 deletions packages/bunyan/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.1.0] - 2023-09-11
52 changes: 52 additions & 0 deletions packages/bunyan/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Axiom Stream for Bunyan logger

This is the official Axiom Stream for Bunyan.

## Quickstart

Install using `npm install`:

```shell
npm install @axiomhq/bunyan
```

create a Bunyan logger with Axiom configured:

```ts
import bunyan from "bunyan"
import { AxiomStream } from '@axiomhq/bunyan'


const stream = new AxiomStream({
dataset: process.env.AXIOM_DATASET as string,
orgId: process.env.AXIOM_ORG_ID as string,
token: process.env.AXIOM_TOKEN as string,
onError: (err) => {
console.log({ err })
}
})

const logger = bunyan.createLogger({
name: "Example app",
streams: [
{
type: 'raw',
stream: stream,
level: 'info'
}
]

})
```

then you can use the logger as usual:

```js
logger.info('Hello from Bunyan!');
```

For further examples, head over to the [examples](../../examples/bunyan) directory.

## License

Distributed under the [MIT License](../../LICENSE).
11 changes: 11 additions & 0 deletions packages/bunyan/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { JestConfigWithTsJest } from 'ts-jest'
import { defaults as tsjPreset } from 'ts-jest/presets'


const jestConfig: JestConfigWithTsJest = {
transform: {
...tsjPreset.transform,
},
testEnvironment: 'node'
};
export default jestConfig;
Bensigo marked this conversation as resolved.
Show resolved Hide resolved
45 changes: 45 additions & 0 deletions packages/bunyan/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "@axiomhq/bunyan",
"version": "0.1.0",
"description": "The official Axiom transport for bunyan",
"main": "dist/cjs/index.ts",
"types": "dist/types/index.d.ts",
"module": "dist/esm/index.js",
"author": "Axiom, Inc.",
"license": "MIT",
"homepage": "https://github.com/axiomhq/axiom-js/tree/main/packages/bunyan#readme",
"scripts": {
"build": "tsc -b",
"build:esm": "tsc --project tsconfig.esm.json",
"format": "eslint 'src/**/*.{js,ts}' --quiet --fix",
"lint": "eslint 'src/**/*.{js,ts}'",
"test": "jest test/unit",
"prepublish": "npm run build && npm run build:esm",
"cover": "nyc -r text -e .ts -x 'tests/unit/**/*.spec.ts' npm run test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/axiomhq/axiom-js.git"
},
"engines": {
"node": ">=16"
},
"keywords": [
"bunyan",
"axiom",
"transport",
"logger"
],
"bugs": {
"url": "https://github.com/axiomhq/axiom-js/issues"
},
"exports": {
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"default": "./dist/cjs/index.js",
"types": "./dist/types/index.d.ts"
},
"dependencies": {
"@axiomhq/js": "workspace:*"
}
}
98 changes: 98 additions & 0 deletions packages/bunyan/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Axiom } from '@axiomhq/js';

export enum AxiomEventLevel {
Trace = 'trace',
Debug = 'debug',
Info = 'info',
Warn = 'warn',
Error = 'error',
Fatal = 'fatal',
Silent = 'silent',
}

enum RecordLevel {
trace = 10,
debug = 20,
info = 30,
warn = 40,
error = 50,
fatal = 60,
}

const noop = () => {};

export class AxiomStream<T extends { msg: string; level: RecordLevel; time: Date }> {
private axiom: Axiom;
dataset: any;
token: any;
orgId?: any;
onError: (err: unknown) => void;

constructor(
opt: Omit<AxiomStream<T>, 'write' | 'onError' | 'flush'> & {
onError?: AxiomStream<T>['onError'];
},
) {
if (!opt.dataset) {
throw new Error('dataset requried');
}

if (!opt.token) {
throw new Error('token requried');
}

this.orgId = opt.orgId;
this.token = opt.token;
this.onError = opt.onError || noop;
this.dataset = opt.dataset;

this.axiom = new Axiom({
orgId: this?.orgId,
token: this.token,
});
}

async write(record: Object) {
try {
const parsedRecord = typeof record === 'string' ? (JSON.parse(record) as T) : (record as T);
const { time, level, msg, ...rest } = parsedRecord;
const event = {
_time: time,
message: msg,
level: this.getLogLevel(level),
...rest,
};

this.axiom.ingest(this.dataset, event);
} catch (err) {
this.onError(err);
}
}

private getLogLevel(level: number) {
if (level <= 10) {
return AxiomEventLevel.Trace;
}
if (level <= 20) {
return AxiomEventLevel.Debug;
}
if (level <= 30) {
return AxiomEventLevel.Info;
}
if (level <= 40) {
return AxiomEventLevel.Warn;
}
if (level <= 50) {
return AxiomEventLevel.Error;
}
if (level <= 60) {
return AxiomEventLevel.Fatal;
}

return AxiomEventLevel.Silent;
}

async flush() {
await this.axiom.flush();
}
}
10 changes: 10 additions & 0 deletions packages/bunyan/test/unit/create-stream.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { describe, it, expect } from '@jest/globals';
import { AxiomStream } from '../../src';

describe('Bunyan stream tests', () => {
it('creates a truthy instance', () => {
const t = new AxiomStream({orgId: 'test', token: 'test', dataset: 'test' });
expect(t).toBeTruthy()
expect(t).toBeDefined()
})
})
13 changes: 13 additions & 0 deletions packages/bunyan/tsconfig.esm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": ".",
"target": "ESNext",
"module": "ES6",
"moduleResolution": "node",
"rootDir": "./src",
"outDir": "dist/esm",
"declarationDir": "dist/types"
},
"include": ["src/**/*"]
}
11 changes: 11 additions & 0 deletions packages/bunyan/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"target": "ES5",
"module": "Commonjs",
"rootDir": "./src",
"outDir": "dist/cjs",
"declarationDir": "dist/types"
},
"include": ["src/**/*"]
}
Loading