juttle-opentsdb-adapter
Advanced tools
Comparing version 0.2.0 to 0.2.1
# Change Log | ||
This file documents all notable changes to the juttle-opentsdb-adapter. The release numbering uses [semantic versioning](http://semver.org). | ||
## 0.2.1 | ||
Released 2016-03-09 | ||
### Major Changes | ||
- Fixed live tests for juttle v0.6.0 | ||
## 0.2.0 | ||
@@ -5,0 +11,0 @@ Released 2016-02-24 |
@@ -10,3 +10,2 @@ 'use strict'; | ||
let Promise = require('bluebird'); | ||
let client = Promise.promisifyAll(opentsdb.client()); | ||
let socket = Promise.promisifyAll(OpentsdbSocket()); | ||
@@ -21,3 +20,3 @@ | ||
static getConnectionDetails() { | ||
static getConnectionDetails(client) { | ||
return _.pick(client, '_host', '_port'); | ||
@@ -30,2 +29,4 @@ } | ||
let client = Promise.promisifyAll(opentsdb.client()); | ||
if (conf.host) { | ||
@@ -37,2 +38,3 @@ client.host(conf.host); | ||
} | ||
return client; | ||
@@ -51,3 +53,3 @@ } | ||
return new Promise((resolve, reject) => { | ||
this.getClient(id); | ||
var client = this.getClient(id); | ||
@@ -54,0 +56,0 @@ if (socket._socket) { |
'use strict'; | ||
/* global JuttleAdapterAPI */ | ||
let ASTVisitor = JuttleAdapterAPI.compiler.ASTVisitor; | ||
let StaticFilterCompiler = JuttleAdapterAPI.compiler.StaticFilterCompiler; | ||
let errors = JuttleAdapterAPI.errors; | ||
class FilterOpenTSDBCompiler extends ASTVisitor { | ||
class FilterOpenTSDBCompiler extends StaticFilterCompiler { | ||
@@ -16,5 +16,2 @@ constructor(query) { | ||
} | ||
visitExpressionFilterTerm(node, query) { | ||
return this.visit(node.expression, query); | ||
} | ||
visitBinaryExpression(node, query) { | ||
@@ -28,25 +25,24 @@ //XXX The latest stable release v2.1 does not support complex filter expressions: | ||
} else if (node.operator === '==') { | ||
return query.tags(this.visit(node.left), this.visit(node.right)); | ||
return this.handleEqualOperator(node, query); | ||
} | ||
this.throwUnsupported(); | ||
this.featureNotSupported(); | ||
} | ||
visitUnaryExpression(node, query) { | ||
switch (node.operator) { | ||
case '*': | ||
return this.visit(node.expression, query); | ||
default: | ||
this.throwUnsupported(); | ||
handleEqualOperator(node, query) { | ||
let left = this.visit(node.left); | ||
if (left === 'name') { | ||
return query.metric(this.visit(node.right)); | ||
} else { | ||
return query.tags(left, this.visit(node.right)); | ||
} | ||
} | ||
visitStringLiteral(node) { | ||
return String(node.value); | ||
} | ||
visitArrayLiteral(node) { | ||
this.throwUnsupported(); | ||
} | ||
visitField(node) { | ||
return node.name; | ||
} | ||
throwUnsupported() { | ||
featureNotSupported() { | ||
throw new errors.compileError('TYPE-ERROR', { | ||
@@ -53,0 +49,0 @@ message: "Only AND and '=' operators with string values are supported in the optimized filter expression." |
@@ -34,9 +34,5 @@ 'use strict'; | ||
if (params.filter_ast) { | ||
this.addFilters(params.filter_ast); | ||
} | ||
this.addFilters(params.filter_ast); | ||
this.total_emitted_points = 0; | ||
this.query.metric(options.name); | ||
} | ||
@@ -49,5 +45,2 @@ | ||
validateOptions(options) { | ||
if (!_.has(options, 'name')) { | ||
throw this.compileError('MISSING-OPTION', { option: "name" }); | ||
} | ||
if (!_.has(options, 'from')) { | ||
@@ -63,4 +56,10 @@ throw this.compileError('MISSING-OPTION', { option: "from" }); | ||
addFilters(filter_ast) { | ||
let compiler = new FilterCompiler(this.query); | ||
return compiler.compile(filter_ast); | ||
if (filter_ast) { | ||
let compiler = new FilterCompiler(this.query); | ||
return compiler.compile(filter_ast); | ||
} | ||
if (!this.query.metric()) { | ||
throw new Error('filter expression must contain a metric name'); | ||
} | ||
} | ||
@@ -90,5 +89,5 @@ | ||
.catch(Promise.TimeoutError, (e) => { | ||
throw this.runtime_error('INTERNAL-ERROR', { | ||
throw this.runtimeError('INTERNAL-ERROR', { | ||
error: 'timed out trying to connect to database: ' | ||
+ JSON.stringify(db.getConnectionDetails()) | ||
+ JSON.stringify(db.getConnectionDetails(this.client)) | ||
}); | ||
@@ -98,3 +97,3 @@ }) | ||
if (err && err.status === 502) { | ||
let connectionInfo = db.getConnectionDetails(); | ||
let connectionInfo = db.getConnectionDetails(this.client); | ||
throw this.runtimeError('INTERNAL-ERROR', { | ||
@@ -101,0 +100,0 @@ error: 'could not connect to database: ' + JSON.stringify(connectionInfo) |
@@ -80,3 +80,3 @@ 'use strict'; | ||
if (pt[this.valueField]) { | ||
if (pt.hasOwnProperty(this.valueField)) { | ||
datum.value(pt[this.valueField]); | ||
@@ -94,2 +94,7 @@ pt[this.valueField] = undefined; | ||
if (_.isEmpty(datum.tags())) { | ||
this.trigger('error', new Error('at least one tag is required to write a point')); | ||
return; | ||
} | ||
this.logger.debug('writing', datum); | ||
@@ -96,0 +101,0 @@ return this.socket.writeAsync( 'put ' + datum.toString() + '\n'); |
{ | ||
"name": "juttle-opentsdb-adapter", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"description": "OpenTSDB Adapter for Juttle", | ||
@@ -26,5 +26,8 @@ "keywords": [ | ||
"bluebird-retry": "^0.5.3", | ||
"opentsdb": "^0.5.5", | ||
"opentsdb": "juttle/opentsdb.js#temp-client", | ||
"opentsdb-socket": "0.0.2", | ||
"underscore": "^1.8.3" | ||
"underscore": "^1.8.3", | ||
"opentsdb-client": "juttle/client#allow-unix-time-zero", | ||
"opentsdb-datum": "juttle/datum#allow-value-zero", | ||
"opentsdb-validate-time": "juttle/validate-time#unix-time-before-2001" | ||
}, | ||
@@ -31,0 +34,0 @@ "devDependencies": { |
@@ -12,3 +12,3 @@ # Juttle OpenTSDB Adapter | ||
```juttle | ||
read opentsdb -from :30 minutes ago: -name "df.bytes.used" | ||
read opentsdb -from :30 minutes ago: name = "df.bytes.used" | ||
``` | ||
@@ -18,3 +18,3 @@ | ||
```juttle | ||
read opentsdb -debug true -from :30 minutes ago: -name "df.bytes.used" | ||
read opentsdb -debug true -from :30 minutes ago: name = "df.bytes.used" | ||
``` | ||
@@ -24,3 +24,3 @@ | ||
```juttle | ||
read opentsdb -from :30 minutes ago: -name "df.bytes.used" host = "test_host_name" | ||
read opentsdb -from :30 minutes ago: name = "df.bytes.used" host = "test_host_name" | ||
``` | ||
@@ -63,3 +63,2 @@ | ||
-----|------|----------|------------- | ||
`name` | string | yes | name of the metric to query | ||
`debug` | boolean | no | output a query url corresponding to current set of options and filters | ||
@@ -76,2 +75,4 @@ `from` | moment | yes | select points after this time (inclusive) | ||
A metric name is required in the filter expression: `name = "df.bytes.used"`. | ||
### Write options | ||
@@ -78,0 +79,0 @@ |
@@ -1,3 +0,4 @@ | ||
require('./shared'); | ||
var config = require('./shared'); | ||
var _ = require('underscore'); | ||
var expect = require('chai').expect; | ||
@@ -10,3 +11,3 @@ var TestUtils = require("./utils"); | ||
return check_juttle({ | ||
program: 'read opentsdb -id "fake" -from :30 minutes ago: -name "' + TestUtils.metric_name + '"' | ||
program: 'read opentsdb -id "fake" -from :30 minutes ago: name = "' + TestUtils.metric_name + '"' | ||
}) | ||
@@ -17,2 +18,17 @@ .then(function(result) { | ||
}); | ||
it('2 reads with different dbs confs', function() { | ||
return check_juttle({ | ||
program: 'read opentsdb -from :-30m: -to :now: name = "' + TestUtils.metric_name + '" | view json;' + | ||
'read opentsdb -id "fake" -from :30 minutes ago: name = "' + TestUtils.metric_name + '";', | ||
realtime: true | ||
}, 3000) | ||
.then(function(result) { | ||
expect(result.errors).to.have.length(1); | ||
expect(result.errors[0]).to.contain('connect to database'); | ||
var fakeConfig = _.findWhere(config, {id: 'fake'}); | ||
expect(result.errors[0]).to.contain(fakeConfig.host); | ||
}); | ||
}); | ||
}); |
@@ -6,2 +6,3 @@ require('./shared'); | ||
var check_juttle = TestUtils.check_juttle; | ||
var check_juttle_error = TestUtils.check_juttle_error; | ||
var check_juttle_success = TestUtils.check_juttle_success; | ||
@@ -11,5 +12,13 @@ var _ = require('underscore'); | ||
describe('test tag filters', function () { | ||
it('error when no metric name indicated', function() { | ||
return check_juttle_error({ | ||
program: 'read opentsdb -from :30 minutes ago:' | ||
}) | ||
.catch(function(err) { | ||
expect(err.message).to.contain('filter expression must contain a metric name'); | ||
}); | ||
}); | ||
it('by single tag', function() { | ||
return check_juttle_success({ | ||
program: 'read opentsdb -from :30 minutes ago: -name "' + TestUtils.metric_name + '" host = "123"' | ||
program: 'read opentsdb -from :30 minutes ago: name = "' + TestUtils.metric_name + '" host = "123"' | ||
}) | ||
@@ -22,3 +31,3 @@ .then(function(result) { | ||
return check_juttle_success({ | ||
program: 'read opentsdb -debug true -from :30 minutes ago: -name "' | ||
program: 'read opentsdb -debug true -from :30 minutes ago: name = "' | ||
+ TestUtils.metric_name + '" host = "123" AND special = "234"' | ||
@@ -32,3 +41,3 @@ }) | ||
return check_juttle_success({ | ||
program: 'read opentsdb -from :30 minutes ago: -name "' | ||
program: 'read opentsdb -from :30 minutes ago: name = "' | ||
+ TestUtils.metric_name + '" host = "123" AND ' | ||
@@ -43,3 +52,3 @@ + 'nonsense = "gibberish"' | ||
return check_juttle_success({ | ||
program: 'read opentsdb -from :30 minutes ago: -name "' | ||
program: 'read opentsdb -from :30 minutes ago: name = "' | ||
+ TestUtils.metric_name + '" host = "888"' | ||
@@ -53,3 +62,3 @@ }) | ||
return check_juttle_success({ | ||
program: 'read opentsdb -from :30 minutes ago: -name "' | ||
program: 'read opentsdb -from :30 minutes ago: name = "' | ||
+ TestUtils.metric_name + '" host = "*"' | ||
@@ -67,3 +76,3 @@ }) | ||
return check_juttle_success({ | ||
program: 'read opentsdb -from :30 minutes ago: -name "' | ||
program: 'read opentsdb -from :30 minutes ago: name = "' | ||
+ TestUtils.metric_name + '" host = "123|456"' | ||
@@ -79,3 +88,3 @@ }) | ||
return check_juttle({ | ||
program: 'read opentsdb -from :30 minutes ago: -name "' + TestUtils.metric_name + '" host != "123"' | ||
program: 'read opentsdb -from :30 minutes ago: name = "' + TestUtils.metric_name + '" host != "123"' | ||
}) | ||
@@ -82,0 +91,0 @@ .then(function() { |
@@ -6,10 +6,7 @@ require('./shared'); | ||
var check_juttle_success = TestUtils.check_juttle_success; | ||
var check_juttle_error = TestUtils.check_juttle_error; | ||
var logger = require('juttle/lib/logger').getLogger('opentsdb-options'); | ||
describe('test options', function () { | ||
it('-debug and -name', function() { | ||
it('-debug', function() { | ||
return check_juttle_success({ | ||
program: 'read opentsdb -debug true -from :30 minutes ago: -name "' + TestUtils.metric_name + '"' | ||
program: 'read opentsdb -debug true -from :30 minutes ago: name = "' + TestUtils.metric_name + '"' | ||
}) | ||
@@ -21,5 +18,5 @@ .then(function(result) { | ||
}); | ||
it('-name and -from indicated', function() { | ||
it('-from indicated', function() { | ||
return check_juttle_success({ | ||
program: 'read opentsdb -from :30 minutes ago: -name "' + TestUtils.metric_name + '"' | ||
program: 'read opentsdb -from :30 minutes ago: name = "' + TestUtils.metric_name + '"' | ||
}) | ||
@@ -33,50 +30,2 @@ .then(function(result) { | ||
}); | ||
it('no -name indicated', function() { | ||
return check_juttle_error({ | ||
program: 'read opentsdb -from :30 minutes ago:' | ||
}) | ||
.catch(function(err) { | ||
expect(err.message).to.contain('required option name'); | ||
}); | ||
}); | ||
it('live', function() { | ||
this.timeout(15000); | ||
var numFuturePoints; | ||
return TestUtils.addFuturePoints() | ||
.then(function(num_future_points) { | ||
numFuturePoints = num_future_points; | ||
var wait = numFuturePoints * 1000 + 2000; | ||
logger.info('Performing live query, waiting ms:', wait); | ||
return check_juttle_success({ | ||
program: `read opentsdb -from :now: -to :end: -name "${TestUtils.metric_name}"`, | ||
realtime: true | ||
}, wait); | ||
}) | ||
.then(function(result) { | ||
expect(result.sinks.table).to.have.length(numFuturePoints); | ||
}); | ||
}); | ||
it('live super query', function() { | ||
this.timeout(10000); | ||
var numFuturePoints; | ||
return TestUtils.addFuturePoints() | ||
.then(function(num_future_points) { | ||
numFuturePoints = num_future_points; | ||
var wait = numFuturePoints * 1000 + 2000; | ||
logger.info('Performing super live query, waiting ms:', wait); | ||
return check_juttle_success({ | ||
program: `read opentsdb -from :-1m: -to :end: -name "${TestUtils.metric_name}"`, | ||
realtime: true | ||
}, wait); | ||
}) | ||
.then(function(result) { | ||
expect(result.sinks.table).to.have.length.gt(numFuturePoints); | ||
}); | ||
}); | ||
}); |
var TestUtils = require("./utils"); | ||
var config = [ | ||
{ | ||
id: "default", | ||
host: '127.0.0.1', | ||
port: 4242, | ||
path: "./" | ||
}, { | ||
id: "fake", | ||
host: '128.7.7.8', //fake | ||
port: 2345, | ||
path: './' | ||
} | ||
]; | ||
config.path = './'; | ||
before(function() { | ||
var config = [ | ||
{ | ||
id: "default", | ||
host: '127.0.0.1', | ||
port: 4242, | ||
path: "./" | ||
}, { | ||
id: "fake", | ||
host: '128.7.7.8', //fake | ||
port: 2345, | ||
path: './' | ||
} | ||
]; | ||
config.path = './'; | ||
@@ -22,1 +23,3 @@ TestUtils.init(config); | ||
}); | ||
module.exports = config; |
@@ -17,6 +17,7 @@ var juttle_test_utils = require('juttle/test').utils; | ||
check_juttle: function(params, deactivateAfter) { | ||
return check_juttle(params, deactivateAfter); | ||
params.deactivateAfter = deactivateAfter; | ||
return check_juttle(params); | ||
}, | ||
check_juttle_success: function(params, deactivateAfter) { | ||
return check_juttle(params, deactivateAfter) | ||
return TestUtils.check_juttle(params, deactivateAfter) | ||
.then(function(res) { | ||
@@ -29,3 +30,3 @@ expect(res.errors[0]).to.equal(undefined); | ||
check_juttle_error: function(params, deactivateAfter) { | ||
return check_juttle(params, deactivateAfter) | ||
return TestUtils.check_juttle(params, deactivateAfter) | ||
.then(function(res) { | ||
@@ -75,3 +76,3 @@ throw new Error('This error should never occur'); | ||
expect(writeResult.errors[0]).equals(undefined); | ||
expect(writeResult.warnings).to.have.length(0); | ||
expect(writeResult.warnings[0]).equals(undefined); | ||
expect(writeResult.sinks).to.not.include.keys('table', 'logger'); | ||
@@ -81,7 +82,7 @@ | ||
return check_juttle({ | ||
program: `read opentsdb -from :30 minutes ago: -name "${metric_name}"` | ||
program: `read opentsdb -from :30 minutes ago: name = "${metric_name}"` | ||
}).then(function(result) { | ||
expect(result.errors).to.have.length(0); | ||
expect(result.warnings).to.have.length(0); | ||
expect(result.sinks.table).to.have.length.gt(0); | ||
expect(result.errors[0]).equals(undefined); | ||
expect(result.warnings[0]).equals(undefined); | ||
expect(result.sinks.table).to.have.length.gte(numberOfMetricsExpected); | ||
@@ -88,0 +89,0 @@ var pt = result.sinks.table[0]; |
@@ -33,11 +33,2 @@ require('./shared'); | ||
}); | ||
it('error writing proc valueless point', function() { | ||
return check_juttle({ | ||
program: `emit -limit 1 | put t = "temp", name = "${metric_name}" | write opentsdb` | ||
}) | ||
.then(function(result) { | ||
expect(result.errors[0]).equals(undefined); | ||
expect(result.warnings[0]).to.contain("without metric value"); | ||
}); | ||
}); | ||
it('error writing nameless point', function() { | ||
@@ -52,3 +43,3 @@ return check_juttle({ | ||
}); | ||
it('write proc timeless point', function() { | ||
it('timeless point', function() { | ||
var timeless_metric_name = 'test.unit.' + Math.random().toString(36).slice(2,10); | ||
@@ -62,2 +53,31 @@ return check_juttle({ | ||
}); | ||
it('error writing point without any tags', function() { | ||
return check_juttle({ | ||
program: `emit -limit 1 | put value = 123, name = "${metric_name}" | keep time,value,name | write opentsdb` | ||
}) | ||
.then(function(result) { | ||
expect(result.errors[0]).to.contain('at least one tag is required to write a point'); | ||
expect(result.warnings[0]).equals(undefined); | ||
}); | ||
}); | ||
describe('metric value field', function() { | ||
var val_zero_metric_name = 'test.unit.' + Math.random().toString(36).slice(2,10); | ||
it('error writing proc valueless point', function() { | ||
return check_juttle({ | ||
program: `emit -limit 1 | put t = "temp", value = 123, name = "${val_zero_metric_name}" | write opentsdb` | ||
}) | ||
.then(function(writeResult) { | ||
return TestUtils.expectMetricsWritten(writeResult, val_zero_metric_name); | ||
}); | ||
}); | ||
it('write proc value=0 point', function() { | ||
return check_juttle({ | ||
program: `emit -limit 1 | put t = "temp", value = 0.00, name = "${val_zero_metric_name}" | write opentsdb` | ||
}) | ||
.then(function(writeResult) { | ||
return TestUtils.expectMetricsWritten(writeResult, val_zero_metric_name, 1); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
GitHub dependency
Supply chain riskContains a dependency which resolves to a GitHub URL. Dependencies fetched from GitHub specifiers are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 4 instances in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 4 instances in 1 package
45234
22
691
116
8
4
4
+ Addedopentsdb-validate-time@juttle/validate-time#unix-time-before-2001
- Removedajv@6.12.6(transitive)
- Removedasn1@0.2.6(transitive)
- Removedassert-plus@1.0.0(transitive)
- Removedasynckit@0.4.0(transitive)
- Removedaws-sign2@0.7.0(transitive)
- Removedaws4@1.13.2(transitive)
- Removedbcrypt-pbkdf@1.0.2(transitive)
- Removedcaseless@0.12.0(transitive)
- Removedcombined-stream@1.0.8(transitive)
- Removedconst-max-uint32@1.0.2(transitive)
- Removedconst-pinf-float64@1.0.0(transitive)
- Removedcore-util-is@1.0.2(transitive)
- Removeddashdash@1.14.1(transitive)
- Removeddelayed-stream@1.0.0(transitive)
- Removedecc-jsbn@0.1.2(transitive)
- Removedextend@3.0.2(transitive)
- Removedextsprintf@1.3.0(transitive)
- Removedfast-deep-equal@3.1.3(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedforever-agent@0.6.1(transitive)
- Removedform-data@2.3.3(transitive)
- Removedgetpass@0.1.7(transitive)
- Removedhar-schema@2.0.0(transitive)
- Removedhar-validator@5.1.5(transitive)
- Removedhttp-signature@1.2.0(transitive)
- Removedis-typedarray@1.0.0(transitive)
- Removedisstream@0.1.2(transitive)
- Removedjsbn@0.1.1(transitive)
- Removedjson-schema@0.4.0(transitive)
- Removedjson-schema-traverse@0.4.1(transitive)
- Removedjson-stringify-safe@5.0.1(transitive)
- Removedjsprim@1.4.2(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedoauth-sign@0.9.0(transitive)
- Removedobject-keys@1.1.1(transitive)
- Removedopentsdb@0.5.7(transitive)
- Removedopentsdb-client@0.0.4(transitive)
- Removedopentsdb-datum@1.0.0(transitive)
- Removedopentsdb-mquery@0.0.1(transitive)
- Removedopentsdb-query@0.0.2(transitive)
- Removedopentsdb-tquery@0.0.2(transitive)
- Removedopentsdb-url@0.0.2(transitive)
- Removedopentsdb-validate-time@0.0.1(transitive)
- Removedperformance-now@2.1.0(transitive)
- Removedpsl@1.15.0(transitive)
- Removedpunycode@2.3.1(transitive)
- Removedqs@6.5.3(transitive)
- Removedregex-regex@1.0.0(transitive)
- Removedrequest@2.88.2(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsshpk@1.18.0(transitive)
- Removedtough-cookie@2.5.0(transitive)
- Removedtunnel-agent@0.6.0(transitive)
- Removedtweetnacl@0.14.5(transitive)
- Removedtype-name@2.0.2(transitive)
- Removeduri-js@4.4.1(transitive)
- Removedutils-copy@1.1.1(transitive)
- Removedutils-copy-error@1.0.1(transitive)
- Removedutils-indexof@1.0.0(transitive)
- Removedutils-regex-from-string@1.0.0(transitive)
- Removeduuid@3.4.0(transitive)
- Removedvalidate.io-array@1.0.6(transitive)
- Removedvalidate.io-array-like@1.0.2(transitive)
- Removedvalidate.io-buffer@1.0.2(transitive)
- Removedvalidate.io-integer@1.0.5(transitive)
- Removedvalidate.io-integer-primitive@1.0.0(transitive)
- Removedvalidate.io-nonnegative-integer@1.0.0(transitive)
- Removedvalidate.io-number@1.0.3(transitive)
- Removedvalidate.io-number-primitive@1.0.0(transitive)
- Removedvalidate.io-string-primitive@1.0.1(transitive)
- Removedverror@1.10.0(transitive)