Skip to content

Commit 7277349

Browse files
Configure the Verbosity of Blitz RPC Logging (#4162)
* improve blitz rpc logging * implement improved setup with jsdoc comments * make it verbose by default * change routePath to resolverName for easier use * Update packages/blitz-rpc/src/index-server.ts * rename to make language more inclusive * set output as debug * Create sixty-rockets-count.md * Update sixty-rockets-count.md * Update sixty-rockets-count.md * fix verbose bug * Apply suggestions from code review Co-authored-by: Brandon Bayer <[email protected]> --------- Co-authored-by: Brandon Bayer <[email protected]>
1 parent 831a493 commit 7277349

File tree

3 files changed

+152
-16
lines changed

3 files changed

+152
-16
lines changed

.changeset/sixty-rockets-count.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
"@blitzjs/rpc": patch
3+
"blitz": patch
4+
---
5+
6+
### Now we can configure Blitz RPC in the following way,
7+
8+
In your `[[...blitz]].ts` api file you can see the following settings
9+
```ts
10+
logging?: {
11+
/**
12+
* allowList Represents the list of routes for which logging should be enabled
13+
* If whiteList is defined then only those routes will be logged
14+
*/
15+
allowList?: string[]
16+
/**
17+
* blockList Represents the list of routes for which logging should be disabled
18+
* If blockList is defined then all routes except those will be logged
19+
*/
20+
blockList?: string[]
21+
/**
22+
* verbose Represents the flag to enable/disable logging
23+
* If verbose is true then Blitz RPC will log the input and output of each resolver
24+
*/
25+
verbose?: boolean
26+
/**
27+
* disablelevel Represents the flag to enable/disable logging for a particular level
28+
*/
29+
disablelevel?: "debug" | "info"
30+
}
31+
```
32+
```ts
33+
import { rpcHandler } from "@blitzjs/rpc"
34+
import { api } from "src/blitz-server"
35+
36+
export default api(
37+
rpcHandler({
38+
onError: console.log,
39+
formatError: (error) => {
40+
error.message = `FormatError handler: ${error.message}`
41+
return error
42+
},
43+
logging: {
44+
...
45+
}
46+
})
47+
)
48+
```
49+
50+
Example:
51+
```ts
52+
export default api(
53+
rpcHandler({
54+
onError: console.log,
55+
formatError: (error) => {
56+
error.message = `FormatError handler: ${error.message}`
57+
return error
58+
},
59+
logging: {
60+
verbose: true,
61+
blockList: ["getCurrentUser", ...], //just write the resolver name [which is the resolver file name]
62+
},
63+
})
64+
)
65+
```
66+
67+
This is enable verbose blitz rpc logging for all resolvers except the resolvers `getCurrentUser` and others mentioned in the `blockList`
68+

apps/toolkit-app/src/pages/api/rpc/[[...blitz]].ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,9 @@ export default api(
88
error.message = `FormatError handler: ${error.message}`
99
return error
1010
},
11+
// logging: {
12+
// verbose: true,
13+
// blockList: ["/getCurrentUser"],
14+
// },
1115
})
1216
)

packages/blitz-rpc/src/index-server.ts

