Axibase Time Series Database API Client for Node.js
Latest commit 4e66073 Nov 23, 2016 @unrealwork unrealwork update version

CircleCI Code Climate codecov

ATSD Node.js API client

The ATSD API Client for Node.js enables developers to easily interact with the Axibase Time Series Database through its Data and Meta API.


This client can be installed using npm:

$ sudo npm install atsd-api


ATSD Client

The base class is ATSDClient, an instance which can be created using ATSDClient(options) where options is an object:

Key Description Required
url full ATSD url with port yes
user username yes
password password yes
strictSSL requires SSL certificate validation no, true by default

The purpose of ATSDClient is to make general requests to ATSD. It has an asynchronous method request, as well as separate methods for each type of request:

ATSDClient.request(method, path, params, payload, callback)
ATSDClient.getRequest(path, params, payload, callback)
ATSDClient.postRequest(path, params, payload, callback)
ATSDClient.putRequest(path, params, payload, callback)
ATSDClient.patchRequest(path, params, payload, callback)
ATSDClient.deleteRequest(path, params, payload, callback)

The arguments are as follows:

Argument Type Description
method string Request method: GET, POST, PUT, PATCH, or DELETE.
path string Path to be added to base ATSD url, i.e. metrics turns into atsd_server/api/v1/metrics.
params object url query string parameters.
payload object json request paylod.
callback function(error, response, body) Callback function.

API Methods

Entities, Metrics, Properties, Alerts, and Series are all subclasses of ATSDClient and use the same constructor. They hold the implementations of ATSD API methods:

Data API

API method Client function
Series Series(options)
Series: Query Series.query(payload, callback)
Series: Insert Series.insert(payload, callback)
Alerts Alerts(options)
Alerts: Query Alerts.query(payload, callback)
Alerts: Update Alerts.update(payload, callback)
Alerts: History Query Alerts.historyQuery(payload, callback)
Alerts: Delete Alerts.delete(payload, callback)
Properties Properties(options)
Properties: Query Properties.query(payload, callback)
Properties: Type Query Properties.typeQuery(payload, callback)
Properties: Insert Properties.insert(payload, callback)
Properties: Delete Properties.delete(payload, callback)
Messages Messages(options)
Messages: Query Messages.query(payload, callback)
Messages: Insert Messages.insert(payload, callback)

Meta API

API method Client function
Entities Entities(options)
Entities: List Entities.list(params, callback)
Entity: Get Entities.get(entity, params, callback)
Entity: Create or Replace Entities.create(entity, payload, callback)
Entity: Update Entities.update(entity, payload, callback)
Entity: Delete Entities.delete(entity, callback)
Metrics Metrics(options)
Metrics: List Metrics.list(params, callback)
Metrics: Get Metrics.get(entity, params, callback)
Metric: Create or Replace Metrics.create(metric, payload, callback)
Metric: Update Metrics.update(metric, payload, callback)
Metric: Delete Metrics.delete(metric, callback)
Entity Groups EntityGroups(options)
Entity Groups: List EntityGroups.list(params, callback)
Entity Groups: Get EntityGroups.get(entity, params, callback)
Entity Groups: Create or Replace EntityGroups.create(entity-group, payload, callback)
Entity Groups: Update EntityGroups.update(entity-group, payload, callback)
Entity Groups: Delete EntityGroups.delete(entity-group, callback)
Entity Groups: GetEntities EntityGroups.getEntities(entity, params, callback)
Entity Groups: AddEntities EntityGroups.addEntities(entity-group, payload, callback)
Entity Groups: ReplaceEntities EntityGroups.setEntities(entity-group, payload, callback)
Entity Groups: DeleteEntities EntityGroups.deleteEntities(entity-group, payload, callback)

There is also a number of convenience functions dedicated to making some requests easier to execute. Unlike the functions listed above, they don't replicate the signatures of ATSD API methods.

