CoolFace
Apppublic

strong-tie/inbound-calls

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
options.test.js582 linesDownload Raw Back to logger
1'use strict'2 3const stream = require('node:stream')4 5const t = require('tap')6const split = require('split2')7const pino = require('pino')8 9const Fastify = require('../../fastify')10const { on } = stream11 12t.test('logger options', (t) => {13  t.setTimeout(60000)14 15  t.plan(16)16 17  t.test('logger can be silenced', (t) => {18    t.plan(17)19    const fastify = Fastify({20      logger: false21    })22    t.teardown(fastify.close.bind(fastify))23    t.ok(fastify.log)24    t.equal(typeof fastify.log, 'object')25    t.equal(typeof fastify.log.fatal, 'function')26    t.equal(typeof fastify.log.error, 'function')27    t.equal(typeof fastify.log.warn, 'function')28    t.equal(typeof fastify.log.info, 'function')29    t.equal(typeof fastify.log.debug, 'function')30    t.equal(typeof fastify.log.trace, 'function')31    t.equal(typeof fastify.log.child, 'function')32 33    const childLog = fastify.log.child()34 35    t.equal(typeof childLog, 'object')36    t.equal(typeof childLog.fatal, 'function')37    t.equal(typeof childLog.error, 'function')38    t.equal(typeof childLog.warn, 'function')39    t.equal(typeof childLog.info, 'function')40    t.equal(typeof childLog.debug, 'function')41    t.equal(typeof childLog.trace, 'function')42    t.equal(typeof childLog.child, 'function')43  })44 45  t.test('Should set a custom logLevel for a plugin', async (t) => {46    const lines = ['incoming request', 'Hello', 'request completed']47    t.plan(lines.length + 2)48 49    const stream = split(JSON.parse)50 51    const loggerInstance = pino({ level: 'error' }, stream)52 53    const fastify = Fastify({54      loggerInstance55    })56    t.teardown(fastify.close.bind(fastify))57 58    fastify.get('/', (req, reply) => {59      req.log.info('Not Exist') // we should not see this log60      reply.send({ hello: 'world' })61    })62 63    fastify.register(function (instance, opts, done) {64      instance.get('/plugin', (req, reply) => {65        req.log.info('Hello') // we should see this log66        reply.send({ hello: 'world' })67      })68      done()69    }, { logLevel: 'info' })70 71    await fastify.ready()72 73    {74      const response = await fastify.inject({ method: 'GET', url: '/' })75      const body = await response.json()76      t.same(body, { hello: 'world' })77    }78 79    {80      const response = await fastify.inject({ method: 'GET', url: '/plugin' })81      const body = await response.json()82      t.same(body, { hello: 'world' })83    }84 85    for await (const [line] of on(stream, 'data')) {86      t.same(line.msg, lines.shift())87      if (lines.length === 0) break88    }89  })90 91  t.test('Should set a custom logSerializers for a plugin', async (t) => {92    const lines = ['incoming request', 'XHello', 'request completed']93    t.plan(lines.length + 1)94 95    const stream = split(JSON.parse)96 97    const loggerInstance = pino({ level: 'error' }, stream)98 99    const fastify = Fastify({100      loggerInstance101    })102    t.teardown(fastify.close.bind(fastify))103 104    fastify.register(function (instance, opts, done) {105      instance.get('/plugin', (req, reply) => {106        req.log.info({ test: 'Hello' }) // we should see this log107        reply.send({ hello: 'world' })108      })109      done()110    }, { logLevel: 'info', logSerializers: { test: value => 'X' + value } })111 112    await fastify.ready()113 114    {115      const response = await fastify.inject({ method: 'GET', url: '/plugin' })116      const body = await response.json()117      t.same(body, { hello: 'world' })118    }119 120    for await (const [line] of on(stream, 'data')) {121      // either test or msg122      t.equal(line.test || line.msg, lines.shift())123      if (lines.length === 0) break124    }125  })126 127  t.test('Should set a custom logLevel for every plugin', async (t) => {128    const lines = ['incoming request', 'info', 'request completed', 'incoming request', 'debug', 'request completed']129    t.plan(lines.length * 2 + 3)130 131    const stream = split(JSON.parse)132 133    const loggerInstance = pino({ level: 'error' }, stream)134 135    const fastify = Fastify({136      loggerInstance137    })138    t.teardown(fastify.close.bind(fastify))139 140    fastify.get('/', (req, reply) => {141      req.log.warn('Hello') // we should not see this log142      reply.send({ hello: 'world' })143    })144 145    fastify.register(function (instance, opts, done) {146      instance.get('/info', (req, reply) => {147        req.log.info('info') // we should see this log148        req.log.debug('hidden log')149        reply.send({ hello: 'world' })150      })151      done()152    }, { logLevel: 'info' })153 154    fastify.register(function (instance, opts, done) {155      instance.get('/debug', (req, reply) => {156        req.log.debug('debug') // we should see this log157        req.log.trace('hidden log')158        reply.send({ hello: 'world' })159      })160      done()161    }, { logLevel: 'debug' })162 163    await fastify.ready()164 165    {166      const response = await fastify.inject({ method: 'GET', url: '/' })167      const body = await response.json()168      t.same(body, { hello: 'world' })169    }170 171    {172      const response = await fastify.inject({ method: 'GET', url: '/info' })173      const body = await response.json()174      t.same(body, { hello: 'world' })175    }176 177    {178      const response = await fastify.inject({ method: 'GET', url: '/debug' })179      const body = await response.json()180      t.same(body, { hello: 'world' })181    }182 183    for await (const [line] of on(stream, 'data')) {184      t.ok(line.level === 30 || line.level === 20)185      t.equal(line.msg, lines.shift())186      if (lines.length === 0) break187    }188  })189 190  t.test('Should set a custom logSerializers for every plugin', async (t) => {191    const lines = ['incoming request', 'Hello', 'request completed', 'incoming request', 'XHello', 'request completed', 'incoming request', 'ZHello', 'request completed']192    t.plan(lines.length + 3)193 194    const stream = split(JSON.parse)195 196    const loggerInstance = pino({ level: 'info' }, stream)197    const fastify = Fastify({198      loggerInstance199    })200    t.teardown(fastify.close.bind(fastify))201 202    fastify.get('/', (req, reply) => {203      req.log.warn({ test: 'Hello' })204      reply.send({ hello: 'world' })205    })206 207    fastify.register(function (instance, opts, done) {208      instance.get('/test1', (req, reply) => {209        req.log.info({ test: 'Hello' })210        reply.send({ hello: 'world' })211      })212      done()213    }, { logSerializers: { test: value => 'X' + value } })214 215    fastify.register(function (instance, opts, done) {216      instance.get('/test2', (req, reply) => {217        req.log.info({ test: 'Hello' })218        reply.send({ hello: 'world' })219      })220      done()221    }, { logSerializers: { test: value => 'Z' + value } })222 223    await fastify.ready()224 225    {226      const response = await fastify.inject({ method: 'GET', url: '/' })227      const body = await response.json()228      t.same(body, { hello: 'world' })229    }230 231    {232      const response = await fastify.inject({ method: 'GET', url: '/test1' })233      const body = await response.json()234      t.same(body, { hello: 'world' })235    }236 237    {238      const response = await fastify.inject({ method: 'GET', url: '/test2' })239      const body = await response.json()240      t.same(body, { hello: 'world' })241    }242 243    for await (const [line] of on(stream, 'data')) {244      t.equal(line.test || line.msg, lines.shift())245      if (lines.length === 0) break246    }247  })248 249  t.test('Should override serializers from route', async (t) => {250    const lines = ['incoming request', 'ZHello', 'request completed']251    t.plan(lines.length + 1)252 253    const stream = split(JSON.parse)254 255    const loggerInstance = pino({ level: 'info' }, stream)256    const fastify = Fastify({257      loggerInstance258    })259    t.teardown(fastify.close.bind(fastify))260 261    fastify.register(function (instance, opts, done) {262      instance.get('/', {263        logSerializers: {264          test: value => 'Z' + value // should override265        }266      }, (req, reply) => {267        req.log.info({ test: 'Hello' })268        reply.send({ hello: 'world' })269      })270      done()271    }, { logSerializers: { test: value => 'X' + value } })272 273    await fastify.ready()274 275    {276      const response = await fastify.inject({ method: 'GET', url: '/' })277      const body = await response.json()278      t.same(body, { hello: 'world' })279    }280 281    for await (const [line] of on(stream, 'data')) {282      t.equal(line.test || line.msg, lines.shift())283      if (lines.length === 0) break284    }285  })286 287  t.test('Should override serializers from plugin', async (t) => {288    const lines = ['incoming request', 'ZHello', 'request completed']289    t.plan(lines.length + 1)290 291    const stream = split(JSON.parse)292 293    const loggerInstance = pino({ level: 'info' }, stream)294    const fastify = Fastify({295      loggerInstance296    })297    t.teardown(fastify.close.bind(fastify))298 299    fastify.register(function (instance, opts, done) {300      instance.register(context1, {301        logSerializers: {302          test: value => 'Z' + value // should override303        }304      })305      done()306    }, { logSerializers: { test: value => 'X' + value } })307 308    function context1 (instance, opts, done) {309      instance.get('/', (req, reply) => {310        req.log.info({ test: 'Hello' })311        reply.send({ hello: 'world' })312      })313      done()314    }315 316    await fastify.ready()317 318    {319      const response = await fastify.inject({ method: 'GET', url: '/' })320      const body = await response.json()321      t.same(body, { hello: 'world' })322    }323 324    for await (const [line] of on(stream, 'data')) {325      t.equal(line.test || line.msg, lines.shift())326      if (lines.length === 0) break327    }328  })329 330  t.test('Should increase the log level for a specific plugin', async (t) => {331    const lines = ['Hello']332    t.plan(lines.length * 2 + 1)333 334    const stream = split(JSON.parse)335 336    const loggerInstance = pino({ level: 'info' }, stream)337 338    const fastify = Fastify({339      loggerInstance340    })341    t.teardown(fastify.close.bind(fastify))342 343    fastify.register(function (instance, opts, done) {344      instance.get('/', (req, reply) => {345        req.log.error('Hello') // we should see this log346        reply.send({ hello: 'world' })347      })348      done()349    }, { logLevel: 'error' })350 351    await fastify.ready()352 353    {354      const response = await fastify.inject({ method: 'GET', url: '/' })355      const body = await response.json()356      t.same(body, { hello: 'world' })357    }358 359    for await (const [line] of on(stream, 'data')) {360      t.equal(line.level, 50)361      t.equal(line.msg, lines.shift())362      if (lines.length === 0) break363    }364  })365 366  t.test('Should set the log level for the customized 404 handler', async (t) => {367    const lines = ['Hello']368    t.plan(lines.length * 2 + 1)369 370    const stream = split(JSON.parse)371 372    const loggerInstance = pino({ level: 'warn' }, stream)373 374    const fastify = Fastify({375      loggerInstance376    })377    t.teardown(fastify.close.bind(fastify))378 379    fastify.register(function (instance, opts, done) {380      instance.setNotFoundHandler(function (req, reply) {381        req.log.error('Hello')382        reply.code(404).send()383      })384      done()385    }, { logLevel: 'error' })386 387    await fastify.ready()388 389    {390      const response = await fastify.inject({ method: 'GET', url: '/' })391      t.equal(response.statusCode, 404)392    }393 394    for await (const [line] of on(stream, 'data')) {395      t.equal(line.level, 50)396      t.equal(line.msg, lines.shift())397      if (lines.length === 0) break398    }399  })400 401  t.test('Should set the log level for the customized 500 handler', async (t) => {402    const lines = ['Hello']403    t.plan(lines.length * 2 + 1)404 405    const stream = split(JSON.parse)406 407    const loggerInstance = pino({ level: 'warn' }, stream)408 409    const fastify = Fastify({410      loggerInstance411    })412    t.teardown(fastify.close.bind(fastify))413 414    fastify.register(function (instance, opts, done) {415      instance.get('/', (req, reply) => {416        req.log.error('kaboom')417        reply.send(new Error('kaboom'))418      })419 420      instance.setErrorHandler(function (e, request, reply) {421        reply.log.fatal('Hello')422        reply.code(500).send()423      })424      done()425    }, { logLevel: 'fatal' })426 427    await fastify.ready()428 429    {430      const response = await fastify.inject({ method: 'GET', url: '/' })431      t.equal(response.statusCode, 500)432    }433 434    for await (const [line] of on(stream, 'data')) {435      t.equal(line.level, 60)436      t.equal(line.msg, lines.shift())437      if (lines.length === 0) break438    }439  })440 441  t.test('Should set a custom log level for a specific route', async (t) => {442    const lines = ['incoming request', 'Hello', 'request completed']443    t.plan(lines.length + 2)444 445    const stream = split(JSON.parse)446 447    const loggerInstance = pino({ level: 'error' }, stream)448 449    const fastify = Fastify({450      loggerInstance451    })452    t.teardown(fastify.close.bind(fastify))453 454    fastify.get('/log', { logLevel: 'info' }, (req, reply) => {455      req.log.info('Hello')456      reply.send({ hello: 'world' })457    })458 459    fastify.get('/no-log', (req, reply) => {460      req.log.info('Hello')461      reply.send({ hello: 'world' })462    })463 464    await fastify.ready()465 466    {467      const response = await fastify.inject({ method: 'GET', url: '/log' })468      const body = await response.json()469      t.same(body, { hello: 'world' })470    }471 472    {473      const response = await fastify.inject({ method: 'GET', url: '/no-log' })474      const body = await response.json()475      t.same(body, { hello: 'world' })476    }477 478    for await (const [line] of on(stream, 'data')) {479      t.equal(line.msg, lines.shift())480      if (lines.length === 0) break481    }482  })483 484  t.test('should pass when using unWritable props in the logger option', (t) => {485    t.plan(8)486    const fastify = Fastify({487      logger: Object.defineProperty({}, 'level', { value: 'info' })488    })489    t.teardown(fastify.close.bind(fastify))490 491    t.equal(typeof fastify.log, 'object')492    t.equal(typeof fastify.log.fatal, 'function')493    t.equal(typeof fastify.log.error, 'function')494    t.equal(typeof fastify.log.warn, 'function')495    t.equal(typeof fastify.log.info, 'function')496    t.equal(typeof fastify.log.debug, 'function')497    t.equal(typeof fastify.log.trace, 'function')498    t.equal(typeof fastify.log.child, 'function')499  })500 501  t.test('Should throw an error if logger instance is passed to `logger`', async (t) => {502    t.plan(2)503    const stream = split(JSON.parse)504 505    const logger = require('pino')(stream)506 507    try {508      Fastify({ logger })509    } catch (err) {510      t.ok(err)511      t.equal(err.code, 'FST_ERR_LOG_INVALID_LOGGER_CONFIG')512    }513  })514 515  t.test('Should throw an error if options are passed to `loggerInstance`', async (t) => {516    t.plan(2)517    try {518      Fastify({ loggerInstance: { level: 'log' } })519    } catch (err) {520      t.ok(err)521      t.equal(err.code, 'FST_ERR_LOG_INVALID_LOGGER_INSTANCE')522    }523  })524 525  t.test('If both `loggerInstance` and `logger` are provided, an error should be thrown', async (t) => {526    t.plan(2)527    const loggerInstanceStream = split(JSON.parse)528    const loggerInstance = pino({ level: 'error' }, loggerInstanceStream)529    const loggerStream = split(JSON.parse)530    try {531      Fastify({532        logger: {533          stream: loggerStream,534          level: 'info'535        },536        loggerInstance537      })538    } catch (err) {539      t.ok(err)540      t.equal(err.code, 'FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED')541    }542  })543 544  t.test('`logger` should take pino configuration and create a pino logger', async (t) => {545    const lines = ['hello', 'world']546    t.plan(2 * lines.length + 2)547    const loggerStream = split(JSON.parse)548    const fastify = Fastify({549      logger: {550        stream: loggerStream,551        level: 'error'552      }553    })554    t.teardown(fastify.close.bind(fastify))555    fastify.get('/hello', (req, reply) => {556      req.log.error('hello')557      reply.code(404).send()558    })559 560    fastify.get('/world', (req, reply) => {561      req.log.error('world')562      reply.code(201).send()563    })564 565    await fastify.ready()566    {567      const response = await fastify.inject({ method: 'GET', url: '/hello' })568      t.equal(response.statusCode, 404)569    }570    {571      const response = await fastify.inject({ method: 'GET', url: '/world' })572      t.equal(response.statusCode, 201)573    }574 575    for await (const [line] of on(loggerStream, 'data')) {576      t.equal(line.level, 50)577      t.equal(line.msg, lines.shift())578      if (lines.length === 0) break579    }580  })581})582