From 449ba004851ca880656fccc4daf39a85838fbd89 Mon Sep 17 00:00:00 2001 From: Serphentas Date: Thu, 19 Oct 2023 17:44:56 +0200 Subject: [PATCH] initial UDP support #19 --- README.md | 11 +++++++---- lib/CarbonClient.js | 3 ++- lib/LazySocket.js | 38 +++++++++++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index b970130..dba8d9b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,10 @@ You first have to define the Graphite client: ```js var graphite = require('graphite'); -var client = graphite.createClient('plaintext://graphite.example.org:2003/'); +// TCP +var client = graphite.createClient('tcp://graphite.example.org:2003/'); +// UDP +var client = graphite.createClient('udp://graphite.example.org:2003/'); ``` You can send metrics without a timestamp. The current Unix epoch will then be used in place: @@ -24,7 +27,7 @@ You can send metrics without a timestamp. The current Unix epoch will then be us ```js var metrics = {foo: 23}; client.write(metrics, function(err) { - // if err is null, your data was sent to graphite! + // if err is null (UDP) or undefined (TCP), your data was sent to graphite! }); ``` @@ -34,7 +37,7 @@ If you wish to set your own timestamp, you must use `Date.now()` (millisecond pr var metrics = {foo: 23}; var timestamp = Date.now(); client.write(metrics, timestamp, function(err) { - // if err is null, your data was sent to graphite! + // if err is null (UDP) or undefined (TCP), your data was sent to graphite! }); ``` @@ -44,7 +47,7 @@ In Graphite [1.1.1 (21.12.17)](http://graphite.readthedocs.io/en/latest/releases var metrics = {foo: 23}; var tags = {'name': 'foo.bar', 'some.fancy.tag': 'somefancyvalue'}; client.writeTagged(metrics, tags, function(err) { - // if err is null, your data was sent to graphite! + // if err is null (UDP) or undefined (TCP), your data was sent to graphite! }); ``` diff --git a/lib/CarbonClient.js b/lib/CarbonClient.js index 3ac8eb3..ce447a2 100644 --- a/lib/CarbonClient.js +++ b/lib/CarbonClient.js @@ -27,8 +27,9 @@ CarbonClient.prototype._lazyConnect = function() { var dsn = url.parse(this._dsn); var port = parseInt(dsn.port, 10) || 2003; var host = dsn.hostname; + var proto = dsn.protocol.replace(':', ''); - this._socket = LazySocket.createConnection(port, host); + this._socket = LazySocket.createConnection(port, host, proto); }; CarbonClient.prototype.end = function() { diff --git a/lib/LazySocket.js b/lib/LazySocket.js index 56daf2c..4249104 100644 --- a/lib/LazySocket.js +++ b/lib/LazySocket.js @@ -1,4 +1,5 @@ var net = require('net'); +const dgram = require('node:dgram'); module.exports = LazySocket; function LazySocket(properties) { @@ -6,14 +7,15 @@ function LazySocket(properties) { this.port = properties.port; this.host = properties.host; + this.protocol = properties.protocol; this._socket = null; this._closed = false; this._callbacks = []; } -LazySocket.createConnection = function(port, host) { - var socket = new this({port: port, host: host}); +LazySocket.createConnection = function(port, host, protocol) { + var socket = new this({port: port, host: host, protocol: protocol}); return socket; }; @@ -37,11 +39,15 @@ LazySocket.prototype.write = function(/* data, encoding, cb */) { this._lazyConnect(); try { - this._socket.write.apply(this._socket, args); + if (this.protocol === 'udp') { + this._socket.send(args[0], this.port, this.host, cbProxy); + } else { + this._socket.write.apply(this._socket, args); + } } catch (err) { if (cbProxy) cbProxy(err); - this._socket.destroy(); + this.destroy(); this._socket = null; } }; @@ -68,18 +74,36 @@ LazySocket.prototype._lazyConnect = function() { } } - this._socket = net + if (this.protocol === 'udp') { + this._socket = dgram.createSocket({type: 'udp4'}) + .once('error', onerror) + .once('close', onend); + } else { + this._socket = net .createConnection(this.port, this.host) .once('error', onerror) .once('end', onend); + } }; LazySocket.prototype.end = function() { this._closed = true; - if (this._socket) this._socket.end(); + if (!this._socket) return; + + if (this.protocol === 'udp') { + this._socket.unref(); + } else { + this._socket.end(); + } }; LazySocket.prototype.destroy = function() { this._closed = true; - if (this._socket) this._socket.destroy(); + if (!this._socket) return; + + if (this.protocol === 'udp') { + this._socket.unref(); + } else { + this._socket.destroy(); + } };