Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement support for passing custom text resolution for starting log… #4698

Merged
merged 9 commits into from
Apr 25, 2023
22 changes: 19 additions & 3 deletions docs/Reference/Server.md
Original file line number Diff line number Diff line change
Expand Up @@ -916,9 +916,25 @@ fastify.ready().then(() => {

Starts the server and internally waits for the `.ready()` event. The signature
is `.listen([options][, callback])`. Both the `options` object and the
`callback` parameters follow the [Node.js
core](https://nodejs.org/api/net.html#serverlistenoptions-callback) parameter
definitions.
`callback` parameters extend the [Node.js
core](https://nodejs.org/api/net.html#serverlistenoptions-callback) options
object. Thus, all core options are available with the following additional
Fastify specific options:

### `listenTextResolver`
<a id="listen-text-resolver"></a>

Set an optional resolver for the text to log after server has been successfully
started.
It is possible to override the default `Server listening at [address]` log
entry using this option.

```js
server.listen({
port: 9080,
listenTextResolver: (address) => { return `Prometheus metrics server is listening at ${address}` }
})
```

By default, the server will listen on the address(es) resolved by `localhost`
when no specific host is provided. If listening on any available interface is
Expand Down
13 changes: 9 additions & 4 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const {
module.exports.createServer = createServer
module.exports.compileValidateHTTPVersion = compileValidateHTTPVersion

function defaultResolveServerListeningText (address) {
return `Server listening at ${address}`
}

function createServer (options, httpHandler) {
const server = getServerInstance(options, httpHandler)

Expand Down Expand Up @@ -166,7 +170,7 @@ function listenCallback (server, listenOptions) {
const wrap = (err) => {
server.removeListener('error', wrap)
if (!err) {
const address = logServerAddress.call(this, server)
const address = logServerAddress.call(this, server, listenOptions.listenTextResolver || defaultResolveServerListeningText)
listenOptions.cb(null, address)
} else {
this[kState].listening = false
Expand Down Expand Up @@ -209,7 +213,7 @@ function listenPromise (server, listenOptions) {
const listen = new Promise((resolve, reject) => {
server.listen(listenOptions, () => {
server.removeListener('error', errEventHandler)
resolve(logServerAddress.call(this, server))
resolve(logServerAddress.call(this, server, listenOptions.listenTextResolver || defaultResolveServerListeningText))
})
// we set it afterwards because listen can throw
this[kState].listening = true
Expand Down Expand Up @@ -339,7 +343,7 @@ function normalizePort (firstArg) {
return port >= 0 && !Number.isNaN(port) && Number.isInteger(port) ? port : 0
}

function logServerAddress (server) {
function logServerAddress (server, listenTextResolver) {
let address = server.address()
const isUnixSocket = typeof address === 'string'
/* istanbul ignore next */
Expand All @@ -353,7 +357,8 @@ function logServerAddress (server) {
/* istanbul ignore next */
address = (isUnixSocket ? '' : ('http' + (this[kOptions].https ? 's' : '') + '://')) + address

this.log.info('Server listening at ' + address)
const serverListeningText = listenTextResolver(address)
this.log.info(serverListeningText)
return address
}

Expand Down
10 changes: 10 additions & 0 deletions test/server.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ test('listen should accept stringified number port', t => {
})
})

test('listen should accept log text resolution function', t => {
t.plan(1)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))
fastify.listen({ port: '1234', listenTextResolver: () => 'hardcoded text' }, (err) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a t.pass('executed') statement here and increment the plan

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, will create a follow-up PR

t.error(err)
})
})

test('listen should reject string port', async (t) => {
t.plan(2)
const fastify = Fastify()
Expand Down
2 changes: 2 additions & 0 deletions test/types/instance.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,15 @@ expectDeprecated(server.listen('3000', ''))
// test listen opts objects
expectAssignable<PromiseLike<string>>(server.listen())
expectAssignable<PromiseLike<string>>(server.listen({ port: 3000 }))
expectAssignable<PromiseLike<string>>(server.listen({ port: 3000, listenTextResolver: (address) => { return `address: ${address}` } }))
expectAssignable<PromiseLike<string>>(server.listen({ port: 3000, host: '0.0.0.0' }))
expectAssignable<PromiseLike<string>>(server.listen({ port: 3000, host: '0.0.0.0', backlog: 42 }))
expectAssignable<PromiseLike<string>>(server.listen({ port: 3000, host: '0.0.0.0', backlog: 42, exclusive: true }))
expectAssignable<PromiseLike<string>>(server.listen({ port: 3000, host: '::/0', ipv6Only: true }))

expectAssignable<void>(server.listen(() => {}))
expectAssignable<void>(server.listen({ port: 3000 }, () => {}))
expectAssignable<void>(server.listen({ port: 3000, listenTextResolver: (address) => { return `address: ${address}` } }, () => {}))
expectAssignable<void>(server.listen({ port: 3000, host: '0.0.0.0' }, () => {}))
expectAssignable<void>(server.listen({ port: 3000, host: '0.0.0.0', backlog: 42 }, () => {}))
expectAssignable<void>(server.listen({ port: 3000, host: '0.0.0.0', backlog: 42, exclusive: true }, () => {}))
Expand Down
6 changes: 6 additions & 0 deletions types/instance.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ export interface FastifyListenOptions {
* @since This option is available only in Node.js v15.6.0 and greater
*/
signal?: AbortSignal;

/**
* Function that resolves text to log after server has been successfully started
* @param address
*/
listenTextResolver?: (address: string) => string;
}

type NotInInterface<Key, _Interface> = Key extends keyof _Interface ? never : Key
Expand Down