General functions

now

Added in revision 1

Function now returns the current time. Time is constant across all the script, so that all operations and queries have the same reference time.

>>> now()
2019-09-01T14:05:10Z

length

Added in revision 1

Function length returns the number of elements in a str, a timeseries or a dict.

>>> length(`analytics:/path/to/data`[0])
1

merge

Added in revision 1

Function merge returns a union of all the dicts contained in a timeseries. In case of key collision, the latest entry is kept.

>>> `analytics:/path/to/data`[1]
timeseries{
        tstamp1: dict{key1: val1, key2: val2, key3: val3}
        tstamp2: dict{key1: val4, key2: val5}
}
>>> merge(_)
dict{key1: val4, key2: val5, key: val3}

deletes

Added in revision 1

Function deletes returns a timeseries of dicts used as sets of the delete keys from the input timeseries. Only works with unfiltered timeseries, as most filters remove the deletes entries. An empty dict as value means the update is a DeleteAll

  • The first and only parameter is the timeseries

>>> deletes(`analytics:/path/to/data`[200])
timeseries{
        tstamp1: dict{key1: nil, key2: nil}
        tstamp2: dict{} # this deletes all keys
}

equal

Added in revision 1

Function equal performs a cross-type equality check on the given arguments using type coercions.

  • The first argument is a value of any type

  • The second argument is a value of any type

>>> equal("1", 1)
true
>>> equal(1, true)
true
>>> equal(0, true)
false

complexKey

Added in revision 1

Function complexKey parses a string containing a literal or json object. Numerical values without floating-point will produce an integer. Numerical values with a floating point will produce a float64 (num). Boolean literals will produce a boolean (bool). Values surrounded with {} or [] will be parsed as JSON. For all cases except float64 (num) and bool, the returned value will be of type unknown (internal interpreter type), but can be used to access complex keys in dicts.

  • The first and only parameter is the str to parse

>>> complexKey("1")
int(1) # AQL type is unknown
>>> complexKey("1.2")
float64(1.2) # AQL type is num
>>> complexKey("{\"key1\": 1, \"key2\": true}")
{"key1":1,"key2":true}# AQL type is unknown
>>> complexKey("[1, 2, true]")
[1,2,true] # AQL type is unknown

Dicts functions

newDict

Added in revision 1

Function newDict returns a new empty dict.

>>> newDict()
dict{}

dictRemove

Added in revision 1

Function dictRemove removes a given key from a dict.

  • The first argument is the dict

  • The second argument is the key to remove

>>> let d = newDict()
>>> d["key"] = 1
>>> d["key2"] = 2
>>> d
dict{"key": 1, "key2": 2}
>>> dictRemove(d, "key")
>>> d
dict{"key2": 2}

dictHasKey

Added in revision 1

Function dictHasKey returns true if a dict contains the specified key, false if it doesn’t.

  • The first parameter is the dict

  • The second parameter is the key

>>> let d = newDict()
>>> d["key"] = 1
>>> d["key2"] = 2
>>> d
dict{"key": 1, "key2": 2}
>>> dictHasKey(d, "key")
true
>>> dictHasKey(d, "key3")
false

dictKeys

Added in revision 1

Function dictKeys returns a timeseries with the list of keys in a dict.

  • The first and only parameter is the dict

>>> let d = newDict()
>>> d["key"] = 1
>>> d["key2"] = 2
>>> d
dict{"key": 1, "key2": 2}
>>> dictKeys(d)
timeseries{
        0000-00-00 00:00:00.000000001: "key"
        0000-00-00 00:00:00.000000002: "key2"
}

unnestTimeseries

Added in revision 4

Function unnestTimeseries merges multiple timeseries nested in dicts, pushes them to the top level, and returns a single flattened timeseries where the former top-level dicts are now nested within the timeseries’ values. The input data is typically what a query using * wildcards would return.

  • The first and only parameter is a dict that contains timeseries, either directly in the value, or nested in more levels of dict.

Example
>>> let ts = `analytics:/Devices/*/versioned-data/interfaces/data/*/aggregate/hardware/xcvr/1m`[1m] | recmap(2, _value | field("temperature") | field("avg"))
>>> let d = newDict() | setFields("AA", ts)
>>> d
dict{AA: dict{
                HSH14280171: dict{
                        Ethernet50: timeseries{
                                start: 2022-08-16 17:10:21.217673 +0200 CEST
                                end: 2022-08-16 17:11:21.217673 +0200 CEST
                                2022-08-16 17:10:00 +0200 CEST: 34.184087816704434
                                2022-08-16 17:11:00 +0200 CEST: 34.18519049983288
                        }
                        Ethernet51: timeseries{
                                start: 2022-08-16 17:10:21.217673 +0200 CEST
                                end: 2022-08-16 17:11:21.217673 +0200 CEST
                                2022-08-16 17:10:00 +0200 CEST: 34.84759166533158
                                2022-08-16 17:11:00 +0200 CEST: 34.84247911778802
                        }
                }
                JAS17070003: dict{
                        Ethernet50: timeseries{
                                start: 2022-08-16 17:10:21.217673 +0200 CEST
                                end: 2022-08-16 17:11:21.217673 +0200 CEST
                                2022-08-16 17:10:00 +0200 CEST: 30.65325390983907
                                2022-08-16 17:11:00 +0200 CEST: 30.65664047328105
                        }
                        Ethernet51: timeseries{
                                start: 2022-08-16 17:10:21.217673 +0200 CEST
                                end: 2022-08-16 17:11:21.217673 +0200 CEST
                                2022-08-16 17:10:00 +0200 CEST: 27.58473123455124
                                2022-08-16 17:11:00 +0200 CEST: 27.597529745280074
                        }
                }
        }}
