API Search Functions

Note: Ardexa hosts clouds in multiple regions as subdomains of ardexa.com. Where you see a reference to mycloud in this document, replace it with the appropriate subdomain for your cloud, eg: mycloud.ardexa.com -> app.ardexa.com or eur1.ardexa.com

API search functions

Our API documentation is available here: http://docs.ardexa.apiary.io/

But the three key sections relating to Search are:

Once you know the orgName you wish to search on and the relevant table you can start searching. For all the examples below, we will be using `org-name` as the orgName and `data` as the table. `data` is a default table, will appear as you install new agents and contains CPU usage.

Getting started

Simply calling on the Search endpoint with no parameters will return a sample of 50 rows sorted in chronological order (that is, ascending event_time)

https://[mycloud].ardexa.com/api/v1/tables/org-name/data/search

Fields

`fields` is an array of strings. Valid field names can be found by looking at the Table Metadata or simply examining the field names return by a default search. The standard way to encode arrays as query parameter is to include the target parameter multiple times, e.g. to select only the fields `device` and `event_time`, the query would be:

https://[mycloud].ardexa.com/api/v1/tables/org-name/data/search?fields=device&fields=event_time

Sort

`sort` takes a single field name and will sort the returned records based on this field. To sort in descending order, simply add a minus sign (hyphen) before the field name, e.g.

https://[mycloud].ardexa.com/api/v1/tables/org-name/data/search?sort=-event_time

Rows

`rows` is an integer defining the maximum number of rows you wish to receive. The maximum supported number of rows is 10,000.

https://[mycloud].ardexa.com/api/v1/tables/org-name/data/search?rows=5

Filters

`filters` is an "Array[Filter]". You can find the Filter definition in the Request section of the API documentation, just below the Parameters table. A Filter is a JSON object consisting of a field, an operator and a value. You can get a list of operators, and what they expect in the value field, from the documentation. As an Array, this parameter is treated in the same way as `fields`, simply list the `filters` parameter multiple times. The difference is that each Filter is an object, so you will need to serialize and encode the object for use as part of a URL. For example, let's say I have the following filter (keeping in mind that all filters are AND based to keep the API as simple as possible. Date fields will accept any ISO 8601 compliant date and time string):

[
  {
    "field": "event_time",
    "operator": ">=",
    "value": "2017-03-10T00:00:00Z"
  },
  {
    "field": "cpu_usage",
    "operator": ">",
    "value": 50
  }
]

This translates to the following URL:

https://[mycloud].ardexa.com/api/v1/tables/org-name/data/search?filters=%7B%22field%22%3A%22event_time%22%2C%22operator%22%3A%22%3E%3D%22%2C%22value%22%3A%222017-03-10T00%3A00%3A00Z%22%7D&filters=%7B%22field%22%3A%22cpu_usage%22%2C%22operator%22%3A%22%3E%22%2C%22value%22%3A50%7D

Generally speaking (depending on the framework or application you are using) you shouldn't have to worry about these specific implementation details like URL encoding and listing query parameters multiple times. Instead you should be able to simply build an Array of Objects and the framework will handle the rest (including parsing the JSON response). For example, curl has an inbuilt feature to encode the filters

curl -G -H "authorization: bearer $TOKEN" \
  'https://[mycloud].ardexa.com/api/v1/tables/$WORKGROUP_ID/table_name/search' \
  --data-urlencode 'filters={"field": "event_time", "operator": ">=", "value": "2017-03-10T00:00:00Z"}' \
  --data-urlencode 'filters={"field": "cpu_usage", "operator": ">", "value": 50}'

Search Operators

Below is a list of valid filter operators. Depending on the Field Type (e.g. float, string, date), some operations may not be available.

<, <=, =, >=, >

{
  "field": "action",
  "operator": "=",
  "value": "send"
}

{
  "field": "port",
  "operator": "<=",
  "value": 1024
}

LIKE

This implementation of LIKE only supports % or * as a wildcard meaning "zero or more characters"

{
  "field": "cmd",
  "operator": "LIKE",
  "value": "rm %"
}

IN, NOT IN

value is an array of exact terms

{
  "field": "action",
  "operator": "IN",
  "value": ["send", "get", "rename"]
}

BETWEEN, NOT BETWEEN

BETWEEN is an inclusive search. That is, it is equivalent to value[0] <= x <= value[1]. For date fields, remember to set the timezone variable.

{
  "field": "event_time",
  "operator": "BETWEEN",
  "value": ["2020-11-01T00:00:00", "2020-11-01T23:59:59"]
}

EXISTS, IS MISSING

Does not require a value

{
  "field": "session_id",
  "operator": "EXISTS",
}

Logical AND/OR (nested filters)

By default, all filters are evaluated using logical AND, for example:

[{
  "field": "source",
  "operator": "=",
  "value": "Black box"
}, {
  "field": "CPU usage",
  "operator": ">",
  "value": 50
}]

is equivalent to the SQL-like clause

WHERE source = "Black box" AND [CPU usage] > 50

This can be stated explicitly in the filter using an Object instead of an Array and passing the operator property along with the filters.

{
  "operator": "AND",
  "filters": [{
    "field": "source",
    "operator": "=",
    "value": "Black box"
  }, {
    "field": "CPU usage",
    "operator": ">",
    "value": 50
  }]
}

The available operators are AND and OR. Using this pattern, you can create complex nested queries. For example, let's say we wanted to monitor the computer resource usage across multiple devices, we could craft the following query

WHERE device IN ["uuidA", "uuidB"]
AND source = "Black box"
AND (
  [CPU usage] > 80 OR
  [MEM usage] > 80 OR
  [DISK usage] > 80
)

which would translate to the following Ardexa filter

{
  "operator":"AND",
  "filters": [{
    "field": "device",
    "operator": "IN",
    "value": ["uuidA", "uuidB"]
  }, {
    "field": "source",
    "operator": "=",
    "value": "Black box"
  }, {
    "operator": "OR",
    "filters": [
      { "field": "CPU usage", "operator":">", "value": 80},
      { "field": "MEM usage", "operator":">", "value": 80},
      { "field":"DISK usage", "operator":">", "value": 80}
    ]
  }
}

Timeframe

`timeframe` is a string field with the primary goal of making it easier for a human to select a window of time dynamically. For example, the timeframe "2 days ago" will translate to "event_time >= 2017-03-08T00:00:00" if I run it on the 10th of March, but it will generate a different filter if I run it a week later (I have deliberately left off the timezone offset as this translation depends on the `timezone` field). While not generally used in API-only queries, you are more than welcome to use it if it helps. Here's the help article detailing other examples of timeframe usage. You can safely ignore the `timezone` field if you are not using this feature.

Complete Example

To select the latest value for a given field (e.g. `cpu_usage`) and deviceId (e.g. `4a96a4a6-606c-438d-a236-ec76559cb415`) you would run the following search:

https://[mycloud].ardexa.com/api/v1/tables/org-name/data/search?sort=-event_time&rows=1&fields=event_time&fields=cpu_usage&filters=%7B%22field%22%3A%22device%22%2C%22operator%22%3A%22%3D%22%2C%22value%22%3A%224a96a4a6-606c-438d-a236-ec76559cb415%22%7D

Here's a quick breakdown:

  • Sort by event_time in descending (reverse chronological) order

  • Select 1 row

  • Only show the event_time and cpu_usage fields

  • Only show values for deviceId `4a96a4a6-606c-438d-a236-ec76559cb415`: {"field":"source","operator":"=","value":"4a96a4a6-606c-438d-a236-ec76559cb415"}

Last updated