menotify: Scripted User-Space Sensors in Lua
The menotify sensor family loads a Lua script from the shared library tree
and runs it as a long-lived event sensor. This is meant for user-space and
third-party integrations where a built-in Rust listener would be too specific
or would require a rebuild for each new use-case.
The listener syntax is:
<id>:
description: <description>
listener: menotify.<module>
[profile]:
- <profile>
[interval]: <interval override>
[opts]:
- <opaque option>
[args]:
key: <opaque value>
[tag]: <optional tag>
Synopsis
Sensor configuration as follows:
github-public-issues:
description: Poll issues on a public GitHub repository
listener: menotify.githubissues
args:
owner: your-github-user-or-org
repo: your-public-repo
state: open
per_page: 20
user_agent: sysinspect-menotify-demo
listener
The listener family root is always
menotify.The part after the dot is the Lua module name. For example:
listener: menotify.githubissuesloads:
${SYSINSPECT_SHARELIB_ROOT}/lib/sensors/lua/githubissues.lua
opts
Optional
This is a list of opaque options passed to the Lua script unchanged. Rust does not interpret them.
args
Optional
This is a dictionary of opaque arguments passed to the Lua script unchanged. Rust does not interpret them.
In current implementation, secrets are not a special API. If a scripted sensor needs a token or another secret, it is passed through
args.
interval
The effective polling interval used for
tick(ctx)scripts.If the Lua script exports
loop(ctx), it is called once and manages its own blocking behavior.
tag
Optional
If defined, the tag is included in the listener portion of the generated event ID.
Example:
github-public-issues|menotify.githubissues@demo|opened@42|0
Lua Contract
The script must return a table with exactly one entrypoint:
return {
tick = function(ctx)
end
}
or:
return {
loop = function(ctx)
end
}
The current ctx fields and helpers are:
ctx.idctx.listenerctx.modulectx.optsctx.argsctx.intervalctx.emit(data, meta?)ctx.sleep(seconds)ctx.now()ctx.timestamp()ctx.state.get(key)ctx.state.set(key, value)ctx.state.has(key)ctx.state.del(key)
Global Lua helpers:
log.error(...)log.warn(...)log.info(...)log.debug(...)http.get(url, opts?)http.request({...})packagekit.available()packagekit.status()packagekit.history(names, count?)packagekit.packages()packagekit.install(names)packagekit.remove(names)packagekit.upgrade(names)
packagekit.*
Optional Linux-oriented helper
packagekitis a convenience namespace for polling PackageKit over D-Bus from Lua. It is intentionally not part of the portable core contract. If a script uses it, that script is making a Linux-specific choice.
packagekit.available()Returns
trueif the PackageKit root service can be reached on the system bus.packagekit.status()Returns a table with current daemon state, including:
available
backend_name
daemon_state
distro_id
locked
network_state
transactions
version_major
version_minor
version_micropackagekit.history(names, count?)Returns PackageKit package history converted to JSON-compatible Lua tables. This is meant for polling scripts that want to detect package installs, removals, upgrades, or other recent transactions.
packagekit.packages()Returns the current installed-package snapshot known to PackageKit. This is useful for scripts that want to diff installed packages across polling cycles and emit add/remove events.
packagekit.install(names)Installs packages by name through PackageKit and returns the operation result as a Lua table.
packagekit.remove(names)Removes packages by name through PackageKit and returns the operation result as a Lua table.
packagekit.upgrade(names)Upgrades packages by name through PackageKit and returns the operation result as a Lua table.
Event Shape
ctx.emit(data, meta?) builds a standard Sysinspect sensor envelope.
Example:
ctx.emit({
number = 42,
title = "New issue"
}, {
action = "opened",
key = "42"
})
This becomes:
github-public-issues|menotify.githubissues|opened@42|0
meta currently accepts:
actionkey
If omitted:
actiondefaults toemittedkeydefaults to-
Packaging and Sync
menotify scripts are shipped as normal library/sharelib artefacts.
Current layout:
lib/
sensors/
lua/
<module>.lua
site-lua/
...
Publish them with the standard library upload command:
sysinspect module -A --path ./lib -l
Then sync the cluster:
sysinspect --sync
Example
The repository ships a working demo:
examples/demos/menotify/
It contains:
lib/sensors/lua/githubissues.luasensors.cfgREADME.md
That example polls GitHub issues on a public repository and emits one event per newly opened issue.