>>> unnestTimeseries(d)
timeseries{
        start: 2022-08-16 17:10:21.217673 +0200 CEST
        end: 2022-08-16 17:11:21.217673 +0200 CEST
        2022-08-16 17:10:00 +0200 CEST: dict{AA: dict{
                        HSH14280171: dict{
                                Ethernet50: 34.184087816704434
                                Ethernet51: 34.84759166533158
                        }
                        JAS17070003: dict{
                                Ethernet50: 30.65325390983907
                                Ethernet51: 27.58473123455124
                        }
                }}
        2022-08-16 17:11:00 +0200 CEST: dict{AA: dict{
                        HSH14280171: dict{
                                Ethernet50: 34.18519049983288
                                Ethernet51: 34.84247911778802
                        }
                        JAS17070003: dict{
                                Ethernet50: 30.65664047328105
                                Ethernet51: 27.597529745280074
                        }
                }}
}
>>> let b = `analytics:/Devices/JPE17191574/versioned-data/interfaces/data/Ethernet50/aggregate/hardware/xcvr/1m`[2m] | field("voltage") | field("max")
>>> let dd = newDict() | setFields("BB", b)
>>> let ddd = newDict() | setFields("DD", ts, "EE", dd)
>>> d["FF"]=ddd
>>> d
dict{
        AA: dict{
                HSH14280171: dict{
                        Ethernet50: timeseries{
                                start: 2022-08-16 17:10:21.217673 +0200 CEST
                                end: 2022-08-16 17:11:21.217673 +0200 CEST
                                2022-08-16 17:10:00 +0200 CEST: 34.184087816704434
                                2022-08-16 17:11:00 +0200 CEST: 34.18519049983288
                        }
                        Ethernet51: timeseries{
                                start: 2022-08-16 17:10:21.217673 +0200 CEST
                                end: 2022-08-16 17:11:21.217673 +0200 CEST
                                2022-08-16 17:10:00 +0200 CEST: 34.84759166533158
                                2022-08-16 17:11:00 +0200 CEST: 34.84247911778802
                        }
                }
                JAS17070003: dict{
                        Ethernet50: timeseries{
                                start: 2022-08-16 17:10:21.217673 +0200 CEST
                                end: 2022-08-16 17:11:21.217673 +0200 CEST
                                2022-08-16 17:10:00 +0200 CEST: 30.65325390983907
                                2022-08-16 17:11:00 +0200 CEST: 30.65664047328105
                        }
                        Ethernet51: timeseries{
                                start: 2022-08-16 17:10:21.217673 +0200 CEST
                                end: 2022-08-16 17:11:21.217673 +0200 CEST
                                2022-08-16 17:10:00 +0200 CEST: 27.58473123455124
                                2022-08-16 17:11:00 +0200 CEST: 27.597529745280074
                        }
                }
        }
        FF: dict{
                DD: dict{
                        HSH14280171: dict{
                                Ethernet50: timeseries{
                                        start: 2022-08-16 17:10:21.217673 +0200 CEST
                                        end: 2022-08-16 17:11:21.217673 +0200 CEST
                                        2022-08-16 17:10:00 +0200 CEST: 34.184087816704434
                                        2022-08-16 17:11:00 +0200 CEST: 34.18519049983288
                                }
                                Ethernet51: timeseries{
                                        start: 2022-08-16 17:10:21.217673 +0200 CEST
                                        end: 2022-08-16 17:11:21.217673 +0200 CEST
                                        2022-08-16 17:10:00 +0200 CEST: 34.84759166533158
                                        2022-08-16 17:11:00 +0200 CEST: 34.84247911778802
                                }
                        }
                        JAS17070003: dict{
                                Ethernet50: timeseries{
                                        start: 2022-08-16 17:10:21.217673 +0200 CEST
                                        end: 2022-08-16 17:11:21.217673 +0200 CEST
                                        2022-08-16 17:10:00 +0200 CEST: 30.65325390983907
                                        2022-08-16 17:11:00 +0200 CEST: 30.65664047328105
                                }
                                Ethernet51: timeseries{
                                        start: 2022-08-16 17:10:21.217673 +0200 CEST
                                        end: 2022-08-16 17:11:21.217673 +0200 CEST
                                        2022-08-16 17:10:00 +0200 CEST: 27.58473123455124
                                        2022-08-16 17:11:00 +0200 CEST: 27.597529745280074
                                }
                        }
                }
                EE: dict{BB: timeseries{
                                start: 2022-08-16 17:14:06.794969 +0200 CEST
                                end: 2022-08-16 17:16:06.794969 +0200 CEST
                                2022-08-16 17:14:00 +0200 CEST: 3.2909
                                2022-08-16 17:15:00 +0200 CEST: 3.2909
                                2022-08-16 17:16:00 +0200 CEST: 3.2909
                        }}
        }
}
>>> unnestTimeseries(d)
timeseries{
        start: 2022-08-16 17:10:21.217673 +0200 CEST
        end: 2022-08-16 17:16:06.794969 +0200 CEST
        2022-08-16 17:10:00 +0200 CEST: dict{
                AA: dict{
                        HSH14280171: dict{
                                Ethernet50: 34.184087816704434
                                Ethernet51: 34.84759166533158
                        }
                        JAS17070003: dict{
                                Ethernet50: 30.65325390983907
                                Ethernet51: 27.58473123455124
                        }
                }
                FF: dict{DD: dict{
                                HSH14280171: dict{
                                        Ethernet50: 34.184087816704434
                                        Ethernet51: 34.84759166533158
                                }
                                JAS17070003: dict{
                                        Ethernet50: 30.65325390983907
                                        Ethernet51: 27.58473123455124
                                }
                        }}
        }
        2022-08-16 17:11:00 +0200 CEST: dict{
                AA: dict{
                        HSH14280171: dict{
                                Ethernet50: 34.18519049983288
                                Ethernet51: 34.84247911778802
                        }
                        JAS17070003: dict{
                                Ethernet50: 30.65664047328105
                                Ethernet51: 27.597529745280074
                        }
                }
                FF: dict{DD: dict{
                                HSH14280171: dict{
                                        Ethernet50: 34.18519049983288
                                        Ethernet51: 34.84247911778802
                                }
                                JAS17070003: dict{
                                        Ethernet50: 30.65664047328105
                                        Ethernet51: 27.597529745280074
                                }
                        }}
        }
        2022-08-16 17:14:00 +0200 CEST: dict{FF: dict{EE: dict{BB: 3.2909}}}
        2022-08-16 17:15:00 +0200 CEST: dict{FF: dict{EE: dict{BB: 3.2909}}}
        2022-08-16 17:16:00 +0200 CEST: dict{FF: dict{EE: dict{BB: 3.2909}}}
}

