Skip to content

Commit

Permalink
Configure the Verbosity of Blitz RPC Logging (#4162)
Browse files Browse the repository at this point in the history
* 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 <b@bayer.ws>

---------

Co-authored-by: Brandon Bayer <b@bayer.ws>
  • Loading branch information
siddhsuresh and flybayer committed Jul 3, 2023
1 parent 831a493 commit 7277349
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 16 deletions.
68 changes: 68 additions & 0 deletions .changeset/sixty-rockets-count.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
"@blitzjs/rpc": patch
"blitz": patch
---

### Now we can configure Blitz RPC in the following way,

In your `[[...blitz]].ts` api file you can see the following settings
```ts
logging?: {
/**
* allowList Represents the list of routes for which logging should be enabled
* If whiteList is defined then only those routes will be logged
*/
allowList?: string[]
/**
* blockList Represents the list of routes for which logging should be disabled
* If blockList is defined then all routes except those will be logged
*/
blockList?: string[]
/**
* verbose Represents the flag to enable/disable logging
* If verbose is true then Blitz RPC will log the input and output of each resolver
*/
verbose?: boolean
/**
* disablelevel Represents the flag to enable/disable logging for a particular level
*/
disablelevel?: "debug" | "info"
}
```
```ts
import { rpcHandler } from "@blitzjs/rpc"
import { api } from "src/blitz-server"

export default api(
rpcHandler({
onError: console.log,
formatError: (error) => {
error.message = `FormatError handler: ${error.message}`
return error
},
logging: {
...
}
})
)
```

Example:
```ts
export default api(
rpcHandler({
onError: console.log,
formatError: (error) => {
error.message = `FormatError handler: ${error.message}`
return error
},
logging: {
verbose: true,
blockList: ["getCurrentUser", ...], //just write the resolver name [which is the resolver file name]
},
})
)
```

This is enable verbose blitz rpc logging for all resolvers except the resolvers `getCurrentUser` and others mentioned in the `blockList`

4 changes: 4 additions & 0 deletions apps/toolkit-app/src/pages/api/rpc/[[...blitz]].ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ export default api(
error.message = `FormatError handler: ${error.message}`
return error
},
// logging: {
// verbose: true,
// blockList: ["/getCurrentUser"],
// },
})
)
96 changes: 80 additions & 16 deletions packages/blitz-rpc/src/index-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,59 @@ async function getResolverMap(): Promise<ResolverFiles | null | undefined> {
interface RpcConfig {
onError?: (error: Error) => void
formatError?: (error: Error) => Error
logging?: {
/**
* allowList Represents the list of routes for which logging should be enabled
* If allowList is defined then only those routes will be logged
*/
allowList?: string[]
/**
* blockList Represents the list of routes for which logging should be disabled
* If blockList is defined then all routes except those will be logged
*/
blockList?: string[]
/**
* verbose Represents the flag to enable/disable logging
* If verbose is true then Blitz RPC will log the input and output of each resolver
*/
verbose?: boolean
/**
* disablelevel Represents the flag to enable/disable logging for a particular level
*/
disablelevel?: "debug" | "info"
}
}

function isBlitzRPCVerbose(resolverName: string, config: RpcConfig, level: string) {
// blitz rpc is by default verbose - to keep current behaviour
if (!config.logging) {
return true
}
//if logging exists and verbose is not defined then default to true
if (config.logging && !("verbose" in config.logging)) {
return true
}
const isLevelDisabled = config.logging?.disablelevel === level
if (config.logging?.verbose) {
// If allowList array is defined then allow only those routes in allowList
if (config.logging?.allowList) {
if (config.logging?.allowList?.includes(resolverName) && !isLevelDisabled) {
return true
}
}
// If blockList array is defined then allow all routes except those in blockList
if (config.logging?.blockList) {
if (!config.logging?.blockList?.includes(resolverName) && !isLevelDisabled) {
return true
}
}
// if both allowList and blockList are not defined, then allow all routes
if (!config.logging?.allowList && !config.logging?.blockList && !isLevelDisabled) {
return true
}
return false
}
return false
}

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

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

const log = baseLogger().getSubLogger({
name: "blitz-rpc",
prefix: [routePath.replace(/(\/api\/rpc)?\//, "") + "()"],
prefix: [resolverName + "()"],
})
const customChalk = new chalk.Instance({
level: log.settings.type === "json" ? 0 : chalk.level,
Expand Down Expand Up @@ -213,11 +267,16 @@ export function rpcHandler(config: RpcConfig) {
? parse(`${req.query.meta}`)
: undefined,
})
log.info(customChalk.dim("Starting with input:"), data ? data : JSON.stringify(data))
if (isBlitzRPCVerbose(resolverName, config, "info")) {
log.info(customChalk.dim("Starting with input:"), data ? data : JSON.stringify(data))
}
const startTime = Date.now()
const result = await resolver(data, (res as any).blitzCtx)
const resolverDuration = Date.now() - startTime
log.info(customChalk.dim("Result:"), result ? result : JSON.stringify(result))

if (isBlitzRPCVerbose(resolverName, config, "debug")) {
log.debug(customChalk.dim("Result:"), result ? result : JSON.stringify(result))
}

const serializerStartTime = Date.now()
const serializedResult = superjsonSerialize(result)
Expand All @@ -231,21 +290,26 @@ export function rpcHandler(config: RpcConfig) {
result: serializedResult.meta,
},
})
log.debug(
customChalk.dim(
`Next.js serialization:${prettyMs(Date.now() - nextSerializerStartTime)}`,
),
)

if (isBlitzRPCVerbose(resolverName, config, "debug")) {
log.debug(
customChalk.dim(
`Next.js serialization:${prettyMs(Date.now() - nextSerializerStartTime)}`,
),
)
}

const serializerDuration = Date.now() - serializerStartTime
const duration = Date.now() - startTime

log.debug(
customChalk.dim(
`Finished: resolver:${prettyMs(resolverDuration)} serializer:${prettyMs(
serializerDuration,
)} total:${prettyMs(duration)}`,
),
)
if (isBlitzRPCVerbose(resolverName, config, "info")) {
log.info(
customChalk.dim(
`Finished: resolver:${prettyMs(resolverDuration)} serializer:${prettyMs(
serializerDuration,
)} total:${prettyMs(duration)}`,
),
)
}
newLine()

return
Expand Down

0 comments on commit 7277349

Please sign in to comment.