Client function Equivalent to Note
Series.query(args, callback) Series.get(payload, callback) with payload being {'queries': [args]} timeFormat for response is set to iso; instead of {'series': [...]} returns [...].
Series.queryDetail(metric, entity, tags, startTime, endTime, callback) Series.query(args, callback) with args being an object consisting of metric, entity etc. startTime and endTime can be a timestamp in milliseconds, a string (ATSD API's startDate and endDate), or a Date object.
Series.queryStatistic(metric, entity, tags, startTime, endTime, statistic, period, callback) Same as above. Same as above.
Series.insertData(metric, entity, tags, data, callback) Series.insert(payload, callback) with payload being [inserts] where inserts is an object consisting of metric, entity etc.

For statistics and units used to aggregate the data through series queries, there exist corresponding "enumerations" in class Series: Series.statistic and Series.unit.


var atsd_api = require('atsd-api');

var options = {
  url: '...',
  user: '...',
  password: '...'

var entities   = new atsd_api.Entities(options);
var metrics    = new atsd_api.Metrics(options);
var series     = new atsd_api.Series(options);
var properties = new atsd_api.Properties(options);
var alerts     = new atsd_api.Alerts(options);



// inserting series data without versions
series.insertData('temperature', 'sensor001', {}, [
    {'d': '2015-11-23T08:19:00.000Z', 'v': 51},
    {'d': '2015-11-23T08:20:00.000Z', 'v': 52}
  ], function(error_insert, response, _) {
    if (!error_insert) {
      console.log('Insert: ' + response.statusCode);
> Insert: 200
// inserting series data with versions
series.insertData('temperature', 'sensor001', {}, [
    {'d': '2015-11-23T08:21:00.000Z', 'v': 50, 'version': {'status': 'provisional', 'source': 'gateway-1'}}
  ], function(error_insert, response, _) {
    if (!error_insert) {
      console.log('Insert with versions: ' + response.statusCode);
> Insert with versions: 200
// retrieving data without versions
  'temperature', 'sensor001', {},
  'current_day', 'next_day',
  function(error_detail, _, body) {
    if (!error_detail) {
      console.log('Detail: ' + JSON.stringify(body));
> Detail: [{"entity":"sensor001","metric":"temperature1","tags":{},"type":"HISTORY","aggregate":{"type":"DETAIL"},"data":[{"d":"2015-11-23T08:19:00.000Z","v":51},{"d":"2015-11-23T08:20:00.000Z","v":52},{"d":"2015-11-23T08:21:00.000Z","v":50}]}]
// retrieving data with versions
    'metric': 'temperature',
    'entity': 'sensor001',
    'startDate': 'current_day',
    'endDate': 'next_day',
    'versioned': true
  }, function(error_detail, _, body) {
    if (!error_detail) {
      console.log('Detail with versions: ' + JSON.stringify(body));
> Detail with versions: [{"entity":"sensor001","metric":"temperature1","tags":{},"type":"HISTORY","aggregate":{"type":"DETAIL"},"data":[{"d":"2015-11-23T08:19:00.000Z","v":51},{"d":"2015-11-23T08:20:00.000Z","v":52},{"d":"2015-11-23T08:21:00.000Z","v":50,"version":{"source":"gateway-1","status":"provisional"}}]}]
// retrieving yesterday's data averaged by 6 hours
  'cpu_busy', 'nurswgvml007', {},
  'previous_day', 'current_day',
  Series.statistic.AVG, {'count': 6, 'unit': Series.unit.HOUR},
  function(error, _, body) {
    if (!error) {
      console.log('Average: ' + JSON.stringify(body));
> Average: [{"entity":"nurswgvml007","metric":"cpu_busy","tags":{},"type":"HISTORY","aggregate":{"type":"AVG","period":{"count":6,"unit":"HOUR"}},"data":[{"d":"2015-11-22T00:00:00.000Z","v":18.35364243323441},{"d":"2015-11-22T06:00:00.000Z","v":14.058392592592591},{"d":"2015-11-22T12:00:00.000Z","v":13.460140845070423},{"d":"2015-11-22T18:00:00.000Z","v":13.851594955489615}]}]


// updating alerts 'evt-1' and 'evt-2'
      'action': 'update',
      'fields': {
        'acknowledge': true
      'alerts': [
        {'id': 'evt-1'},
        {'id': 'evt-2'}
  function(error, response, _) {
    if (!error) {
      console.log('Update: ' + response.statusCode);
> Update: 200


// getting property types of entity 'atsd'
entities.getPropertyTypes('atsd', {}, function (error, _, body) {
  if (!error) {
    console.log('Property types: ' + JSON.stringify(body));
> Property types: ["jfs","system","disk","cpu","java_method","configuration","network"]
// inserting a property
      'tags':{'name-1': 'value-1'}
  function(error_insert, response, _) {
    if (!error_insert) {
      console.log('Insert: ' + response.statusCode);

      // retrieving the same property
        'entity-1', 'type-1', {},
        function (error_get, _, body) {
          if (!error_get) {
            console.log('Properties by entity and type: ' + JSON.stringify(body));
> Insert: 200
> Properties by entity and type: [{"type":"type-1","entity":"entity-1","key":{"server_name":"server","user_name":"system"},"tags":{"name-1":"value-1","name.1":"value-1"},"timestamp":1448122917843}]

Series Dump

entities.getAll({}, function (error_entities, _, body_entities) {
  if (!error_entities) {
    // choosing the first entity
    var entity = body_entities[0]['name'];

    console.log('First entity: ' + entity);

    // retrieving all metrics for that entity
    metrics.getByEntity(entity, {}, function (error_metrics, _, body_metrics) {
      if (!error_metrics) {
        // choosing the first metric
        var metric = body_metrics[0]['name'];

        console.log('First metric: ' + metric);

        // getting data for the chosen entity and metric
          metric, entity, {},
          'current_hour', 'current_hour + 10 * second',
          function (error_series, _, body_series) {
            if (!error_series) {
              var data = body_series[0]['data'];

              console.log('Data: ' + JSON.stringify(data));
> First entity: atsd
> First metric: actions_per_minute
> Data: [{"d":"2015-11-21T14:00:02.497Z","v":0}]