Socket and Client for udp logging with possibility to encrypt data.
- Fast — little overhead above UDP to send messages
- Secure — built-in encryption for sensitive logs
- Simple — used well-known Node streams to manipulate and move data
- ESM and CJS
npm i --save udp-logger//app.js
import { logger } from 'udp-logger'
function main () {
/* ... */
logger.log('some data to log')
/* ... */
}
main()//logger-client.js
import { UdpLoggerClient } from 'udp-logger'
export const logger = new UdpLoggerClient({ encryption: '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff' })//logger-server.js
import { UdpLoggerServer } from 'udp-logger'
const server = new UdpLoggerServer({
filePath: './my-app.log',
decryption: '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'
})
await server.start()After just start the logger server node logger-server.js and start your app node app.js. That's all and everything works.
Extends EventEmitter
options<object>– optionaltype<'udp4' | 'udp6'>– optional. Default'udp4'port<string | number>– optional. Default44002host<string>– optional. Default'127.0.0.1'or'::1'packetSize<number>– optional. Number of bytes in each packet (chunk). Default1280isAsync<boolean>– optional. Enables delayed message sending. Useful if you don't want to wait even for somensin your business flow for logging. Defaultfalseencryption<string> | <(payload: Buffer) => Buffer>– optional. Defaultundefined- if passed
string- will be appliedaes-256-ctrencryption with passed string as a secret, so it should be64charlong; - if passed
function- will be used that function to encrypt every message; - if passed
undefined- will not use any kind of encryption.
- if passed
serializer<(payload: any) => Buffer>- optional. Defaultv8.serialize- Used v8.serialize, but you could use something like bson, or great avsc if you could make all your logs are perfectly typed. Or you even can use
JSON.stringify/JSON.parseif your logs are simple. It will be faster than v8 serialize/deserialize. Check this Binary serialization comparison, it is cool.
- Used v8.serialize, but you could use something like bson, or great avsc if you could make all your logs are perfectly typed. Or you even can use
log (...args: any):<void>– just log whatever you need.
'ready':<void>– emitted when the client "establishes" udp connection.
import { UdpLoggerClient } from 'udp-logger'
const logger = new UdpLoggerClient({
port: 44002,
// encryption: (buf) => buf.map(byte => byte ^ 83) // not safe at all, but better than nothing
encryption: '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'
})
logger.log('Hello, world!')
logger.log(new Error('Goodbye, world...'))import { UdpLoggerClient } from 'udp-logger'
const encryption = '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'
const logs = new UdpLoggerClient({ port: 45001, encryption })
const errors = new UdpLoggerClient({ port: 45002, encryption })
const statistics = new UdpLoggerClient({ port: 45003, encryption })
const logger = {
log: logs.log,
error: errors.log,
stat: statistics.log
}
logger.log('logger created')
export default loggerExtends EventEmitter
It is a simple wrapper around UdpLoggerSocket and UdpLoggerWriter created to simplify rapid start
options<object>– optionalfilePath<string>– optional. Supports absolute and relative paths. If passed relative path then will useprocess.cwd()as a base path. Default./udp-port-${port}.logencoding<string>— optional. Encoding for writer to your disk. Default'utf8',flags<string>– optional. More info about flags you can check on NodeJS File System Flags. Default'a'type<'udp4' | 'udp6'>– optional. Default'udp4'port<string> | <number>– optional. Default44002host<string>– optional Default'127.0.0.1'or'::1'decryption<string> | <(payload: Buffer) => Buffer>– optional. For more details check UdpLoggerSocket Arguments Section Defaultundefineddeserializer<(payload: Buffer) => any>- optional. For more details check UdpLoggerSocket Arguments Section Defaultv8.deserializeformatMessage<(data:any, date:Date, id:number|string) => string | Buffer | Uint8Array>- optional. DefaultDEFAULT_MESSAGE_FORMATTERfrom constants
start ():<Promise<UdpLoggerServer>>stop ():<Promise<UdpLoggerServer>>
'ready':<void>– emitted when server started'close':<void>– emitted when server closed'error':<Error~object>– emitted when some error occurs insocketorwriter. Requires you to handle errors on instance of server.'warning':<any>– emitted when warning occurs. For more details check UdpLoggerSocket Events Sections
import { UdpLoggerServer } from 'udp-logger'
const server = new UdpLoggerServer({
filePath: './my-app.log',
port: 44002,
// decryption: (buf) => buf.map(byte => byte ^ 83) // not safe at all, but better than nothing
decryption: '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'
})
await server.start()
console.log('log udp server started')Extends Readable Stream
It is a UDP socket in readable stream form.
options<object>– requiredtype<'udp4' | 'udp6'>– optional. Default'udp4'port<string | number>– optional. Default44002host<string>– optional Default'127.0.0.1'or'::1'decryption<string> | <(payload: Buffer) => Buffer>– optional. Defaultundefined- if passed
string- will be appliedaes-256-ctrdecryption with passed string as a secret, so it should be64charlong; - if passed
function- will be used that function to decrypt every message; - if passed
undefined- will not use any kind of decryption.
- if passed
deserializer<(payload: Buffer) => any>- optional. Defaultv8.deserialize- Used v8.deserialize, but you could use something like bson, or great avsc if you could make all your logs are perfectly typed. Or you even can use
JSON.stringify/JSON.parseif your logs are simple. It will be faster than v8 serialize/deserialize. Check this Binary serialization comparison, it is cool.
- Used v8.deserialize, but you could use something like bson, or great avsc if you could make all your logs are perfectly typed. Or you even can use
formatMessage<(data: any, date:Date, id:number|string) => string | Buffer | Uint8Array>- optional. DefaultDEFAULT_MESSAGE_FORMATTERfrom constantsgcIntervalTime<number>— optional. How often instance will check internal buffer to delete expired messages (in ms). Default5000gcExpirationTime<number>— optional. How long chunks can await all missing chunks in internal buffer (in ms). Default10000
port:<number>address:<string>
All Readable events of course and:
Emitted when socket started and ready to receive data.
Emitted right after a message was compiled and formatted. Can be used for creating some business logic based on logs (for example pushing some data into google statistics)
message<string>- messagectx<object>body<any>- deserialized delivered bodydate<Date>id<string>
Emitted when warning occurs.
payload<object | Error>message<string>id<string>– optionaldate<Date>– optional
A message might be:
missing_message– when some messages didn't receive all chunks and got expired.compile_message_error– when some messages failed to be compiled from chunks.
import { UdpLoggerSocket } from 'udp-logger'
const socket = new UdpLoggersocket({
port: 44002,
// decryption: (buf) => buf.map(byte => byte ^ 83) // not safe at all, but better than nothing
decryption: '11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff'
})
for await (const message of socket) {
/*handle messages*/
}Example how to use socket and use UdpLoggerWriter
import { UdpLoggerSocket, UdpLoggerWriter } from 'udp-logger'
const socket = new UdpLoggersocket()
const writer = new UdpLoggerWriter({ filePath: './my-app.log' })
socket.pipe(writer)Example with [file-stream-rotator][https://github.com/rogerc/file-stream-rotator]
import { UdpLoggerSocket, UdpLoggerWriter } from 'udp-logger'
const socket = new UdpLoggersocket()
const fileStreamWithRotating = (await import('file-stream-rotator'))
.getStream({ filename: '/tmp/test-%DATE%.log', frequency: 'daily', verbose: false, date_format: 'YYYY-MM-DD' })
socket.pipe(fileStreamWithRotating)Extends Writable Stream
UdpLoggerWriter handles file moving, renaming, etc.. and keeps working after all. Usable if you will use any kind of logrotating (linux logrotate for example)
options<object>– requiredfilePath<string>– required. Supports absolute and relative paths. If passed relative path then will useprocess.cwd()as a base pathencoding<string>— optional. Encoding for writer to your disk. Default'utf8'flagsstring– optional. More info about flags you can check on NodeJS File System Flags. Default'a'
path:<string>fd:<number>bytesWritten:<number>pending:<boolean>
'ready':<void>– emitted when write stream ready
Example how to use socket and use UdpLoggerSocket
import { UdpLoggerSocket, UdpLoggerWriter } from 'udp-logger'
const socket = new UdpLoggersocket()
const writer = new UdpLoggerWriter({ filePath: './my-app.log' })
socket.pipe(writer)data<any[]>— deserialized arguments oflogfunction fromUdpLoggerClientdate<Date>id<string>- Returns:
<Buffer>|<string>|<Uint8Array>
Default format function to write logs. Underhood it uses util-inspect function. For more info, you can check the source files.
<number>:44002
There are _identifier and _constants exposed also, but they are used for internal needs. They could be removed in next releases, so it is not recommended to use it in your project.
License (MIT)