Data Analysis Functions

groupby

Added in revision 1

Function groupby, applied to a timeseries, returns a dict with keys corresponding to the ‘group by field’ parameter, and values corresponding to the associate method and field.

The function takes 4 parameters:

  • A timeseries of dicts to apply this function to

  • The name of the ‘group by field’ (a str)

  • The name of one of the supported associative methods (a str)

  • The name of the field whose values will be operated on by the associative method (a str)

The entries in the timeseries are grouped by the values of the field from parameter 1. For each entry, the value corresponding to the associative field of parameter 4 is obtained. This results in a map with entries of the following format:

  • key: values of the ‘group by field’

  • value: lists of values of the ‘associative field’

On each of these lists, the following associative methods can be applied:

  • count: returns the length of the list (i.e. the item count)

  • max: returns the max entry in the list

  • mean: returns the mean of the values in the list

  • min: returns the min entry in the list

  • sum: returns the sum of the entries in the list

>>> `analytics:/path/to/data`[3]
timeseries{
        tstamp1: dict{"name": "name1", "value": 1}
        tstamp2: dict{"name": "name2", "value": 10}
        tstamp3: dict{"name": "name1", "value": 2}
        tstamp4: dict{"name": "name2", "value": 11}
}
>>> let ts = _
>>> groupby(ts, "name", "mean", "value")
dict{
        "name1": 1.5
        "name2": 10.5
}
>>> groupby(ts, "name", "count", "value")
dict{
        "name1": 2
        "name2": 2
}
>>> groupby(ts, "name", "sum", "value")
dict{
        "name1": 3
        "name2": 21
}

histogram

Added in revision 1

Function histogram, for a given timeseries of non-dict values, returns a dict with entries of the following format:

  • key: value in the timeseries (range if a timeseries of num values)

  • value: time-weighted frequency in the timeseries

Arguments:

  • A timeseries of non-dict values is the only argument to this function

>>> `analytics:/path/to/data`[3] | field("strfield")
timeseries{
        start: 2019-08-31 00:00:00
        end: 2019-08-31 00:12:00
        2019-08-31 00:00:00: "string1"
        2019-08-31 00:01:00: "string2"
        2019-08-31 00:10:00: "string1"
        2019-08-31 00:11:00: "string1"
}
>>> histogram(_)
dict{
        "string1": 0.25
        "string2": 0.75
} # the count is weighted accordingly to the intervals
>>> `analytics:/path/to/data`[5] | field("numfield")
timeseries{
        start: 2019-08-31 00:00:00
        end: 2019-08-31 01:00:00
        2019-08-31 00:00:00: 1
        2019-08-31 00:01:00: 1.01
        2019-08-31 00:10:00: 1.011
        2019-08-31 00:30:00: 5.2
        2019-08-31 00:44:00: 5.22
        2019-08-31 00:56:00: 5.23
}
>>> histogram(_)
dict{
        "1.0-1.011": 0.5
        "5.2-5.23": 0.5
} # the count is weighted accordingly to the intervals

