This is the multi-page printable view of this section. Click here to print.
Reference Section
- 1: Cron Syntax
- 2: Dates & Times
- 3: Documents
- 4: Editor Completion Snippets
- 5: Expression functions
- 5.1: Aggregate Functions
- 5.2: Cast Functions
- 5.3: Date Functions
- 5.4: Link Functions
- 5.5: Logic Funtions
- 5.6: Mathematics Functions
- 5.7: Selection Functions
- 5.8: String Functions
- 5.9: Type Checking Functions
- 5.10: URI Functions
- 5.11: Value Functions
- 6: Background Jobs
- 7: Keyboard Shortcuts
- 8: Pipeline Elements
- 9: Templating
1 - Cron Syntax
cron is a syntax for expressing schedules.
Stroom uses a scheduler called Quartz which supports cron expressions for scheduling. The full details of the cron syntax supported by Quartz can be found here .
Cron expressions are used in:
Field Specification
Field Name | Mandatory | Allowed Values | Allowed Special Characters |
---|---|---|---|
Seconds | YES | 0-59 | , - * / |
Minutes | YES | 0-59 | , - * / |
Hours | YES | 0-23 | , - * / |
Day of month | YES | 1-31 | , - * ? / L W |
Month | YES | 1-12 or JAN-DEC | , - * / |
Day of week | YES | 1-7 or SUN-SAT | , - * ? / L # |
Year | NO | empty, 1970-2099 | , - * / |
Special Characters
-
*
(all values) - used to select all values within a field. For example,*
in the minute field meansevery minute
. -
?
(no specific value) - useful when you need to specify something in one of the two fields in which the character is allowed, but not the other. For example, if I want my trigger to fire on a particular day of the month (say, the 10th), but don’t care what day of the week that happens to be, I would put10
in the day-of-month field, and?
in the day-of-week field. See the examples below for clarification. -
-
- used to specify ranges. For example,10-12
in the hour field means the hours 10, 11 and 12. -
,
- used to specify additional values. For example,MON,WED,FRI
in the day-of-week field means the days Monday, Wednesday, and Friday. -
/
- used to specify increments. For example,0/15
in the seconds field means the seconds 0, 15, 30, and 45. And5/15
in the seconds field means the seconds 5, 20, 35, and 50. You can also specify ‘/’ after the ‘’ character - in this case ‘’ is equivalent to having ‘0’ before the ‘/’. ‘1/3’ in the day-of-month field means fire every 3 days starting on the first day of the month. -
L
(last) - has different meaning in each of the two fields in which it is allowed. For example, the valueL
in the day-of-month field means the last day of the month - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means7
orSAT
. But if used in the day-of-week field after another value, it means the last xxx day of the month - for example6L
means the last friday of the month. You can also specify an offset from the last day of the month, such asL-3
which would mean the third-to-last day of the calendar month. When using the ‘L’ option, it is important not to specify lists, or ranges of values, as you’ll get confusing/unexpected results. -
W
(weekday) - used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify15W
as the value for the day-of-month field, the meaning is: the nearest weekday to the 15th of the month. So if the 15th is a Saturday, the trigger will fire on Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. However if you specify1W
as the value for day-of-month, and the 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not ‘jump’ over the boundary of a month’s days. The ‘W’ character can only be specified when the day-of-month is a single day, not a range or list of days.Note
The ‘L’ and ‘W’ characters can also be combined in the day-of-month field to yield ‘LW’, which translates to “last weekday of the month”. -
#
- used to specify the nth XXX day of the month. For example, the value of6#3
in the day-of-week field means the third Friday of the month (day 6 = Friday and#3
= the 3rd one in the month). Other examples:2#1
= the first Monday of the month and4#5
= the fifth Wednesday of the month. Note that if you specify#5
and there is not 5 of the given day-of-week in the month, then no firing will occur that month.Note
The legal characters and the names of months and days of the week are not case sensitive. MON is the same as mon.
Examples
Expression | Meaning |
---|---|
0 0 12 * * ? |
Fire at 12pm (noon) every day |
0 15 10 ? * * |
Fire at 10:15am every day |
0 15 10 * * ? |
Fire at 10:15am every day |
0 15 10 * * ? * |
Fire at 10:15am every day |
0 15 10 * * ? 2005 |
Fire at 10:15am every day during the year 2005 |
0 * 14 * * ? |
Fire every minute starting at 2pm and ending at 2:59pm, every day |
0 0/5 14 * * ? |
Fire every 5 minutes starting at 2pm and ending at 2:55pm, every day |
0 0/5 14,18 * * ? |
Fire every 5 minutes starting at 2pm and ending at 2:55pm, AND fire every 5 minutes starting at 6pm and ending at 6:55pm, every day |
0 0-5 14 * * ? |
Fire every minute starting at 2pm and ending at 2:05pm, every day |
0 10,44 14 ? 3 WED |
Fire at 2:10pm and at 2:44pm every Wednesday in the month of March. |
0 15 10 ? * MON-FRI |
Fire at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday |
0 15 10 15 * ? |
Fire at 10:15am on the 15th day of every month |
0 15 10 L * ? |
Fire at 10:15am on the last day of every month |
0 15 10 L-2 * ? |
Fire at 10:15am on the 2nd-to-last last day of every month |
0 15 10 ? * 6L |
Fire at 10:15am on the last Friday of every month |
0 15 10 ? * 6L |
Fire at 10:15am on the last Friday of every month |
0 15 10 ? * 6L 2002-2005 |
Fire at 10:15am on every last friday of every month during the years 2002, 2003, 2004 and 2005 |
0 15 10 ? * 6#3 |
Fire at 10:15am on the third Friday of every month |
0 0 12 1/5 * ? |
Fire at 12pm (noon) every 5 days every month, starting on the first day of the month. |
0 11 11 11 11 ? |
Fire every November 11th at 11:11am. |
2 - Dates & Times
Standard Format
Stroom’s standard format for displaying dates and times is ISO 8601 and specifically in the format
yyyy-MM-dd'T'HH:mm:ss.SSSXX
(where 'T'
is the constant T
and XX
is the timezone offset or Z
for Zulu/UTC).
The time part is always represented with three digits for the millisecond part.
Parsing
Parsing is the action of reading a string like 2010-01-01T23:59:59.123Z
and converting it into a date/time value.
There are two types of parsing, standard parsing and parsing with an explicit format.
Standard Parsing
The standard format is used when parsing dates with no specific date format, for example in the EffectiveTime
header that is used when sending reference data to Stroom.
There is a degree of leniency when parsing date time strings with no explicit format. The following table shows the acceptable date time strings and how they are represented in the standard form.
Input String | Standard Form |
---|---|
2010-01-01T23:59:59.1Z |
2010-01-01T23:59:59.100Z |
2010-01-01T23:59:59.123Z |
2010-01-01T23:59:59.123Z |
2010-01-01T23:59:59.123456Z |
2010-01-01T23:59:59.123Z |
2010-01-01T23:59:59.000123Z |
2010-01-01T23:59:59.000Z |
2010-01-01T23:59:59.0Z |
2010-01-01T23:59:59.000Z |
2010-01-01T23:59:59.000Z |
2010-01-01T23:59:59.000Z |
2010-01-01T23:59Z |
2010-01-01T23:59:00.000Z |
2010-01-01T23:59:59Z |
2010-01-01T23:59:59.000Z |
2010-01-01T23:59:59+02:00 |
2010-01-01T23:59:59.000+0200 |
2010-01-01T23:59:59.123+02 |
2010-01-01T23:59:59.123+0200 |
2010-01-01T23:59:59.123+00:00 |
2010-01-01T23:59:59.123Z |
2010-01-01T23:59:59.123+02:00 |
2010-01-01T23:59:59.123+0200 |
2010-01-01T23:59:59.123-03:00 |
2010-01-01T23:59:59.123-0300 |
Custom Date Formats
Parsing and formatting with an explicit date time format is done in a few places in Stroom.
-
The XSLT function
format-date()
. This function is a bit of a misnomer as it is doing both parsing and formatting. -
The Dashboard/Query expression
parseDate()
.
Stroom uses Java’s DateTimeFormatter syntax for expressing an explicit date format.
All letters A
to Z
and a
to z
are reserved as pattern letters.
The following pattern letters are defined:
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
G |
era | text | AD , Anno Domini , A |
u |
year | year | 2004 , 04 |
y |
year-of-era | year | 2004 , 04 |
D |
day-of-year | number | 189 |
M/L |
month-of-year | number/text | 7 , 07 , Jul , July , J |
d |
day-of-month | number | 10 |
g |
modified-julian-day | number | 2451334 |
Q/q |
quarter-of-year | number/text | 3 , 03 , Q3 , 3rd quarter |
Y |
week-based-year | year | 1996 , 96 |
w |
week-of-week-based-year | number | 27 |
W |
week-of-month | number | 4 |
E |
day-of-week | text | Tue , Tuesday , T |
e/c |
localized day-of-week | number/text | 2 , 02 , Tue , Tuesday , T |
F |
aligned-week-of-month | number | 3 |
a |
am-pm-of-day | text | PM |
B |
period-of-day | text | in the morning |
h |
clock-hour-of-am-pm (1-12) | number | 12 |
K |
hour-of-am-pm (0-11) | number | 0 |
k |
clock-hour-of-day (1-24) | number | 24 |
H |
hour-of-day (0-23) | number | 0 |
m |
minute-of-hour | number | 30 |
s |
second-of-minute | number | 55 |
S |
fraction-of-second | fraction | 978 |
A |
milli-of-day | number | 1234 |
n |
nano-of-second | number | 987654321 |
N |
nano-of-day | number | 1234000000 |
V |
time-zone ID | zone-id | America/Los_Angeles , Z , -08:30 |
v |
generic time-zone name | zone-name | Pacific Time , PT |
z |
time-zone name | zone-name | Pacific Standard Time , PST |
O |
localized zone-offset | offset-O | GMT+8 , GMT+08:00 , UTC-08:00 |
X |
zone-offset Z for zero |
offset-X | Z , -08 , -0830 , -08:30 , -083015 , -08:30:15 |
x |
zone-offset | offset-x | +0000 , -08 , -0830 , -08:30 , -083015 , -08:30:15 |
Z |
zone-offset | offset-Z | +0000 , -0800 , -08:00 |
p |
pad next | pad modifier | 1 |
' |
escape for text | delimiter | |
'' |
single quote | literal | ' |
[ |
optional section start | ||
] |
optional section end | ||
# |
reserved for future use | ||
{ |
reserved for future use | ||
} |
reserved for future use |
The count of pattern letters determines the format.
Presentation Types
-
Text: The text style is determined based on the number of pattern letters used. Less than 4 pattern letters will use the short form Exactly 4 pattern letters will use the full form Exactly 5 pattern letters will use the narrow form Pattern letters
L
,c
, andq
specify the stand-alone form of the text styles. -
Number: If the count of letters is one, then the value is output using the minimum number of digits and without padding Otherwise, the count of digits is used as the width of the output field, with the value zero-padded as necessary The following pattern letters have constraints on the count of letters Only one letter of
c
andF
can be specified Up to two letters ofd
,H
,h
,K
,k
,m
, ands
can be specified Up to three letters ofD
can be specified. -
Number/Text: If the count of pattern letters is 3 or greater, use the Text rules above Otherwise use the Number rules above.
-
Fraction: Outputs the nano-of-second field as a fraction-of-second The nano-of-second value has nine digits, thus the count of pattern letters is from 1 to 9 If it is less than 9, then the nano-of-second value is truncated, with only the most significant digits being output.
-
Year: The count of letters determines the minimum field width below which padding is used If the count of letters is two, then a reduced two digit form is used For printing, this outputs the rightmost two digits For parsing, this will parse using the base value of 2000, resulting in a year within the range 2000 to 2099 inclusive If the count of letters is less than four (but not two), then the sign is only output for negative years as per SignStyle.NORMAL Otherwise, the sign is output if the pad width is exceeded, as per SignStyle.EXCEEDS_PAD.
-
ZoneId: This outputs the time-zone ID, such as
Europe/Paris
If the count of letters is two, then the time-zone ID is output Any other count of letters throws IllegalArgumentException. -
Zone names: This outputs the display name of the time-zone ID If the pattern letter is
z
the output is the daylight saving aware zone name If there is insufficient information to determine whether DST applies, the name ignoring daylight saving time will be used If the count of letters is one, two or three, then the short name is output If the count of letters is four, then the full name is output Five or more letters throws IllegalArgumentException.If the pattern letter is
v
the output provides the zone name ignoring daylight saving time If the count of letters is one, then the short name is output If the count of letters is four, then the full name is output Two, three and five or more letters throw IllegalArgumentException. -
Offset X and x: This formats the offset based on the number of pattern letters One letter outputs just the hour, such as
+01
, unless the minute is non-zero in which case the minute is also output, such as+0130
Two letters outputs the hour and minute, without a colon, such as+0130
Three letters outputs the hour and minute, with a colon, such as+01:30
Four letters outputs the hour and minute and optional second, without a colon, such as+013015
Five letters outputs the hour and minute and optional second, with a colon, such as+01:30:15
Six or more letters throws IllegalArgumentException Pattern letterX
(upper case) will outputZ
when the offset to be output would be zero, whereas pattern letterx
(lower case) will output+00
,+0000
, or+00:00
. -
Offset O: With a non-zero offset, this formats the localized offset based on the number of pattern letters One letter outputs the short form of the localized offset, which is localized offset text, such as
GMT
, with hour without leading zero, optional 2-digit minute and second if non-zero, and colon, for exampleGMT+8
Four letters outputs the full form, which is localized offset text, such as GMT, with 2-digit hour and minute field, optional second field if non-zero, and colon, for exampleGMT+08:00
If the offset is zero, only localized text is output Any other count of letters throws IllegalArgumentException. -
Offset Z: This formats the offset based on the number of pattern letters One, two or three letters outputs the hour and minute, without a colon, such as
+0130
The output will be+0000
when the offset is zero Four letters outputs the full form of localized offset, equivalent to four letters of Offset-O The output will be the corresponding localized offset text if the offset is zero Five letters outputs the hour, minute, with optional second if non-zero, with colon It outputsZ
if the offset is zero Six or more letters throws IllegalArgumentException. -
Optional section: The optional section markers work exactly like calling DateTimeFormatterBuilder.optionalStart() and DateTimeFormatterBuilder.optionalEnd().
-
Pad modifier: Modifies the pattern that immediately follows to be padded with spaces The pad width is determined by the number of pattern letters This is the same as calling DateTimeFormatterBuilder.padNext(int).
For example, ppH
outputs the hour-of-day padded on the left with spaces to a width of 2.
Any unrecognized letter is an error
Any non-letter character, other than [
, ]
, {
, }
, #
and the single quote will be output directly
Despite this, it is recommended to use single quotes around all characters that you want to output directly to ensure that future changes do not break your application.
For further details, see the DateTimeFormatter documentation.
For examples of the parsing/formatting patterns in use, see format-date()
.
Formatting
Stroom can format dates with an explicit format in a few places:
-
The XSLT function
format-date()
. This function is a bit of a misnomer as it is both parsing and formatting. -
The Dashboard/Query expression
formatDate()
. -
The User Preferences dialog.
When formatting a date time, the format syntax is the same as used in parsing, as shown above.
Durations
Durations are represented in Stroom in two different forms, Stroom Durations and ISO 8601 Durations.
Stroom Duration
Stroom’s standard duration syntax takes the form of a numeric value followed by an optional unit suffix, e.g. 10m
for ten minutes.
Prefix | Time Unit |
---|---|
milliseconds | |
ms |
milliseconds |
s |
seconds |
m |
minutes |
h |
hours |
d |
days |
Stroom Duration strings are used in a number of places in Stroom:
- Frequency Schedules.
- Date Expressions.
- Configuration properties.
- Dashboard/Query expression functions
parseDuration
andformatDuration
.
ISO 8601 Duration
ISO 8601 durations are an international standard format for expressing durations.
ISO 8601 duration strings are used in a number of places in Stroom:
- Configuration properties.
- Dashboard/Query expression functions
parseISODuration
andformatISODuration
.
Date Expressions
Date expressions are a way to represent relative dates or to express simple date arithmetic. They can be used in the following places in Strom:
- Dashboard expression term values.
- Dashboard/Query time range settings.
- Dashboard/Query expression language.
Date expressions consist of a mixture of:
- StroomDuration.
- Relative date functions like
minute()
. - Absolute date/times in the Standard Format
The available relative date functions are:
Function | Meaning | Example |
---|---|---|
now() | The current time | 2024-04-26T17:41:55.239Z |
second() | The current time rounded down to the last second | 2024-04-26T17:41:55.000Z |
minute() | The current time rounded down to the last minute | 2024-04-26T17:41:00.000Z |
hour() | The current time rounded down to the last hour | 2024-04-26T17:00:00.000Z |
day() | The current time rounded down to the start of the day | 2024-04-26T00:00:00.000Z |
week() | The current time rounded down to the start of the last Monday | 2024-04-22T00:00:00.000Z (Monday) |
month() | The current time rounded down to the start of the month | 2024-04-01T00:00:00.000Z |
year() | The current time rounded down to the start of the year | 2024-01-01T00:00:00.000Z |
In the examples above, the current time is taken to be 2024-04-26T17:41:55.239Z
which is a Friday.
The following are some examples of date expressions:
Expression | Result | Meaning |
---|---|---|
now()+1d |
2024-04-27T17:41:55.239Z |
The same time tomorrow. |
day() - 1d |
2024-04-25T00:00:00.000Z |
The start of yesterday. |
day() +1d +12h |
2024-04-27T12:00:00.000Z |
Noon tomorrow. |
2024-04-27T17:41:55.239Z - 24y |
2000-04-27T17:41:55.239Z |
24 years before 2024-04-27T17:41:55.239Z |
In the examples above, the current time is taken to be 2024-04-26T17:41:55.239Z
which is a Friday.
3 - Documents
All Documents in Stroom share some common elements:
- UUID - Uniquely identifies the document within Stroom and when exported into another stroom.
- Type - This is the type as used in the DocRef .
- Documentation - Every Document has a Documentation tab for recording any documentation that relates to the Document, see Documenting Content.
Some Documents are very simple with just text content and documentation, e.g. XSLT. Others are much more complex, e.g. Pipeline, with various different tabs to manage the content of the Document.
The following is a list of all Document types in Stroom.
Configuration
Documents that are used as configuration for other documents.
Dictionary
- Icon:
- Type:
Dictionary
A Dictionary is essentially a list of ‘words’, where each ‘word’ is separated by a new line.
Dictionaries can be used in filter expressions, i.e. IN DICTIONARY
.
They allow for the reuse of the same set of values across many search expressions.
Dictionaries also support inheritance so one dictionary can import the contents of other dictionaries.
Documentation
- Icon:
- Type:
Documentation
A Document type for simply storing user created documentation, e.g. adding a Documentation document into a folder to describe the contents of that folder.
Elastic Cluster
- Icon:
- Type:
ElasticCluster
Defines the connection details for a single Elasticsearch cluster. This Elastic Cluster Document can then be used by one or more Elastic Index Documents.
Kafka Configuration
- Icon:
- Type:
KafkaConfig
Defines the connection details for a single Kafka cluster. This Kafka Configuration Document can then be used by one or more StandardKafkaProducer pipeline elements.
Script
- Icon:
- Type:
Script
Contains a Javascript script that is used as the source for a visualisation Document. Scripts can have dependencies on other Script Documents, e.g. to allow re-use of common code.
Visualisation
- Icon:
- Type:
Visualisation
Defines a data visualisation that can be used in a Dashboard Document. The Visualisation defines the settings that will be available to the user when it is embedded in a Dashboard. A Visualisation is dependent on a Script Document for the Javascript code to make it work.
Data Processing
Documents relating to the processing of data.
Feed
- Icon:
- Type:
Feed
The Feed is Stroom’s way of compartmentalising data that has been ingested or created by a Pipeline. Ingested data must specify the Feed that is it destined for.
The Feed Document defines the character encoding for the data in the Feed, the type of data that will be received into it (e.g. Raw Events
) and optionally a Volume Group to use for data storage.
The Feed Document can also control the ingest of data using its Feed Status
property and be used for viewing data that belonging to that feed.
Pipeline
- Icon:
- Type:
Pipeline
A Pipeline defines a chain of Pipeline elements that consumes from a source of data (a Stream of raw data or cooked events) then processes it according to the elements used in the chain. Pipelines can be linear or branching and support inheritance of other pipelines to allow re-use of common structural parts.
The Pipeline Document defines the structure of the pipeline and the configuration of each of the elements in that pipeline. It also defines the filter(s) that will be used to control what data is passed through the pipeline and the priority of processing. The Pipeline Document can be used to view the data produced by the pipeline and to monitor its processing state and progress.
See Also
PipelinesIndexing
Documents relating to the process of adding data into an index, such as Lucene or Elasticsearch.
Elastic Index
- Icon:
- Type:
ElasticIndex
Defines an index that exists within an Elasticsearch cluster. This Document is used in the configuration of the ElasticIndexingFilter pipeline element.
See Also
ElasticsearchLucene Index
- Icon:
- Type:
Index
Lucene Index is the standard built-in index within Stroom and is one of may data sources. An index is like a catalog in a library and provides a very fast way to access documents/records/events when searching using fields that have been indexed. The index stores the field values and pointers to the document they came from (the Stream and Event IDs). Data can be indexed using multiple indexes to allow fast access in different ways.
The Lucene Index Document optionally defines the fields that will be indexed (it is possible to define the fields dynamically) and their types. It also allows for configuration of the way the data in the index will be stored, partitioned and retained.
The Lucene Index Document is used by the IndexingFilter and DynamicIndexingFilter pipeline elements.
See Also
Lucene IndexesSolr Index
- Icon:
- Type:
SolrIndex
Solr Index represents an index on a Solr cluster. It defines the connection details for connecting to that cluster and the structure of the index. It is used by the SolrIndexingFilter pipeline element.
See Also
Solr IntegrationStatistic Store
- Icon:
- Type:
StatisticStore
Defines a logical statistic store used to hold statistical data of a particular type and aggregation window. Statistics in Stroom is a way to capture counts or values from events and record how they change over time, with the counts/values aggregated (sum/mean) across time windows.
The Statistic Store Document configures the type of the statistic (Count or Value), the tags that are used to qualify a statistic event and the size of the aggregation windows.
It also supports the definition of roll-ups that allow for aggregation over all values of a tag.
Tags can be things like user
, node
, feed
, etc. and can be used to filter data when querying the statistic store in a Dashboard/Query.
It is used by the StatisticsFilter pipeline element.
Stroom-Stats Store
- Icon:
- Type:
StroomStatsStore
The Stroom-Stats Store Document is deprecated and should not be used.
Search
Documents relating to searching for data in Stroom.
Analytic Rule
- Icon:
- Type:
AnalyticRule
Defines an analytic rule which can be run to alert on events meeting a criteria. The criteria is defined using a StroomQL query. The analytic can be processed in different ways:
- Streaming
- Table Builder
- Scheduled Query
Dashboard
- Icon:
- Type:
Dashboard
The Dashboard Document defines a data querying and visualisation dashboard. The dashboard is highly customisable to allow querying of many different data sources of different types. Queried data can be displayed in tabular form, visualised using interactive charts/graphs or render as HTML.
The Dashboard Doc can either be used for ad-hoc querying/visualising of data, to construct a dashboard for others to view or to just view an already constructed dashboard. Dashboards can be parameterised so that all queries on the dashboard are displaying data for the same user, for example. For ad-hoc querying of data from one data source, you are recommended to use a Query instead.
Query
- Icon:
- Type:
Query
A Query Document defines a StroomQL query and is used to execute that query and view its results. A Query can query main types of data source including Views, Lucene Indexes, and Searchables .
View
- Icon:
- Type:
View
A view is an abstraction over a data source (such as a Lucene Indexe) and optionally an extraction pipeline. Views provide a much simpler way for users to query data as the user can simply query against the View without any knowledge of the underlying data source or extraction of that data.
Transformation
Documents relating to the transformation of data.
Text Converter
- Icon:
- Type:
TextConverter
A Text Converter Document defines the specification for splitting text data into records/fields using Data Splitter or for wrapping fragment XML with a
XMLFragmentParser
pipeline element.
The content of the Document is either XML in the data-splitter:3
namespace or a fragment parser specification (see Pipeline Recipies).
This Document is used by the following pipeline elements:
XML Schema
- Icon:
- Type:
XMLSchema
This Document defines an XML Schema that can be used within Stroom for validation of XML documents. The XML Schema Document content is the XMLSchema text. This Document also defines the following:
- Namespace URI - The XML namespace of the XMLSchema and the XML document that the schema will validate.
- System Id - An ID (that is unique in Stroom) that can be used in the
xsi:schemaLocation
attribute, e.g.xsi:schemaLocation="event-logging:3 file://event-logging-v3.4.2.xsd"
. - Schema Group - A name to group multiple versions of the same schema. The SchemaFilter can be configured to only use schemas matching a configured group.
The XML Schema Document also provides a handy interactive viewer for viewing and navigating the XMLSchema in a graphical representation.
This Document is used by the SchemaFilter pipeline element.
XSL Translation
- Icon:
- Type:
XSLT
The content of this Document is an XSLT document for transforming data in a pipeline. This Document is used by the XSLTFilter pipeline element.
4 - Editor Completion Snippets
Overview
Completion snippets are a way to quickly insert snippets of text into the editor. This is very useful for example when editing XSLT documents as you can quickly insert common chunks of XSLT.
This page lists all the snippets available in Stroom. Snippets are specific to the type of content being edited, e.g. When editing an XSLT, you will only be able to use XML/XSLT snippets.
Tab Positions
A snippet is not just a static block of text, it can contain various tab position placeholders. The following is an example of a snippet with multiple tab positions:
<xsl:apply-templates select="${1:*}">
<xsl:with-param name="${2:param}">${3}</xsl:with-param>
${0}
</xsl:apply-templates>
Tab positions are expressed like ${n}
or ${n:xxx}
, where n
is a number indication the order of the tab position and xxx
is the default value at that tab position. Sometimes xxx
will not be a default value, but will instead be a string to hint at the kind of thing the user is expected to overtype with where no obvious default is available.
${0}
is a special tab position in that it defines the last tab position.
To insert a snippet do one of the following:
- Type the whole Tab Trigger then hit Tab ↹ .
- Type some characters from the Name then hit Ctrl ^ + Space ␣ to select it from the list.
The snippet will be inserted (replacing the Tab Trigger if used) and the cursor will be position on the first tab position (${1}
if present, otherwise ${0}
).
If the tab position has a default value then the whole of that default value will be selected allowing the user to quickly over type it.
Once the user is happy with the first tab position (whether they inserted text, over typed or did nothing), they can hit tab
to move to the next tab position.
Advanced Tab Positions
It is possible for a tab position to be used multiple times in a snippet, like in the following example. All subsequent uses of a tab stop will take the value entered by the user on the first use of it. The subsequent uses will not act as tab stops.
<xsl:stylesheet xmlns="${1}" xpath-default-namespace="${1}">
${0}
</xsl:stylesheet>
If you want a reused tab position to also be a tab stop so that the user can chose to override the re-used value, then you can nest the tab stops like in this example:
<xsl:stylesheet xmlns="${1}" xpath-default-namespace="${2:${1}}">
${0}
</xsl:stylesheet>
Adding Snippets to Stroom
We have plans for improving how completion snippets are defined, i.e. allowing users to define their own. Therefore, available snippets may be subject to change.
However, until then, if there are any generic snippets that you think would be useful to add to Stroom then please raise an issue on GitHub .
XML/XSLT Snippets
Apply-templates with-param (wapply
)
Name: Apply-templates with-param
, Tab Trigger: wapply
<xsl:apply-templates select="${1:*}">
<xsl:with-param name="${2:param}">${3}</xsl:with-param>
${0}
</xsl:apply-templates>
Apply-templates sort-by (applysort
)
Name: Apply-templates sort-by
, Tab Trigger: applysort
<xsl:apply-templates select="${1:*}">
<xsl:sort select="${2:node}" order="${3:ascending}" data-type="${4:text}">${5}
</xsl:apply-templates>
${0}
Apply-templates plain (apply
)
Name: Apply-templates plain
, Tab Trigger: apply
<xsl:apply-templates select="${1:*}" />
${0}
Attribute blank (attr
)
Name: Attribute blank
, Tab Trigger: attr
<xsl:attribute name="${1:name}">${2}</xsl:attribute>
${0}
Attribute value-of (attrval
)
Name: Attribute value-of
, Tab Trigger: attrval
<xsl:attribute name="${1:name}">
<xsl:value-of select="${2:*}" />
</xsl:attribute>
${0}
Call-template (call
)
Name: Call-template
, Tab Trigger: call
<xsl:call-template name="${1:template}" />
${0}
Call-template with-param (wcall
)
Name: Call-template with-param
, Tab Trigger: wcall
<xsl:call-template name="${1:template}">
<xsl:with-param name="${2:param}">${3}</xsl:with-param>${4}
</xsl:call-template>
${0}
Choose (choose
)
Name: Choose
, Tab Trigger: choose
<xsl:choose>
<xsl:when test="${1:value}">
${2}
</xsl:when>${3}
</xsl:choose>
${0}
Copy-of (copyof
)
Name: Copy-of
, Tab Trigger: copyof
<xsl:copy-of select="${1:*}" />
${0}
Element blank (elem
)
Name: Element blank
, Tab Trigger: elem
<xsl:element name="${1:name}">
${2}
</xsl:element>
${0}
For-each (foreach
)
Name: For-each
, Tab Trigger: foreach
<xsl:for-each select="${1:*}">
${2}
</xsl:for-each>
${0}
If (if
)
Name: If
, Tab Trigger: if
<xsl:if test="${1:test}">
${2}
</xsl:if>
${0}
Import (imp
)
Name: Import
, Tab Trigger: imp
<xsl:import href="${1:stylesheet}" />
${0}
Include (inc
)
Name: Include
, Tab Trigger: inc
<xsl:include href="${1:stylesheet}" />
${0}
Otherwise (otherwise
)
Name: Otherwise
, Tab Trigger: otherwise
<xsl:otherwise>
${1}
</xsl:otherwise>
$0
Param (param
)
Name: Param
, Tab Trigger: param
<xsl:param name="${1:name}">
${2}
</xsl:param>
${0}
Stylesheet (style
)
Name: Stylesheet
, Tab Trigger: style
<xsl:stylesheet
version="1.0"
xmlns="${1}"
xpath-default-namespace="${2:${1}}"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
${0}
</xsl:stylesheet>
Template (temp
)
Name: Template
, Tab Trigger: temp
<xsl:template match="${1:*}">
${2}
</xsl:template>
$0
Template named (ntemp
)
Name: Template named
, Tab Trigger: ntemp
<xsl:template name="${1:name}">
${2}
</xsl:template>
$0
Text (text
)
Name: Text
, Tab Trigger: text
<xsl:text>${1}</xsl:text>
$0
Value-of (valof
)
Name: Value-of
, Tab Trigger: valof
<xsl:value-of select="${1:*}" />
${0}
Variable blank (var
)
Name: Variable blank
, Tab Trigger: var
<xsl:variable name="${1:name}">
${0}
</xsl:variable>
Variable select (varsel
)
Name: Variable select
, Tab Trigger: varsel
<xsl:variable select="${1:*}" />
${0}
When (when
)
Name: When
, Tab Trigger: when
<xsl:when test="${1:test}">
${0}
</xsl:when>
With-param (wparam
)
Name: With-param
, Tab Trigger: wparam
<xsl:with-param name="${1:name}">${2}</xsl:with-param>
${0}
With-param select (wparamsel
)
Name: With-param select
, Tab Trigger: wparamsel
<xsl:with-param name="${1:name}" select="${2:*}" />
${0}
Fatal message (fatal
)
Name: Fatal message
, Tab Trigger: fatal
<xsl:message terminate="yes">${1}</xsl:message>
${0}
Error message (error
)
Name: Error message
, Tab Trigger: error
<xsl:message><error>${1}</error></xsl:message>
${0}
Warning message (warn
)
Name: Warning message
, Tab Trigger: warn
<xsl:message><warn>${1}</warn></xsl:message>
${0}
Info message (info
)
Name: Info message
, Tab Trigger: info
<xsl:message><info>${1}</info></xsl:message>
${0}
Identity skeleton (ident
)
Name: Identity skeleton
, Tab Trigger: ident
<xsl:stylesheet version="1.0" xpath-default-namespace="${1:event-logging:3}" xmlns="${2:${1}}" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Whenever you match any node or any attribute -->
<xsl:template match="node( )|@*">
<!-- Copy the current node -->
<xsl:copy>
<!-- Including any attributes it has and any child nodes -->
<xsl:apply-templates select="@*|node( )"/>
</xsl:copy>
</xsl:template>
${0}
</xsl:stylesheet>
Records identity skeleton (recident
)
Name: Records identity skeleton
, Tab Trigger: recident
<xsl:stylesheet version="1.0" xpath-default-namespace="records:2" xmlns="event-logging:3" xmlns:stroom="stroom" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Match Root Object -->
<xsl:template match="records">
<Events xmlns="event-logging:3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="event-logging:3 file://event-logging-v3.4.2.xsd" Version="3.4.2">
<xsl:apply-templates />
</Events>
</xsl:template>
<xsl:template match="record">
<Event>
<EventTime>
<TimeCreated>${1:time}</TimeCreated>
</EventTime>
<EventSource>
<System>
<Name>${2:name}</Name>
<Environment>${3:environment}</Environment>
</System>
<Generator>${4:generator}</Generator>
<Device>${5:device}</Device>
</EventSource>
<EventDetail>
<TypeId>${6:type}</TypeId>
${0}
<xsl:apply-templates />
</EventDetail>
</Event>
</xsl:template>
<!-- Whenever you match any node or any attribute -->
<xsl:template match="node( )|@*">
<!-- Copy the current node -->
<xsl:copy>
<!-- Including any attributes it has and any child nodes -->
<xsl:apply-templates select="@*|node( )" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Events identity skeleton (evtident
)
Name: Events identity skeleton
, Tab Trigger: evtident
<xsl:stylesheet version="1.0" xpath-default-namespace="event-logging:3" xmlns="event-logging:3" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Match Root Object -->
<xsl:template match="Events">
<Events xmlns="event-logging:3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="event-logging:3 file://event-logging-v3.4.2.xsd" Version="3.4.2">
<xsl:apply-templates />
</Events>
</xsl:template>
${0}
<!-- Whenever you match any node or any attribute -->
<xsl:template match="node( )|@*">
<!-- Copy the current node -->
<xsl:copy>
<!-- Including any attributes it has and any child nodes -->
<xsl:apply-templates select="@*|node( )" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Data Splitter Snippets
CSV Splitter (csv
)
Name: CSV Splitter
, Tab Trigger: csv
<?xml version="1.0" encoding="UTF-8"?>
<dataSplitter
xmlns="data-splitter:3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="data-splitter:3 file://data-splitter-v3.0.xsd"
version="3.0">
<!-- Match each line using a new line character as the delimiter -->
<split delimiter="\n">
<!-- Take the matched line (using group 1 ignores the delimiters,
without this each match would include the new line character) -->
<group value="\$1">
<!-- Match each value separated by a comma as the delimiter -->
<split delimiter=",">
<!-- Output the value from group 1 (as above using group 1
ignores the delimiters, without this each value would include
the comma) -->
<data value="\$1"/>
${0}
</split>
</group>
</split>
</dataSplitter>
CSV Splitter with heading (csvh
)
Name: CSV Splitter with heading
, Tab Trigger: csvh
<?xml version="1.0" encoding="UTF-8"?>
<dataSplitter
xmlns="data-splitter:3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="data-splitter:3 file://data-splitter-v3.0.xsd"
version="3.0">
<!-- Match heading line (note that maxMatch="1" means that only the
first line will be matched by this splitter) -->
<split delimiter="\n" maxMatch="1">
<!-- Store each heading in a named list -->
<group>
<split delimiter=",">
<var id="heading" />
</split>
</group>
</split>
<!-- Match each record -->
<split delimiter="\n">
<!-- Take the matched line -->
<group value="\$1">
<!-- Split the line up -->
<split delimiter=",">
<!-- Output the stored heading for each iteration and the value
from group 1 -->
<data name="\$heading\$1" value="\$1" />
${0}
</split>
</group>
</split>
</dataSplitter>
Data Splitter Template (ds
)
Name: Data Splitter Template
, Tab Trigger: ds
<?xml version="1.0" encoding="UTF-8"?>
<dataSplitter
xmlns="data-splitter:3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="data-splitter:3 file://data-splitter-v3.0.xsd"
version="3.0">
${0}
</dataSplitter>
Data element with name attribute (nval
)
Name: Data element with name attribute
, Tab Trigger: nval
<data name="${1}" value="${2}"/>
${0}
Data element without name attribute (val
)
Name: Data element without name attribute
, Tab Trigger: val
<data value="${1}"/>
${0}
Var element (var
)
Name: Var element
, Tab Trigger: var
<var id="${1}"/>
${0}
Split element (spl
)
Name: Split element
, Tab Trigger: spl
<split delimiter="${1:\n}">
<group value="${2:\$1}">
${3}
</group>
</split>
${0}
Group element (gr
)
Name: Group element
, Tab Trigger: gr
<group value="${1:\$1}">
${2}
</group>
${0}
All element (all
)
Name: All element
, Tab Trigger: all
<all>
${1}
</all>
${0}
Regex element (reg
)
Name: Regex element
, Tab Trigger: reg
<regex ${1:dotall="true" }${2:caseInsensitive="true" }pattern="${3}">
<group>
${0}
</group>
</regex>
XMLFragmentParser Snippets
Events fragment template (evt
)
Name: Events fragment template
, Tab Trigger: evt
<?xml version="1.1" encoding="utf-8"?>
<!DOCTYPE Events [
<!ENTITY fragment SYSTEM "fragment">]>
<Events
xmlns="event-logging:${1:3}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="event-logging:${1} file://event-logging-v${2:3.4.2}.xsd"
version="${2}">
&fragment;
</records>
${0}
Records fragment template (rec
)
Name: Records fragment template
, Tab Trigger: rec
<?xml version="1.1" encoding="utf-8"?>
<!DOCTYPE Records [
<!ENTITY fragment SYSTEM "fragment">]>
<records
xmlns="records:${1:2}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="records:${1} file://records-v${2:2.0}.xsd"
version="${2}">
&fragment;
</records>
${0}
Documentation (Markdown) Snippets
Heading level 1 (h1
)
Name: Heading level 1
, Tab Trigger: h1
# ${1:heading}
${0}
Heading level 2 (h2
)
Name: Heading level 2
, Tab Trigger: h2
## ${1:heading}
${0}
Heading level 3 (h3
)
Name: Heading level 3
, Tab Trigger: h3
### ${1:heading}
${0}
Heading level 4 (h4
)
Name: Heading level 4
, Tab Trigger: h4
#### ${1:heading}
${0}
Heading level 5 (h5
)
Name: Heading level 5
, Tab Trigger: h5
##### ${1:heading}
${0}
Heading level 6 (h6
)
Name: Heading level 6
, Tab Trigger: h6
###### ${1:heading}
${0}
Fenced Block (fence
)
Name: Fenced Block
, Tab Trigger: fence
```${1:language}
${2}
```
${0}
Fenced block of XML (fxml
)
Name: Fenced block of XML
, Tab Trigger: fxml
```xml
${1}
```
${0}
Fenced block of plain text (ftext
)
Name: Fenced block of plain text
, Tab Trigger: ftext
```text
${1}
```
${0}
Inline code (inline
)
Name: Inline code
, Tab Trigger: inline
`${1:code}`${0}
Bold text (b
)
Name: Bold text
, Tab Trigger: b
**${1:bold_text}**${0}
Italic text (i
)
Name: Italic text
, Tab Trigger: i
_${1:italic_text}_${0}
Strike-through text (s
)
Name: Strike-through text
, Tab Trigger: s
~~${1:strikethrough_text}~~${0}
Bold italic text (bi
)
Name: Bold italic text
, Tab Trigger: bi
***${1:bold_italic_text}***${0}
Stroom Query Language Snippets
All Expression Functions are available as snippets.
They do not currently have tab
triggers.
Eval first StreamId (str
)
Name: Eval first StreamId
, Tab Trigger: str
eval StreamId = first(StreamId)
$0
Eval first EventId (evt
)
Name: Eval first EventId
, Tab Trigger: evt
eval EventId = first(EventId)
$0
Eval first Stream/EventIds (ids
)
Name: Eval first Stream/EventIds
, Tab Trigger: ids
eval StreamId = first(StreamId)
eval EventId = first(EventId)
$0
Eval first first value (first
)
Name: Eval first first value
, Tab Trigger: first
eval ${1:field_name} = first(${1})
$0
Dashboard Table Expression Editor Snippets
All Expression Functions are available as snippets.
They do not currently have tab
triggers.
5 - Expression functions
Expressions can be used to manipulate data on Stroom Dashboards and Queries.
Each function has a name, and some have additional aliases.
In some cases, functions can be nested. The return value for some functions being used as the arguments for other functions.
The arguments to functions can either be other functions, literal values, or they can refer to fields on the input data using the field reference ${val}
syntax.
5.1 - Aggregate Functions
Aggregate functions require that the dashboard columns without aggregate functions have a grouping level applied. The aggregate function will then be evaluated against the values in the group.
Average
Takes an average value of the arguments
average(arg)
mean(arg)
Examples
average(${val})
${val} = [10, 20, 30, 40]
> 25
mean(${val})
${val} = [10, 20, 30, 40]
> 25
Count
Counts the number of records that are passed through it. Doesn’t take any notice of the values of any fields.
count()
Example
Supplying 3 values...
count()
> 3
Count Groups
This is used to count the number of unique values where there are multiple group levels. For Example, a data set grouped as follows
- Group by Name
- Group by Type
A groupCount could be used to count the number of distinct values of ’type’ for each value of ’name'
Count Unique
This is used to count the number of unique values passed to the function where grouping is used to aggregate values in other columns. For Example, a data set grouped as follows
- Group by Name
- Group by Type
countUnique()
could be used to count the number of distinct values of ’type’ for each value of ’name'
Example
countUnique(${val})
${val} = ['bill', 'bob', 'fred', 'bill']
> 3
Distinct
Concatenates all distinct (unique) values together into a single string.
Works in the same way as joining()
except that it discards duplicate values.
Values are concatenated in the order that they are given to the function.
If a delimiter is supplied then the delimiter is placed between each concatenated string.
If a limit is supplied then it will only concatenate up to limit values.
distinct(values)
distinct(values, delimiter)
distinct(values, delimiter, limit)
Examples
distinct(${val}, ', ')
${val} = ['bill', 'bill', 'bob', 'fred', 'bill']
> 'bill, bob, fred'
distinct(${val}, '|', 2)
${val} = ['bill', 'bill', 'bob', 'fred', 'bill']
> 'bill|bob'
See Also
Selection Functions that work in a similar way to distinct()
.
Joining
Concatenates all values together into a single string.
Works in the same way as distinct()
except that duplicate values are included.
Values are concatenated in the order that they are given to the function.
If a delimiter is supplied then the delimiter is placed between each concatenated string.
If a limit is supplied then it will only concatenate up to limit values.
joining(values)
joining(values, delimiter)
joining(values, delimiter, limit)
Example
joining(${val}, ', ')
${val} = ['bill', 'bob', 'fred', 'bill']
> 'bill, bob, fred, bill'
See Also
Selection Functions that work in a similar way to joining()
.
Max
Determines the maximum value given in the args.
max(arg)
Examples
max(${val})
${val} = [100, 30, 45, 109]
> 109
# They can be nested
max(max(${val}), 40, 67, 89)
${val} = [20, 1002]
> 1002
Min
Determines the minimum value given in the args.
min(arg)
Examples
min(${val})
${val} = [100, 30, 45, 109]
> 30
# They can be nested
min(max(${val}), 40, 67, 89)
${val} = [20, 1002]
> 20
StDev (Standard Deviation)
Calculate the standard deviation for a set of input values.
stDev(arg)
Examples
round(stDev(${val}))
${val} = [600, 470, 170, 430, 300]
> 147
Sum
Sums all the arguments together
sum(arg)
Examples
sum(${val})
${val} = [89, 12, 3, 45]
> 149
Variance
Calculate the variance of a set of input values.
variance(arg)
Examples
variance(${val})
${val} = [600, 470, 170, 430, 300]
> 21704
5.2 - Cast Functions
To Boolean
Attempts to convert the passed value to a boolean data type.
toBoolean(arg1)
Examples:
toBoolean(1)
> true
toBoolean(0)
> false
toBoolean('true')
> true
toBoolean('false')
> false
To Double
Attempts to convert the passed value to a double data type.
toDouble(arg1)
Examples:
toDouble('1.2')
> 1.2
To Integer
Attempts to convert the passed value to a integer data type.
toInteger(arg1)
Examples:
toInteger('1')
> 1
To Long
Attempts to convert the passed value to a long data type.
toLong(arg1)
Examples:
toLong('1')
> 1
To String
Attempts to convert the passed value to a string data type.
toString(arg1)
Examples:
toString(1.2)
> '1.2'
5.3 - Date Functions
Parse Date
Parse a date and return a long number of milliseconds since the epoch. For details of the pattern syntax, see Dates & Times.
parseDate(aString)
parseDate(aString, pattern)
parseDate(aString, pattern, timeZone)
Example
parseDate('2014 02 22', 'yyyy MM dd', '+0400')
> 1393012800000
Format Date
Format a date supplied as milliseconds since the epoch. For details of the format pattern syntax, see Dates & Times.
formatDate(aLong)
formatDate(aLong, pattern)
formatDate(aLong, pattern, timeZone)
Example
formatDate(1393071132888, 'yyyy MM dd', '+1200')
> '2014 02 23'
Ceiling Year/Month/Day/Hour/Minute/Second
ceilingYear(args...)
ceilingMonth(args...)
ceilingDay(args...)
ceilingHour(args...)
ceilingMinute(args...)
ceilingSecond(args...)
Examples
ceilingSecond("2014-02-22T12:12:12.888Z"
> "2014-02-22T12:12:13.000Z"
ceilingMinute("2014-02-22T12:12:12.888Z"
> "2014-02-22T12:13:00.000Z"
ceilingHour("2014-02-22T12:12:12.888Z"
> "2014-02-22T13:00:00.000Z"
ceilingDay("2014-02-22T12:12:12.888Z"
> "2014-02-23T00:00:00.000Z"
ceilingMonth("2014-02-22T12:12:12.888Z"
> "2014-03-01T00:00:00.000Z"
ceilingYear("2014-02-22T12:12:12.888Z"
> "2015-01-01T00:00:00.000Z"
Floor Year/Month/Day/Hour/Minute/Second
floorYear(args...)
floorMonth(args...)
floorDay(args...)
floorHour(args...)
floorMinute(args...)
floorSecond(args...)
Examples
floorSecond("2014-02-22T12:12:12.888Z"
> "2014-02-22T12:12:12.000Z"
floorMinute("2014-02-22T12:12:12.888Z"
> "2014-02-22T12:12:00.000Z"
floorHour("2014-02-22T12:12:12.888Z"
> 2014-02-22T12:00:00.000Z"
floorDay("2014-02-22T12:12:12.888Z"
> "2014-02-22T00:00:00.000Z"
floorMonth("2014-02-22T12:12:12.888Z"
> "2014-02-01T00:00:00.000Z"
floorYear("2014-02-22T12:12:12.888Z"
> "2014-01-01T00:00:00.000Z"
Round Year/Month/Day/Hour/Minute/Second
roundYear(args...)
roundMonth(args...)
roundDay(args...)
roundHour(args...)
roundMinute(args...)
roundSecond(args...)
Examples
roundSecond("2014-02-22T12:12:12.888Z")
> "2014-02-22T12:12:13.000Z"
roundMinute("2014-02-22T12:12:12.888Z")
> "2014-02-22T12:12:00.000Z"
roundHour("2014-02-22T12:12:12.888Z"
> "2014-02-22T12:00:00.000Z"
roundDay("2014-02-22T12:12:12.888Z"
> "2014-02-23T00:00:00.000Z"
roundMonth("2014-02-22T12:12:12.888Z"
> "2014-03-01T00:00:00.000Z"
roundYear("2014-02-22T12:12:12.888Z"
> "2014-01-01T00:00:00.000Z"
5.4 - Link Functions
Links can be inserted into dashboard tables using the link
function.
All link types described in Internal Links can be added to dashboard tables using the link
function.
In addition to the link
function there are convenience functions such as annotation
, dashboard
, data
and stepping
that make it easier to supply the required link parameters.
Annotation
See Also
A helper function to make forming links to annotations easier than using Link. The Annotation function allows you to create a link to open the Annotation editor, either to view an existing annotation or to begin creating one with pre-populated values.
annotation(text, annotationId)
annotation(text, annotationId, [streamId, eventId, title, subject, status, assignedTo, comment])
If you provide just the text and an annotationId then it will produce a link that opens an existing annotation with the supplied ID in the Annotation Edit dialog.
Example
annotation('Open annotation', ${annotation:Id})
> [Open annotation](?annotationId=1234){annotation}
annotation('Create annotation', '', ${StreamId}, ${EventId})
> [Create annotation](?annotationId=&streamId=1234&eventId=45){annotation}
annotation('Escalate', '', ${StreamId}, ${EventId}, 'Escalation', 'Triage required')
> [Escalate](?annotationId=&streamId=1234&eventId=45&title=Escalation&subject=Triage%20required){annotation}
If you don’t supply an annotationId then the link will open the Annotation Edit dialog pre-populated with the optional arguments so that an annotation can be created.
If the annotationId is not provided then you must provide a streamId and an eventId.
If you don’t need to pre-populate a value then you can use ''
or null()
instead.
Example
annotation('Create suspect event annotation', null(), 123, 456, 'Suspect Event', null(), 'assigned', 'jbloggs')
> [Create suspect event annotation](?streamId=123&eventId=456&title=Suspect%20Event&assignedTo=jbloggs){annotation}
Dashboard
See Also
A helper function to make forming links to dashboards easier than using Link.
dashboard(text, uuid)
dashboard(text, uuid, params)
Example
dashboard('Click Here','e177cf16-da6c-4c7d-a19c-09a201f5a2da')
> [Click Here](?uuid=e177cf16-da6c-4c7d-a19c-09a201f5a2da){dashboard}
dashboard('Click Here','e177cf16-da6c-4c7d-a19c-09a201f5a2da', 'userId=user1')
> [Click Here](?uuid=e177cf16-da6c-4c7d-a19c-09a201f5a2da¶ms=userId%3Duser1){dashboard}
Data
See Also
A helper function to make forming links to data easier than using Link.
data(text, id, partNo, [recordNo, lineFrom, colFrom, lineTo, colTo, viewType, displayType])
Example
data('Quick View', ${StreamId}, 1)
> [Quick View]?id=1234&&partNo=1)
Example of non-segmented raw data section, viewed un-formatted in a stroom tab:
data('View Raw', ${StreamId}, ${partNo}, null(), 5, 1, 5, 342, 'source', 'tab')
Example of a single record (event) from a segmented stream, viewed formatted in a popup dialog:
data('View Cooked', ${StreamId}, 1, ${eventId})
Example of a single record (event) from a segmented stream, viewed formatted in a stroom tab:
data('View Cooked', ${StreamId}, 1, ${eventId}, null(), null(), null(), null(), 'preview', 'tab')
Link
See Also
Create a string that represents a hyperlink for display in a dashboard table.
link(url)
link(text, url)
link(text, url, type)
Example
link('https://www.somehost.com/somepath')
> [https://www.somehost.com/somepath](https://www.somehost.com/somepath)
link('Click Here','https://www.somehost.com/somepath')
> [Click Here](https://www.somehost.com/somepath)
link('Click Here','https://www.somehost.com/somepath', 'dialog')
> [Click Here](https://www.somehost.com/somepath){dialog}
link('Click Here','https://www.somehost.com/somepath', 'dialog|Dialog Title')
> [Click Here](https://www.somehost.com/somepath){dialog|Dialog Title}
Stepping
See Also
Open the Stepping tab for the requested data source.
stepping(text, id)
stepping(text, id, partNo)
stepping(text, id, partNo, recordNo)
Example
stepping('Click here to step',${StreamId})
> [Click here to step](?id=1)
5.5 - Logic Funtions
Equals
Evaluates if arg1 is equal to arg2
arg1 = arg2
equals(arg1, arg2)
Examples
'foo' = 'bar'
> false
'foo' = 'foo'
> true
51 = 50
> false
50 = 50
> true
equals('foo', 'bar')
> false
equals('foo', 'foo')
> true
equals(51, 50)
> false
equals(50, 50)
> true
Note that equals
cannot be applied to null
and error
values, e.g. x=null()
or x=err()
. The isNull()
and isError()
functions must be used instead.
Greater Than
Evaluates if arg1 is greater than to arg2
arg1 > arg2
greaterThan(arg1, arg2)
Examples
51 > 50
> true
50 > 50
> false
49 > 50
> false
greaterThan(51, 50)
> true
greaterThan(50, 50)
> false
greaterThan(49, 50)
> false
Greater Than or Equal To
Evaluates if arg1 is greater than or equal to arg2
arg1 >= arg2
greaterThanOrEqualTo(arg1, arg2)
Examples
51 >= 50
> true
50 >= 50
> true
49 >= 50
> false
greaterThanOrEqualTo(51, 50)
> true
greaterThanOrEqualTo(50, 50)
> true
greaterThanOrEqualTo(49, 50)
> false
If
Evaluates the supplied boolean condition and returns one value if true or another if false
if(expression, trueReturnValue, falseReturnValue)
Examples
if(5 < 10, 'foo', 'bar')
> 'foo'
if(5 > 10, 'foo', 'bar')
> 'bar'
if(isNull(null()), 'foo', 'bar')
> 'foo'
Less Than
Evaluates if arg1 is less than to arg2
arg1 < arg2
lessThan(arg1, arg2)
Examples
51 < 50
> false
50 < 50
> false
49 < 50
> true
lessThan(51, 50)
> false
lessThan(50, 50)
> false
lessThan(49, 50)
> true
Less Than or Equal To
Evaluates if arg1 is less than or equal to arg2
arg1 <= arg2
lessThanOrEqualTo(arg1, arg2)
Examples
51 <= 50
> false
50 <= 50
> true
49 <= 50
> true
lessThanOrEqualTo(51, 50)
> false
lessThanOrEqualTo(50, 50)
> true
lessThanOrEqualTo(49, 50)
> true
And
If all supplied arguments evaluate to true then return true, else false.
and(booleanValue, booleanValue)
Or
If one or more of the supplied arguments evaluate to true then return true, else false.
or(booleanValue, booleanValue)
Not
Inverts boolean values making true, false etc.
not(booleanValue)
Examples
not(5 > 10)
> true
not(5 = 5)
> false
not(false())
> true
5.6 - Mathematics Functions
Add
arg1 + arg2
Or reduce the args by successive addition
add(args...)
Examples
34 + 9
> 43
add(45, 6, 72)
> 123
Divide
Divides arg1 by arg2
arg1 / arg2
Or reduce the args by successive division
divide(args...)
Examples
42 / 7
> 6
divide(1000, 10, 5, 2)
> 10
divide(100, 4, 3)
> 8.33
Max
Determines the maximum value given in the args
max(args...)
Examples
max(100, 30, 45, 109)
> 109
# They can be nested
max(max(${val}), 40, 67, 89)
${val} = [20, 1002]
> 1002
Min
Determines the minimum value given in the args
min(args...)
Examples
min(100, 30, 45, 109)
> 30
They can be nested
min(max(${val}), 40, 67, 89)
${val} = [20, 1002]
> 20
Modulo
Determines the modulus of the dividend divided by the divisor.
modulo(dividend, divisor)
Examples
modulo(100, 30)
> 10
Multiply
Multiplies arg1 by arg2
arg1 * arg2
Or reduce the args by successive multiplication
multiply(args...)
Examples
4 * 5
> 20
multiply(4, 5, 2, 6)
> 240
Negate
Multiplies arg1 by -1
negate(arg1)
Examples
negate(80)
> -80
negate(23.33)
> -23.33
negate(-9.5)
> 9.5
Power
Raises arg1 to the power arg2
arg1 ^ arg2
Or reduce the args by successive raising to the power
power(args...)
Examples
4 ^ 3
> 64
power(2, 4, 3)
> 4096
Random
Generates a random number between 0.0 and 1.0
random()
Examples
random()
> 0.78
random()
> 0.89
...you get the idea
Subtract
arg1 - arg2
Or reduce the args by successive subtraction
subtract(args...)
Examples
29 - 8
> 21
subtract(100, 20, 34, 2)
> 44
Sum
Sums all the arguments together
sum(args...)
Examples
sum(89, 12, 3, 45)
> 149
Rounding Functions
These functions require a value, and an optional decimal places. If the decimal places are not given it will give you nearest whole number.
Ceiling
ceiling(value, decimalPlaces<optional>)
Examples
ceiling(8.4234)
> 9
ceiling(4.56, 1)
> 4.6
ceiling(1.22345, 3)
> 1.223
Floor
floor(value, decimalPlaces<optional>)
Examples
floor(8.4234)
> 8
floor(4.56, 1)
> 4.5
floor(1.2237, 3)
> 1.223
Round
round(value, decimalPlaces<optional>)
Examples
round(8.4234)
> 8
round(4.56, 1)
> 4.6
round(1.2237, 3)
> 1.224
Statistical Functions
Average
Takes an average value of the arguments.
The alias mean
can be used instead.
average(args...)
mean(args...)
Examples
average(10, 20, 30, 40)
> 25
mean(8.9, 24, 1.2, 1008)
> 260.525
StDev (Standard Deviation)
Calculate the standard deviation for a set of input values.
stDev(args...)
Examples
round(stDev(600, 470, 170, 430, 300))
> 147
Variance
Calculate the variance of a set of input values.
variance(args...)
Examples
variance(600, 470, 170, 430, 300)
> 21704
5.7 - Selection Functions
Selection functions are a form of aggregate function operating on grouped data. They select a sub-set of the child values.
See Also
Aggregate functions joining()
and distinct()
that work in a similar way to these selection functions.
Any
Selects the first value found in the group that is not null()
or err()
.
If no explicit ordering is set then the value selected is indeterminate.
any(${val})
Examples
any(${val})
${val} = [10, 20, 30, 40]
> 10
Bottom
Selects the bottom N values and returns them as a delimited string in the order they are read.
bottom(${val}, delimiter, limit)
Example
bottom(${val}, ', ', 2)
${val} = [10, 20, 30, 40]
> '30, 40'
First
Selects the first value found in the group even if it is null()
or err()
.
If no explicit ordering is set then the value selected is indeterminate.
first(${val})
Example
first(${val})
${val} = [10, 20, 30, 40]
> 10
Last
Selects the last value found in the group even if it is null()
or err()
.
If no explicit ordering is set then the value selected is indeterminate.
last(${val})
Example
last(${val})
${val} = [10, 20, 30, 40]
> 40
Nth
Selects the Nth value in a set of grouped values. If there is no explicit ordering on the field selected then the value returned is indeterminate.
nth(${val}, position)
Example
nth(${val}, 2)
${val} = [20, 40, 30, 10]
> 40
Top
Selects the top N values and returns them as a delimited string in the order they are read.
top(${val}, delimiter, limit)
Example
top(${val}, ', ', 2)
${val} = [10, 20, 30, 40]
> '10, 20'
5.8 - String Functions
Concat
Appends all the arguments end to end in a single string
concat(args...)
Example
concat('this ', 'is ', 'how ', 'it ', 'works')
> 'this is how it works'
Contains
Tests if inputString contains subString.
contains(inputString, subString)
Example
contains('this', 'this')
> true
contains('this', 'that')
> false
Current User
Returns the username of the user running the query.
currentUser()
Example
currentUser()
> 'jbloggs'
Decode
The arguments are split into 3 parts
- The input value to test
- Pairs of regex matchers with their respective output value
- A default result, if the input doesn’t match any of the regexes
decode(input, test1, result1, test2, result2, ... testN, resultN, otherwise)
It works much like a Java Switch/Case statement
Example
decode(${val}, 'red', 'rgb(255, 0, 0)', 'green', 'rgb(0, 255, 0)', 'blue', 'rgb(0, 0, 255)', 'rgb(255, 255, 255)')
${val}='blue'
> rgb(0, 0, 255)
${val}='green'
> rgb(0, 255, 0)
${val}='brown'
> rgb(255, 255, 255) // falls back to the 'otherwise' value
in Java, this would be equivalent to
String decode(value) {
switch(value) {
case "red":
return "rgb(255, 0, 0)"
case "green":
return "rgb(0, 255, 0)"
case "blue":
return "rgb(0, 0, 255)"
default:
return "rgb(255, 255, 255)"
}
}
decode('red')
> 'rgb(255, 0, 0)'
DecodeUrl
Decodes a URL
decodeUrl('userId%3Duser1')
> userId=user1
EncodeUrl
Encodes a URL
encodeUrl('userId=user1')
> userId%3Duser1
Exclude
If the supplied string matches one of the supplied match strings then return null, otherwise return the supplied string
exclude(aString, match...)
Example
exclude('hello', 'hello', 'hi')
> null
exclude('hi', 'hello', 'hi')
> null
exclude('bye', 'hello', 'hi')
> 'bye'
Hash
Cryptographically hashes a string
hash(value)
hash(value, algorithm)
hash(value, algorithm, salt)
Example
hash(${val}, 'SHA-512', 'mysalt')
> A hashed result...
If not specified the hash()
function will use the SHA-256
algorithm. Supported algorithms are determined by Java runtime environment.
Include
If the supplied string matches one of the supplied match strings then return it, otherwise return null
include(aString, match...)
Example
include('hello', 'hello', 'hi')
> 'hello'
include('hi', 'hello', 'hi')
> 'hi'
include('bye', 'hello', 'hi')
> null
Index Of
Finds the first position (zero based) of subString in inputString or -1
if it cannot be found. Uses a simple literal match.
indexOf(inputString, subString)
Example
indexOf('aa-bb-cc', '-')
> 2
Last Index Of
Finds the last position (zero based) of subString in inputString or -1
if it cannot be found. Uses a simple literal match.
lastIndexOf(inputString, subString)
Example
lastIndexOf('aa-bb-cc', '-')
> 5
Lower Case
Converts the string to lower case
lowerCase(aString)
Example
lowerCase('Hello DeVeLoPER')
> 'hello developer'
Match
Test an input string using a regular expression to see if it matches
match(input, regex)
Example
match('this', 'this')
> true
match('this', 'that')
> false
Query Param
Returns the value of the requested query parameter.
queryParam(paramKey)
Examples
queryParam('user')
> 'jbloggs'
Query Params
Returns all query parameters as a space delimited string.
queryParams()
Examples
queryParams()
> 'user=jbloggs site=HQ'
Replace
Perform text replacement on an input string using a regular expression to match part (or all) of the input string and a replacement string to insert in place of the matched part
replace(input, regex, replacement)
Example
replace('this', 'is', 'at')
> 'that'
String Length
Takes the length of a string
stringLength(aString)
Example
stringLength('hello')
> 5
Substring
Take a substring based on start/end index of letters
substring(aString, startIndex, endIndex)
Example
substring('this', 1, 2)
> 'h'
Substring After
Get the substring from the first string that occurs after the presence of the second string
substringAfter(firstString, secondString)
Example
substringAfter('aa-bb', '-')
> 'bb'
Substring Before
Get the substring from the first string that occurs before the presence of the second string
substringBefore(firstString, secondString)
Example
substringBefore('aa-bb', '-')
> 'aa'
Upper Case
Converts the string to upper case
upperCase(aString)
Example
upperCase('Hello DeVeLoPER')
> 'HELLO DEVELOPER'
5.9 - Type Checking Functions
Is Boolean
Checks if the passed value is a boolean data type.
isBoolean(arg1)
Examples:
isBoolean(toBoolean('true'))
> true
Is Double
Checks if the passed value is a double data type.
isDouble(arg1)
Examples:
isDouble(toDouble('1.2'))
> true
Is Error
Checks if the passed value is an error caused by an invalid evaluation of an expression on passed values, e.g. some values passed to an expression could result in a divide by 0 error.
Note that this method must be used to check for error
as error equality using x=err()
is not supported.
isError(arg1)
Examples:
isError(toLong('1'))
> false
isError(err())
> true
Is Integer
Checks if the passed value is an integer data type.
isInteger(arg1)
Examples:
isInteger(toInteger('1'))
> true
Is Long
Checks if the passed value is a long data type.
isLong(arg1)
Examples:
isLong(toLong('1'))
> true
Is Null
Checks if the passed value is null
.
Note that this method must be used to check for null
as null equality using x=null()
is not supported.
isNull(arg1)
Examples:
isNull(toLong('1'))
> false
isNull(null())
> true
Is Number
Checks if the passed value is a numeric data type.
isNumber(arg1)
Examples:
isNumber(toLong('1'))
> true
Is String
Checks if the passed value is a string data type.
isString(arg1)
Examples:
isString(toString(1.2))
> true
Is Value
Checks if the passed value is a value data type, e.g. not null
or error
.
isValue(arg1)
Examples:
isValue(toLong('1'))
> true
isValue(null())
> false
Type Of
Returns the data type of the passed value as a string.
typeOf(arg1)
Examples:
typeOf('abc')
> string
typeOf(toInteger(123))
> integer
typeOf(err())
> error
typeOf(null())
> null
typeOf(toBoolean('false'))
> false
5.10 - URI Functions
Fields containing a Uniform Resource Identifier (URI) in string form can queried to extract the URI’s individual components of authority
, fragment
, host
, path
, port
, query
, scheme
, schemeSpecificPart
and userInfo
. See either RFC 2306: Uniform Resource Identifiers (URI): Generic Syntax or Java’s java.net.URI Class for details regarding the components. If any component is not present within the passed URI, then an empty string is returned.
The extraction functions are
- extractAuthorityFromUri() - extract the Authority component
- extractFragmentFromUri() - extract the Fragment component
- extractHostFromUri() - extract the Host component
- extractPathFromUri() - extract the Path component
- extractPortFromUri() - extract the Port component
- extractQueryFromUri() - extract the Query component
- extractSchemeFromUri() - extract the Scheme component
- extractSchemeSpecificPartFromUri() - extract the Scheme specific part component
- extractUserInfoFromUri() - extract the UserInfo component
If the URI is http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details
the table below displays the extracted components
Expression | Extraction |
---|---|
extractAuthorityFromUri(${URI}) | foo:bar@w1.superman.com:8080 |
extractFragmentFromUri(${URI}) | more-details |
extractHostFromUri(${URI}) | w1.superman.com |
extractPathFromUri(${URI}) | /very/long/path.html |
extractPortFromUri(${URI}) | 8080 |
extractQueryFromUri(${URI}) | p1=v1&p2=v2 |
extractSchemeFromUri(${URI}) | http |
extractSchemeSpecificPartFromUri(${URI}) | //foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2 |
extractUserInfoFromUri(${URI}) | foo:bar |
extractAuthorityFromUri
Extracts the Authority component from a URI
extractAuthorityFromUri(uri)
Example
extractAuthorityFromUri('http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details')
> 'foo:bar@w1.superman.com:8080'
extractFragmentFromUri
Extracts the Fragment component from a URI
extractFragmentFromUri(uri)
Example
extractFragmentFromUri('http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details')
> 'more-details'
extractHostFromUri
Extracts the Host component from a URI
extractHostFromUri(uri)
Example
extractHostFromUri('http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details')
> 'w1.superman.com'
extractPathFromUri
Extracts the Path component from a URI
extractPathFromUri(uri)
Example
extractPathFromUri('http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details')
> '/very/long/path.html'
extractPortFromUri
Extracts the Port component from a URI
extractPortFromUri(uri)
Example
extractPortFromUri('http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details')
> '8080'
extractQueryFromUri
Extracts the Query component from a URI
extractQueryFromUri(uri)
Example
extractQueryFromUri('http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details')
> 'p1=v1&p2=v2'
extractSchemeFromUri
Extracts the Scheme component from a URI
extractSchemeFromUri(uri)
Example
extractSchemeFromUri('http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details')
> 'http'
extractSchemeSpecificPartFromUri
Extracts the SchemeSpecificPart component from a URI
extractSchemeSpecificPartFromUri(uri)
Example
extractSchemeSpecificPartFromUri('http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details')
> '//foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2'
extractUserInfoFromUri
Extracts the UserInfo component from a URI
extractUserInfoFromUri(uri)
Example
extractUserInfoFromUri('http://foo:bar@w1.superman.com:8080/very/long/path.html?p1=v1&p2=v2#more-details')
> 'foo:bar'
5.11 - Value Functions
Err
Returns err
err()
False
Returns boolean false
false()
Null
Returns null
null()
True
Returns boolean true
true()
6 - Background Jobs
The jobs in the list are in the order they appear in the Stroom UI.
Data Delete
Before data is physically removed from the database and file system it is marked as logically deleted by adding a flag to the metadata record in the database.
Data can be logically deleted by a user from the UI or via a process such as data retention.
Data is deleted logically as it is faster to do than a physical delete (important in the UI), and it also allows for data to be restored (undeleted) from the UI.
This job performs the actual physical deletion of data that has been marked logically deleted for longer than the duration configured with stroom.data.store.deletePurgeAge
.
All data files associated with a metadata record are deleted from the file system before the metadata is physically removed from the database.
Data Processor
Processes data by finding data that matches processing filters on each pipeline.
When enabled, each worker node asks the master node for data processing tasks.
The master node creates tasks based on processing filters added to the Processors
screen of each pipeline and supplies them to the requesting workers.
Node Status
How frequently we try write stats about node status including JVM and memory usage.
Processor Task Creator
Create Processor Tasks from Processor Filters.
Query History Clean
How frequently items in the query history are removed from the history if their age is older than stroom.history.daysRetention
or if the number of items in the history exceeds stroom.history.itemsRetention
.
Account Maintenance
This job checks user accounts on the system and de-activates them under the following conditions:
- An unused account that has been inactive for longer than the age configured by
stroom.security.identity.passwordPolicy.neverUsedAccountDeactivationThreshold
. - An account that has been inactive for longer than the age configured by
stroom.security.identity.passwordPolicy.unusedAccountDeactivationThreshold
.
Analytic Executor: Scheduled Query
Run scheduled index query analytics periodically
Analytic Executor: Table Builder
Analytic Executor: Table Builder
Attribute Value Data Retention
Deletes Meta attribute values (additional and less valuable metadata) older than stroom.data.meta.metaValue.deleteAge
.
Elastic Index Retention
Logically delete indexed documents in Elasticsearch indexes based on the specified deletion query.
File System Volume Status
Scans your data volumes to ensure they are available and determines how much free space they have. Records this status in the Volume Status table.
Index Shard Delete
How frequently index shards that have been logically deleted are physically deleted from the file system.
Index Shard Retention
How frequently index shards that are older then their retention period are logically deleted.
Index Volume Status
Scans your index volumes to ensure they are available and determines how much free space they have. Records this status in the Index Volume Status table.
Index Writer Cache Sweep
How frequently entries in the Index Shard Writer cache are evicted based on the time-to-live, time-to-idle and cache size settings.
Index Writer Flush
How frequently in-memory changes to the index shards are flushed to the file system and committed to the index.
Java Heap Histogram Statistics
How frequently heap histogram statistics will be captured. This can be useful for diagnosing issues or seeing where memory is being used. Each run will result in a JVM pause so car should be taken when running this on a production system.
Orphan File Finder
Job to find files that do not exist in the meta store.
Orphan Meta Finder
Job to find items in the meta store that have no associated data.
Pipeline Destination Roll
How frequently rolling pipeline destinations, e.g. a Rolling File Appender are checked to see if they need to be rolled. This frequency should be at least as short as the most frequent rolling frequency.
Policy Based Data Retention
Run the policy based data retention rules over the data and logically delete and data that should no longer be retained.
Processor Task Manager Disown Dead Tasks
Tasks that seem to be stuck processing due to the death of a processing node are disowned and added back to the task queue for processing after stroom.processor.disownDeadTasksAfter
.
Processor Task Manager Release Old Queued Tasks
Release queued tasks from old master nodes.
Processor Task Queue Statistics
How frequently statistics about the state of the stream processing task queue are captured.
Processor Task Retention
This job is responsible for cleaning up redundant processors, tasks and filters. If it is not run then these will build up on the system consuming space in the database.
This job relies on the property stroom.processor.deleteAge
to govern what is deemed old.
The deleteAge
is used to derive the delete threshold, i.e. the current time minus deleteAge
.
When the job runs it executes the following steps:
-
Logically Delete Processor Tasks - Logically delete all processor tasks belonging to processor filters that have been logically deleted.
-
Logically Delete Processor Filters - Logically delete old processor filters with a state of
COMPLETE
and no associated tasks. Filters are considered old if the last poll time is less than the delete threshold. -
Physically Delete Processor Tasks - Physically delete all old processor tasks with a status of
COMPLETE
orDELETED
. Tasks are considered old if they have no status time or the status time (the time the status was last changed) is less than the delete threshold. -
Physically Delete Processor Filters - Physically delete all old processor filters that have already been logically deleted. Filters are considered old if the last update time is less than the delete threshold. A filter can be logically deleted either by the step above or explicitly by a user in the user interface.
-
Physically Delete Processors - Physically delete all old processors that have already been logically deleted. Processors are considered old if the last update time is less than the delete threshold. A processor can only be logically deleted by the user in the user interface.
Therefore for items not deleted by a user, there will be a delay equal to deleteAge
before logical deletion, then another delay equal to deleteAge
before final physical deletion.
Property Cache Reload
Stroom’s configuration properties can each be configured globally in the database. This job controls the frequency that each node refreshes the values of its properties cache from the global database values. See also Properties.
Ref Data Off-heap Store Purge
Purges all data older than the purge age defined by property stroom.pipeline.purgeAge
.
See also Reference Data.
SQL Stats Database Aggregation
This job controls the frequency that the database statistics aggregation process is run.
This process takes the entries in SQL_STAT_VAL_SRC
and merges them into the main statistics tables SQL_STAT_KEY
and SQL_STAT_KEY
.
As this process is reliant on data flushed by the SQL Stats In Memory Flush job it is advisable to schedule it to run after that, leaving some time for the in-memory flush to finish.
SQL Stats In Memory Flush
SQL Statistics are initially held and aggregated in memory.
This job controls the frequency that the in memory statistics are flushed from the in memory buffer to the staging table SQL_STAT_VAL_SRC
in the database.
Solr Index Optimise
How frequently Solr index segments are explicitly optimised by merging them into one.
Solr Index Retention
How frequently a process is run to delete items from the Solr indexes that don’t meet the retention rule of that index.
7 - Keyboard Shortcuts
This section describes all the keyboard shortcuts that are available to use in Stroom. Some shortcuts apply everywhere and some are specific to the screen that you are in or the user interface component that has focus.
Keyboard shortcuts can take two forms:
- Combination - Multiple keys pressed at the same time, e.g. Ctrl ^ + Enter ↵ .
- Sequence* - Multiple keys pressed in sequence with only one key pressed at a time, e.g. g , t , press
Warning
Currently these keyboard shortcuts will not work if a visualisation or documentation preview pane has focus. This is a known issue that will be addressed in the future.General Shortcuts
Action | Shortcut | Notes |
---|---|---|
Cancel | Esc | Closes/cancels an open popup or dialog discarding any changes. Equivalent to clicking | on a dialog.
Select / toggle | Space ␣ | Selects a row/item in a table, list, selection box or tab bar. Toggles a focused checkbox. Selects a radio button. |
Execute | Enter ↵ | Selects a row/item in a table, list, selection box or tab bar. Opens a Document/Date picker dialog on a Document/Date field. |
OK | Ctrl ^ + Enter ↵ | Equivalent to clicking | on a dialog, closes the dialog accepting any changes.
Context Menu | Menu ☰ | Shows the context menu for the selected item, e.g. the selected item in the explorer tree. |
Select all | Ctrl ^ + a | |
Save | Ctrl ^ + s | Save the current tab. |
Save all | Ctrl ^ + Shift ⇧ + s | Saves all open and un-saved tabs. |
Close | Alt + w | Close the current tab. |
Close all | Shift ⇧ + Alt + w | Closes all open tabs. |
Movement
Movement within lists, selection boxes or tab bars you can use the cursor keys, hjkl
or wasd
to move between items.
Action | Shortcut |
---|---|
Up | ⬆ or k or w |
Down | ⬇ or j or s |
Left | ⬅ or h or a |
Right | ➡ or l or d |
You can also move up or down by page using:
Action | Shortcut |
---|---|
Page Up | PageUp |
Page Down | PageDown |
Home / Start | Home |
End | End |
Finding Things
Action | Shortcut | Notes |
---|---|---|
Find documents by name | Shift ⇧ + Alt + f or Shift ⇧ , Shift ⇧ | Find documents by name, type, UUID . |
Find in content | Ctrl ^ + Shift ⇧ + f | Find documents whose content contains the search term. This is the same as clicking the icon on the explorer tree. |
Recent items | Ctrl ^ + e | Find a document in a list of the most recently opened items. |
Locate document | Alt + l | Locate the currently open document in the explorer tree. This is the same as clicking the | icon on the explorer tree.
Help | F1 | Show the help popup for the currently focused screen control, e.g. a text box. This shortcut will only work if there is a help | next to the control.
Focus the Explorer Tree filter | Ctrl ^ + / | Changes focus to the Quick Filter in the Explorer Tree pane. |
Focus the current tab Quick Filter | / | If the currently open tab has a Quick Filter bar it will change focus to that so a filter term can be entered. |
Direct Access to Screens
The following shortcuts are all of the sequential type with the mnemonic Goto X. These shortcuts may not do anything if you do not have the required permissions for the screen in question.
Action | Shortcut | Notes |
---|---|---|
Goto Application Permissions | g , a | |
Goto Caches | g , c | |
Goto Dependencies | g , d | |
Goto Explorer Tree | g , e | Changes focus to the Explorer Tree so the user can use the Movement shortcuts to move around the tree to select different documents. |
Goto Index Volumes | g , i | |
Goto Jobs | g , j | |
Goto API Keys | g , k | |
Goto Nodes | g , n | |
Goto Properties | g , p | |
Goto Data Retention | g , r | |
Goto Search Results | g , s | |
Goto Server Tasks | g , t | |
Goto User Preferences | g , u | |
Goto Data Volumes | g , v | |
Goto User Accounts | g , x |
Creating New Documents
The following shortcuts will open the dialog to create a new document in the currently selected explorer tree folder. If a document is currently selected in the explorer tree then the new document will be created in the same folder as the selected document. If nothing is selected or multiple items are selected then these key sequences have no effect.
Action | Shortcut |
---|---|
Create Elastic Index | c , c |
Create Dashboard | c , d |
Create Feed | c , e |
Create Folder | c , f |
Create Dictionary | c , i |
Create Lucene Index | c , l |
Create Documentation | c , o |
Create Pipeline | c , p |
Create Query | c , q |
Create Analytic Rule | c , r |
Create Text Converter | c , t |
Create View | c , v |
Create XSLT | c , x |
Screen Specific Shortcuts
Dashboard
The following shortcuts are available when editing a Dashboard
.Action | Shortcut | Notes |
---|---|---|
Execute all queries | Ctrl ^ + Enter ↵ | Executes all queries on the Dashboard. This is the same as clicking | .
Pipeline Stepping
The following shortcuts are available when stepping
a pipeline.Action | Shortcut | Notes |
---|---|---|
Step refresh | Ctrl ^ + Enter ↵ | Refresh the current step. This is the same as clicking | .
Query
The following shortcuts are available when editing a Query
.Action | Shortcut | Notes |
---|---|---|
Execute query | Ctrl ^ + Enter ↵ | Execute the current query. This is the same as clicking | .
Text Editor
The following common shortcuts are available when editing text editing text in the Ace text editor that is used on many screens in Stroom, e.g. when editing a Pipeline or Query.
Action | Shortcut | Notes |
---|---|---|
Undo | Ctrl ^ + z | Undo last action. |
Redo | Ctrl ^ + Shift ⇧ + z | Redo previously undone action. |
Toggle comment | Ctrl ^ + / | Toggle commenting of current line/selection. Applies when editing XML, XSLT or Javascript. |
Move line up | Alt + ⬆ | Move line/selection up. |
Move line down | Alt + ⬇ | Move line/selection down. |
Delete line | Ctrl ^ + d | Delete the current line. |
Find | Ctrl ^ + f | Open find dialog. |
Find/replace | Ctrl ^ + h | Open find/replace dialog. |
Find next match | Ctrl ^ + k | Find next match. |
Find previous match | Ctrl ^ + Shift ⇧ + k | Find previous match. |
Indent selection | Tab ↹ | Indent the selected text. |
Outdent selection | Shift ⇧ + Tab ↹ | Un-indent the selected text. |
Upper-case | Ctrl ^ + u | Make the selected text upper-case. |
Open Completion list | Ctrl ^ + Space ␣ | Open the code completion list to show suggestions based on the current word. See Auto-Completion. |
Trigger snippet | Tab ↹ | Trigger the insertion of a snippet for the currently entered snippet trigger text. See Tab Triggers. |
See Ace Default keyboard shortcuts for more.
If you know Vim key bindings then the Ace editor supports a reasonable sub-set of them, see Vim Key Bindings.
8 - Pipeline Elements
Reader
Reader elements decode the data in raw byte form using the Feed’s configured character encoding. Some of them will also transform the data at the character level before the data are parsed into a structured form.
BOMRemovalFilterInput
Removes the Byte Order Mark (if present) from the stream.
BadTextXMLFilterReader
Escapes the content of a configured list of named XML elements that are know to potentially contain un-escaped XML reserved characters.
For example the element <Expression>$time < now()</Expression>
would be transformed to <Expression>$time < now()</Expression>
if property leafList
is set to Expression
.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
tags | A comma separated list of XML element names (case sensitive) between which non-escaped XML characters will be escaped, e.g. ‘>’ => ‘>’. | - | String |
FindReplaceFilter
Replaces strings or regexes with new strings.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
bufferSize | The number of characters to buffer when matching the regex. | 1000 | Integer |
dotAll | Let ‘.’ match all characters in a regex. | false | Boolean |
escapeFind | Whether or not to escape find pattern or text. | true | Boolean |
escapeReplacement | Whether or not to escape replacement text. | true | Boolean |
find | The text or regex pattern to find and replace. | - | String |
maxReplacements | The maximum number of times to try and replace text. There is no limit by default. | - | String |
regex | Whether the pattern should be treated as a literal or a regex. | false | Boolean |
replacement | The replacement text. | - | String |
showReplacementCount | Show total replacement count | true | Boolean |
InvalidCharFilterReader
Removes any characters that are not in the standard XML character set. The version of XML (e.g. 1.0 or 1.1) can be set using the ‘xmlVersion’ property.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
warnOnRemoval | Log a warning if any characters have been removed from the input stream. | true | Boolean |
xmlVersion | XML version, e.g. ‘1.0’ or ‘1.1’ | 1.1 | String |
InvalidXMLCharFilterReader
Replaces any characters that are not in the standard XML character set with a ‘�’. The version of XML (e.g. 1.0 or 1.1) can be set using the ‘xmlVersion’ property.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
warnOnReplacement | Log a warning if any characters have been replaced in the input stream. | true | Boolean |
xmlVersion | XML version, e.g. ‘1.0’ or ‘1.1’ | 1.1 | String |
Reader
A basic reader that simply decodes the raw bytes using the Feed’s configured character encoding. It does not transform the data in any other way.
Parser
Parser elements parse raw text data that has an expected structure (e.g. XML, JSON, CSV) into XML events (elements, attributes, text, etc) that can be further validated or transformed using XSLT. The choice of Parser will be dictated by the structure of the data. If no Reader is used before the Parser, the Parser will also do the job of a simple Reader and decode the raw bytes using the Feed’s configured character encoding.
CombinedParser
The original general-purpose reader/parser that covers all source data types but provides less flexibility than the source format-specific parsers such as dsParser.
It effectively combines a BOMRemovalFilterInput, an InvalidCharFilterReader and Parser (based on the type
property.
Warning
It is strongly recommended to instead use a combination of Readers and one of the type specific Parsers. This will make the intent of the pipeline much clearer and allow for much greater control.Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
fixInvalidChars | Fix invalid XML characters from the input stream. | false | Boolean |
namePattern | A name pattern to load a text converter dynamically. | - | String |
suppressDocumentNotFoundWarnings | If the text converter cannot be found to match the name pattern suppress warnings. | false | Boolean |
textConverter | The text converter configuration that should be used to parse the input data. | - | Document |
type | The parser type, e.g. ‘JSON’, ‘XML’, ‘Data Splitter’. | - | String |
DSParser
A parser for handling structured plain text data (e.g. CSV or fixed width fields) using the Data Splitter domain specific language. For more details see Data Splitter.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
namePattern | A name pattern to load a data splitter dynamically. | - | String |
suppressDocumentNotFoundWarnings | If the data splitter cannot be found to match the name pattern suppress warnings. | false | Boolean |
textConverter | The data splitter configuration that should be used to parse the input data. | - | Document |
JSONParser
A built-in parser for parsing JSON source data (in JSON fragment format) into an XML representation of the JSON. The Resulting XML will conform to the http://www.w3.org/2013/XSL/json namespace.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
addRootObject | Add a root map element. | true | Boolean |
allowBackslashEscapingAnyCharacter | Feature that can be enabled to accept quoting of all character using backslash quoting mechanism: if not enabled, only characters that are explicitly listed by JSON specification can be thus escaped (see JSON spec for small list of these characters) | false | Boolean |
allowComments | Feature that determines whether parser will allow use of Java/C++ style comments (both ‘/’+’*’ and ‘//’ varieties) within parsed content or not. | false | Boolean |
allowMissingValues | Feature allows the support for “missing” values in a JSON array: missing value meaning sequence of two commas, without value in-between but only optional white space. | false | Boolean |
allowNonNumericNumbers | Feature that allows parser to recognize set of “Not-a-Number” (NaN) tokens as legal floating number values (similar to how many other data formats and programming language source code allows it). | false | Boolean |
allowNumericLeadingZeros | Feature that determines whether parser will allow JSON integral numbers to start with additional (ignorable) zeroes (like: 000001). | false | Boolean |
allowSingleQuotes | Feature that determines whether parser will allow use of single quotes (apostrophe, character ‘'’) for quoting Strings (names and String values). If so, this is in addition to other acceptable markers but not by JSON specification). | false | Boolean |
allowTrailingComma | Feature that determines whether we will allow for a single trailing comma following the final value (in an Array) or member (in an Object). These commas will simply be ignored. | false | Boolean |
allowUnquotedControlChars | Feature that determines whether parser will allow JSON Strings to contain unquoted control characters (ASCII characters with value less than 32, including tab and line feed characters) or not. If feature is set false, an exception is thrown if such a character is encountered. | false | Boolean |
allowUnquotedFieldNames | Feature that determines whether parser will allow use of unquoted field names (which is allowed by Javascript, but not by JSON specification). | false | Boolean |
allowYamlComments | Feature that determines whether parser will allow use of YAML comments, ones starting with ‘#’ and continuing until the end of the line. This commenting style is common with scripting languages as well. | false | Boolean |
XMLFragmentParser
A parser to convert multiple XML fragments into an XML document. For example the data may contain:
<Event>...</Event>
<Event>...</Event>
i.e. with no root element, so not valid XML.
The XMLFragmentParser will wrap the fragments with a root element as defined in the TextConverter document configured with the textConverterRef
property.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
namePattern | A name pattern to load a text converter dynamically. | - | String |
suppressDocumentNotFoundWarnings | If the text converter cannot be found to match the name pattern suppress warnings. | false | Boolean |
textConverter | The XML fragment wrapper that should be used to wrap the input XML. | - | Document |
XMLParser
A parser to parse data that is expected to be XML into a series of XML events that can be consumed by a Filter element.
Filter
Filter elements work with XML events that have been generated by a parser. They can consume the events without modifying them, e.g. RecordCountFilter or modify them in some way, e.g. XSLTFilter. Multiple filters can be used one after another with each using the output from the last as its input.
DynamicIndexingFilter
A filter to send source data to an index.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
index | The index to send records to. | - | Document |
DynamicSearchResultOutputFilter
DynamicSearchResultOutputFilter
Used in a search extraction pipeline for extracting field values that have not been stored in the index and where the fields are dynamic and derived from the data rather than being defined in the Index settings.
Consumes XML events in the index-documents:1
namespace to convert them into a form so that they can be used in a Dashboard/Query/Analytic.
ElasticIndexingFilter
A filter consuming XML events in the records:2
namespace to index/store the fields
and their values in an Elasticsearch Index.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
batchSize | Maximum number of documents to index in each bulk request. | 10000 | Integer |
cluster | Target Elasticsearch cluster. | - | Document |
indexName | Name of the Elasticsearch index. Variables specified such as {year} are replaced with the corresponding field values contained in the document root. Field names beginning with an underscore are not written to the document and are only used in the index name pattern. |
- | String |
ingestPipeline | Name of the Elasticsearch ingest pipeline to execute when indexing. | - | String |
purgeOnReprocess | When reprocessing a stream, first delete any documents from the index matching the source stream ID. | true | Boolean |
refreshAfterEachBatch | Refresh the index after each batch is processed, making the indexed documents visible to searches. | false | Boolean |
HttpPostFilter
This element is deprecated, you should instead use the much more flexible HTTPAppender . This element will simply POST the output of the XML events to the configured URL.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
receivingApiUrl | The URL of the receiving API. | - | String |
IdEnrichmentFilter
Adds the attributes ‘StreamId’ and ‘EventId’ to the ’event’ element to enrich the event with its ordinal number in the stream and the ID of the stream that it belongs to.
ID enrichment is required to be able to index events as it provides them with an ID that is unique within Stroom.
It assumes that an record/event is an XML element at the first level below the root element, i.e. for ’event-logging:3’ XML this means the <Event>
element.
IndexingFilter
A filter consuming XML events in the records:2
namespace to index/store the fields
and their values in a Lucene Index.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
index | The index to send records to. | - | Document |
RecordCountFilter
Counts events/records in the stream.
An event/record is taken to be an XML element that is at the first level below the root element, i.e. for ’event-logging:3’ XML this means the <Event>
element.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
countRead | Is this filter counting records read or records written? | true | Boolean |
RecordOutputFilter
Filters out records/events that have raised an Error or Fatal Error during processing.
If all records/events have raised at least an Error then no XML events will be output.
It assumes that an record/event is an XML element at the first level below the root element, i.e.
for ’event-logging:3’ XML this means the <Event>
element.""",
ReferenceDataFilter
Takes XML input (conforming to the reference-data:2 schema) and loads the data into the Reference Data Store. Reference data values can be either simple strings or XML fragments.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
overrideExistingValues | Allow duplicate keys to override existing values? | true | Boolean |
warnOnDuplicateKeys | Warn if there are duplicate keys found in the reference data? | false | Boolean |
SafeXMLFilter
Restricts the characters to a very simple set consisting of [a-zA-Z0-9]
and [ .:-_/]
.
All other characters are replaced by ~NNN
, where NNN
is a three digit codepoint for the replaced character.
SchemaFilter
Checks the format of the source data against one of a number of XML schemas. This ensures that if non-compliant data is generated, it will be flagged as in error and will not be passed to any subsequent processing elements.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
namespaceURI | Limits the schemas that can be used to validate data to those with a matching namespace URI. | - | String |
schemaGroup | Limits the schemas that can be used to validate data to those with a matching schema group name. | - | String |
schemaLanguage | The schema language that the schema is written in. | http://www.w3.org/2001/XMLSchema | String |
schemaValidation | Should schema validation be performed? | true | Boolean |
systemId | Limits the schemas that can be used to validate data to those with a matching system id. | - | String |
SearchResultOutputFilter
Used in a search extraction pipeline for extracting field values that have not been stored in the index and where the field definitions are defined in the Index settings.
Consumes XML events in the records:2
namespace to convert them into a form so that they can be used in a Dashboard/Query/Analytic.
SolrIndexingFilter
Delivers source data to the specified index in an external Solr instance/cluster.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
batchSize | How many documents to send to the index in a single post. | 1000 | Integer |
commitWithinMs | Commit indexed documents within the specified number of milliseconds. | -1 | Integer |
index | The index to send records to. | - | Document |
softCommit | Perform a soft commit after every batch so that docs are available for searching immediately (if using NRT replicas). | true | Boolean |
SplitFilter
Splits multi-record source data into smaller groups of records prior to delivery to an XSLT. This allows the XSLT to process data more efficiently than loading a potentially huge input stream into memory.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
splitCount | The number of elements at the split depth to count before the XML is split. | 10000 | Integer |
splitDepth | The depth of XML elements to split at. | 1 | Integer |
storeLocations | Should this split filter store processing locations. | true | Boolean |
StatisticsFilter
An element to allow the source data (conforming to the statistics
XML Schema) to be sent to the MySQL based statistics data store.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
statisticsDataSource | The statistics data source to record statistics against. | - | Document |
StroomStatsFilter
An element to allow the source data (conforming to the statistics
XML Schema) to be sent to an external stroom-stats service.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
flushOnSend | At the end of the stream, wait for acknowledgement from the Kafka broker for all the messages sent. This ensures errors are caught in the pipeline process. | true | Boolean |
kafkaConfig | The Kafka config to use. | - | Document |
statisticsDataSource | The stroom-stats data source to record statistics against. | - | Document |
XPathExtractionOutputFilter
TODO - Add description
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
multipleValueDelimiter | The string to delimit multiple simple values. | , | String |
XSLTFilter
An element used to transform XML data from one form to another using XSLT. The specified XSLT can be used to transform the input XML into XML conforming to another schema or into other forms such as JSON, plain text, etc.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
suppressXSLTNotFoundWarnings | If XSLT cannot be found to match the name pattern suppress warnings. | false | Boolean |
usePool | Advanced: Choose whether or not you want to use cached XSLT templates to improve performance. | true | Boolean |
xslt | The XSLT to use. | - | Document |
xsltNamePattern | A name pattern to load XSLT dynamically. | - | String |
Writer
Writers consume XML events (from Parsers and Filters) and convert them into a stream of bytes using the character encoding configured on the Writer (if applicable). The output data can then be fed to a Destination.
JSONWriter
Writer to convert XML data conforming to the http://www.w3.org/2013/XSL/json XML Schema into JSON format.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
encoding | The output character encoding to use. | UTF-8 | String |
indentOutput | Should output JSON be indented and include new lines (pretty printed)? | false | Boolean |
TextWriter
Writer to convert XML character data events into plain text output.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
encoding | The output character encoding to use. | UTF-8 | String |
footer | Footer text that can be added to the output at the end. | - | String |
header | Header text that can be added to the output at the start. | - | String |
XMLWriter
Writer to convert XML events data into XML output in the specified character encoding.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
encoding | The output character encoding to use. | UTF-8 | String |
indentOutput | Should output XML be indented and include new lines (pretty printed)? | false | Boolean |
suppressXSLTNotFoundWarnings | If XSLT cannot be found to match the name pattern suppress warnings. | false | Boolean |
xslt | A previously saved XSLT, used to modify the output via xsl:output attributes. | - | Document |
xsltNamePattern | A name pattern for dynamic loading of an XSLT, that will modfy the output via xsl:output attributes. | - | String |
Destination
Destination elements consume a stream of bytes from a Writer and persist then to a destination. This could be a file on a file system or to Stroom’s stream store.
AnnotationWriter
Consume XML documents in the annotation:1
namespace and writes them as Stroom Annotations.
Allows for the annotating of events that meet some criteria.
FileAppender
A destination used to write an output stream to a file on the file system. If multiple paths are specified in the ‘outputPaths’ property it will pick one at random to write to.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
filePermissions | Set file system permissions of finished files (example: ‘rwxr–r–’) | - | String |
outputPaths | One or more destination paths for output files separated with commas. Replacement variables can be used in path strings such as ${feed}. | - | String |
rollSize | When the current output file exceeds this size it will be closed and a new one created. | - | String |
splitAggregatedStreams | Choose if you want to split aggregated streams into separate output files. | false | Boolean |
splitRecords | Choose if you want to split individual records into separate output files. | false | Boolean |
useCompression | Apply GZIP compression to output files | false | Boolean |
HDFSFileAppender
A destination used to write an output stream to a file on a Hadoop Distributed File System. If multiple paths are specified in the ‘outputPaths’ property it will pick one at random.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
fileSystemUri | URI for the Hadoop Distributed File System (HDFS) to connect to, e.g. hdfs://mynamenode.mydomain.com:8020 | - | String |
outputPaths | One or more destination paths for output files separated with commas. Replacement variables can be used in path strings such as ${feed}. | - | String |
rollSize | When the current output file exceeds this size it will be closed and a new one created. | - | String |
runAsUser | The user to connect to HDFS as | - | String |
splitAggregatedStreams | Choose if you want to split aggregated streams into separate output files. | false | Boolean |
splitRecords | Choose if you want to split individual records into separate output files. | false | Boolean |
HTTPAppender
A destination used to write an output stream to a remote HTTP(S) server.
This element should be preferred over the deprecated HttpPostFilter .
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
connectionTimeout | How long to wait before we abort sending data due to connection timeout | - | String |
contentType | The content type | application/json | String |
forwardChunkSize | Should data be sent in chunks and if so how big should the chunks be | - | String |
forwardUrl | The URL to send data to | - | String |
hostnameVerificationEnabled | Verify host names | true | Boolean |
httpHeadersIncludeStreamMetaData | Provide stream metadata as HTTP headers | true | Boolean |
httpHeadersUserDefinedHeader1 | Additional HTTP Header 1, format is ‘HeaderName: HeaderValue’ | - | String |
httpHeadersUserDefinedHeader2 | Additional HTTP Header 2, format is ‘HeaderName: HeaderValue’ | - | String |
httpHeadersUserDefinedHeader3 | Additional HTTP Header 3, format is ‘HeaderName: HeaderValue’ | - | String |
keyStorePassword | The key store password | - | String |
keyStorePath | The key store file path on the server | - | String |
keyStoreType | The key store type | JKS | String |
logMetaKeys | Which meta data values will be logged in the send log | guid,feed,system,environment,remotehost,remoteaddress | String |
readTimeout | How long to wait for data to be available before closing the connection | - | String |
requestMethod | The request method, e.g. POST | POST | String |
rollSize | When the current output exceeds this size it will be closed and a new one created. | - | String |
splitAggregatedStreams | Choose if you want to split aggregated streams into separate output. | false | Boolean |
splitRecords | Choose if you want to split individual records into separate output. | false | Boolean |
sslProtocol | The SSL protocol to use | TLSv1.2 | String |
trustStorePassword | The trust store password | - | String |
trustStorePath | The trust store file path on the server | - | String |
trustStoreType | The trust store type | JKS | String |
useCompression | Should data be compressed when sending | true | Boolean |
useJvmSslConfig | Use JVM SSL config. Set this to true if the Stroom node has been configured with key/trust stores using java system properties like ‘javax.net.ssl.keyStore’.Set this to false if you are explicitly setting key/trust store properties on this HttpAppender. | true | Boolean |
RollingFileAppender
A destination used to write an output stream to a file on the file system.
If multiple paths are specified in the ‘outputPaths’ property it will pick one at random to write to.
This is distinct from the FileAppender in that when the rollSize
is reached it will move the current file to the path specified in rolledFileName
and resume writing to the original path.
This allows other processes to follow the changes to a single file path, e.g. when using tail
.
On system shutdown all active files will be rolled.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
fileName | Choose the name of the file to write. | - | String |
filePermissions | Set file system permissions of finished files (example: ‘rwxr–r–’) | - | String |
frequency | Choose how frequently files are rolled. | 1h | String |
outputPaths | One or more destination paths for output files separated with commas. Replacement variables can be used in path strings such as ${feed}. | - | String |
rollSize | When the current output file exceeds this size it will be closed and a new one created, e.g. 10M, 1G. | 100M | String |
rolledFileName | Choose the name that files will be renamed to when they are rolled. | - | String |
schedule | Provide a cron expression to determine when files are rolled. | - | String |
useCompression | Apply GZIP compression to output files | false | Boolean |
RollingStreamAppender
A destination used to write one or more output streams to a new stream which is then rolled when it reaches a certain size or age. A new stream will be created after the size or age criteria has been met. On system shutdown all active streams will be rolled.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
feed | The feed that output stream should be written to. If not specified the feed the input stream belongs to will be used. | - | Document |
frequency | Choose how frequently streams are rolled. | 1h | String |
rollSize | Choose the maximum size that a stream can be before it is rolled. | 100M | String |
schedule | Provide a cron expression to determine when streams are rolled. | - | String |
segmentOutput | Should the output stream be marked with indexed segments to allow fast access to individual records? | true | Boolean |
streamType | The stream type that the output stream should be written as. This must be specified. | - | String |
volumeGroup | Optionally override the default volume group of the destination feed. | - | String |
StandardKafkaProducer
Consumes XML documents in the kafka-records:2
namespace.
For each <kafkaRecord>
element converts it into a Kafka message that is passed to the Kafka producer defined by the kafkaConfig
property
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
flushOnSend | At the end of the stream, wait for acknowledgement from the Kafka broker for all the messages sent. This ensures errors are caught in the pipeline process. | true | Boolean |
kafkaConfig | Kafka configuration details relating to where and how to send Kafka messages. | - | Document |
StreamAppender
A destination used to write the output stream to a new stream in the stream store. The configuration allows for starting a new stream once a size threshold is reached.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
feed | The feed that output stream should be written to. If not specified the feed the input stream belongs to will be used. | - | Document |
rollSize | When the current output stream exceeds this size it will be closed and a new one created. | - | String |
segmentOutput | Should the output stream be marked with indexed segments to allow fast access to individual records? | true | Boolean |
splitAggregatedStreams | Choose if you want to split aggregated streams into separate output streams. | false | Boolean |
splitRecords | Choose if you want to split individual records into separate output streams. | false | Boolean |
streamType | The stream type that the output stream should be written as. This must be specified. | - | String |
volumeGroup | Optionally override the default volume group of the destination feed. | - | String |
StroomStatsAppender
This element is deprecated and should not be used.
Element properties:
Name | Description | Default Value | Value Type |
---|---|---|---|
flushOnSend | At the end of the stream, wait for acknowledgement from the Kafka broker for all the messages sent. This ensures errors are caught in the pipeline process. | true | Boolean |
kafkaConfig | The Kafka config to use. | - | Document |
maxRecordCount | Choose the maximum number of records or events that a message will contain | 1 | String |
statisticsDataSource | The stroom-stats data source to record statistics against. | - | Document |
9 - Templating
Overview
Templating is the process of creating a reusable format or layout for presenting data in a consistent manner. Templating is currently used in Stroom for creating email templates for Analytic Rule
detections.Stroom’s templating uses a sub-set of the template syntax called jinja and specifically the JinJava library. The templating syntax includes support for variables, filters, condition blocks, loops, etc. Full details of the syntax can be found here .
When a template is rendered, Stroom will populate the template context with data that can be used by the template.
Basic Templating Syntax
Jinja templating is very powerful and has a rich language so this is quick guide to the very basic features. See the full syntax here here .
Data Types
The following data types are available in the Jinja language.
Data type | What does it represent | Example values |
---|---|---|
None | Represents no or lack of value. | none , None |
Integer | Whole numbers. | 42 , 12 , 3134 |
Boolean | Boolean value, i.e. true/false. | true , True , false , False |
Float | Real numbers (with decimal separator). | 12.34 , 423.52341 , 3.1415 , 15.0 |
String | Any string of characters. | "dog" , 'Cat' |
List | List/array of items of any type. Can be modified after being assigned. | [1, 2, 3] , ["Apple", "Orange"] |
Tuple | Like a list but cannot be modified. | (1, 2, 3) , ("Apple", "Orange") |
Dictionary | Object containing key/value pairs, also known as a map. | { "fruit": "Apple", "weight": 320 } |
Conditions
Valid conditions are:
==
Compares two objects for equality!=
Compares two objects for inequality>
true if the left-hand side is greater than the right-hand side>=
true if the left-hand side is greater or equal to the right-hand side<
true if the left-hand side is lower than the right-hand side<=
true if the left-hand side is lower or equal to the right-hand side
Logical Operators
The logic operators for use with boolean values are:
and
Boolean andor
Boolean ornot
Boolean negation
Expressions
Syntax: {{ ... }}
Expressions will render the value of a variable that has been defined in the template context or in a previous statement. An example of a simple value expression is
The detection time is {{detectionTime}}.
The detection time is 2024-05-03T09:15:13.454Z.
An expression can also contain variables that are passed through one or more Filters.
Statements
Syntax: {% ... %}
Statements are used to create conditional blocks, loops, define variables, etc.
Setting Variables
Syntax: {% set <variable name> = <value or expression> %}
{% set colour = '#F7761F' %}
Colour: {{colour}}
{% set fruits = ["Apple", "Orange"] %}
Top Fruit: {{ fruits | first }}
{% set fullName = "% %" | format(firstName, surname) %}
Name: {{fullName}}
Colour: #F7761F
Top Fruit: Apple
Name: Joe Bloggs
Conditional Blocks
Syntax:
{% if <value, variable or expression> <condition> <value, variable or expression> %}
< optional content, expressions or statements>
{% elif <value, variable or expression> <condition> <value, variable or expression>%}
< optional content, expressions or statements>
{% else %}
< optional content, expressions or statements>
{% endif %}
Conditional blocks can be used to optional render content depending on the value of a variable. See conditions for the list of valid conditions.
{% if (values | length) > 0 -%}
This detection has {{ values | length }} values.
{%- else -%}
This detection has no values.
{%- endif -%}
This detection has 10 values.
Loops
Syntax:
{% for <item name> in <variable or expression> %}
<content, expressions or statements to repeat for each item>
{% endif %}
For loops allow you to loop over items in a list/tuple or entries in a dictionary.
{% for key, val in values | dictsort %}
{{ key }}: {{ val }}
{% endfor %}
fruit: Apple
weight: 320
Note
Note, the filterdictsort
is used here to sort the dictionary by its keys.
Note
Note the use of -
to prevent an additional line break appearing in the rendered output, see White Space below.
Filters
Syntax: ... | <filter name>
Filters are essentially functions that take an input and return an output. Some functions have additional parameters to control the behaviour of the function.
Filters can be chained together with the output of one filter becoming the input to the next filter in the chain in the same way that Stroom pipeline elements work.
Some useful filters are:
Filter | Description | Example |
---|---|---|
length |
The number of items in the list/sequence/tuple/string/dictionary | {{ "hello" | length }} => 5 |
escape |
Escapes any HTML special characters | <p>{{ "10 > 3" | escape }}</p> => <p>10 > 3</p> |
default |
Return the first argument if the input is undefined or empty | {{ None | default("foo", true) }} => foo |
For a full list of filters see here or here .
Comments
Syntax: {# <comment text> #}
Non-rendered Comments can be added to the template.
{#- Show the time -#}
The detection time is {{detectionTime}}.
The detection time is 2024-05-03T09:15:13.454Z.
Note
Note the use of -
to prevent an additional line break appearing in the rendered output, see White Space below.
White Space
When JinJava renders the template, each expression or statement is evaluated and then removed or replaced by it’s output, but any white space around them, e.g. line breaks remain. This can result in unwanted line breaks in the output.
To avoid unwanted white space you can add the -
character to the opening and/or closing tag to strip leading/trailing whitespace outside the block, e.g.
{{ ... }}
=>{{- ... -}}
{% ... %}
=>{%- ... -%}
{{ firstName -}}
{{ surname }}
JoeBloggs
For a detailed guide to how white space works see here .
Template Context
The context is a data structure that contains the dynamic content to use when rendering the template. The variables and values in the context are set by Stroom depending on where the template is being used.
Rule Detections Context
When an email subject/body template is rendered for an Analytic Rule
detection, field values from the detection are placed in the context which allows them to be used in the template.For example {{ detectTime }}
will render the date/time the detection happened.
The fields available in the context are those taken from the detection:1
XMLSchema with some additional fields.
The template has access to the following fields from the detection:
Field Name | Type | Description |
---|---|---|
detectTime | String | When the detection occurred. |
detectorName | String | Recommended detector detail - name of detector. This should be unique within the system. Some detectors are very specific and only ever create one kind of detection, and in these cases it is likely that the name of the detector will be very similar to the name of the detection headline that it creates. Example: detectorSourceName= Bad Thing Detector headline=Bad Thing Detected .However, it is possible to create detectors that are sufficiently configurable that they can create many kinds of detection. In these cases, this field should always be assigned to the same literal regardless of the detection/headline. Example: detectorSourceName= Really Configurable Detector headline=Good Thing Detected , and detectorSourceName=Really Configurable Detector headline=Bad Thing Detected .For detectors that run within Stroom pipelines, the name of the XSLT can be specified here. |
detectorUuid | String | This is the UUID of the Analytic Rule document. |
detectorVersion | String | Recommended detector detail - version of detector. This is the version of the detector identified in detectorSourceName field. Different versions might produce different detections. For detectors that run within Stroom pipelines, the version of the XSLT can be specified here. Example: v1.0 . |
detectorEnvironment | String | Recommended detector detail - where the detector was deployed. For analytics that run within Stroom itself, the name of the processing pipeline can be used. Note: the XSLT function stroom: pipeline-name() can be used within Stroom XSLT processing to determine pipeline name.Other analytics might run within an external processing framework, such as Apache Spark.Example: DevOps Spark Cluster |
headline | String | |
detailedDescription | String | Recommended detection detail. A more detailed description of what was detected than provided by headline. This will normally include some information relating to what triggered the detection, such as a specific device, location, or user. In addition to descriptive text that will be the same for all detections of this kind, there are typically several possible variable dimensions that could be used to populate parts of the string that is assigned to this field. Normally, only one such dimension is selected, based on the likely triage process (the kind of analysis that takes place, and principal area of interest of the analysts). It should be possible to group by this field value to collect all detections that relate to the thing that the analysts are most interested in during triage. Example: Charitable Donation By 'Freya Bloggs' Detected or Charitable Donation To 'Happy Cats Cattery' Detected depending on anticipated area of analyst interest(perhaps philanthropic activities of individuals or financial transactions to organisations, respectively).For some detections, this field will have the same value as that for headline as no further information is available. |
fullDescription | String | Recommended detection detail. Complete description of what was detected. This will normally include some detail relating to what triggered the detection. All dimensions with ordinal (literal) values that are useful for triage are output. Numeric and other continuous values such as timestamps are not included in this full description, in order that grouping by this single field will work effectively. Example: Charitable Donation By 'Freya Bloggs' to 'Happy Cats Cattery' Detected .For some detections, this field will have the same value as that for detailedDescription as no further information is available. |
detectionUniqueId | String | This field does not need to be assigned. Any assignment should be to a value that is sufficiently unique to identify a specific detection from a specific detector. Typically, but not necessarily, the value of this field is a UUID . It can be useful to assign this field in order to support analytic development / debugging. It is necessary to assign this field if detectionRevision field is assigned a value. |
detectionRevision | Integer | Can be used, in conjunction with detectionUniqueId to allow detectors that run continuously, in a streaming fashion to revise their detections in the light of new information. For example, it might be useful to revise the same detection with additional linked events and a new standard deviation. Where more than one detection has the same detectionUniqueId value, then the one with the highest detectionRevision will be the current one and all previous revisions (lower numbers in detectionRevision field) are superseded / ignored. |
defunct | Boolean | This field allows a detection to declare that all previous revisions (same detectionUniqueId, lower detectionRevision numbers) are now considered invalid. For example, new data might arrive later than expected and invalidate a detection that has already been sent into Stroom. Default value is false . |
executionSchedule | String | The name of the schedule that fired this detection, if the detection was fired by a Scheduled Query. |
executionTime | String | This is the actual wall clock time that the rule ran. |
effectiveExecutionTime | String | This is the time used in any relative date expressions relative data expressions name in the rule’s query or time range, e.g. day() - 1w . The effective time is relevant when executing historic time ranges in a scheduled query. |
values | List of DetectionValue | This a list of all the field/column names and their values from the Query with the exception of StreamId and EventId . |
linkedEvents | List of DetectionLinkedEvent | This is a list of the event(s) that are linked to this detection. |
DetectionValue fields:
Field Name | Type | Description |
---|---|---|
name | String | The name of the field/column in the Query. |
value | String | The field/column value in the query result. |
DetectionLinkedEvent fields:
Field Name | Type | Description |
---|---|---|
stroom | String | The Stroom instance within which this event exists, assumed to be this instance of Stroom if not supplied. |
streamId | String | The ID of the Stream that contains the associated event. |
eventId | String | The ID of the Event that is associated with this detection. |