@platformatic/runtime 3.13.1 → 3.15.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/lib/logger.js CHANGED
@@ -1,23 +1,154 @@
1
- import { buildPinoFormatters, buildPinoTimestamp } from '@platformatic/foundation'
1
+ import { buildPinoFormatters, buildPinoTimestamp, usePrettyPrint } from '@platformatic/foundation'
2
2
  import { isatty } from 'node:tty'
3
3
  import pino from 'pino'
4
4
  import pretty from 'pino-pretty'
5
5
 
6
6
  export { abstractLogger } from '@platformatic/foundation'
7
7
 
8
- const customPrettifiers = {
9
- name (name, _, obj) {
10
- if (typeof obj.worker !== 'undefined') {
11
- name += ':' + obj.worker
12
- obj.worker = undefined // Do not show the worker in a separate line
13
- }
8
+ // A valid color in the ANSI 256 color palette - Adiacent colors are purposely different
9
+ const colors = [
10
+ 196, // bright red
11
+ 46, // bright green
12
+ 33, // light blue
13
+ 226, // bright yellow
14
+ 201, // bright magenta
15
+ 51, // cyan
16
+ 208, // orange
17
+ 118, // lime
18
+ 39, // deep sky blue
19
+ 220, // gold
20
+ 129, // violet
21
+ 82, // spring green
22
+ 33, // blue
23
+ 214, // amber
24
+ 99, // orchid
25
+ 190, // light yellow-green
26
+ 45, // turquoise
27
+ 197, // rose
28
+ 50, // aqua
29
+ 202, // orange-red
30
+ 141, // lavender
31
+ 154, // pale green
32
+ 93, // pink
33
+ 33, // light blue again (for spacing)
34
+ 220, // gold
35
+ 201, // magenta
36
+ 46, // green
37
+ 27, // navy blue
38
+ 214, // amber
39
+ 99, // orchid
40
+ 190, // light yellow-green
41
+ 39, // cyan-blue
42
+ 200, // violet
43
+ 82, // neon green
44
+ 208, // orange
45
+ 135, // purple
46
+ 118, // lime
47
+ 33, // bright blue
48
+ 220, // gold
49
+ 201, // bright magenta
50
+ 46, // bright green
51
+ 21, // bright blue
52
+ 202, // orange-red
53
+ 141, // purple
54
+ 118, // spring green
55
+ 208, // orange
56
+ 93, // pink
57
+ 190, // yellow-green
58
+ 39, // cyan
59
+ 196, // bright red
60
+ 226 // bright yellow
61
+ ]
62
+
63
+ function createLoggerContext () {
64
+ const context = {
65
+ colors: {},
66
+ maxLength: 0,
67
+ updatePrefixes (ids) {
68
+ context.colors = {}
69
+ context.maxLength = 0
70
+
71
+ for (const id of ids) {
72
+ context.maxLength = Math.max(context.maxLength, id.length)
73
+ let hash = 0
74
+
75
+ if (!pretty.isColorSupported && process.env.FORCE_COLOR !== 'true') {
76
+ context.colors[id] = ''
77
+ continue
78
+ }
79
+
80
+ // Calculate the hash of the id to pick a color
81
+ for (const char of id) {
82
+ for (let i = 0; i < char.length; i++) {
83
+ hash = ((hash << 5) - hash) ^ char.charCodeAt(i)
84
+ hash = Math.abs(hash) % Number.MAX_SAFE_INTEGER
85
+ }
86
+ }
14
87
 
15
- return name
88
+ context.colors[id] = `\u001B[38;5;${colors[hash % colors.length]}m`
89
+ }
90
+ }
16
91
  }
92
+
93
+ return context
94
+ }
95
+
96
+ function createPrettifier (context) {
97
+ return pretty({
98
+ messageFormat (log, key) {
99
+ const { name, pid, hostname, caller, worker } = log
100
+
101
+ context.current = {
102
+ name,
103
+ pid,
104
+ hostname,
105
+ caller,
106
+ worker
107
+ }
108
+
109
+ let prefix = ''
110
+ let color = ''
111
+
112
+ if (name) {
113
+ prefix = name.match(/:\d+$/) ? name : `${name}:${worker}`
114
+ color = context.colors[prefix] ?? ''
115
+ }
116
+
117
+ context.current.prefix = `(${pid}) ` + prefix.padStart(context.maxLength, ' ')
118
+ context.current.color = color
119
+
120
+ // We need to nullify all these so that prettifierMetadata in pino-pretty returns an empty string
121
+ log.name = undefined
122
+ log.pid = undefined
123
+ log.hostname = undefined
124
+ log.caller = undefined
125
+ log.worker = undefined
126
+
127
+ return log[key]
128
+ },
129
+ customPrettifiers: {
130
+ time (time) {
131
+ return `${context.current.color}[${time}]`
132
+ },
133
+ level (_u1, _u2, _u3, { label, labelColorized }) {
134
+ // No applications registered yet, no need to pad
135
+ if (context.maxLength === 0) {
136
+ return context.current.prefix + labelColorized
137
+ }
138
+
139
+ const current = context.current
140
+ const level = current.caller ? current.caller : labelColorized.replace(label, label.padStart(6, ' '))
141
+
142
+ return `${current.prefix} | \u001B[0m ${level}`
143
+ }
144
+ }
145
+ })
17
146
  }
18
147
 
19
148
  // Create the runtime logger
20
149
  export async function createLogger (config) {
150
+ const context = createLoggerContext()
151
+
21
152
  const loggerConfig = { ...config.logger, transport: undefined }
22
153
  if (config.logger.base === null) {
23
154
  loggerConfig.base = undefined
@@ -27,8 +158,10 @@ export async function createLogger (config) {
27
158
 
28
159
  if (config.logger.transport) {
29
160
  cliStream = pino.transport(config.logger.transport)
161
+ } else if ((process.env.FORCE_TTY || isatty(1)) && usePrettyPrint()) {
162
+ cliStream = createPrettifier(context)
30
163
  } else {
31
- cliStream = isatty(1) ? pretty({ customPrettifiers }) : pino.destination(1)
164
+ cliStream = pino.destination(1)
32
165
  }
33
166
 
34
167
  if (loggerConfig.formatters) {
@@ -40,7 +173,7 @@ export async function createLogger (config) {
40
173
  }
41
174
 
42
175
  if (!config.managementApi) {
43
- return [pino(loggerConfig, cliStream), cliStream]
176
+ return [pino(loggerConfig, cliStream), cliStream, context]
44
177
  }
45
178
 
46
179
  const multiStream = pino.multistream([{ stream: cliStream, level: loggerConfig.level }])
@@ -53,5 +186,5 @@ export async function createLogger (config) {
53
186
  logsLimitCount = 1
54
187
  }
55
188
 
56
- return [pino(loggerConfig, multiStream), multiStream]
189
+ return [pino(loggerConfig, multiStream), multiStream, context]
57
190
  }