summaryrefslogtreecommitdiffstats
path: root/contrib/mmtaghostname/mmtaghostname.c
blob: ae7225222608f1986317a767cb209d961a3a299b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/* 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 <philippe.duveau@free.fr>
 *
 * 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 <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <ctype.h>

#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