dhistogram

Added in revision 1

Function dhistogram, has a similar behaviour as histogram but its result is not time-weighted. For a given timeseries of non-dict values, returns a dict with entries of the following format:

Arguments:

A timeseries of non-dict values is the only argument to this function

>>> `analytics:/path/to/data`[3] | field("strfield")
timeseries{
        start: 2019-08-31 00:00:00
        end: 2019-08-31 00:05:00
        2019-08-31 00:00:00: "string1"
        2019-08-31 00:01:00: "string2"
        2019-08-31 00:10:00: "string1"
        2019-08-31 00:11:00: "string1"
} # the count does not depend of the time intervals between the updates
>>> dhistogram(_)
dict{
        "string1": 3
        "string2": 1
} # the count does not depend of the time intervals between the updates
>>> `analytics:/path/to/data`[5] | field("numfield")
timeseries{
        2019-08-31 00:00:00: 1
        2019-08-31 00:01:00: 1.01
        2019-08-31 00:10:00: 1.011
        2019-08-31 00:30:00: 5.2
        2019-08-31 00:44:12: 5.22
        2019-08-31 02:01:34: 5.23
}
>>> dhistogram(_)
dict{
        "1.0-1.011": 3
        "5.2-5.23": 3
} # the count does not depend of the time intervals between the updates

aggregate

Added in revision 4

Function aggregate merges multiple timeseries contained in a dict (like the result of a wildcarded query) using the associative method specified in the second parameter. The dict must contain timeseries, all of which must contain identical timestamps.

If one of the timeseries is empty, it will be ignored.

If some values’ timestamps are not matched in all the other non-empty timeseries of the dict, these timestamp-value pairs will not be present in the output timeseries.

aggregate returns a simple timeseries with the aggregated data of all the input timeseries.

  • The first argument is the dict containing timeseries to aggregate

  • The second argument is the name of the associative method to apply

Like with groupby, the following associative methods can be applied:

  • count: returns the length of the list (i.e. the item count)

  • max: returns the max entry in the list (requires the timeseries to be numerical)

  • mean: returns the mean of the values in the list (requires the timeseries to be numerical)

  • min: returns the min entry in the list (requires the timeseries to be numerical)

  • sum: returns the sum of the entries in the list (requires the timeseries to be numerical)

>>> let data = `analytics:/Devices/*/versioned-data/interfaces/data/*/aggregate/hardware/xcvr/15m`[1h]
>>> let avg = data | recmap(2, _value | field("temperature") | field("avg"))
>>> avg
        JPE123456: dict{
                Ethernet1: timeseries{
                        start: 2021-11-09 13:02:18.923904 +0000 GMT
                        end: 2021-11-09 13:32:18.923904 +0000 GMT
                        2021-11-09 13:00:00 +0000 GMT: 28.64315689104305
                        2021-11-09 13:15:00 +0000 GMT: 28.64771549594622
                        2021-11-09 13:30:00 +0000 GMT: 28.647003241959368
                }
                Ethernet2: timeseries{
                        start: 2021-11-09 13:02:18.923904 +0000 GMT
                        end: 2021-11-09 13:32:18.923904 +0000 GMT
                        2021-11-09 13:00:00 +0000 GMT: 26.52073192182222
                        2021-11-09 13:15:00 +0000 GMT: 26.57132998707
                        2021-11-09 13:30:00 +0000 GMT: 26.562415784963335
                }
                [...]
        }
        JPE654321: dict{
                Ethernet1: timeseries{
                        start: 2021-11-09 13:02:18.923904 +0000 GMT
                        end: 2021-11-09 13:32:18.923904 +0000 GMT
                        2021-11-09 13:00:00 +0000 GMT: 27.872056741171672
                        2021-11-09 13:15:00 +0000 GMT: 26.422506200403397
                        2021-11-09 13:30:00 +0000 GMT: 27.889330661612725
                }
                Ethernet2: timeseries{
                        start: 2021-11-09 13:02:18.923904 +0000 GMT
                        end: 2021-11-09 13:32:18.923904 +0000 GMT
                        2021-11-09 13:00:00 +0000 GMT: 25.501376131906685
                        2021-11-09 13:15:00 +0000 GMT: 24.06172043150084
                        2021-11-09 13:30:00 +0000 GMT: 25.520567819910998
                }
                [...]
        }
        [...]