Lines changed: 80 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,59 @@ async function getResolverMap(): Promise<ResolverFiles | null | undefined> {
146146
interface RpcConfig {
147147
onError?: (error: Error) => void
148148
formatError?: (error: Error) => Error
149+
logging?: {
150+
/**
151+
* allowList Represents the list of routes for which logging should be enabled
152+
* If allowList is defined then only those routes will be logged
153+
*/
154+
allowList?: string[]
155+
/**
156+
* blockList Represents the list of routes for which logging should be disabled
157+
* If blockList is defined then all routes except those will be logged
158+
*/
159+
blockList?: string[]
160+
/**
161+
* verbose Represents the flag to enable/disable logging
162+
* If verbose is true then Blitz RPC will log the input and output of each resolver
163+
*/
164+
verbose?: boolean
165+
/**
166+
* disablelevel Represents the flag to enable/disable logging for a particular level
167+
*/
168+
disablelevel?: "debug" | "info"
169+
}
170+
}
171+
172+
function isBlitzRPCVerbose(resolverName: string, config: RpcConfig, level: string) {
173+
// blitz rpc is by default verbose - to keep current behaviour
174+
if (!config.logging) {
175+
return true
176+
}
177+
//if logging exists and verbose is not defined then default to true
178+
if (config.logging && !("verbose" in config.logging)) {
179+
return true
180+
}
181+
const isLevelDisabled = config.logging?.disablelevel === level
182+
if (config.logging?.verbose) {
183+
// If allowList array is defined then allow only those routes in allowList
184+
if (config.logging?.allowList) {
185+
if (config.logging?.allowList?.includes(resolverName) && !isLevelDisabled) {
186+
return true
187+
}
188+
}
189+
// If blockList array is defined then allow all routes except those in blockList
190+
if (config.logging?.blockList) {
191+
if (!config.logging?.blockList?.includes(resolverName) && !isLevelDisabled) {
192+
return true
193+
}
194+
}
195+
// if both allowList and blockList are not defined, then allow all routes
196+
if (!config.logging?.allowList && !config.logging?.blockList && !isLevelDisabled) {
197+
return true
198+
}
199+
return false
200+
}
201+
return false
149202
}
150203

151204
export function rpcHandler(config: RpcConfig) {
@@ -159,10 +212,11 @@ export function rpcHandler(config: RpcConfig) {
159212

160213
const relativeRoutePath = (req.query.blitz as string[])?.join("/")
161214
const routePath = "/" + relativeRoutePath
215+
const resolverName = routePath.replace(/(\/api\/rpc)?\//, "")
162216

163217
const log = baseLogger().getSubLogger({
164218
name: "blitz-rpc",
165-
prefix: [routePath.replace(/(\/api\/rpc)?\//, "") + "()"],
219+
prefix: [resolverName + "()"],
166220
})
167221
const customChalk = new chalk.Instance({
168222
level: log.settings.type === "json" ? 0 : chalk.level,
@@ -213,11 +267,16 @@ export function rpcHandler(config: RpcConfig) {
213267
? parse(`${req.query.meta}`)
214268
: undefined,
215269
})
216-
log.info(customChalk.dim("Starting with input:"), data ? data : JSON.stringify(data))
270+
if (isBlitzRPCVerbose(resolverName, config, "info")) {
271+
log.info(customChalk.dim("Starting with input:"), data ? data : JSON.stringify(data))
272+
}
217273
const startTime = Date.now()
218274
const result = await resolver(data, (res as any).blitzCtx)
219275
const resolverDuration = Date.now() - startTime
220-
log.info(customChalk.dim("Result:"), result ? result : JSON.stringify(result))
276+
277+
if (isBlitzRPCVerbose(resolverName, config, "debug")) {
278+
log.debug(customChalk.dim("Result:"), result ? result : JSON.stringify(result))
279+
}
221280

222281
const serializerStartTime = Date.now()
223282
const serializedResult = superjsonSerialize(result)
@@ -231,21 +290,26 @@ export function rpcHandler(config: RpcConfig) {
231290
result: serializedResult.meta,
232291
},
233292
})
234-
log.debug(
235-
customChalk.dim(
236-
`Next.js serialization:${prettyMs(Date.now() - nextSerializerStartTime)}`,
237-
),
238-
)
293+
294+
if (isBlitzRPCVerbose(resolverName, config, "debug")) {
295+
log.debug(
296+
customChalk.dim(
297+
`Next.js serialization:${prettyMs(Date.now() - nextSerializerStartTime)}`,
298+
),
299+
)
300+
}
301+
239302
const serializerDuration = Date.now() - serializerStartTime
240303
const duration = Date.now() - startTime
241-
242-
log.debug(
243-
customChalk.dim(
244-
`Finished: resolver:${prettyMs(resolverDuration)} serializer:${prettyMs(
245-
serializerDuration,
246-
)} total:${prettyMs(duration)}`,
247-
),
248-
)
304+
if (isBlitzRPCVerbose(resolverName, config, "info")) {
305+
log.info(
306+
customChalk.dim(
307+
`Finished: resolver:${prettyMs(resolverDuration)} serializer:${prettyMs(
308+
serializerDuration,
309+
)} total:${prettyMs(duration)}`,
310+
),
311+
)
312+
}
249313
newLine()
250314

251315
return

0 commit comments

Comments
 (0)