2. Using unique for fast set membership checking
3. Listing the attributes of an object
2. Hexadecimal and Octal numbers are not supported
3. Use of brackets to overcome parsing errors
4. Samples method on non-polling streams
5. StormWorks type arithmetic
Useful functions:
The help() function is often the best way of finding a function or information on its usage. Please see the below table for some commonly used and/or useful functions. Call help() with the function name for more information. This is only a small fraction of the functions available - use help() with wildcards and the optional second argument set to true, so that you can seach the help entries for functions on a particular topic:
Function Name | Description |
---|---|
now ds_time |
returns the current time as a unix timestamp. |
find find_all find_by_attribute |
finds StormWorks objects via a cached look-up. |
sqr sqrt pow log log10 sin cos mean mode max min sd |
various mathematical functions. |
substr findstr toupper tolower strlen split split_max split_on_string concat join trim fill regex |
various string functions. |
list_union list_intersection |
return the union or intersection of two lists. |
isinview | returns true if current object is in given view. |
get_config_var | get value of an entuity.cfg variable. |
sql | run SQL against the EYE database. |
call_rpc_function | useful for debugging StormWorks RPC methods. |
test_evaluate_collector test_evaluate_stream |
run a named StormWorks collector or stream. |
list_stream_collectors | list the collectors for a stream. |
logMessage println |
log a message to DsKernelStatic.log or to STDOUT |
stash_get stash_put stash_exists |
stores and retrieves data in a global map. |
Tips:
1. Casting to list or struct:
Sometimes you have a value that you know is a list or struct, but because the compiler doesn't know it is a list/struct, the compiler will not let you perform the appropriate operations on it.
This can happen, for example, when it is the return value from a function whose signature cannot specify the type, e.g. the stash_get() function. In this case, you can cast the data to a list or struct, but since the compiler still doesn't know the type of the elements, you will need to do further casting on them when you iterate over it, or when you index into it to get a specific element. For example:
stash_put("test", [ { 1, "one"}, { 2, "two" }, { 3, "three" } ]);
struct(list(stash_get("test"))[1])[1]
2. Using unique for fast set membership checking:
When applied to a list, the unique operator returns the list with duplicates removed and in sorted order. It does this by inserting the items from the list into an SDContainerSet and returning the list.
The function in() takes an item argument and a list argument, and returns true if the item is found in the list. If the list is an SDContainerSet, the operator will use the more efficient exists() method on it, rather than iterating over the contents.
This means that it is possible to use unique to make significant performance improvements to expressions that use in(), particularly when the following are true:
- the number of items in the list must be relatively large (not just a handful).
- the set must not have to be rebuilt every time the check is done. This can be the case either:
- if you are reusing the list multiple times in the expression (e.g. in a foreach loop), OR
- if the statement is being stored in its compiled form (true for config, not for Flex queries), AND
- the list is a fixed list that the compiler can optimise into a constant.
Please see the below two example expressions that benefit from the use of unique:
- This gets all the raw util samples for a port, that have a timestamp exactly on an hourly boundary:
variable start = report_start(now(), "24@1h");
variable end = report_end(now(), "24@1h");
variable hourBoundaries = unique(foreach(timestamps(start, end, 60*60), this[0]));
variable sampleData = stream.portUtilRawData[1];
foreach(sampleData, this, in(this.timestamp, hourBoundaries)) - This checks if a device's sysOid is in a fixed list:
!in(ref.device.sysOid,
unique([".1.3.6.1.4.1.11.2.3.7.11.18",
".1.3.6.1.4.1.11.2.3.7.11.27",
".1.3.6.1.4.1.11.2.3.7.11.31",
".1.3.6.1.4.1.11.2.3.7.11.19",
".1.3.6.1.4.1.11.2.3.7.11.45",
".1.3.6.1.4.1.11.2.3.7.11.44",
".1.3.6.1.4.1.11.2.3.7.11.23",
".1.3.6.1.4.1.9.5.31",
".1.3.6.1.4.1.9.5.18",
".1.3.6.1.4.1.9.5.28",
".1.3.6.1.4.1.9.5.20",
".1.3.6.1.4.1.9.5.12"]))
3. Listing the attributes of an object:
You can use dump_object() to list the attributes of your context's object with their current values. However, the output is one continuous line that is difficult to read. You can use the following syntax to reformat the output so that each attribute occupies its own line:
simple;join(dump_object(),"\n")
Notes:
1. foreach over non-list:
If the first item in a foreach expression was not a list, then the expression will 'promote' the item to a list consisting of one element.
2. Hexadecimal and Octal numbers are not supported:
If the statement language is presented with a literal integer that looks like a hexadecimal or octal, it is parsed successfully but then it tries to treat the resulting string as a decimal integer. In some cases, it will appear that the number was handled correctly, whereas in others it will not be.
3. Use of brackets to overcome parsing errors:
In some cases, the parser has trouble parsing what should be a perfectly valid expression. This happens when using variables within a subexpression, or when parsing the sAttr references inside the timeseries function. In these cases, it is usually possible to overcome the problem by helping the parser out by surrounding the subexpression with brackets to create a separate scope.
4. Samples method on non-polling streams:
Some StormWorks streams are specified as being 'non-polling' (search for NoPoll=true in the StormWorks config), which means they are populated by some other means. This means that their samples are not evenly distributed at regular intervals in the same way that normally polling streams are.
This impacts the samples method for accessing stream samples, because all this samples method does is calculate a period that is based upon the streams obtain rate and the number of samples requested, and get all the samples in that period.
5. StormWorks type arithmetic:
The statement language recognizes StormWorks type names, such as RouterDevice, portEx, MonitoredApplication. This allows expressions to use these symbolic names in e.g. the isa operator and the find() function, rather than having to know type ID numbers.
However, the symbolic name is simply replaced with the type ID. As a consequence, type names can be used as numbers in arithmetic expressions. For example, the expression:
DeviceEx + IpAddress
will compile and run without any errors, producing an integer result.
Comments
0 comments
Please sign in to leave a comment.