>>> let deviceAvg = avg | map(aggregate(_value, "mean"))
>>> deviceAvg
        JPE123456: timeseries{
                start: 2021-11-09 13:02:18.923904 +0000 GMT
                end: 2021-11-09 13:32:18.923904 +0000 GMT
                2021-11-09 13:00:00 +0000 GMT: 29.46781924765547
                2021-11-09 13:15:00 +0000 GMT: 28.739134103556832
                2021-11-09 13:30:00 +0000 GMT: 29.756429823529587
        }
        JPE654321: timeseries{
                start: 2021-11-09 13:02:18.923904 +0000 GMT
                end: 2021-11-09 13:32:18.923904 +0000 GMT
                2021-11-09 13:00:00 +0000 GMT: 27.581944406432633
                2021-11-09 13:15:00 +0000 GMT: 27.60952274150811
                2021-11-09 13:30:00 +0000 GMT: 27.60470951346135
        }
        [...]
>>> aggregate(deviceAvg, "mean") # average temp accross all interfaces of all devices
timeseries{
        start: 2021-11-09 13:02:18.923904 +0000 GMT
        end: 2021-11-09 13:32:18.923904 +0000 GMT
        2021-11-09 13:00:00 +0000 GMT: 33.261383897237806
        2021-11-09 13:15:00 +0000 GMT: 33.16722874112898
        2021-11-09 13:30:00 +0000 GMT: 33.37487749955894
}

Math functions

abs

Added in revision 1

Function abs returns the absolute value (num) of the given value.

  • The first and only argument \(x\) is the value (num) of which the absolute value \(\lvert x \lvert\) is wanted

>>> abs(-11)
11
>>> abs(200)
200

ceil

Added in revision 1

Function ceil returns the closest integer (num) succeeding the given value.

  • The first and only argument \(x\) is the value (num) of which the ceil \(\lceil x \rceil\) is wanted

>>> ceil(12)
12
>>> ceil(12.1)
13
>>> ceil(-12.1)
-12

floor

Added in revision 1

Function floor returns the closest integer (num) preceding the given value.

  • The first and only argument \(x\) is the value (num) of which the floor \(\lfloor x \rfloor\) is wanted

>>> floor(3)
3
>>> floor(3.2)
3
>>> floor(-3.2)
-4

trunc

Added in revision 1

Function trunc returns the truncated (num) given value.

  • The first and only argument is the value (num) to be truncated

>>> trunc(2.6)
2
>>> trunc(-2.49)
-2

exp

Added in revision 1

Function exp returns the exponential (num) of the given value.

  • The first and only argument \(x\) is the value (num) of which the exp \(e^x\) is wanted

>>> exp(0)
1
>>> exp(12.1)
179871.86225375105

factorial

Added in revision 1

Function factorial returns the factorial (num) of the given value.

  • The first and only argument \(x\) is the value (num) of which the factorial \(x!\) is wanted

>>> factorial(3)
6

gcd

Added in revision 1

Function gcd returns the greatest common divisor (num) of two given integers.

  • The first two arguments are the integers (num) of which the GCD is wanted

>>> gcd(25, 30)
5

log

Added in revision 1

Function log returns the natural log (num) of the given value.

  • The first and only argument \(x\) is the value (num) of which the natural log \(log_e x\) is wanted

>>> log(10)
2.302585092994046

log10

Added in revision 1

Function log10 returns the decimal log (num) of the given value.

  • The first and only argument \(x\) is the value (num) of which the decimal log \(log_{10} x\) is wanted

>>> log10(10)
1

pow

Added in revision 1

Function pow returns the first given value (num) to the power of the second given value.

  • The two arguments are the values \(x\) (num), \(y\) (num) used to compute \(x^y\)

>>> pow(3, 2)
9
>>> pow(9, 1/2)
3

round

Added in revision 1

Function round returns the rounded (num) given value.

  • The first and only argument \(x\) is the value used to compute \(\lfloor x\rceil\) i.e. the rounded value (num)

>>> round(2.5)
3
>>> round(2.49)
2

sqrt

Added in revision 1

Function sqrt returns the square root (num) of the given value.

  • The first and only argument \(x\) is the value (num) of which the square root \(\sqrt{x}\) is wanted

>>> sqrt(9)
3

max

Added in revision 1

Function max returns the max value (num) in a timeseries or a dict.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> max(_)
200

min

Added in revision 1

Function min returns the min value (num) in a timeseries or a dict.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> min(_)
1

formatInt

Added in revision 4

Function formatInt formats a num into a str using the specified base. The num will be treated as an integer and any decimal part will be truncated.

  • The first argument is the num to convert

  • The second argument is the base (num)

>>> formatInt(4, 2)
100
>>> formatInt(4.5, 2)
100
>>> formatInt(33, 2)
100001
>>> formatInt(15, 16)
f
>>> formatInt(29, 16)
1d
>>> type(_)
str

formatFloat

Added in revision 4

Function formatFloat formats a num (float64) into a str, according to the specified format and precision.

  • The first argument is the num to convert

  • The second argument is a str of one letter describing the format:

    • 'b': binary exponent

    • 'e': decimal exponent

    • 'f': no exponent

    • 'x': hexadecimal fraction and binary exponent

  • The third argument is :ref:a num specifying the precision, i.e. the number of digits after the decimal point

