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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ This is a monorepo, for specific documentation, check out the different projects
* [`@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

Distributed under the [MIT License](LICENSE).
Expand Down
19 changes: 19 additions & 0 deletions examples/bunyan/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"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"
Bensigo marked this conversation as resolved.
Show resolved Hide resolved
}
}
29 changes: 29 additions & 0 deletions examples/bunyan/src/bunyan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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,
Bensigo marked this conversation as resolved.
Show resolved Hide resolved
onError: (err) => {
console.log({ err })
}
})

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

})

logger.info("Hello world!!")
Bensigo marked this conversation as resolved.
Show resolved Hide resolved



Bensigo marked this conversation as resolved.
Show resolved Hide resolved
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/**/*"]
}
26 changes: 26 additions & 0 deletions packages/bunyan/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 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.2] - 2023-06-26

### Fixed

- Add types to package.json exports ([#29](https://github.com/axiomhq/axiom-js/pull/29))
- Fake process.env for browsers ([#26](https://github.com/axiomhq/axiom-js/pull/26))

## [0.1.1] - 2023-06-20

### Fixed

- Updated @axiomhq/js dependency

## [0.1.0] - 2023-06-14
Bensigo marked this conversation as resolved.
Show resolved Hide resolved


Bensigo marked this conversation as resolved.
Show resolved Hide resolved

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).
10 changes: 10 additions & 0 deletions packages/bunyan/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const jestConfig = {
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
transform: {
'^.+\\.ts?$': 'ts-jest',
},
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:*"
}
}
96 changes: 96 additions & 0 deletions packages/bunyan/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
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 }> {
Bensigo marked this conversation as resolved.
Show resolved Hide resolved
private axiom: Axiom;
dataset: string;
token: string;
orgId: string;
onError: (err: unknown) => void

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

if (!opt.orgId){
Bensigo marked this conversation as resolved.
Show resolved Hide resolved
throw new Error('orgId 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) {
Bensigo marked this conversation as resolved.
Show resolved Hide resolved
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
}

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

}
private getLogLevel(level: number) {
Bensigo marked this conversation as resolved.
Show resolved Hide resolved
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;
}
}

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