@contember/logger 1.2.0-alpha.16

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.
Files changed (61) hide show
  1. package/dist/src/formatting.d.ts +9 -0
  2. package/dist/src/formatting.d.ts.map +1 -0
  3. package/dist/src/formatting.js +68 -0
  4. package/dist/src/formatting.js.map +1 -0
  5. package/dist/src/handlers/FingerCrossedLoggerHandler.d.ts +20 -0
  6. package/dist/src/handlers/FingerCrossedLoggerHandler.d.ts.map +1 -0
  7. package/dist/src/handlers/FingerCrossedLoggerHandler.js +66 -0
  8. package/dist/src/handlers/FingerCrossedLoggerHandler.js.map +1 -0
  9. package/dist/src/handlers/JsonStreamLoggerHandler.d.ts +14 -0
  10. package/dist/src/handlers/JsonStreamLoggerHandler.d.ts.map +1 -0
  11. package/dist/src/handlers/JsonStreamLoggerHandler.js +28 -0
  12. package/dist/src/handlers/JsonStreamLoggerHandler.js.map +1 -0
  13. package/dist/src/handlers/LoggerHandlerList.d.ts +10 -0
  14. package/dist/src/handlers/LoggerHandlerList.d.ts.map +1 -0
  15. package/dist/src/handlers/LoggerHandlerList.js +26 -0
  16. package/dist/src/handlers/LoggerHandlerList.js.map +1 -0
  17. package/dist/src/handlers/NullLoggerHandler.d.ts +7 -0
  18. package/dist/src/handlers/NullLoggerHandler.d.ts.map +1 -0
  19. package/dist/src/handlers/NullLoggerHandler.js +14 -0
  20. package/dist/src/handlers/NullLoggerHandler.js.map +1 -0
  21. package/dist/src/handlers/PrettyPrintLoggerHandler.d.ts +28 -0
  22. package/dist/src/handlers/PrettyPrintLoggerHandler.d.ts.map +1 -0
  23. package/dist/src/handlers/PrettyPrintLoggerHandler.js +84 -0
  24. package/dist/src/handlers/PrettyPrintLoggerHandler.js.map +1 -0
  25. package/dist/src/impl.d.ts +27 -0
  26. package/dist/src/impl.d.ts.map +1 -0
  27. package/dist/src/impl.js +105 -0
  28. package/dist/src/impl.js.map +1 -0
  29. package/dist/src/index.d.ts +10 -0
  30. package/dist/src/index.d.ts.map +1 -0
  31. package/dist/src/index.js +28 -0
  32. package/dist/src/index.js.map +1 -0
  33. package/dist/src/levels.d.ts +23 -0
  34. package/dist/src/levels.d.ts.map +1 -0
  35. package/dist/src/levels.js +11 -0
  36. package/dist/src/levels.js.map +1 -0
  37. package/dist/src/proxy.d.ts +5 -0
  38. package/dist/src/proxy.d.ts.map +1 -0
  39. package/dist/src/proxy.js +51 -0
  40. package/dist/src/proxy.js.map +1 -0
  41. package/dist/src/tsconfig.tsbuildinfo +1 -0
  42. package/dist/src/types.d.ts +53 -0
  43. package/dist/src/types.d.ts.map +1 -0
  44. package/dist/src/types.js +3 -0
  45. package/dist/src/types.js.map +1 -0
  46. package/package.json +16 -0
  47. package/readme.md +3 -0
  48. package/src/formatting.ts +70 -0
  49. package/src/handlers/FingerCrossedLoggerHandler.ts +82 -0
  50. package/src/handlers/JsonStreamLoggerHandler.ts +36 -0
  51. package/src/handlers/LoggerHandlerList.ts +28 -0
  52. package/src/handlers/NullLoggerHandler.ts +13 -0
  53. package/src/handlers/PrettyPrintLoggerHandler.ts +93 -0
  54. package/src/impl.ts +141 -0
  55. package/src/index.ts +9 -0
  56. package/src/levels.ts +7 -0
  57. package/src/proxy.ts +60 -0
  58. package/src/tsconfig.json +7 -0
  59. package/src/types.ts +57 -0
  60. package/tsconfig.json +5 -0
  61. package/tsconfig.settings.json +3 -0
