mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-19 22:00:42 +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
|
#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
|
/* this structure is used in pure polling mode as well one of the support
|
||||||
* structures for inotify.
|
* structures for inotify.
|
||||||
*/
|
*/
|
||||||
@ -217,6 +226,7 @@ typedef struct fileTable_s fileTable_t;
|
|||||||
*/
|
*/
|
||||||
struct dirInfo_s {
|
struct dirInfo_s {
|
||||||
uchar *dirName;
|
uchar *dirName;
|
||||||
|
int bDirType; /* Configured or dynamic */
|
||||||
fileTable_t active; /* associated active files */
|
fileTable_t active; /* associated active files */
|
||||||
fileTable_t configured; /* associated configured files */
|
fileTable_t configured; /* associated configured files */
|
||||||
};
|
};
|
||||||
@ -224,11 +234,11 @@ typedef struct dirInfo_s dirInfo_t;
|
|||||||
static dirInfo_t *dirs = NULL;
|
static dirInfo_t *dirs = NULL;
|
||||||
static int allocMaxDirs;
|
static int allocMaxDirs;
|
||||||
static int currMaxDirs;
|
static int currMaxDirs;
|
||||||
|
|
||||||
/* the following two macros are used to select the correct file table */
|
/* the following two macros are used to select the correct file table */
|
||||||
#define ACTIVE_FILE 1
|
#define ACTIVE_FILE 1
|
||||||
#define CONFIGURED_FILE 0
|
#define CONFIGURED_FILE 0
|
||||||
|
|
||||||
|
|
||||||
/* We need to map watch descriptors to our actual objects. Unfortunately, the
|
/* 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
|
* 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
|
* 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)
|
if(inst->pszFileName == NULL)
|
||||||
ABORT_FINALIZE(RS_RET_INTERNAL_ERROR);
|
ABORT_FINALIZE(RS_RET_INTERNAL_ERROR);
|
||||||
|
|
||||||
i = getBasename(basen, inst->pszFileName);
|
i = getBasename(basen, inst->pszFileName);
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
errmsg.LogError(0, RS_RET_CONFIG_ERROR, "imfile: file path '%s' does not include a basename component",
|
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:
|
finalize_it:
|
||||||
RETiRet;
|
RETiRet;
|
||||||
}
|
}
|
||||||
/* uncomment if needed
|
|
||||||
|
#if ULTRA_DEBUG == 1
|
||||||
static void
|
static void
|
||||||
fileTableDisplay(fileTable_t *tab)
|
fileTableDisplay(fileTable_t *tab)
|
||||||
{
|
{
|
||||||
int f;
|
int f;
|
||||||
uchar *baseName;
|
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) {
|
for(f = 0 ; f < tab->currMax ; ++f) {
|
||||||
baseName = tab->listeners[f].pLstn->pszBaseName;
|
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
|
static int
|
||||||
fileTableSearch(fileTable_t *const __restrict__ tab, uchar *const __restrict__ fn)
|
fileTableSearch(fileTable_t *const __restrict__ tab, uchar *const __restrict__ fn)
|
||||||
{
|
{
|
||||||
int f;
|
int f;
|
||||||
uchar *baseName = NULL;
|
uchar *baseName = NULL;
|
||||||
/* UNCOMMENT FOR DEBUG fileTableDisplay(tab); */
|
#if ULTRA_DEBUG == 1
|
||||||
|
fileTableDisplay(tab);
|
||||||
|
#endif
|
||||||
for(f = 0 ; f < tab->currMax ; ++f) {
|
for(f = 0 ; f < tab->currMax ; ++f) {
|
||||||
baseName = tab->listeners[f].pLstn->pszBaseName;
|
baseName = tab->listeners[f].pLstn->pszBaseName;
|
||||||
if(!fnmatch((char*)baseName, (char*)fn, FNM_PATHNAME | FNM_PERIOD))
|
if(!fnmatch((char*)baseName, (char*)fn, FNM_PATHNAME | FNM_PERIOD))
|
||||||
@ -1524,7 +1538,7 @@ dirsAdd(uchar *dirName, int* piIndex)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save Index for higher functions */
|
/* Save Index for higher functions */
|
||||||
if (piIndex != NULL )
|
if (piIndex != NULL )
|
||||||
*piIndex = newindex;
|
*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 */
|
/* 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].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].active, INIT_FILE_IN_DIR_TAB_SIZE));
|
||||||
CHKiRet(fileTableInit(&dirs[newindex].configured, 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);
|
wdmapAdd(wd, dirIdx, NULL);
|
||||||
DBGPRINTF("imfile: in_setupDirWatch: watch %d added for dir %s\n", wd,
|
DBGPRINTF("imfile: in_setupDirWatch: watch %d added for dir %s(Idx=%d)\n", wd,
|
||||||
(dirnamelen == 0) ? (char*) dirs[dirIdx].dirName : (char*) dirnametrunc);
|
(dirnamelen == 0) ? (char*) dirs[dirIdx].dirName : (char*) dirnametrunc, dirIdx);
|
||||||
done: return;
|
done: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1728,7 +1743,7 @@ lstnDup(lstn_t **ppExisting, uchar *const __restrict__ newname, uchar *const __r
|
|||||||
lstn_t *const existing = *ppExisting;
|
lstn_t *const existing = *ppExisting;
|
||||||
lstn_t *pThis;
|
lstn_t *pThis;
|
||||||
CHKiRet(lstnAdd(&pThis));
|
CHKiRet(lstnAdd(&pThis));
|
||||||
|
|
||||||
/* Use dynamic dirname if newdirname is set! */
|
/* Use dynamic dirname if newdirname is set! */
|
||||||
if (newdirname == NULL) {
|
if (newdirname == NULL) {
|
||||||
pThis->pszDirName = existing->pszDirName; /* read-only */
|
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 */
|
/* Add dir to table and create watch */
|
||||||
DBGPRINTF("imfile: Adding new dir '%s' to dirs table \n", fulldn);
|
DBGPRINTF("imfile: Adding new dir '%s' to dirs table \n", fulldn);
|
||||||
dirsAdd((uchar*)fulldn, &newdiridx);
|
dirsAdd((uchar*)fulldn, &newdiridx);
|
||||||
|
dirs[newdiridx].bDirType = DIR_DYNAMIC; /* Set to DYNAMIC directory! */
|
||||||
in_setupDirWatch(newdiridx);
|
in_setupDirWatch(newdiridx);
|
||||||
} else {
|
} else {
|
||||||
DBGPRINTF("imfile: dir '%s' already exists in dirs table (Idx %d)\n", fulldn, newdiridx);
|
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)
|
in_handleDirEventFileCREATE(struct inotify_event *ev, const int dirIdx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
lstn_t *pLstn;
|
lstn_t *pLstn = NULL;
|
||||||
int ftIdx;
|
int ftIdx;
|
||||||
char fullfn[MAXFNAME];
|
char fullfn[MAXFNAME];
|
||||||
uchar* pszDir = NULL;
|
uchar* pszDir = NULL;
|
||||||
@ -2047,48 +2063,59 @@ in_handleDirEventFileCREATE(struct inotify_event *ev, const int dirIdx)
|
|||||||
if(ftIdx >= 0) {
|
if(ftIdx >= 0) {
|
||||||
pLstn = dirs[dirIdxFinal].active.listeners[ftIdx].pLstn;
|
pLstn = dirs[dirIdxFinal].active.listeners[ftIdx].pLstn;
|
||||||
} else {
|
} else {
|
||||||
DBGPRINTF("imfile: in_handleDirEventFileCREATE '%s' not associated with dir '%s' (CurMax:%d)\n",
|
DBGPRINTF("imfile: in_handleDirEventFileCREATE '%s' not associated with dir '%s' "
|
||||||
ev->name, dirs[dirIdxFinal].dirName, dirs[dirIdxFinal].active.currMax);
|
"(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);
|
ftIdx = fileTableSearch(&dirs[dirIdxFinal].configured, (uchar*)ev->name);
|
||||||
if(ftIdx == -1) {
|
if(ftIdx == -1) {
|
||||||
/* Search all other configured directories for proper index! */
|
if (dirs[dirIdxFinal].bDirType == DIR_DYNAMIC) {
|
||||||
if (currMaxDirs > 0) {
|
/* Search all other configured directories for proper index! */
|
||||||
/* Store Dirname as we need to overwrite it in in_setupFileWatchDynamic */
|
if (currMaxDirs > 0) {
|
||||||
pszDir = dirs[dirIdxFinal].dirName;
|
/* Store Dirname as we need to overwrite it in in_setupFileWatchDynamic */
|
||||||
|
pszDir = dirs[dirIdxFinal].dirName;
|
||||||
|
|
||||||
/* Combine directory and filename */
|
/* Combine directory and filename */
|
||||||
snprintf(fullfn, MAXFNAME, "%s/%s", pszDir, (uchar*)ev->name);
|
snprintf(fullfn, MAXFNAME, "%s/%s", pszDir, (uchar*)ev->name);
|
||||||
|
|
||||||
for(i = 0 ; i < currMaxDirs ; ++i) {
|
for(i = 0 ; i < currMaxDirs ; ++i) {
|
||||||
ftIdx = fileTableSearch(&dirs[i].configured, (uchar*)ev->name);
|
ftIdx = fileTableSearch(&dirs[i].configured, (uchar*)ev->name);
|
||||||
if(ftIdx != -1) {
|
if(ftIdx != -1) {
|
||||||
/* Found matching directory! */
|
/* Found matching directory! */
|
||||||
dirIdxFinal = i; /* Have to correct directory index for listnr dupl
|
dirIdxFinal = i; /* Have to correct directory index for listnr dupl
|
||||||
in in_setupFileWatchDynamic */
|
in in_setupFileWatchDynamic */
|
||||||
break;
|
|
||||||
|
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) {
|
if(ftIdx == -1) {
|
||||||
DBGPRINTF("imfile: file '%s' not associated with dir '%s' and also no "
|
DBGPRINTF("imfile: file '%s' not associated with dir '%s' and also no "
|
||||||
"matching wildcard directory found\n", ev->name, dirs[dirIdxFinal].dirName);
|
"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;
|
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
|
||||||
pLstn = dirs[dirIdxFinal].configured.listeners[ftIdx].pLstn;
|
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;
|
done: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export IMFILEINPUTFILES="10"
|
|||||||
# generate input files first. Note that rsyslog processes it as
|
# generate input files first. Note that rsyslog processes it as
|
||||||
# soon as it start up (so the file should exist at that point).
|
# 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
|
./inputfilegen -m 1 > $imfilebefore
|
||||||
|
|
||||||
# Start rsyslog now before adding more files
|
# Start rsyslog now before adding more files
|
||||||
@ -18,8 +18,8 @@ sleep 1
|
|||||||
|
|
||||||
for i in `seq 2 $IMFILEINPUTFILES`;
|
for i in `seq 2 $IMFILEINPUTFILES`;
|
||||||
do
|
do
|
||||||
cp $imfilebefore rsyslog.input.$i
|
cp $imfilebefore rsyslog.input.$i.log
|
||||||
imfilebefore="rsyslog.input.$i"
|
imfilebefore="rsyslog.input.$i.log"
|
||||||
done
|
done
|
||||||
ls -l rsyslog.input.*
|
ls -l rsyslog.input.*
|
||||||
|
|
||||||
|
|||||||
@ -6,12 +6,20 @@ module( load="../plugins/imfile/.libs/imfile"
|
|||||||
PollingInterval="1")
|
PollingInterval="1")
|
||||||
|
|
||||||
input(type="imfile"
|
input(type="imfile"
|
||||||
File="./rsyslog.input.*"
|
File="./rsyslog.input.*.log"
|
||||||
Tag="file:"
|
Tag="file:"
|
||||||
Severity="error"
|
Severity="error"
|
||||||
Facility="local7"
|
Facility="local7"
|
||||||
addMetadata="on"
|
addMetadata="on"
|
||||||
)
|
)
|
||||||
|
input(type="imfile"
|
||||||
|
File="/does/not/exist/*.log"
|
||||||
|
Tag="file:"
|
||||||
|
Severity="error"
|
||||||
|
Facility="local7"
|
||||||
|
addMetadata="on"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
template(name="outfmt" type="list") {
|
template(name="outfmt" type="list") {
|
||||||
constant(value="HEADER ")
|
constant(value="HEADER ")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user