rsyslog/plugins/MM_INTERFACE.md
Rainer Gerhards 0fc3bb05ec
Document native message modification plugin interface (#5757)
* doc: document native mm interface
2025-07-08 12:57:40 +02:00

128 lines
3.2 KiB
Markdown

# Message Modification Module Native Interface
This document summarizes the C interface used by *mm* plugins inside the
`plugins/` directory. No standalone documentation exists; existing
modules reference the macros from `runtime/module-template.h`.
Message modification modules are implemented as output modules. Each
plugin declares
```
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
MODULE_CNFNAME("module_name")
```
and uses the helper macros from `module-template.h` to define entry
points. Typical modules implement `doAction()` for per-message
processing and do **not** implement the transaction interface.
## Calling Convention
A worker instance receives a pointer to an array of `smsg_t*` pointers via `doAction()`. For message modification modules, this array contains a single message. The function is declared using `BEGINdoAction_NoStrings`
```c
BEGINdoAction_NoStrings
smsg_t **ppMsg = (smsg_t **) pMsgData;
smsg_t *pMsg = ppMsg[0];
/* modify pMsg as needed */
CODESTARTdoAction
ENDdoAction
```
This interface processes one message at a time. Existing modules such as
`mmjsonparse` and `mmnormalize` all use this form.
While macros exist for transactional interfaces (`beginTransaction`,
`commitTransaction`, `endTransaction`) they are unused by mm modules.
## Minimal Module Skeleton
Below is a minimal skeleton that compiles against the native interface.
It omits error checking and configuration for brevity.
```c
#include "config.h"
#include "rsyslog.h"
#include "module-template.h"
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
MODULE_CNFNAME("mmskeleton")
DEF_OMOD_STATIC_DATA
typedef struct instanceData {
/* module parameters */
} instanceData;
typedef struct wrkrInstanceData {
instanceData *pData;
} wrkrInstanceData_t;
BEGINcreateInstance
CODESTARTcreateInstance
ENDcreateInstance
BEGINfreeInstance
CODESTARTfreeInstance
ENDfreeInstance
BEGINcreateWrkrInstance
CODESTARTcreateWrkrInstance
ENDcreateWrkrInstance
BEGINfreeWrkrInstance
CODESTARTfreeWrkrInstance
ENDfreeWrkrInstance
BEGINparseSelectorAct
CODESTARTparseSelectorAct
CODE_STD_STRING_REQUESTparseSelectorAct(1)
if(strncmp((char*)p, ":mmskeleton:", sizeof(":mmskeleton:") - 1))
ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
p += sizeof(":mmskeleton:") - 1;
CHKiRet(createInstance(&pData));
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_TPL_AS_MSG, (uchar*)"RSYSLOG_FileFormat"));
CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct
BEGINnewActInst
CODESTARTnewActInst
CODE_STD_STRING_REQUESTnewActInst(1)
CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG));
CODE_STD_FINALIZERnewActInst
ENDnewActInst
BEGINdoAction_NoStrings
smsg_t **ppMsg = (smsg_t **)pMsgData;
smsg_t *pMsg = ppMsg[0];
CODESTARTdoAction
/* modify pMsg as needed */
/* The following lines are to prevent compiler warnings for unused variables.
* Remove them if you use the variables in your code. */
(void)pWrkrData;
(void)pMsg;
ENDdoAction
NO_LEGACY_CONF_parseSelectorAct
BEGINmodExit
CODESTARTmodExit
ENDmodExit
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_OMOD_QUERIES
CODEqueryEtryPt_STD_OMOD8_QUERIES
CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES
CODEqueryEtryPt_STD_CONF2_QUERIES
ENDqueryEtryPt
BEGINmodInit()
CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION;
CODEmodInit_QueryRegCFSLineHdlr
ENDmodInit
```