/* mmtaghostname.c * This is a message modification module. * * The name of the module is inspired by the parser module pmnull * Its objectives are closed to this parser but as a message modification * it can be used in a different step of the message processing without * interfering in the parser chain process and can be applied before or * after parsing process. * * Its purposes are : * - to add a tag on message produce by input module which does not provide * a tag like imudp or imtcp. Useful when the tag is used for routing the * message. * - to force message hostname to the rsyslog valeur. The use case is * application in auto-scaling systems (AWS) providing logs through udp/tcp * were the name of the host is based on an ephemeral IPs with a short term * meaning. In this situation rsyslog local host name is generally the * auto-scaling name then logs produced by the application is affected to * the application instead of the ephemeral VM. * * * This file is a contribution of rsyslog. * * Author : Ph. Duveau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include "rsyslog.h" #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include "dirty.h" #include "unicode-helper.h" MODULE_TYPE_OUTPUT MODULE_TYPE_NOKEEP MODULE_CNFNAME("mmtaghostname") /* internal structures */ DEF_OMOD_STATIC_DATA DEFobjCurrIf(glbl) /* parser instance parameters */ static struct cnfparamdescr parserpdescr[] = { { "tag", eCmdHdlrString, 0 }, { "forcelocalhostname", eCmdHdlrBinary, 0 }, }; static struct cnfparamblk parserpblk = { CNFPARAMBLK_VERSION, sizeof(parserpdescr)/sizeof(struct cnfparamdescr), parserpdescr }; typedef struct _instanceData { char *pszTag; size_t lenTag; int bForceLocalHostname; } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; static const uchar *pszHostname = NULL; static size_t lenHostname = 0; BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance ENDcreateWrkrInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance ENDfreeWrkrInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo dbgprintf("mmtaghostname:\n"); dbgprintf("\ttag='%s'\n", pData->pszTag); dbgprintf("\tforce local hostname='%d'\n", pData->bForceLocalHostname); ENDdbgPrintInstInfo BEGINcreateInstance CODESTARTcreateInstance pData->pszTag = NULL; pData->lenTag = 0; pData->bForceLocalHostname = 0; ENDcreateInstance BEGINfreeInstance CODESTARTfreeInstance free(pData->pszTag); ENDfreeInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature ENDisCompatibleWithFeature BEGINnewActInst struct cnfparamvals *pvals = NULL; int i; CODESTARTnewActInst DBGPRINTF("newParserInst (mmtaghostname)\n"); CHKiRet(createInstance(&pData)); if(lst == NULL) FINALIZE; /* just set defaults, no param block! */ if((pvals = nvlstGetParams(lst, &parserpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if(Debug) { dbgprintf("parser param blk in mmtaghostname:\n"); cnfparamsPrint(&parserpblk, pvals); } for(i = 0 ; i < parserpblk.nParams ; ++i) { if(!pvals[i].bUsed) continue; if(!strcmp(parserpblk.descr[i].name, "tag")) { pData->pszTag = (char *) es_str2cstr(pvals[i].val.d.estr, NULL); pData->lenTag = strlen(pData->pszTag); } else if(!strcmp(parserpblk.descr[i].name, "forcelocalhostname")) { pData->bForceLocalHostname = pvals[i].val.d.n; } else { dbgprintf("program error, non-handled param '%s'\n", parserpblk.descr[i].name); } } CODE_STD_STRING_REQUESTnewActInst(1) CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); CODE_STD_FINALIZERnewActInst if(lst != NULL) cnfparamvalsDestruct(pvals, &parserpblk); ENDnewActInst BEGINdoAction_NoStrings smsg_t **ppMsg = (smsg_t **) pMsgData; smsg_t *pMsg = ppMsg[0]; instanceData *pData = pWrkrData->pData; CODESTARTdoAction DBGPRINTF("Message will now be managed by mmtaghostname\n"); if(pData->pszTag != NULL) { MsgSetTAG(pMsg, (uchar *)pData->pszTag, pData->lenTag); } if (pData->bForceLocalHostname) { if (pszHostname == NULL) { pszHostname = glbl.GetLocalHostName(); lenHostname = ustrlen(glbl.GetLocalHostName()); } MsgSetHOSTNAME(pMsg, pszHostname, lenHostname); DBGPRINTF("Message hostname forced to local\n"); } ENDdoAction BEGINtryResume CODESTARTtryResume ENDtryResume BEGINparseSelectorAct CODESTARTparseSelectorAct CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct BEGINmodExit CODESTARTmodExit objRelease(glbl, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES CODEqueryEtryPt_STD_OMOD8_QUERIES CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); ENDmodInit