logixlysia 2.3.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.0.0](https://github.com/PunGrumpy/logixlysia/compare/v2.3.1...v3.0.0) (2024-04-08)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * **options:**
9
+
10
+ ### Features
11
+
12
+ * **options:** add support for custom log format ([acc9380](https://github.com/PunGrumpy/logixlysia/commit/acc9380ea25691e7d7fec175094cb6a9878b6c69))
13
+
3
14
  ## [2.3.1](https://github.com/PunGrumpy/logixlysia/compare/v2.3.0...v2.3.1) (2024-04-07)
4
15
 
5
16
 
package/README.md CHANGED
@@ -18,7 +18,13 @@ import { logger } from 'logixlysia'
18
18
 
19
19
  const app = new Elysia({
20
20
  name: 'Logixlysia Example'
21
- }).use(logger())
21
+ }).use(
22
+ logger({
23
+ ip: false,
24
+ customLogMessage:
25
+ '🦊 {now} {level} {duration} {method} {pathname} {status} {message} {ip}'
26
+ })
27
+ )
22
28
 
23
29
  app.listen(3000)
24
30
  ```
@@ -27,9 +33,10 @@ app.listen(3000)
27
33
 
28
34
  ### Options
29
35
 
30
- | Option | Type | Description | Default |
31
- | ------ | --------- | --------------------------------------------------------------------- | ------- |
32
- | `ip` | `boolean` | Display the incoming IP address based on the `X-Forwarded-For` header | `false` |
36
+ | Option | Type | Description | Default |
37
+ | ------------------ | --------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------- |
38
+ | `ip` | `boolean` | Display the incoming IP address based on the `X-Forwarded-For` header | `false` |
39
+ | `customLogMessage` | `string` | Custom log message to display | `🦊 {now} {level} {duration} {method} {pathname} {status} {message} {ip}` |
33
40
 
34
41
  ## `📄` License
35
42
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "logixlysia",
3
- "version": "2.3.1",
3
+ "version": "3.0.0",
4
4
  "description": "🦊 Logixlysia is a logger for Elysia",
5
5
  "type": "module",
6
6
  "module": "src/index.ts",
package/src/logger.ts CHANGED
@@ -7,17 +7,36 @@ import statusString from './utils/status'
7
7
  import { HttpError, RequestInfo } from './types'
8
8
  import { LogLevel, LogData, Logger, StoreData, Options } from './types'
9
9
 
10
- async function log(
10
+ /**
11
+ * Logs a message.
12
+ *
13
+ * @param {LogLevel} level The log level.
14
+ * @param {RequestInfo} request The request.
15
+ * @param {LogData} data The log data.
16
+ * @param {StoreData} store The store data.
17
+ * @param {Options} options The options.
18
+ */
19
+ function log(
11
20
  level: LogLevel,
12
21
  request: RequestInfo,
13
22
  data: LogData,
14
23
  store: StoreData,
15
24
  options?: Options
16
- ): Promise<void> {
25
+ ): void {
17
26
  const logMessage = buildLogMessage(level, request, data, store, options)
18
27
  console.log(logMessage)
19
28
  }
20
29
 
30
+ /**
31
+ * Builds a log message.
32
+ *
33
+ * @param {LogLevel} level The log level.
34
+ * @param {RequestInfo} request The request.
35
+ * @param {LogData} data The log data.
36
+ * @param {StoreData} store The store data.
37
+ * @param {Options} options The options.
38
+ * @returns {string} The log message.
39
+ */
21
40
  function buildLogMessage(
22
41
  level: LogLevel,
23
42
  request: RequestInfo,
@@ -32,24 +51,47 @@ function buildLogMessage(
32
51
  const pathnameStr = pathString(request)
33
52
  const statusStr = statusString(data.status || 200)
34
53
  const messageStr = data.message || ''
54
+ const ipStr =
55
+ options?.ip && request.headers.get('x-forwarded-for')
56
+ ? `IP: ${request.headers.get('x-forwarded-for')}`
57
+ : ''
35
58
 
36
- let logMessage = `🦊 ${nowStr} ${levelStr} ${durationStr} ${methodStr} ${pathnameStr} ${statusStr} ${messageStr}`
37
-
38
- if (options?.ip) {
39
- const forwardedFor = request.headers.get('x-forwarded-for')
40
- if (forwardedFor) {
41
- logMessage += ` IP: ${forwardedFor}`
42
- }
43
- }
59
+ const logFormat =
60
+ options?.customLogFormat ||
61
+ '🦊 {now} {level} {duration} {method} {pathname} {status} {message} {ip}'
62
+ const logMessage = logFormat
63
+ .replace('{now}', nowStr)
64
+ .replace('{level}', levelStr)
65
+ .replace('{duration}', durationStr)
66
+ .replace('{method}', methodStr)
67
+ .replace('{pathname}', pathnameStr || '')
68
+ .replace('{status}', statusStr)
69
+ .replace('{message}', messageStr)
70
+ .replace('{ip}', ipStr || '')
44
71
 
45
72
  return logMessage
46
73
  }
47
74
 
75
+ /**
76
+ * Creates a logger.
77
+ *
78
+ * @param {Options} options The options.
79
+ * @returns {Logger} The logger.
80
+ */
48
81
  export const createLogger = (options?: Options): Logger => ({
49
82
  log: (level, request, data, store) =>
50
- log(level, request, data, store, options)
83
+ log(level, request, data, store, options),
84
+ customLogFormat: options?.customLogFormat
51
85
  })
52
86
 
87
+ /**
88
+ * Handles an HTTP error.
89
+ *
90
+ * @param {RequestInfo} request The request.
91
+ * @param {Error} error The error.
92
+ * @param {StoreData} store The store data.
93
+ * @param {Options} options The options.
94
+ */
53
95
  export const handleHttpError = (
54
96
  request: RequestInfo,
55
97
  error: Error,
package/src/types.ts CHANGED
@@ -28,6 +28,7 @@ interface Logger {
28
28
  data: LogData,
29
29
  store: StoreData
30
30
  ): void
31
+ customLogFormat?: string
31
32
  }
32
33
 
33
34
  interface StoreData {
@@ -45,6 +46,7 @@ class HttpError extends Error {
45
46
 
46
47
  interface Options {
47
48
  ip?: boolean
49
+ customLogFormat?: string
48
50
  }
49
51
 
50
52
  export {
@@ -10,7 +10,13 @@ describe('Logixlysia with IP logging enabled', () => {
10
10
 
11
11
  beforeAll(() => {
12
12
  server = new Elysia()
13
- .use(logger({ ip: true }))
13
+ .use(
14
+ logger({
15
+ ip: true,
16
+ customLogFormat:
17
+ '🦊 {now} {duration} {level} {method} {pathname} {status} {message} {ip}'
18
+ })
19
+ )
14
20
  .get('/', ctx => {
15
21
  const ipAddress = ctx.request.headers.get('x-forwarded-for') || 'null'
16
22
  return '🦊 Logixlysia Getting'
@@ -35,7 +41,9 @@ describe('Logixlysia with IP logging enabled', () => {
35
41
  }
36
42
 
37
43
  logs.forEach(log => {
38
- expect(log).toMatch(/^IP: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)
44
+ expect(log).toMatch(
45
+ /^🦊 .+ INFO .+ .+ GET \/ .+ IP: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
46
+ )
39
47
  })
40
48
  })
41
49
 
@@ -47,7 +55,7 @@ describe('Logixlysia with IP logging enabled', () => {
47
55
  }
48
56
 
49
57
  logs.forEach(log => {
50
- expect(log).toBe('IP: null')
58
+ expect(log).toMatch(/^🦊 .+ INFO .+ .+ GET \/ .+ IP: null$/)
51
59
  })
52
60
  })
53
61
  })
@@ -59,7 +67,13 @@ describe('Logixlysia with IP logging disabled', () => {
59
67
 
60
68
  beforeAll(() => {
61
69
  server = new Elysia()
62
- .use(logger({ ip: false }))
70
+ .use(
71
+ logger({
72
+ ip: false,
73
+ customLogFormat:
74
+ '🦊 {now} {duration} {level} {method} {pathname} {status} {message} {ip}'
75
+ })
76
+ )
63
77
  .get('/', () => '🦊 Logixlysia Getting')
64
78
  .post('logixlysia', () => '🦊 Logixlysia Posting')
65
79
  .listen(3000)