Skip to content

Commit

Permalink
Implement support for passing custom text resolution for starting log… (
Browse files Browse the repository at this point in the history
#4698)

Co-authored-by: Frazer Smith <frazer.dev@outlook.com>
  • Loading branch information
kibertoad and Fdawgs committed Apr 25, 2023
1 parent b36fd26 commit c035a18
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 7 deletions.
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) => {
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

0 comments on commit c035a18

Please sign in to comment.