@fatmatto/jetpack
v1.6.4
Published
Common utilities for nodejs
Downloads
553
Readme
Logger
const {Logger} = require('@fatmatto/jetpack')
const config = {
logger: {
type: 'file', // file | console | noop
directory: 'path/to/logs'
}
}
const logger = Logger.getLogger(config)
logger.log('info','Messaggio',{foo:{bar:{baz:1}}})
Logging Express Requests
app.use(Logger.logFinishedRequests)
// Or build a logger with the default formatter
app.use(Logger.buildRequestLogger())
// Or pass a custom formatter
app.use(Logger.buildRequestLogger({
formatter: (req,res) => {
return {...}
}
}))
Queue
Creates a queue client for some message brokers such as:
- ~~Franz~~ (Apio Internal, deprecated)
- Kafka
- NATS
- RabbitMQ (AMQP in general)
- Mqtt
const config = {
queue: {
type: 'kafka', // kafka or nats or rabbitmq
uri: 'http://franz:8000',
id: 'my-consumer'
}
}
const eventsQueue = Queue.buildQueueClient(config, {
queueName: 'events'
})
eventsQueue.push([{hello:'world'}])
eventsQueue.on('messages', messages => {
console.log({messages})
})
eventsQueue.on('error', error => {
console.log({error})
})
Rabbitmq
Nel caso di rabbitmq la topologia della coda è leggermente complicata dalla semantica di rabbitmq stesso:
- I publisher pubblicano su un exchange.
- Gli exchange rigirano i messaggi alle code
- I consumer ascoltano sulle code
Un esempio pratico:
Supponiamo di volere che il broker pubblichi su apio-core-uplink Che il trasformer legga su apio-core-uplink e allo stesso tempo anche message parser legga da apio-core-uplink. Significa che trasformer e message-parser devono ricevere gli stessi messaggi. Se entrambi leggessero dalla stessa coda, si smisterebbero i messaggi. La soluzione è creare un exchange apio-core-uplink di tipo fanout, fare il bind a due queue, una chiamata apio-core-uplink-transformer e una chiamata apio-core-uplink-message-parser. A questo punto queste due code riceveranno tutti i messaggi pubblicati su exchange apio-core-uplink.
NATS
Nel caso di NATS, poiché usiamo i consumer in pull, è necessario specificare il nome del consumer (attraverso il parametro "id") oltreché il nome della coda; in questo modo NATS può provvedere al bilanciamento: lo fa in automatico, basta che due o più consumer vadano a leggere dalla stessa coda. Questo spiega la necessità di mantenere due parametri distinti. Però il durable (cioè il nome del consumer) deve essere univoco e quindi in caso di autoscaling potrebbero esserci problemi; a meno che non si possano passare configurazioni ad hoc alle repliche tramite docker-compose.
Inoltre, visto che è necessario mandare esplicitamente l'ACK, i messaggi vengono restituiti direttamente col formato dati di NATS arricchiti dal campo "payload", che contiene il messaggio parsato. In questo modo - dopo aver esaminato il singolo messaggio - è possibile chiamare i metodi "ack", "nak" o "term" a seconda del caso. Infine, i messaggi vengono messi in stato di "working" prima di essere restituiti; questo evita che in caso di timeout - o altra ragione - essi vengano ricevuti una seconda volta (comportamento di NATS in caso di mancata ricezione dell'ACK).