Tap Stream Processors
Stream processors for the tap service are written in Javascript, and will be automatically bundled by Morio core.
The stream processor object
Each processor is bundled a so-called stream processor object or . This SPO has the following properties:
id
Mandatory
The id property of an holds a string that is the ID of
the stream processor.
const processor = {
id: `my_custom_stream_processor_with_a_unique_id`,
}
The stream processor ID is used to bundle the processor code. In general, you should ensure the ID is unique. However, when two stream processors share the same ID, the later-loaded on will overwrite the earlier-loaded one.
So while in general, stream processor IDs should be unique, you can deliberately use this to overwrite a stream processor in the generated bundle.
info
Recommended
The info property of the holds a string that is a
description of the stream processor. It is intended for humans to clarify
the role and purpose of the stream processor.
const processor = {
info: `This stream processor shows how it's done`,
}
settings
Mandatory
The settings property of the holds the stream processor’s configuration.
settings.topics
Mandatory
The settings.topics property of an holds an array of strings that are
the names of the Kafka topics to subscribe to.
const processor = {
settings: {
topics: ['logs'],
}
}
settings.modules
Optional
The settings.modules property of an holds an array of strings that are
the names of the Morio modules to subscribe to.
const processor = {
settings: {
modules: ['linux-system'],
}
}
If no settings.modules are specified, the stream processor will be
subscribed to (data generated by) all modules.
settings.datasets
Optional
The settings.dataset property of an holds an array of strings that are
the names of the Morio datasets to subscribe to.
const processor = {
settings: {
datasets: ['journald'],
}
}
If no settings.datasets are specified, the stream processor will be
subscribed to (data generated by) all datasets.
settings.custom
Optional
The settings property can also hold custom keys that allow you to expose the
configuration of the underlying stream processor.
How they are configured depends on the data type they hold:
The data type below is used to render these settings in the Morio UI. It is not enforced by Morio core or the Tap service.
Custom settings with a number value
Use dflt to specify the default value, and title to descibe the setting.
Make sure to set type to number:
const processor = {
settings: {
some_number: {
dflt: 666,
title: `Just an example of a number you can configure`,
type: 'number'
}
}
}
Custom settings with a string value
Use dflt to specify the default value, and title to descibe the setting.
Make sure to set type to string:
const processor = {
settings: {
some_string: {
dflt: 'hello there',
title: `Just an example of a string you can configure`,
type: 'string'
}
}
}
Custom settings with a list of options
Use dflt to specify the default value, and populate list with objects to describe
the choices, where each holds:
val: the valuelabel: the lableabout: Optional extra text to clarify the choice
Make sure to set type to list:
const processor = {
settings: {
my_list: {
dflt: true,
title: `Do you like Morio?`,
type: 'list',
list: [
{
val: false,
label: `I don't even like myself`,
},
{
val: true,
label: `I love it`,
about: 'Ok, maybe love is a bit much, so choose this option if you think it's ok.'
},
],
},
}
}
handler
Mandatory
The handler property of a stream processor holds a Javascript function that
implements the logic of your stream processor.
const processor = {
handler: function(params) {
// do something here
},
// Rest of the stream processor object
}
The handler function will be invoked for every message that matches the
subscription data (topics, modules, and datasets).
Refer to Tap params for details about what your handler function receives as parameters.
Refer to the Tap Stream Processing Guide for help on how to write your own logic.
Folder structure
Stream processors are seeded in Morio. In other words, they are not part of the configuration, and are expected to be loaded from a git repository. You can use your own git repository for your custom stream processors, refer to the seeding guide for details.
For the seeding to function, you should make sure to respect the following rules:
- Morio core will recursively look for
index.mjsfiles - It will import the default export from those files
- If the default export is an array, it will be treated as an array of stream processor objects
- If the default export is an object, it will be treated as a single stream processor object
File structure
A single object as default export
The default export can be a single object like this:
const processor = {
id: `my_custom_stream_processor_with_a_unique_id`,
// Rest of the stream processor object
}
export default processor
An array as default export
You can bundle multiple stream processors in the same file by exporting an array:
const processors = [
{
id: `my_first_custom_stream_processor_with_a_unique_id`,
// Rest of the first stream processor object
},
{
id: `my_second_custom_stream_processor_with_a_unique_id`,
// Rest of the second stream processor object
},
]
export default processors
Exporting via a barrel file
If you have a bunch of processors, a common approach is to keep each in its
own file, and make the index.mjs a barrel file that merely re-exports them:
import processor1 from './my-great-processor.mjs'
import processor2 from './my-even-better-processors.mjs'
import otherProcessor from './this-is-a-test.mjs'
export default [
processor1,
processor2,
otherProcessor
]
By naming your barrel file index.mjs Morio core will pick it up, and follow
the imports. This gives you maximum flexibility on how to structure your code.