mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-19 19:40:41 +01:00
Merge pull request #1455 from alorbach/imfile-wildcardfix
imfile: Fixed an issue monitoring wrong files when using multiple imf…
This commit is contained in:
commit
74f47a0908
@ -84,6 +84,15 @@ static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config para
|
||||
|
||||
#define ADD_METADATA_UNSPECIFIED -1
|
||||
|
||||
/*
|
||||
* Helpers for wildcard in directory detection
|
||||
*/
|
||||
#define DIR_CONFIGURED 0
|
||||
#define DIR_DYNAMIC 1
|
||||
|
||||
/* If set to 1, fileTableDisplay will be compiled and used for debugging */
|
||||
#define ULTRA_DEBUG 0
|
||||
|
||||
/* this structure is used in pure polling mode as well one of the support
|
||||
* structures for inotify.
|
||||
*/
|
||||
@ -217,6 +226,7 @@ typedef struct fileTable_s fileTable_t;
|
||||
*/
|
||||
struct dirInfo_s {
|
||||
uchar *dirName;
|
||||
int bDirType; /* Configured or dynamic */
|
||||
fileTable_t active; /* associated active files */
|
||||
fileTable_t configured; /* associated configured files */
|
||||
};
|
||||
@ -224,11 +234,11 @@ typedef struct dirInfo_s dirInfo_t;
|
||||
static dirInfo_t *dirs = NULL;
|
||||
static int allocMaxDirs;
|
||||
static int currMaxDirs;
|
||||
|
||||
/* the following two macros are used to select the correct file table */
|
||||
#define ACTIVE_FILE 1
|
||||
#define CONFIGURED_FILE 0
|
||||
|
||||
|
||||
/* We need to map watch descriptors to our actual objects. Unfortunately, the
|
||||
* inotify API does not provide us with any cookie, so a simple O(1) algorithm
|
||||
* cannot be done (what a shame...). We assume that maintaining the array is much
|
||||
@ -826,7 +836,7 @@ checkInstance(instanceConf_t *inst)
|
||||
*/
|
||||
if(inst->pszFileName == NULL)
|
||||
ABORT_FINALIZE(RS_RET_INTERNAL_ERROR);
|
||||
|
||||
|
||||
i = getBasename(basen, inst->pszFileName);
|
||||
if (i == -1) {
|
||||
errmsg.LogError(0, RS_RET_CONFIG_ERROR, "imfile: file path '%s' does not include a basename component",
|
||||
@ -1392,26 +1402,30 @@ fileTableInit(fileTable_t *const __restrict__ tab, const int nelem)
|
||||
finalize_it:
|
||||
RETiRet;
|
||||
}
|
||||
/* uncomment if needed
|
||||
|
||||
#if ULTRA_DEBUG == 1
|
||||
static void
|
||||
fileTableDisplay(fileTable_t *tab)
|
||||
{
|
||||
int f;
|
||||
uchar *baseName;
|
||||
DBGPRINTF("imfile: dirs.currMaxfiles %d\n", tab->currMax);
|
||||
DBGPRINTF("imfile: fileTableDisplay = dirs.currMaxfiles %d\n", tab->currMax);
|
||||
for(f = 0 ; f < tab->currMax ; ++f) {
|
||||
baseName = tab->listeners[f].pLstn->pszBaseName;
|
||||
DBGPRINTF("imfile: TABLE %p CONTENTS, %d->%p:'%s'\n", tab, f, tab->listeners[f].pLstn, (char*)baseName);
|
||||
DBGPRINTF("imfile: fileTableDisplay = TABLE %p CONTENTS, %d->%p:'%s'\n",
|
||||
tab, f, tab->listeners[f].pLstn, (char*)baseName);
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
static int
|
||||
fileTableSearch(fileTable_t *const __restrict__ tab, uchar *const __restrict__ fn)
|
||||
{
|
||||
int f;
|
||||
uchar *baseName = NULL;
|
||||
/* UNCOMMENT FOR DEBUG fileTableDisplay(tab); */
|
||||
#if ULTRA_DEBUG == 1
|
||||
fileTableDisplay(tab);
|
||||
#endif
|
||||
for(f = 0 ; f < tab->currMax ; ++f) {
|
||||
baseName = tab->listeners[f].pLstn->pszBaseName;
|
||||
if(!fnmatch((char*)baseName, (char*)fn, FNM_PATHNAME | FNM_PERIOD))
|
||||
@ -1524,7 +1538,7 @@ dirsAdd(uchar *dirName, int* piIndex)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Save Index for higher functions */
|
||||
if (piIndex != NULL )
|
||||
*piIndex = newindex;
|
||||
@ -1546,6 +1560,7 @@ dirsAdd(uchar *dirName, int* piIndex)
|
||||
|
||||
/* if we reach this point, there is space in the file table for the new entry */
|
||||
dirs[newindex].dirName = (uchar*)strdup((char*)dirName); /* Get a copy of the string !*/
|
||||
dirs[newindex].bDirType = DIR_CONFIGURED; /* Default to configured! */
|
||||
CHKiRet(fileTableInit(&dirs[newindex].active, INIT_FILE_IN_DIR_TAB_SIZE));
|
||||
CHKiRet(fileTableInit(&dirs[newindex].configured, INIT_FILE_IN_DIR_TAB_SIZE));
|
||||
|
||||
@ -1681,8 +1696,8 @@ in_setupDirWatch(const int dirIdx)
|
||||
}
|
||||
}
|
||||
wdmapAdd(wd, dirIdx, NULL);
|
||||
DBGPRINTF("imfile: in_setupDirWatch: watch %d added for dir %s\n", wd,
|
||||
(dirnamelen == 0) ? (char*) dirs[dirIdx].dirName : (char*) dirnametrunc);
|
||||
DBGPRINTF("imfile: in_setupDirWatch: watch %d added for dir %s(Idx=%d)\n", wd,
|
||||
(dirnamelen == 0) ? (char*) dirs[dirIdx].dirName : (char*) dirnametrunc, dirIdx);
|
||||
done: return;
|
||||
}
|
||||
|
||||
@ -1728,7 +1743,7 @@ lstnDup(lstn_t **ppExisting, uchar *const __restrict__ newname, uchar *const __r
|
||||
lstn_t *const existing = *ppExisting;
|
||||
lstn_t *pThis;
|
||||
CHKiRet(lstnAdd(&pThis));
|
||||
|
||||
|
||||
/* Use dynamic dirname if newdirname is set! */
|
||||
if (newdirname == NULL) {
|
||||
pThis->pszDirName = existing->pszDirName; /* read-only */
|
||||
@ -2028,6 +2043,7 @@ in_handleDirEventDirCREATE(struct inotify_event *ev, const int dirIdx)
|
||||
/* Add dir to table and create watch */
|
||||
DBGPRINTF("imfile: Adding new dir '%s' to dirs table \n", fulldn);
|
||||
dirsAdd((uchar*)fulldn, &newdiridx);
|
||||
dirs[newdiridx].bDirType = DIR_DYNAMIC; /* Set to DYNAMIC directory! */
|
||||
in_setupDirWatch(newdiridx);
|
||||
} else {
|
||||
DBGPRINTF("imfile: dir '%s' already exists in dirs table (Idx %d)\n", fulldn, newdiridx);
|
||||
@ -2038,7 +2054,7 @@ static void
|
||||
in_handleDirEventFileCREATE(struct inotify_event *ev, const int dirIdx)
|
||||
{
|
||||
int i;
|
||||
lstn_t *pLstn;
|
||||
lstn_t *pLstn = NULL;
|
||||
int ftIdx;
|
||||
char fullfn[MAXFNAME];
|
||||
uchar* pszDir = NULL;
|
||||
@ -2047,48 +2063,59 @@ in_handleDirEventFileCREATE(struct inotify_event *ev, const int dirIdx)
|
||||
if(ftIdx >= 0) {
|
||||
pLstn = dirs[dirIdxFinal].active.listeners[ftIdx].pLstn;
|
||||
} else {
|
||||
DBGPRINTF("imfile: in_handleDirEventFileCREATE '%s' not associated with dir '%s' (CurMax:%d)\n",
|
||||
ev->name, dirs[dirIdxFinal].dirName, dirs[dirIdxFinal].active.currMax);
|
||||
DBGPRINTF("imfile: in_handleDirEventFileCREATE '%s' not associated with dir '%s' "
|
||||
"(CurMax:%d, DirIdx:%d, DirType:%s)\n", ev->name, dirs[dirIdxFinal].dirName,
|
||||
dirs[dirIdxFinal].active.currMax, dirIdxFinal,
|
||||
(dirs[dirIdxFinal].bDirType == DIR_CONFIGURED ? "configured" : "dynamic") );
|
||||
ftIdx = fileTableSearch(&dirs[dirIdxFinal].configured, (uchar*)ev->name);
|
||||
if(ftIdx == -1) {
|
||||
/* Search all other configured directories for proper index! */
|
||||
if (currMaxDirs > 0) {
|
||||
/* Store Dirname as we need to overwrite it in in_setupFileWatchDynamic */
|
||||
pszDir = dirs[dirIdxFinal].dirName;
|
||||
if (dirs[dirIdxFinal].bDirType == DIR_DYNAMIC) {
|
||||
/* Search all other configured directories for proper index! */
|
||||
if (currMaxDirs > 0) {
|
||||
/* Store Dirname as we need to overwrite it in in_setupFileWatchDynamic */
|
||||
pszDir = dirs[dirIdxFinal].dirName;
|
||||
|
||||
/* Combine directory and filename */
|
||||
snprintf(fullfn, MAXFNAME, "%s/%s", pszDir, (uchar*)ev->name);
|
||||
/* Combine directory and filename */
|
||||
snprintf(fullfn, MAXFNAME, "%s/%s", pszDir, (uchar*)ev->name);
|
||||
|
||||
for(i = 0 ; i < currMaxDirs ; ++i) {
|
||||
ftIdx = fileTableSearch(&dirs[i].configured, (uchar*)ev->name);
|
||||
if(ftIdx != -1) {
|
||||
/* Found matching directory! */
|
||||
dirIdxFinal = i; /* Have to correct directory index for listnr dupl
|
||||
in in_setupFileWatchDynamic */
|
||||
break;
|
||||
for(i = 0 ; i < currMaxDirs ; ++i) {
|
||||
ftIdx = fileTableSearch(&dirs[i].configured, (uchar*)ev->name);
|
||||
if(ftIdx != -1) {
|
||||
/* Found matching directory! */
|
||||
dirIdxFinal = i; /* Have to correct directory index for listnr dupl
|
||||
in in_setupFileWatchDynamic */
|
||||
|
||||
DBGPRINTF("imfile: Found matching directory for file '%s' in dir '%s' (Idx=%d)\n",
|
||||
ev->name, dirs[dirIdxFinal].dirName, dirIdxFinal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Found Listener to se */
|
||||
pLstn = dirs[dirIdxFinal].configured.listeners[ftIdx].pLstn;
|
||||
|
||||
if(ftIdx == -1) {
|
||||
DBGPRINTF("imfile: file '%s' not associated with dir '%s' and also no "
|
||||
"matching wildcard directory found\n", ev->name, dirs[dirIdxFinal].dirName);
|
||||
if(ftIdx == -1) {
|
||||
DBGPRINTF("imfile: file '%s' not associated with dir '%s' and also no "
|
||||
"matching wildcard directory found\n", ev->name, dirs[dirIdxFinal].dirName);
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
DBGPRINTF("imfile: file '%s' not associated with dir '%s', using dirIndex %d instead\n",
|
||||
ev->name, (pszDir == NULL) ? dirs[dirIdxFinal].dirName : pszDir, dirIdxFinal);
|
||||
}
|
||||
} else {
|
||||
DBGPRINTF("imfile: file '%s' not associated with dir '%s'\n",
|
||||
ev->name, dirs[dirIdxFinal].dirName);
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
DBGPRINTF("imfile: file '%s' not associated with dir '%s', using dirIndex %d instead\n",
|
||||
ev->name, (pszDir == NULL) ? dirs[dirIdxFinal].dirName : pszDir, dirIdxFinal);
|
||||
}
|
||||
} else {
|
||||
DBGPRINTF("imfile: file '%s' not associated with dir '%s'\n",
|
||||
ev->name, dirs[dirIdxFinal].dirName);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
pLstn = dirs[dirIdxFinal].configured.listeners[ftIdx].pLstn;
|
||||
} else
|
||||
pLstn = dirs[dirIdxFinal].configured.listeners[ftIdx].pLstn;
|
||||
}
|
||||
if (pLstn != NULL) {
|
||||
DBGPRINTF("imfile: file '%s' associated with dir '%s' (Idx=%d)\n",
|
||||
ev->name, (pszDir == NULL) ? dirs[dirIdxFinal].dirName : pszDir, dirIdxFinal);
|
||||
in_setupFileWatchDynamic(pLstn, (uchar*)ev->name, (pszDir == NULL) ? NULL : (uchar*)fullfn);
|
||||
}
|
||||
DBGPRINTF("imfile: file '%s' associated with dir '%s'\n",
|
||||
ev->name, (pszDir == NULL) ? dirs[dirIdxFinal].dirName : pszDir);
|
||||
in_setupFileWatchDynamic(pLstn, (uchar*)ev->name, (pszDir == NULL) ? NULL : (uchar*)fullfn);
|
||||
done: return;
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ export IMFILEINPUTFILES="10"
|
||||
# generate input files first. Note that rsyslog processes it as
|
||||
# soon as it start up (so the file should exist at that point).
|
||||
|
||||
imfilebefore="rsyslog.input.1"
|
||||
imfilebefore="rsyslog.input.1.log"
|
||||
./inputfilegen -m 1 > $imfilebefore
|
||||
|
||||
# Start rsyslog now before adding more files
|
||||
@ -18,8 +18,8 @@ sleep 1
|
||||
|
||||
for i in `seq 2 $IMFILEINPUTFILES`;
|
||||
do
|
||||
cp $imfilebefore rsyslog.input.$i
|
||||
imfilebefore="rsyslog.input.$i"
|
||||
cp $imfilebefore rsyslog.input.$i.log
|
||||
imfilebefore="rsyslog.input.$i.log"
|
||||
done
|
||||
ls -l rsyslog.input.*
|
||||
|
||||
|
||||
@ -6,12 +6,20 @@ module( load="../plugins/imfile/.libs/imfile"
|
||||
PollingInterval="1")
|
||||
|
||||
input(type="imfile"
|
||||
File="./rsyslog.input.*"
|
||||
File="./rsyslog.input.*.log"
|
||||
Tag="file:"
|
||||
Severity="error"
|
||||
Facility="local7"
|
||||
addMetadata="on"
|
||||
)
|
||||
input(type="imfile"
|
||||
File="/does/not/exist/*.log"
|
||||
Tag="file:"
|
||||
Severity="error"
|
||||
Facility="local7"
|
||||
addMetadata="on"
|
||||
)
|
||||
|
||||
|
||||
template(name="outfmt" type="list") {
|
||||
constant(value="HEADER ")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user