#Logging Payload API Requests
1 messages · Page 1 of 1 (latest)
@sand slate Good question - I wonder if Pino's config can be extended to catch the missing requests?
I know the default level is "info", how about debug or trace?
If that exposes the payload requests, you could check the level of those and add a custom logging level
That's my best guess, I'll keep my eye open for other possibilities, though another community member or a team member may have more insight
Hi! @jade obsidian I've tried debug and trace but those don't add request logging.
For context - we use CloudWatch Logs Insights extensively with all of our deployed APIs (typically with custom 'topic' properties in log messages), and if we were to deploy Payload CMS to AWS we'd ideally like to do the same.
Hmm
@sand slate Did you say you tried to add a middleware to express, prior to Payload?
No not yet.
const requestLoggerMiddleware = ({ logger }) => (req, res, next) => {
console.log('Should run on every request')
next();
};
app.use(requestLoggerMiddleware)
Thanks - yup - was about to try that.
@jade obsidian close....
const requestLoggerMiddleware =
({ logger }) =>
(req, res, next) => {
logger.info(`request: ${req.method} ${req.url}`)
next()
}
const start = async () => {
// Initialize Payload
await payload.init({
secret: process.env.PAYLOAD_SECRET,
mongoURL: process.env.MONGODB_URI,
express: app,
loggerOptions: {
level: 'debug',
},
onInit: async () => {
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`)
},
})
app.use(requestLoggerMiddleware({ logger: payload.logger }))
// Add your own express routes here
app.listen(process.env.PORT, async () => {
payload.logger.info(`Server listening on port ${process.env.PORT}`)
})
}
start()
Ooooo
I can pass in a configured instance of payload - but for any route that matches the payload runtime, the middleware will not log the request
for example if I pass an API request to /api/foo (not a payload collection) then I will get a middleware logged request - since express is handling this route now
So I suspect Payload needs to decide if it's going to log its own handled requests.
@sand slate @muted glade Using custom middleware is the right approach here but I think you need to define it at the router level, like this:
import express from "express";
import payload from "payload";
const app = express();
const start = async () => {
// Initialize Payload
await payload.init({
secret: process.env.PAYLOAD_SECRET,
mongoURL: process.env.MONGODB_URI,
express: app,
loggerOptions: {
level: 'debug',
},
onInit: async () => {
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`)
},
})
const router = express.Router();
router.use(requestLoggerMiddleware({ logger: payload.logger });
app.listen(process.env.PORT, async () => {
payload.logger.info(`Server listening on port ${process.env.PORT}`)
})
}
start()
@orchid raft @jade obsidian <plays sad trombone> - sorry Jacob but this didn't work either. Highly likely I'm doing something wrong here, as we're not very familiar with Express (we're a Fastify shop).
It appears this is an undocumented feature but might work for you - You could try sending in some logging middleware into preMiddleware in your Payload config via the express options
postMiddleware is available as well
@mystic crescent thanks a bunch - will give it a try. Was also going to guess that Payload's middleware / handlers are not calling next() - and so we might try registering our own logger middleware before payload.
It all depends on if you want to use Payload's pino logger instance or not
Understood. Thanks @mystic crescent @orchid raft @jade obsidian - as per Elliot's suggestions, this works...
Middleware:
const requestLoggerMiddleware = (req, res, next) => {
req.payload.logger.info(`request: ${req.method} ${req.url}`)
next()
}
And then in payload.config.ts
express: {
preMiddleware: [requestLoggerMiddleware],
},
Beautiful! 🙌
Also heads up on json logging w/ Pino (especially if querying in cloudwatch). If you want to have more json properties, you'll want to log an object w/ msg property for the message. Multiple parameters didn't appear to pass to json properly despite the TS type saying so.
req.payload.logger.info({ msg: 'my message', method: req.method, url: req.url})
@mystic crescent - thanks - and yup - that's how we're doing it in production with a topic top level property, followed by the payload / params.
and so we would probably do something like this ( although it's late here, so ¯_(ツ)_/¯)
req.payload.logger.info({ payload_request: { method: req.method, url: req.url } })
For anyone stumbling upon this thread, the mentioned custom middleware above is now documented here: https://payloadcms.com/docs/configuration/express#custom-middleware
why do u use fastify over express