A Moment for Times
InfluxDB is a time series database, so it would make sense that the concept of time is moderately important when dealing with it.
By default, Influx will store all dates you give to it as a nanosecond-precision timestamp, whereas in JavaScript, most of the time we're dealing with millisecond precision timestamps, which we get from Date.now()
or myDate.getTime()
. This presents a bit of a problem for us JavaScripters, since nanosecond-precision timestamps are stored as 64-bit unsigned integers that JavaScript simply cannot represent accurately.
➜ node-influx git:(master) node
> 1475985480231035677
1475985480231035600
This module tries to make dates as easy as possible for you to deal with, and out of the box everything should "just work".
There are three places that dates can get passed around:
- Dates coming from Influx queries, like
select * from my_series
- Dates being interpolated into Influx queries
- Dates being used when writing points on the line protocol, via
.writePoints()
or.writeMeasurement()
To deal with this, we introduce a new type called NanoDate. These dates behave just like the normal Date
type, but have two additional methods: .getNanoTime()
and .getNanoISOString()
. They behave just like the normal .getTime()
and getISOString
methods, but they both return nanosecond-precision strings instead of millisecond-precision numbers and timestamps.
expect(myNanoDate.getTime()).to.equal(1475985480231)
expect(myNanoDate.getNanoTime()).to.equal('1475985480231035677')
expect(myNanoDate.toISOString()).to.equal('2016-10-09T03:58:00.231Z')
expect(myNanoDate.toNanoISOString()).to.equal('2016-10-09T03:58:00.231035677Z')
All times returned from Influx queries are parsed to INanoDates. For example, you can do something like the following:
influx.query('select * from perf').then(results => {
results.forEach(row => console.log(`Used ${row.cpu} at ${row.time.toNanoISOString()}`))
})
When writing data to Influx, all write methods accept INanoDates in all situations. This means if you select data from Influx and want to update a data point, you can pass that time right back into the write
method. (Remember, points within series are unique by their time!) If you have a nanosecond timestamp from some external source, you can convert it to a INanoDate using toNanoDate
.
import { toNanoDate } from 'influx'
const myNanoDate = toNanoDate('1475985480231035600')
expect(myNanoDate.getTime()).to.equal(1475985480231)
expect(myNanoDate.getNanoTime()).to.equal('1475985480231035600')
expect(myNanoDate.toNanoISOString()).to.equal('2016-10-09T03:58:00.231035600Z')
Finally, if you want to embed a INanoDate into an Influx query, you should should use toNanoISOString
to so do:
influx.query(`select * from perf where time > "${myNanoDate.toNanoISOString()}"`)
Anything unclear? Have some remaining questions or found a bug? Feel free to open an issue, we respond quickly!
Browser Setup
For Node.js, influx
can be installed and you can use it out of the box!
npm install --save influx@next
For browsers, this will also work provided you have a bundler which can polyfill Node modules, such as Browserify, Webpack, Jspm, or Rollup with rollup-plugin-node-resolve.
However, at the time of writing, request timeouts will not work by default on any of these platforms until they update to the latest Node API changes. If this is an important feature for you, we recommend that you instruct your bundler to use our patched version of stream-http
as your http
polyfill. You can install it via:
npm install --save node-influx/stream-http
You can tell Webpack to use this module by adding the following section in your webpack.config.js
:
const http = path.resolve(__dirname, 'node_modules/stream-http/index.js')
module.exports = {
resolve: {
alias: { http, https: http }
}
// the rest of your webpack config
}
You can tell Browserify to use this module by adding the following into your build config:
const http = require('stream-http')
browserify(myFiles, {
builtins: Object.assign(
{}, require('browserify/lib/builtins'),
{ http, https: http }
)
// the rest of your browserify config
})
Testing
influx
is tested primarily with a suite of unit tests in additional to functional tests which require an InfluxDB instance to run. The recommended way of running Influx is use their official Docker image:
docker run -d -p 8083:8083 -p 8086:8086 --expose 8090 --expose 8099 influxdb
Alternately, you can use a local installation of the package. If you would like to contribute and don't want to set up a full Influx testing environment, you can run solely unit tests and linting via npm-run-all test:unit test:lint
, which do not require anything other than an npm install
.
When running tests you can configure where Influx lives by setting an environment variable which is a valid host to pass into the IClusterConfig object.
➜ node-influx git:(master) export INFLUX_HOST='{"host":"127.0.0.1","port":12345}'
➜ node-influx git:(master) npm test
You can run npm run test:watch
to watch files and automatically re-run tests when they change.
Contributing
We'd like to encourage you to contribute to the repository. You can do this by making an issue ticket or, even better, submitting a patch via a pull request.
We try to make it as easy as possible for you but there are a few things to consider when contributing. The following guidelines for contribution should be followed if you want to submit a pull request:
How to prepare
- You need a GitHub account
- Submit an issue ticket for your issue if there is not one yet.
- Describe the issue and include steps to reproduce if it's a bug.
- Ensure to mention the earliest version that you know is affected.
- If you are able and want to fix this, fork the repository on GitHub
Make Changes
- In your forked repository, create a topic branch for your upcoming patch. (e.g.
feature--autoplay
orbugfix--ios-crash
)- Usually this is based on the master branch.
- Create a branch based on master;
git branch fix/master/my_contribution master
then checkout the new branch withgit checkout fix/master/my_contribution
. Please avoid working directly on themaster
branch.
- Make sure you follow the established coding style. You can run
npm run test:lint
to verify you're all set. - Make use of the
.editorconfig
-file if provided with the repository. - Make commits of logical units and describe them properly, documenting anything new that you add.
- If possible, submit tests to your patch / new feature so it can be tested easily.
- Assure nothing is broken by running all the tests via
npm test
.
Submit Changes
- Push your changes to a topic branch in your fork of the repository.
- Open a pull request to the this repository and choose the right original branch you want to patch.
- If not done in commit messages (which you really should do) please reference and update your issue with the code changes. But please do not close the issue yourself.
- We'll review your changes and respond soon, usually within a day!