I'm migrating an application to Next.js and one requirement that we have is to be able to monitor the application (using Prometheus for example).
Here are 2 examples of metrics that could make sense:
getInitialProps().I think this would require the developer to use the custom server approach: we could provide a few new options on the const app = next({ dev }) call.
Options proposal:
onRenderStart or beforeRenderonRenderEnd or afterRenderonGetInitialPropsStart or beforeGetInitialPropsonGetInitialPropsEnd or afterGetInitialPropsAll the options above would be callbacks called at the right time. They could also be grouped inside a single timings option maybe.
One thing to consider as well is that a timer started in a start/before callback needs to be stopped in the end/after one. This means we need to have a context shared between those...
One other way that could enable this context could be to return the end function:
next({
onRender: () => {
const endTimer = timer.start()
return () => endTimer()
}
})
I don't have other ideas in my mind so far as I'm still beginning with using Next.js, I'm probably lacking a wider vision.
Gonna add my comment here as well then:
One idea could be to add a Server-Timing header/trailer. Not sure if that would be enough for your use case.
This won't need as much configuration. It could be parsed by middleware and exposed to prometheus that way.
@Janpot I'm not sure to understand how this would work, could you detail a bit more?
The headers would be sent to the browser?
With Prometheus, you need to able to increment a counter/metric that is stored on the server because you need to expose them on a specific port to be scraped by Prometheus.
I didn't test it yet, but AFAIK, this should be possible:
const { createServer } = require('http')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
res.on('finish', () => {
const timing = res.getHeader('Server-Timing')
// parse header and log with prometheus or anything else
})
handle(req, res)
}).listen(3000, err => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
Yes this makes sense. I understand now :)
However, it means that it will be Next's responsibility to measure the time and not the wrapping app. It can also be an issue with Prometheus because the developer needs to start and stop a counter/histogram by herself.
Yes, one could definitely imagine more powerful hooks. I'm just putting it on the table as a low config alternative, that uses already available standards.
Closing this in favor of #8069 and other work Houssein has been doing.
@timneutkens does this PR only enable monitoring on client side or these metrics are available on the server as well?
The specific PR is client-only but there's more coming.
Most helpful comment
The specific PR is client-only but there's more coming.