package/src/impl.ts ADDED
@@ -0,0 +1,141 @@
1
+ import {
2
+ LogEntry,
3
+ LogEntryFormatted,
4
+ Logger,
5
+ LoggerAttributes,
6
+ LoggerChildOptions,
7
+ LoggerHandler,
8
+ LoggerOptions,
9
+ LogLevel,
10
+ } from './types'
11
+ import { LogLevels } from './levels'
12
+ import { formatLogEntryAttributes, formatLoggerAttributes, FormattedAttributes, stringify } from './formatting'
13
+ import { LoggerHandlerList } from './handlers/LoggerHandlerList'
14
+ import { withLogger } from './proxy'
15
+
16
+ export const createLogger = (
17
+ handler: LoggerHandler,
18
+ attributes: LoggerAttributes = {},
19
+ options: LoggerOptions = {},
20
+ ): Logger => {
21
+ return LoggerImpl.create(handler, attributes, options)
22
+ }
23
+
24
+
25
+ export class LoggerImpl implements Logger {
26
+
27
+ public readonly attributes: LoggerAttributes
28
+ private formattedAttributes: FormattedAttributes | undefined
29
+ private minLevelValue: number
30
+ private handlerList: LoggerHandlerList | undefined
31
+
32
+ private constructor(
33
+ private handler: LoggerHandler,
34
+ private readonly ownAttributes: LoggerAttributes,
35
+ private readonly depth: number,
36
+ private readonly parent: LoggerImpl | undefined,
37
+ private readonly options: LoggerOptions,
38
+ ) {
39
+ this.attributes = { ...parent?.attributes, ...ownAttributes }
40
+ this.minLevelValue = handler.getMinLevel()
41
+ }
42
+
43
+ public static create(
44
+ handler: LoggerHandler,
45
+ attributes: LoggerAttributes = {},
46
+ options: LoggerOptions = {},
47
+ ) {
48
+ return new LoggerImpl(handler, attributes, 0, undefined, options)
49
+ }
50
+
51
+ public crit(messageOrError: unknown, attributes?: LoggerAttributes) {
52
+ this.minLevelValue <= LogLevels.crit.value && this.log(LogLevels.crit, messageOrError, attributes)
53
+ }
54
+
55
+ public error(messageOrError: unknown, attributes?: LoggerAttributes) {
56
+ this.minLevelValue <= LogLevels.error.value && this.log(LogLevels.error, messageOrError, attributes)
57
+ }
58
+
59
+ public warn(messageOrError: unknown, attributes?: LoggerAttributes) {
60
+ this.minLevelValue <= LogLevels.warn.value && this.log(LogLevels.warn, messageOrError, attributes)
61
+ }
62
+
63
+ public info(messageOrError: unknown, attributes?: LoggerAttributes) {
64
+ this.minLevelValue <= LogLevels.info.value && this.log(LogLevels.info, messageOrError, attributes)
65
+ }
66
+
67
+ public debug(messageOrError: unknown, attributes?: LoggerAttributes) {
68
+ this.minLevelValue <= LogLevels.debug.value && this.log(LogLevels.debug, messageOrError, attributes)
69
+ }
70
+
71
+ public child(attributes: LoggerAttributes = {}, options: Partial<LoggerChildOptions> = {}): Logger {
72
+ const newHandler = options.handler ? options.handler(this.handler, this.options) : this.handler
73
+ return new LoggerImpl(newHandler, attributes, this.depth + 1, this, { ...this.options, ...options })
74
+ }
75
+
76
+ public async scope<T>(cb: (logger: Logger) => Promise<T> | T, attributes: LoggerAttributes = {}, options: Partial<LoggerChildOptions> = {}): Promise<T> {
77
+ const logger = this.child(attributes, options)
78
+ try {
79
+ return await withLogger(logger, () => cb(logger))
80
+ } finally {
81
+ logger.close()
82
+ }
83
+ }
84
+
85
+ private log(level: LogLevel, errorOrMessage: unknown, { error: errorAttr, message: messageAttr, ...attributes }: LoggerAttributes = {}) {
86
+ const error: unknown | undefined = typeof errorOrMessage !== 'string' ? errorOrMessage : errorAttr
87
+ const message: string = typeof errorOrMessage === 'string'
88
+ ? errorOrMessage
89
+ : (typeof messageAttr === 'string')
90
+ ? messageAttr
91
+ : typeof error === 'object' && error !== null && typeof (error as any).message === 'string'
92
+ ? (error as any).message
93
+ : 'unknown error'
94
+
95
+ const now = new Date()
96
+ let formatted: LogEntryFormatted
97
+ const entry: LogEntry = {
98
+ level,
99
+ error,
100
+ message,
101
+ ownAttributes: attributes,
102
+ time: now,
103
+ isoTime: now.toISOString(),
104
+ depth: this.depth,
105
+ loggerAttributes: this.attributes,
106
+ format: () => {
107
+ return formatted ??= {
108
+ attributes: formatLogEntryAttributes(this.getFormattedAttributes(), entry),
109
+ message: stringify(entry.message),
110
+ error: entry.error ? `, "error": ${stringify(entry.error)}` : '',
111
+ }
112
+ },
113
+ }
114
+ this.handler.handle(entry)
115
+ }
116
+
117
+ addHandler(handler: LoggerHandler): void {
118
+ if (!this.handlerList) {
119
+ this.handlerList = new LoggerHandlerList([this.handler])
120
+ this.handler = this.handlerList
121
+ }
122
+ this.handlerList.addHandler(handler)
123
+ this.minLevelValue = Math.min(this.minLevelValue, handler.getMinLevel())
124
+ }
125
+
126
+ close(): void {
127
+ this.handler.close()
128
+ }
129
+
130
+ private getFormattedAttributes(): FormattedAttributes {
131
+ if (this.formattedAttributes) {
132
+ return this.formattedAttributes
133
+ }
134
+ const parentAttributes = this.parent?.getFormattedAttributes()
135
+ this.formattedAttributes = formatLoggerAttributes(parentAttributes, this.ownAttributes)
136
+ return this.formattedAttributes
137
+ }
138
+ }
139
+
140
+
141
+
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ export { createLogger } from './impl'
2
+ export * from './types'
3
+ export * from './levels'
4
+ export * from './proxy'
5
+ export * from './handlers/FingerCrossedLoggerHandler'
6
+ export * from './handlers/JsonStreamLoggerHandler'
7
+ export * from './handlers/PrettyPrintLoggerHandler'
8
+ export * from './handlers/LoggerHandlerList'
9
+ export * from './handlers/NullLoggerHandler'
package/src/levels.ts ADDED
@@ -0,0 +1,7 @@
1
+ export const LogLevels = {
2
+ debug: { name: 'debug', value: 10 },
3
+ info: { name: 'info', value: 20 },
4
+ warn: { name: 'warn', value: 30 },
5
+ error: { name: 'error', value: 40 },
6
+ crit: { name: 'crit', value: 50 },
7
+ }
package/src/proxy.ts ADDED
@@ -0,0 +1,60 @@
1
+ import { Logger, LoggerAttributes, LoggerHandler, LoggerOptions } from './types'
2
+ import { AsyncLocalStorage } from 'node:async_hooks'
3
+
4
+ const loggerStore = new AsyncLocalStorage<Logger>()
5
+
6
+ class CurrentLoggerProxy implements Logger {
7
+ crit(a: any, b?: any, c?: any) {
8
+ getLogger().crit(a, b)
9
+ }
10
+
11
+ error(a: any, b?: any, c?: any) {
12
+ getLogger().error(a, b)
13
+ }
14
+
15
+ warn(a: any, b?: any, c?: any) {
16
+ getLogger().warn(a, b)
17
+ }
18
+
19
+ info(a: any, b?: any, c?: any) {
20
+ getLogger().info(a, b)
21
+ }
22
+
23
+ debug(a: any, b?: any, c?: any) {
24
+ getLogger().crit(a, b)
25
+ }
26
+
27
+ child(attributes?: LoggerAttributes, options?: Partial<LoggerOptions>): Logger {
28
+ return getLogger().child(attributes, options)
29
+ }
30
+
31
+ get attributes() {
32
+ return getLogger().attributes
33
+ }
34
+
35
+ close(): void {
36
+ getLogger().close()
37
+ }
38
+
39
+ scope<T>(cb: (logger: Logger) => (Promise<T> | T), attributes?: LoggerAttributes, options?: Partial<LoggerOptions>): Promise<T> {
40
+ return getLogger().scope(cb, attributes, options)
41
+ }
42
+
43
+ addHandler(handler: LoggerHandler): void {
44
+ getLogger().addHandler(handler)
45
+ }
46
+ }
47
+
48
+ export const logger: Logger = new CurrentLoggerProxy()
49
+
50
+ export const withLogger = <R>(logger: Logger, callback: () => R): R => {
51
+ return loggerStore.run(logger, callback)
52
+ }
53
+
54
+ export const getLogger = (): Logger => {
55
+ const logger = loggerStore.getStore()
56
+ if (!logger) {
57
+ throw new Error('Logger was not set')
58
+ }
59
+ return logger
60
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "../tsconfig.settings.json",
3
+ "compilerOptions": {
4
+ "esModuleInterop": true,
5
+ "outDir": "../dist/src"
6
+ }
7
+ }
package/src/types.ts ADDED
@@ -0,0 +1,57 @@
1
+ import { FingerCrossedLoggerHandlerOptions } from './handlers/FingerCrossedLoggerHandler'
2
+
3
+ export type LogFn = ((errorOrMessage: unknown, attributes?: LoggerAttributes) => void)
4
+
5
+ export interface Logger {
6
+ attributes: LoggerAttributes
7
+
8
+ crit: LogFn
9
+ error: LogFn
10
+ warn: LogFn
11
+ info: LogFn
12
+ debug: LogFn
13
+
14
+ child(attributes?: LoggerAttributes, options?: Partial<LoggerChildOptions>): Logger
15
+ scope<T>(cb: (logger: Logger) => Promise<T> | T, attributes?: LoggerAttributes, options?: Partial<LoggerChildOptions>): Promise<T>
16
+ close(): void
17
+
18
+ addHandler(handler: LoggerHandler): void
19
+ }
20
+
21
+ export interface LoggerHandler {
22
+ getMinLevel(): number
23
+ handle(logEntry: LogEntry): void
24
+ close(): void
25
+ }
26
+
27
+ export type LoggerAttributes = {
28
+ error?: unknown
29
+ message?: string
30
+ } & {
31
+ [key: string | symbol]: any
32
+ }
33
+
34
+ export type LogLevel = { name: string; value: number }
35
+
36
+ export type LogEntry = {
37
+ level: LogLevel
38
+ time: Date
39
+ isoTime: string
40
+ message: string
41
+ error?: unknown
42
+ ownAttributes: LoggerAttributes
43
+ loggerAttributes: LoggerAttributes
44
+ depth: number
45
+ format: () => LogEntryFormatted
46
+ }
47
+ export type LogEntryFormatted = { attributes: string; message: string; error: string }
48
+
49
+ export type LoggerHandlerFactory = (current: LoggerHandler, globalOptions: LoggerOptions) => LoggerHandler
50
+
51
+ export interface LoggerOptions {
52
+ fingerCrossedOptions?: Partial<FingerCrossedLoggerHandlerOptions>
53
+ }
54
+
55
+ export interface LoggerChildOptions extends LoggerOptions {
56
+ handler?: LoggerHandlerFactory
57
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "files": [],
3
+ "include": [],
4
+ "references": [{ "path": "./src" }]
5
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "../../tsconfig.settings.json"
3
+ }