>>> formatFloat(15682.8729, "e", 10)
1.5682872900e+04
>>> formatFloat(15682.8729, "f", 10)
15682.8729000000
>>> formatFloat(15, "x", 3)
0x1.e00p+03
>>> formatFloat(15, "b", 3)
8444249301319680p-49
>>> type(_)
str

Stats functions

dsum

Added in revision 1

Function dsum returns the non-weighted sum of values (num) in a timeseries.

  • The first and only argument is a timeseries containing plain num values

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> dsum(_)
216

dmean

Added in revision 1

Function dmean returns the non-weighted mean value (num) of a timeseries.

  • The first and only argument is a timeseries containing plain num values

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> dmean(_)
54

dmedian

Added in revision 1

Function dmedian returns the non-weighted median (num) of a timeseries.

  • The first and only argument is a timeseries containing plain num values

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> dmedian(_)
2

dpercentile

Added in revision 1

Function dpercentile returns the non-weighted nth percentile (num) of a timeseries.

  • The first argument is a timeseries containing plain num values

  • The second argument is a num specifying the percentile. If it is greater than 100 or lower than 0, the return value will be 0.

>>> let a = `analytics:/path/to/data`[3] | field("numfield")
>>> a
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> dpercentile(a, 50)
2
>>> dpercentile(a, 90)
200

dvariance

Added in revision 1

Function dvariance returns the non-weighted statistical variance (num) of a timeseries.

  • The first and only argument is a timeseries containing plain num values

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> dvariance(_)
9503.333333333334

dstddev

Added in revision 1

Function dstddev returns the non-weighted standard deviation (num) of a timeseries.

  • The first and only argument is a timeseries containing plain num values

>>> let a = `analytics:/path/to/data`[3] | field("numfield")
>>> a
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> dstddev(a)
97.48504158758581
>>> sqrt(dvariance(a))
97.48504158758581

dskew

Added in revision 1

Function dskew returns the non-weighted skewness of distribution (num) for data in a timeseries.

  • The first and only argument is a timeseries containing plain num values

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> dskew(_)
0.7431002727844832

dkurtosis

Added in revision 1

Function dkurtosis returns the non-weighted kurtosis of distribution (num) for data in a timeseries.

  • The first and only argument is a timeseries containing plain num values

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> dkurtosis(_)
-1.6923313578244437

sum

Added in revision 1

Function sum returns the sum of the num values in a timeseries or a dict. If applied to a timeseries, the result is time-weighted.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> sum(_)
216
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> sum(d)
216

mean

Added in revision 1

Function mean returns the mean of the num values in a timeseries or a dict. If applied to a timeseries, the result is time-weighted.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> mean(_)
54 # will be different from dmean if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> mean(d)
54

median

Added in revision 1

Function median returns the median of the num values in a timeseries or a dict. If applied to a timeseries, the result is time-weighted.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> median(_)
2 # will be different from dmedian if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> median(d)
2

percentile

Added in revision 1

Function percentile returns the time-weighted nth percentile (num) of a timeseries or a dict. If applied to a timeseries, the result is time-weighted.

  • The first argument is a timeseries or a dict containing plain num values

  • The second argument is a num specifying the percentile. If it is greater than \(100\) or lower than \(0\), the return value will be \(0\).

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> percentile(_, 90)
200 # will be different from dpercentile if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> percentile(d, 90)
200

variance

Added in revision 1

Function variance returns the statistical variance of the num values in a timeseries or a dict. If applied to a timeseries, the result is time-weighted.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> variance(_)
9503.333333333334 # will be different from dvariance if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> variance(d, 90)
9503.33333333

stddev

Added in revision 1

Function stddev returns the standard deviation of the num values in a timeseries or a dict. If applied to a timeseries, the result is time-weighted.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> stddev(_)
97.485041588 # will be different from dstddev if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> stddev(d, 90)
97.485041588

skew

Added in revision 1

Function skew returns the skewness of dist.n of the num values in a timeseries or a dict. If applied to a timeseries, the result is time-weighted. If the timeseries has exactly one element, \(0\) is returned.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> skew(_)
0.7431002727844832 # will be different from dskew if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> skew(d, 90)
0.7431002727844832

kurtosis

Added in revision 1

Function kurtosis returns the kurtosis of dist.n of the num values in a timeseries or a dict. If applied to a timeseries, the result is time-weighted. If the timeseries has exactly one element, \(0\) is returned.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        tstamp1: 13
        tstamp2: 1
        tstamp3: 2
        tstamp4: 200
}
>>> skew(_)
0.7431002727844832 # will be different from dskew if space between the timestamps (weight) is not constant
>>> let d = newDict()
>>> d["key1"] = 13
>>> d["key2"] = 1
>>> d["key3"] = 2
>>> d["key4"] = 200
>>> skew(d, 90)
0.7431002727844832

rate

Added in revision 1

Function rate returns a timeseries of rates computed from the initial timeseriesnum values.

