Skip to content

Commit

Permalink
feat(transports): add custom tranporter support for flexible logging
Browse files Browse the repository at this point in the history
Introduces a new custom transporter feature to Logixlysia, allowing users to send logs to various destinations

fix #51
  • Loading branch information
PunGrumpy committed Jul 24, 2024
1 parent ad05b61 commit 69e1b89
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 3 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ const app = new Elysia({
app.listen(3000)
```

> [!NOTE]
> You can discover more about example in the [example](example) directory.
## `📚` Documentation

### Options
Expand Down
21 changes: 21 additions & 0 deletions example/transports/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Elysia } from 'elysia'

import logixlysia from '~/index'

import MyCustomTransport from './myCustomTransport'

const app = new Elysia()
.use(
logixlysia({
config: {
transports: [new MyCustomTransport()]
}
})
)
.get('/', () => {
return {
message: 'Basic Example'
}
})

app.listen(3000)
13 changes: 13 additions & 0 deletions example/transports/myCustomTransport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { LogData, LogLevel, RequestInfo, StoreData, Transport } from '~/types'

class MyCustomTransport implements Transport {
async log(
level: LogLevel,
message: string,
meta: { request: RequestInfo; data: LogData; store: StoreData }
): Promise<void> {
console.log(`Custom log: ${level} - ${message} - ${meta.request.method}`)
}
}

export default MyCustomTransport
3 changes: 3 additions & 0 deletions src/logger/createLogger.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { logToTransports } from '~/transports'
import {
LogData,
Logger,
Expand Down Expand Up @@ -42,6 +43,8 @@ async function log(
options
)
}

await logToTransports(level, request, data, store, options)
}

/**
Expand Down
22 changes: 22 additions & 0 deletions src/transports/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { buildLogMessage } from '~/logger/buildLogMessage'
import { LogData, LogLevel, Options, RequestInfo, StoreData } from '~/types'

export async function logToTransports(
level: LogLevel,
request: RequestInfo,
data: LogData,
store: StoreData,
options?: Options
): Promise<void> {
if (!options?.config?.transports || options.config.transports.length === 0) {
return
}

const message = buildLogMessage(level, request, data, store, options, false)

const promises = options.config.transports.map(transport =>
transport.log(level, message, { request, data, store })
)

await Promise.all(promises)
}
23 changes: 21 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,34 @@ class HttpError extends Error {
}
}

interface TransportFunction {
(
level: LogLevel,
message: string,
meta: {
request: RequestInfo
data: LogData
store: StoreData
}
): Promise<void> | void
}

interface Transport {
log: TransportFunction
}

interface Options {
config?: {
ip?: boolean
customLogFormat?: string
logFilePath?: string
logFilter?: {
level?: LogLevel | LogLevel[]
method?: string | string[]
status?: number | number[]
} | null
ip?: boolean
showBanner?: boolean
transports?: Transport[]
}
}

Expand All @@ -67,5 +84,7 @@ export {
Options,
RequestInfo,
Server,
StoreData
StoreData,
Transport,
TransportFunction
}
84 changes: 84 additions & 0 deletions test/logger/transports.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { beforeEach, describe, expect, it, jest } from 'bun:test'

import { logToTransports } from '~/transports'
import {
LogData,
LogLevel,
Options,
RequestInfo,
StoreData,
Transport
} from '~/types'

describe('Custom Transports', () => {
let mockTransport: Transport
let options: Options

beforeEach(() => {
mockTransport = {
log: jest.fn().mockResolvedValue(undefined)
}
options = {
config: {
transports: [mockTransport]
}
}
})

it('should call the custom transport log function', async () => {
const level: LogLevel = 'INFO'
const request: RequestInfo = {
url: '/test',
method: 'GET',
headers: { get: () => null }
}
const data: LogData = { status: 200 }
const store: StoreData = { beforeTime: BigInt(0) }

await logToTransports(level, request, data, store, options)

expect(mockTransport.log).toHaveBeenCalledTimes(1)
expect(mockTransport.log).toHaveBeenCalledWith(level, expect.any(String), {
request,
data,
store
})
})

it('should not call any transports if none are configured', async () => {
const options: Options = { config: {} }
const level: LogLevel = 'INFO'
const request: RequestInfo = {
url: '/test',
method: 'GET',
headers: { get: () => null }
}
const data: LogData = { status: 200 }
const store: StoreData = { beforeTime: BigInt(0) }

await logToTransports(level, request, data, store, options)

expect(mockTransport.log).not.toHaveBeenCalled()
})

it('should call multiple transports if configured', async () => {
const secondMockTransport: Transport = {
log: jest.fn().mockResolvedValue(undefined)
}
options.config!.transports!.push(secondMockTransport)

const level: LogLevel = 'INFO'
const request: RequestInfo = {
url: '/test',
method: 'GET',
headers: { get: () => null }
}
const data: LogData = { status: 200 }
const store: StoreData = { beforeTime: BigInt(0) }

await logToTransports(level, request, data, store, options)

expect(mockTransport.log).toHaveBeenCalledTimes(1)
expect(secondMockTransport.log).toHaveBeenCalledTimes(1)
})
})
2 changes: 1 addition & 1 deletion test/logixlysia.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { edenTreaty } from '@elysiajs/eden'
import { beforeAll, beforeEach, describe, expect, it } from 'bun:test'
import { Elysia } from 'elysia'

import logixlysia from '../src'
import logixlysia from '~/index'

describe('Logixlysia', () => {
let server: Elysia
Expand Down

0 comments on commit 69e1b89

Please sign in to comment.