From 4988652a02054f0939a1e2be001e44ec35d2efc7 Mon Sep 17 00:00:00 2001 From: Michael Cebrian Date: Mon, 28 Sep 2015 11:25:49 -0400 Subject: [PATCH 1/7] Add endpoint for JSON Update influx module to use line protocol for 0.9 Add warning logging to influx module when receiving a response from the DB Update syntax for server.coffee, remove parenthesis where not required Update version to 0.6 --- lib/influxdb.coffee | 113 +++++++++++++++++++++++++------------------- package.json | 2 +- server.coffee | 21 +++++--- 3 files changed, 79 insertions(+), 57 deletions(-) diff --git a/lib/influxdb.coffee b/lib/influxdb.coffee index 368bff5..b35885b 100644 --- a/lib/influxdb.coffee +++ b/lib/influxdb.coffee @@ -1,78 +1,93 @@ -request = require('request') -dgram = require('dgram') +request = require "request" +dgram = require "dgram" class Client constructor: (@config={}, @logger) -> do @init init: -> - useUDP = @config.get('influxdb.use_udp').get() ? false + useUDP = @config.get("influxdb.use_udp").get() ? false @send = if useUDP then @sendUDP() else @sendHTTP() write: (metrics) -> - @send @metricsJson metrics + @send @formatMetrics metrics sendHTTP: -> - version = @config.get('influxdb.version').get() ? '0.9' - host = @config.get('influxdb.host').get() ? 'localhost' - port = @config.get('influxdb.port').get() ? 8086 - database = @config.get('influxdb.database').get() ? 'bucky' - username = @config.get('influxdb.username').get() ? 'root' - password = @config.get('influxdb.password').get() ? 'root' + version = @config.get("influxdb.version").get() ? "0.9" + host = @config.get("influxdb.host").get() ? "localhost" + port = @config.get("influxdb.port").get() ? 8086 + database = @config.get("influxdb.database").get() ? "bucky" + username = @config.get("influxdb.username").get() ? "root" + password = @config.get("influxdb.password").get() ? "root" + retentionPolicy = @config.get("influxdb.retentionPolicy").get() ? "default" logger = @logger - if version == '0.8' - endpoint = 'http://' + host + ':' + port + '/db/' + database + '/series' - else - endpoint = 'http://' + host + ':' + port + '/write' - client = request.defaults - method: 'POST' - url: endpoint + + clientConfig = + method: "POST" qs: u: username p: password - (metricsJson) -> - client form: metricsJson, (error, response, body) -> - logger.log error if error + if version == "0.9" + clientConfig.url = "http://" + host + ":" + port + "/write" + clientConfig.qs.db = database + clientConfig.qs.rp = retentionPolicy + else + clientConfig.url = "http://" + host + ":" + port + "/db/" + database + "/series" + + client = request.defaults clientConfig + + (formatMetrics) -> + if version == "0.9" + metrics = formatMetrics.join "\n" + # logger.log "db: " + database + "\n" + metrics + client body: metrics, (error, response, body) -> + logger.log "Warning:" if body && body.length > 0 + logger.log "\tresponse:\n", body if body && body.length > 0 + logger.log error if error + else + metrics = JSON.stringify formatMetrics + client form: metrics, (error, response, body) -> + logger.log "Warning:" if body && body.length > 0 + logger.log "\tresponse:\n", body if body && body.length > 0 + logger.log error if error sendUDP: -> - host = @config.get('influxdb.host').get() ? 'localhost' - port = @config.get('influxdb.port').get() ? 4444 - client = dgram.createSocket 'udp4' - - (metricsJson) -> - message = new Buffer metricsJson + version = @config.get("influxdb.version").get() ? "0.9" + host = @config.get("influxdb.host").get() ? "localhost" + port = @config.get("influxdb.port").get() ? 4444 + client = dgram.createSocket "udp4" + + (formatMetrics) -> + if version == "0.9" + formatMetrics.forEach (metric) -> + message = new Buffer metric + client.send message, 0, message.length, port, host + else + message = new Buffer JSON.stringify formatMetrics + client.send message, 0, message.length, port, host - client.send message, 0, message.length, port, host + formatMetrics: (metrics) -> + version = @config.get("influxdb.version").get() ? "0.9" + data = [] - metricsJson: (metrics) -> - version = @config.get('influxdb.version').get() ? '0.9' - if version == '0.8' - data = [] - else - data = - database: @config.get('influxdb.database').get() ? 'bucky' - retentionPolicy: @config.get('influxdb.retentionPolicy').get() ? "default" - time: new Date().toISOString() - points: [] for key, desc of metrics [val, unit, sample] = @parseRow desc - if version == '0.8' - data.push + if version == "0.9" + fields = key.replace(/\\? /g, "\\ ") + fields += " value=" + parseFloat val + fields += ',unit="' + unit.replace(/"/g, '\\"') + '"' if unit + fields += ",sample=" + sample if sample + else + fields = name: key, - columns: ['value'], + columns: ["value"], points: [[parseFloat val]] - else - data.points.push - measurement: key - fields: - value: parseFloat val - unit: unit - sample: sample - # @logger.log(JSON.stringify(data, null, 2)) - JSON.stringify data + data.push fields + + data parseRow: (row) -> re = /([0-9\.]+)\|([a-z]+)(?:@([0-9\.]+))?/ diff --git a/package.json b/package.json index cb10e7c..071428b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bucky-server", - "version": "0.5.0", + "version": "0.6.0", "description": "Server to collect stats from the client", "main": "./start.js", "bin": "./start.js", diff --git a/server.coffee b/server.coffee index d1976ef..2371e01 100755 --- a/server.coffee +++ b/server.coffee @@ -5,7 +5,7 @@ _ = require 'underscore' express = require 'express' # Set cwd for config, and load config file -process.chdir(__dirname); +process.chdir __dirname config = require 'config' configWrapper = require './lib/configWrapper' @@ -14,7 +14,7 @@ load = require './lib/load' MODULES = config.modules loadLogger = -> if MODULES.logger - load(MODULES.logger, {config}) + load MODULES.logger, {config} else console @@ -22,15 +22,21 @@ loadLogger = -> # app can optionally swap it out for something else. loadConfig = (logger) -> if MODULES.config - load(MODULES.config, {config, logger}) + load MODULES.config, {config, logger} else - configWrapper(config) + configWrapper config setCORSHeaders = (req, res, next) -> res.setHeader 'Access-Control-Allow-Origin', '*' res.setHeader 'Access-Control-Allow-Methods', 'POST' res.setHeader 'Access-Control-Max-Age', '604800' res.setHeader 'Access-Control-Allow-Credentials', 'true' + res.setHeader 'Access-Control-Allow-Headers', 'content-type' + + next() + +setJSONHeader = (req, res, next) -> + req.headers['content-type'] = 'application/json' next() @@ -103,6 +109,7 @@ loadApp = (logger, loadedConfig) -> for path, handlers of routes # Bind all request modules as middleware and install the collectors + app.post "#{ path }/json", setJSONHeader, express.json(), setCORSHeaders, handlers... app.post path, parser, setCORSHeaders, handlers... app.options path, setCORSHeaders, (req, res) -> @@ -112,14 +119,14 @@ loadApp = (logger, loadedConfig) -> res.send('OK\n') port = process.env.PORT ? loadedConfig.get('server.port').get() ? 5000 - app.listen(port) + app.listen port - logger.log('Server listening on port %d in %s mode', port, app.settings.env) + logger.log 'Server listening on port %d in %s mode', port, app.settings.env Q.when(loadLogger()).then (logger) -> logger.log "Loading Config" - Q.when(loadConfig(logger)).then (loadedConfig) -> + Q.when(loadConfig logger).then (loadedConfig) -> logger.log "Loading App" loadApp(logger, loadedConfig) From 8dd81224799cc753d89275c858c91e913cd50920 Mon Sep 17 00:00:00 2001 From: Michael Cebrian Date: Tue, 29 Sep 2015 10:21:54 -0400 Subject: [PATCH 2/7] Add comments --- lib/influxdb.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/influxdb.coffee b/lib/influxdb.coffee index b35885b..a0a75ca 100644 --- a/lib/influxdb.coffee +++ b/lib/influxdb.coffee @@ -41,6 +41,7 @@ class Client (formatMetrics) -> if version == "0.9" metrics = formatMetrics.join "\n" + # uncomment to see data sent to DB # logger.log "db: " + database + "\n" + metrics client body: metrics, (error, response, body) -> logger.log "Warning:" if body && body.length > 0 @@ -48,6 +49,7 @@ class Client logger.log error if error else metrics = JSON.stringify formatMetrics + # logger.log "db: " + database + "\n" + metrics client form: metrics, (error, response, body) -> logger.log "Warning:" if body && body.length > 0 logger.log "\tresponse:\n", body if body && body.length > 0 From 82562673779fe29b3371e05369aa14d5b1ae9740 Mon Sep 17 00:00:00 2001 From: Michael Cebrian Date: Tue, 29 Sep 2015 14:34:07 -0400 Subject: [PATCH 3/7] Update README.md --- README.md | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index efeadac..4d132d3 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ to `/APP_ROOT/v1/send` on whichever port you specify. # Install nodejs # This assumes you're on a 64 bit machine wget http://nodejs.org/dist/v0.10.19/node-v0.10.19-linux-x64.tar.gz -tar xvf node-v0.10.19-linux-x64.tar.gz +tar xvf node-v0.10.19-linux-x64.tar.gz sudo ln -s `pwd`/node-v0.10.19-linux-x64/bin/{node,npm} /usr/local/bin/ # Grab a Bucky release @@ -180,7 +180,7 @@ called with like this: You are free to implement the `on` method as a dud if live reloading doesn't make sense using your config system. Take a look at [lib/configWrapper.coffee](lib/configWrapper.coffee) for an example of how a basic object can be converted (and feel free to use it). - + #### App App modules get loaded once, and can optionally provide a function to be ran with each request. @@ -236,7 +236,10 @@ module.exports = ({app, logger, config}, next) -> ### Format -If you are interested in writing new clients, the format of metric data is the same as is used by statsd: +If you are interested in writing new clients, there are two endpoints for inbound data. +The default endpoint uses the same format as statsd: + +default endpoint: `{hostname}:{port}/v1/{appRoot}` uses ``` :|[@] @@ -249,4 +252,24 @@ my.awesome.metric:35|ms some.other.metric:3|c@0.5 ``` -All requests are sent with content-type `text/plain`. +All post reqeusts sent to the default endpoint must use content-type `text/plain`. + +JSON endpoint: `{hostname}:{port}/v1/{appRoot}/json` uses + +```javascript +{ + "": "[|[@]" +} +``` + +This allows for the ':' character to be included in your metrics. This is valid for InfluxDB Line Protocol. + +For example: +```javascript +{ + "page,browser=Chrome,browserVersion=44,url=http://localhost:3000/#customHash/%7Bexample%3A%22encoded%20data%22%7D,key=domContentLoadedEventEnd": "500|ms", + "ajax,browser=Microsoft\\ Internet\\ Explorer,browserVersion=8,url=http://localhost:3000/#customHash/%7Bexample%3A%22encoded%20data%22%7D,endpoint=your/awesome/template.html,method=GET,status=200": "1|c" +} +``` + +All post request to the json endpoint will be *converted* to content-type 'application/json'. This allows for backwards compatibility with IE8 which can't send XDomainRequest with a content-type other than 'plain/text'. From c12964e7817d275b52c4871adc7add636b49fe79 Mon Sep 17 00:00:00 2001 From: Michael Cebrian Date: Wed, 30 Sep 2015 13:01:57 -0400 Subject: [PATCH 4/7] Add https support --- config/default.yaml | 12 ++++++++++-- package.json | 2 +- server.coffee | 9 ++++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/config/default.yaml b/config/default.yaml index 3d250d8..793cb72 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -2,6 +2,14 @@ server: port: 5999 appRoot: "/bucky" + # If the following values are set, bucky will run as https and parse the key and cert files + # Place the key and cert files in the BuckyServer directory with server.coffee + + # https: + # options: + # key: "key.pem" + # cert: "cert.pem" + statsd: host: 'localhost' port: 8125 @@ -18,7 +26,7 @@ influxdb: password: 'root' use_udp: false retentionPolicy: 'default' - # Acceptable version are: '0.8' and '0.9' + # All version other than '0.9' will default to '0.8' version: '0.9' @@ -32,7 +40,7 @@ modules: collectors: # Uncomment the modules that you'd like to use - # - ./modules/collectionLogger + - ./modules/collectionLogger # - ./modules/statsd # - ./modules/openTSDB # - ./modules/influxdb diff --git a/package.json b/package.json index 071428b..cef8dd2 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "express": "~3.2.5", "coffee-script": "~1.6.2", "lynx": "~0.0.11", - "underscore": "~1.4.4", + "underscore": "~1.8.3", "nopents": "~0.1.0", "config": "~0.4.27", "q": "~0.9.6", diff --git a/server.coffee b/server.coffee index 2371e01..57ba2b0 100755 --- a/server.coffee +++ b/server.coffee @@ -119,7 +119,14 @@ loadApp = (logger, loadedConfig) -> res.send('OK\n') port = process.env.PORT ? loadedConfig.get('server.port').get() ? 5000 - app.listen port + if loadedConfig.get('server.https.options').get() instanceof Object + https = require 'https' + fs = require 'fs' + httpsOptions = _.mapObject loadedConfig.get('server.https.options').get(), (v, k) -> + fs.readFileSync(v) + https.createServer(httpsOptions, app).listen port + else + app.listen port logger.log 'Server listening on port %d in %s mode', port, app.settings.env From fe2d81240989c6be1e706621368625e3c847491c Mon Sep 17 00:00:00 2001 From: Michael Cebrian Date: Wed, 30 Sep 2015 16:31:30 -0400 Subject: [PATCH 5/7] Add option to disable http mode Update documentation --- README.md | 15 +++++++++++---- config/default.yaml | 15 ++++++++------- server.coffee | 22 +++++++++++++++------- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 4d132d3..f76715f 100644 --- a/README.md +++ b/README.md @@ -57,9 +57,9 @@ to `/APP_ROOT/v1/send` on whichever port you specify. ```bash # Install nodejs # This assumes you're on a 64 bit machine -wget http://nodejs.org/dist/v0.10.19/node-v0.10.19-linux-x64.tar.gz -tar xvf node-v0.10.19-linux-x64.tar.gz -sudo ln -s `pwd`/node-v0.10.19-linux-x64/bin/{node,npm} /usr/local/bin/ +wget https://nodejs.org/dist/v4.1.1/node-v4.1.1-linux-x64.tar.gz +tar xvf node-v4.1.1-linux-x64.tar.gz +sudo ln -s `pwd`/node-v4.1.1-linux-x64/bin/{node,npm} /usr/local/bin/ # Grab a Bucky release # You should use the latest release available at https://github.com/HubSpot/BuckyServer/releases @@ -101,7 +101,14 @@ If you need more customization, you can write a module: There are a few of types of modules: - +- Server - Use to set properties of the Bucky Server + - port - Use to set the port that Bucky Server will listen to + - appRoot - Use to define the root of the endpoint + - https - Use to set options for running Bucky Server in https mode + - port - Use to specify the port for https, if not populated the http server port + 1 + - options - Use to define the certificates for https. [List of all possible options](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener) + - For all options that accept a buffer you can use the path to the file and they'll be read in + - httpsOnly - If this flag is set to true then Bucky Server will not run in http mode - Logger - Use to have Bucky log to something other than the console - Config - Use to have Bucky pull config from somewhere other than the default file - App - Use to do things when Bucky loads and/or on requests. Auth, monitoring initialization, etc. diff --git a/config/default.yaml b/config/default.yaml index 793cb72..7bedf2f 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -1,14 +1,15 @@ server: port: 5999 appRoot: "/bucky" - - # If the following values are set, bucky will run as https and parse the key and cert files - # Place the key and cert files in the BuckyServer directory with server.coffee - + # If https options are set then bucky will also listen on https # https: - # options: - # key: "key.pem" - # cert: "cert.pem" + # port: 5599 + # See full list of options at: https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener + # options: + # key: "ssl/key.pem" + # cert: "ssl/cert.pem" + # If the following is set to true then bucky server will not run in http mode + # httpsOnly: true statsd: host: 'localhost' diff --git a/server.coffee b/server.coffee index 57ba2b0..7e61950 100755 --- a/server.coffee +++ b/server.coffee @@ -3,6 +3,7 @@ Q = require 'q' _ = require 'underscore' express = require 'express' +http = require 'http' # Set cwd for config, and load config file process.chdir __dirname @@ -118,17 +119,24 @@ loadApp = (logger, loadedConfig) -> app.get "#{ APP_ROOT }/v1/health-check", (req, res) -> res.send('OK\n') - port = process.env.PORT ? loadedConfig.get('server.port').get() ? 5000 if loadedConfig.get('server.https.options').get() instanceof Object https = require 'https' fs = require 'fs' httpsOptions = _.mapObject loadedConfig.get('server.https.options').get(), (v, k) -> - fs.readFileSync(v) - https.createServer(httpsOptions, app).listen port - else - app.listen port - - logger.log 'Server listening on port %d in %s mode', port, app.settings.env + if _.isString(v) + try + fs.readFileSync(v) + catch + v + else + v + httpsPort = loadedConfig.get('server.https.port').get() ? (port + 1) + https.createServer(httpsOptions, app).listen httpsPort + logger.log "HTTPS Server listening on port %d in %s mode", httpsPort, app.settings.env + if !loadedConfig.get('server.httpsOnly').get() + port = process.env.PORT ? loadedConfig.get('server.port').get() ? 5000 + http.createServer(app).listen port + logger.log 'HTTP Server listening on port %d in %s mode', port, app.settings.env Q.when(loadLogger()).then (logger) -> From fde87e80f2b7dd9998a86785418720b363619b84 Mon Sep 17 00:00:00 2001 From: Michael Cebrian Date: Wed, 7 Oct 2015 17:12:17 -0400 Subject: [PATCH 6/7] Update configuration section of README.md Add filePath to https options in default.yaml Replace double quotes with single quotes in influxdb.coffee Update logic for loading https config, only load from file when filePath property exists --- README.md | 85 +++++++++++++++++++++++++++++++++++++-------- config/default.yaml | 6 ++-- lib/influxdb.coffee | 68 ++++++++++++++++++------------------ server.coffee | 8 ++--- 4 files changed, 112 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index f76715f..d66ae70 100644 --- a/README.md +++ b/README.md @@ -95,27 +95,82 @@ If you're not already running a stats collection service, you should take a look Most people will only need to specify [the config](config/default.yaml) they're interested in and start up the server. -If you need more customization, you can write a module: +Configuration Options: + +- `server:` {Object} +Use to set properties of the Bucky Server. + - `port:` {Number} + Use to set the port that Bucky Server will listen to. + - `appRoot:` {String} + Use to define the root of the endpoint. + - `https:` {Object} + Defines a set of options for running Bucky in https mode. + - `port:` {Number} + Use to specify the port for https, if not populated the default is the http server port + 1. + - `options:` {Object} + Use to define the options for https. + key and cert are mandatory options, here is a full [list of all available options](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener). + For all options that accept a buffer you can use the path to the file containing the option's data. + - `key:` {Object|String|Buffer} + `key` can be an Object that contains a filePath to the key file, or `key` can contain the entire String/Buffer for the key. + - `filePath:` {String} + Path to key file. The filePath is only required for loading the key from a file. + - `cert:` {Object|String|Buffer} + `cert` can be an Object that contains a filePath to the key file, or `cert` can contain the entire String/Buffer for the certificate. + - `filePath:` {String} + Path to certificate file. The filePath is only required for loading the certificate from a file. + - `httpsOnly:` {Boolean} + If this flag is set to `true` then Bucky Server will not run in http mode. + +- `statsd:` +Configuration for connecting to statsd. Only required when using statsd module. + - `host:` {String} + The hostname for your statsd server. + - `port:` {Number} + The port for your statsd server. + +- `opentsdb:` +Configuration for connecting to openTSDB. Only required when using openTSDB module. + - `host:` {String} + The hostname for your openTSDB server. + - `port:` {Number} + The port for your openTSDB server. + +- `influxdb:` +Configuration for connecting to InfluxDB. Only required when using InfluxDB module. + - `host:` {String} + The hostname for your InfluxDB server. + - `port:` {Number} + The port for your InfluxDB server. + - `database:` {String} + The database to write data to inside InfluxDB. + - `username:` {String} + A user in InfluxDB that has write permissions to the specified database. + - `password:` {String} + The password for the specified user. + - `use_udp:` {Boolean} (optional) + When this option is set to `true` Bucky Server will communicate with InfluxDB using UDP instead of TCP. + - `retentionPolicy:` {String} (optional) + The name of a retention policy that's been created in InfluxDB. + - `version:` {String} (optional) + The major version of InfluxDB that you're using (either '0.8' or '0.9'). + This defaults to '0.8' if it's omitted. + +- `modules:` +Defines which modules will load when BuckyServer starts. + - `app:` + List of core modules to be required by BuckyServer. + - `collectors:` + List of modules that will be used by the collectors module for consuming, formatting, and handling the data that's sent to BuckyServer. ### Modules There are a few of types of modules: - -- Server - Use to set properties of the Bucky Server - - port - Use to set the port that Bucky Server will listen to - - appRoot - Use to define the root of the endpoint - - https - Use to set options for running Bucky Server in https mode - - port - Use to specify the port for https, if not populated the http server port + 1 - - options - Use to define the certificates for https. [List of all possible options](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener) - - For all options that accept a buffer you can use the path to the file and they'll be read in - - httpsOnly - If this flag is set to true then Bucky Server will not run in http mode -- Logger - Use to have Bucky log to something other than the console -- Config - Use to have Bucky pull config from somewhere other than the default file +- Logger - Use to have Bucky log to something other than the console. +- Config - Use to have Bucky pull config from somewhere other than the default file. - App - Use to do things when Bucky loads and/or on requests. Auth, monitoring initialization, etc. - Collectors - Use to send Bucky data to new and exciting places. - -We can only have one logger and one config, but you can specify as many app and collector modules -as you like. +We can only have one logger and one config, but you can specify as many app and collector modules as you like. All modules follow the same basic sketch. You export a method which is called when Bucky starts up. That method is provided with as much of `{app, config, logger}` as we have diff --git a/config/default.yaml b/config/default.yaml index 7bedf2f..5923d66 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -6,8 +6,10 @@ server: # port: 5599 # See full list of options at: https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener # options: - # key: "ssl/key.pem" - # cert: "ssl/cert.pem" + # key: + # filePath: "ssl/key.pem" + # cert: + # filePath: "ssl/cert.pem" # If the following is set to true then bucky server will not run in http mode # httpsOnly: true diff --git a/lib/influxdb.coffee b/lib/influxdb.coffee index a0a75ca..cd464e9 100644 --- a/lib/influxdb.coffee +++ b/lib/influxdb.coffee @@ -1,12 +1,12 @@ -request = require "request" -dgram = require "dgram" +request = require 'request' +dgram = require 'dgram' class Client constructor: (@config={}, @logger) -> do @init init: -> - useUDP = @config.get("influxdb.use_udp").get() ? false + useUDP = @config.get('influxdb.use_udp').get() ? false @send = if useUDP then @sendUDP() else @sendHTTP() @@ -14,55 +14,55 @@ class Client @send @formatMetrics metrics sendHTTP: -> - version = @config.get("influxdb.version").get() ? "0.9" - host = @config.get("influxdb.host").get() ? "localhost" - port = @config.get("influxdb.port").get() ? 8086 - database = @config.get("influxdb.database").get() ? "bucky" - username = @config.get("influxdb.username").get() ? "root" - password = @config.get("influxdb.password").get() ? "root" - retentionPolicy = @config.get("influxdb.retentionPolicy").get() ? "default" + version = @config.get('influxdb.version').get() ? '0.9' + host = @config.get('influxdb.host').get() ? 'localhost' + port = @config.get('influxdb.port').get() ? 8086 + database = @config.get('influxdb.database').get() ? 'bucky' + username = @config.get('influxdb.username').get() ? 'root' + password = @config.get('influxdb.password').get() ? 'root' + retentionPolicy = @config.get('influxdb.retentionPolicy').get() ? 'default' logger = @logger clientConfig = - method: "POST" + method: 'POST' qs: u: username p: password - if version == "0.9" - clientConfig.url = "http://" + host + ":" + port + "/write" + if version == '0.9' + clientConfig.url = 'http://' + host + ':' + port + '/write' clientConfig.qs.db = database clientConfig.qs.rp = retentionPolicy else - clientConfig.url = "http://" + host + ":" + port + "/db/" + database + "/series" + clientConfig.url = 'http://' + host + ':' + port + '/db/' + database + '/series' client = request.defaults clientConfig (formatMetrics) -> - if version == "0.9" - metrics = formatMetrics.join "\n" + if version == '0.9' + metrics = formatMetrics.join '\n' # uncomment to see data sent to DB - # logger.log "db: " + database + "\n" + metrics + # logger.log 'db: ' + database + '\n' + metrics client body: metrics, (error, response, body) -> - logger.log "Warning:" if body && body.length > 0 - logger.log "\tresponse:\n", body if body && body.length > 0 + logger.log 'Warning:' if body && body.length > 0 + logger.log '\tresponse:\n', body if body && body.length > 0 logger.log error if error else metrics = JSON.stringify formatMetrics - # logger.log "db: " + database + "\n" + metrics + # logger.log 'db: ' + database + '\n' + metrics client form: metrics, (error, response, body) -> - logger.log "Warning:" if body && body.length > 0 - logger.log "\tresponse:\n", body if body && body.length > 0 + logger.log 'Warning:' if body && body.length > 0 + logger.log '\tresponse:\n', body if body && body.length > 0 logger.log error if error sendUDP: -> - version = @config.get("influxdb.version").get() ? "0.9" - host = @config.get("influxdb.host").get() ? "localhost" - port = @config.get("influxdb.port").get() ? 4444 - client = dgram.createSocket "udp4" + version = @config.get('influxdb.version').get() ? '0.9' + host = @config.get('influxdb.host').get() ? 'localhost' + port = @config.get('influxdb.port').get() ? 4444 + client = dgram.createSocket 'udp4' (formatMetrics) -> - if version == "0.9" + if version == '0.9' formatMetrics.forEach (metric) -> message = new Buffer metric client.send message, 0, message.length, port, host @@ -71,21 +71,21 @@ class Client client.send message, 0, message.length, port, host formatMetrics: (metrics) -> - version = @config.get("influxdb.version").get() ? "0.9" + version = @config.get('influxdb.version').get() ? '0.9' data = [] for key, desc of metrics [val, unit, sample] = @parseRow desc - if version == "0.9" - fields = key.replace(/\\? /g, "\\ ") - fields += " value=" + parseFloat val + if version == '0.9' + fields = key.replace(/\\? /g, '\\ ') + fields += ' value=' + parseFloat val fields += ',unit="' + unit.replace(/"/g, '\\"') + '"' if unit - fields += ",sample=" + sample if sample + fields += ',sample=' + sample if sample else fields = name: key, - columns: ["value"], + columns: ['value'], points: [[parseFloat val]] data.push fields @@ -97,7 +97,7 @@ class Client groups = re.exec(row) unless groups - @logger.log "Unparsable row: #{ row }" + @logger.log 'Unparsable row: #{ row }' return groups.slice(1, 4) diff --git a/server.coffee b/server.coffee index 7e61950..e8c48fa 100755 --- a/server.coffee +++ b/server.coffee @@ -123,11 +123,11 @@ loadApp = (logger, loadedConfig) -> https = require 'https' fs = require 'fs' httpsOptions = _.mapObject loadedConfig.get('server.https.options').get(), (v, k) -> - if _.isString(v) + if _.isObject v and _.has v, 'filePath' try - fs.readFileSync(v) - catch - v + fs.readFileSync v.filePath + catch e + logger.error "Unable to load file: " + v.filePath, e else v httpsPort = loadedConfig.get('server.https.port').get() ? (port + 1) From d9024e4492dfd6faed0280c6585cae6896c7551a Mon Sep 17 00:00:00 2001 From: Michael Cebrian Date: Wed, 7 Oct 2015 17:43:44 -0400 Subject: [PATCH 7/7] Update download path in readme to match tag Update package.json to match tag Add version check for influxdb --- README.md | 2 +- lib/influxdb.coffee | 4 +++- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d66ae70..7a977b3 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ sudo ln -s `pwd`/node-v4.1.1-linux-x64/bin/{node,npm} /usr/local/bin/ # Grab a Bucky release # You should use the latest release available at https://github.com/HubSpot/BuckyServer/releases -wget https://github.com/HubSpot/BuckyServer/archive/v0.3.0.tar.gz -O BuckyServer.tar.gz +wget https://github.com/HubSpot/BuckyServer/archive/v0.6.2.tar.gz -O BuckyServer.tar.gz tar xvf BuckyServer.tar.gz cd BuckyServer diff --git a/lib/influxdb.coffee b/lib/influxdb.coffee index cd464e9..c0bcdb2 100644 --- a/lib/influxdb.coffee +++ b/lib/influxdb.coffee @@ -7,7 +7,9 @@ class Client init: -> useUDP = @config.get('influxdb.use_udp').get() ? false - + version = @config.get('influxdb.version').get() ? '0.9' + throw new Error "Invalid InfluxDB Version" if version not in ['0.8', '0.9'] + @send = if useUDP then @sendUDP() else @sendHTTP() write: (metrics) -> diff --git a/package.json b/package.json index cef8dd2..963b449 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bucky-server", - "version": "0.6.0", + "version": "0.6.2", "description": "Server to collect stats from the client", "main": "./start.js", "bin": "./start.js",