>>> `analytics:/path/to/data`[3] | field("numfield")
timeseries{
        2019-08-31 00:00:00: 1
        2019-08-31 00:01:00: 10
        2019-08-31 00:02:00: 50
        2019-08-31 00:03:00: 110
        2019-08-31 00:04:00: 230
}
>>> rate(_)
timeseries{
        2019-08-31 00:00:00: 0.016666666666666666
        2019-08-31 00:01:00: 0.15
        2019-08-31 00:02:00: 0.6666666666666666
        2019-08-31 00:03:00: 1
        2019-08-31 00:04:00: 2
}

linregression

Added in revision 3

Function linregression produces a linear fit of a timeseries of num.

It returns a dict with 4 entries slope, intercept, R2 and fit. The fit entry is a timeseries with num values corresponding to the fitted line on the input timeseries’ timestamps. The slope and intercept are in seconds.

>>> `analytics:/path/to/data`[5m] | field("numfield")
timeseries{
        start: 2021-10-14 13:57:55.000545 +0100 IST
        end: 2021-10-14 14:02:55.000545 +0100 IST
        2021-10-14 13:57:00 +0100 IST: 3.801633107494212e-05
        2021-10-14 13:58:00 +0100 IST: 7.653320559746086e-05
        2021-10-14 13:59:00 +0100 IST: 3.971200542852744e-05
        2021-10-14 14:00:00 +0100 IST: 3.981215360110563e-05
        2021-10-14 14:01:00 +0100 IST: 5.2121957107961934e-05
        2021-10-14 14:02:00 +0100 IST: 3.838672949594982e-05
}
>>> linregression(_)
dict{
        R2: 0.06273653863866613
        fit: timeseries{
                start: 2021-10-14 13:57:00 +0100 IST
                end: 2021-10-14 14:02:00 +0100 IST
                2021-10-14 13:57:00 +0100 IST: 5.252194027605128e-05
                2021-10-14 13:58:00 +0100 IST: 5.0485322987015024e-05
                2021-10-14 13:59:00 +0100 IST: 4.844870569797877e-05
                2021-10-14 14:00:00 +0100 IST: 4.641208840183708e-05
                2021-10-14 14:01:00 +0100 IST: 4.4375471112800824e-05
                2021-10-14 14:02:00 +0100 IST: 4.2338853823764566e-05
        }
        intercept: 55.47126937459381
        slope: -3.39436215194667e-08
}

ewlinregression

Added in revision 3

Function ewlinregression produces a linear fit of a timeseries of num using exponentially decaying weights. The older the value in the timeseries the smaller the weight. The latest value is always given a weight of \(1\).

  • The first argument is the input timeseries of num

  • The second argument is the desired weight that a point with time x seconds in the past would have

  • the third argument is how long ago that time \(x\) is, in seconds

It returns a dict with 4 entries slope, intercept, R2 and fit. The fit entry is a timeseries with num values corresponding to the fitted line on the input timeseries’ timestamps. The slope and intercept are in seconds.

>>> `analytics:/path/to/data`[5m] | field("numfield")
timeseries{
        start: 2021-10-14 13:57:55.000545 +0100 IST
        end: 2021-10-14 14:02:55.000545 +0100 IST
        2021-10-14 13:57:00 +0100 IST: 3.801633107494212e-05
        2021-10-14 13:58:00 +0100 IST: 7.653320559746086e-05
        2021-10-14 13:59:00 +0100 IST: 3.971200542852744e-05
        2021-10-14 14:00:00 +0100 IST: 3.981215360110563e-05
        2021-10-14 14:01:00 +0100 IST: 5.2121957107961934e-05
        2021-10-14 14:02:00 +0100 IST: 3.838672949594982e-05
}
>>> ewlinregression(_, 0.01, 100.0)
dict{
        R2: 0.34201204121343765
        fit: timeseries{
                start: 2021-10-14 14:03:00 +0100 IST
                end: 2021-10-14 14:08:00 +0100 IST
                2021-10-14 14:03:00 +0100 IST: 4.5425229615148055e-05
                2021-10-14 14:04:00 +0100 IST: 4.4509288322558405e-05
                2021-10-14 14:05:00 +0100 IST: 4.359334702641604e-05
                2021-10-14 14:06:00 +0100 IST: 4.267740573382639e-05
                2021-10-14 14:07:00 +0100 IST: 4.176146444123674e-05
                2021-10-14 14:08:00 +0100 IST: 4.0845523145094376e-05
        }
        intercept: 24.94748623552414
        slope: -1.526568822982724e-08
}

String manipulation

strToUpper

Added in revision 1

Function strToUpper returns uppercase version of given str.

  • The first and only parameter is a str to convert to uppercase

>>> strToUpper("ToUpper")
"TOUPPER"

strToLower

Added in revision 1

Function strToLower returns lowercase version of given str.

  • The first and only parameter is a str to convert to lowercase

>>> strToLower("ToLower")
"TOLOWER"

strContains

Added in revision 1

Function strContains returns whether the first str contains the second str.

  • Both arguments to the function are str

>>> strContains("thatistext", "is")
true

strCount

Added in revision 1

Function strCount returns the number of occurrences of the second str in the first str.

  • Both arguments to the function are str

>>> strCount("tertarter", "te")
2

strIndex

Added in revision 1

Function strIndex returns the index of the first occurrence of the second str in the first str, and -1 if it is not present.

  • Both arguments to the function are str

>>> strIndex("thatistext", "is")
4

strReplace

Added in revision 1

Function strReplace returns a copy of the first str, where occurrences of the second str are replaced by the third str.

  • The three arguments to the function are str

>>> strReplace("thatistext", "is", "was")
"thatwastext"

strHasPrefix

Added in revision 1

Function strHasPrefix returns whether the first str starts with the second str.

  • Both arguments to the function are str

>>> strHasPrefix("thatistext", "is")
false
>>> strHasPrefix("thatistext", "that")
true

strHasSuffix

Added in revision 1

Function strHasSuffix returns whether the first str ends with the second str.

  • Both arguments to the function are str

>>> strHasSuffix("thatistext", "xt")
true

strSplit

Added in revision 1

Function strSplit returns a timeseries of str. The function splits the first str into substrings, separated by the second str.

  • Both arguments to the function are str

>>> strSplit("that./is.text", "./")
timeseries{
        0000-00-00 00:00:00.000000001: "that"
        0000-00-00 00:00:00.000000002: "is.text"
}

strCut

Added in revision 4

Function strCut returns the portion of a str between two indexes (excluding ending index).

Negative indexes start from the end of the input str.

  • The first argument (str) is the string from which the portion is returned

  • The second argument (num) is the starting index

  • The third argument (num) is the ending index

>>> strCut("0123456789", 1, 4)
123
>>> strCut("0123456789", -8, -2)
234567
>>> strCut("abcd", 1, 3)
bc

reFindAll

Added in revision 1

Function reFindAll returns a timeseries of str which contains matches of the second str (regex) in the first str.

  • Both arguments to the function are str

>>> reFindAll("i am a string with text", "i[a-z]+")
timeseries{
        0000-00-00 00:00:00.000000001: "ing"
        0000-00-00 00:00:00.000000002: "ith"
}

reMatch

Added in revision 1

Function reMatch returns whether the first str contains matches of the second str (regex).

  • Both arguments to the function are str

>>> reMatch("i am a string with text", "i[a-z]+")
true

reFindCaptures

Added in revision 1

Function reFindCaptures returns a timeseries of str lists. Each list contains the full match followed by each capture

  • Both arguments to the function are str. The first one is the str to match, and the second is the regular expression

>>> reFindCaptures("foobarbaztootartaz", "foo")
timeseries{
        0000-00-00 00:00:00.000000001: ["foo"]
}
>>> reFindCaptures("foobarbaztootartaz", "(foo)")
timeseries{
        0000-00-00 00:00:00.000000001: ["foo", "foo"]
}
>>> reFindCaptures("foobarbaztootartaz", "f(oo)")
timeseries{
        0000-00-00 00:00:00.000000001: ["foo", "oo"]
}
>>> reFindCaptures("foobarbaztootartaz", "(oo)")
timeseries{
        0000-00-00 00:00:00.000000001: ["oo", "oo"]
        0000-00-00 00:00:00.000000002: ["oo", "oo"]
}
>>> reFindCaptures("foobarbaztootartaz", "[ft](oo)")
timeseries{
        0000-00-00 00:00:00.000000001: ["foo", "oo"]
        0000-00-00 00:00:00.000000002: ["too", "oo"]
}
>>> reFindCaptures("foobarbaztootartaz", "([ft])(oo)")
timeseries{
        0000-00-00 00:00:00.000000001: ["foo", "f", "oo"]
        0000-00-00 00:00:00.000000002: ["too", "t", "oo"]
}
>>> reFindCaptures("foobarbaztootartaz", "[ft](oo).*(az)")
timeseries{
        0000-00-00 00:00:00.000000001: ["foobarbaztootartaz", "oo", "az"]
}

CLI-only Functions

Warning

The functions described in this section can only be used in CLI. They cannot be called from a service or through a Web interface.

help

Added in revision 1

Function help returns the help of all filters and functions as a formatted str.

>>> help()
# Functions
## now
- Function `now` returns the current time. Time is constant across all the script, so that all operations and queries have the same reference time
[...]

dump

Added in revision 1

Function dump attempts to dump variables from the interpreter into a file.

  • The first and only argument is the path to the file (str)

>>> let myVar = 2
>>> dump("file.dump")

load

Added in revision 1

Function load attempts to load variables into the interpreter from a file.

  • The first and only argument is the path to the file (str)

>>> load("file.dump")
true
>>> myVar
2
>>> let myVar = 5
>>> if load("file.dump") {
...     myVar
... }
2

plot

Added in revision 1

Function plot plots a timeseries or dict of num values.

  • The first argument is the timeseries or dict of num values to plot

  • The second argument (optional) is the path (str) to the image PNG file to write the plot to. If not specified, defaults to plot.png

>>> plot(myTimeseriesOrDict, "myplotimg.png")