add property options to support ISO week/year number

This commit is contained in:
Mattia Barbon 2021-12-27 23:49:56 +01:00
parent d682192b14
commit a11ad1a451
7 changed files with 111 additions and 1 deletions

View File

@ -86,6 +86,21 @@ static const long long yearInSecs[] = {
3944678399, 3976214399, 4007836799, 4039372799, 4070908799,
4102444799};
/* note ramge is 1969 -> 2100 because it needs to access previous/next year */
/* for x in $(seq 1969 2100) ; do
* printf %s', ' $(date --date="Dec 28 ${x} UTC 12:00:00" +%V)
* done | fold -w 70 -s */
static const int weeksInYear[] = {
52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52,
52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52,
52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52,
53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52,
53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52,
53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52,
53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52,
53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52,
};
static const char* monthNames[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
@ -1265,6 +1280,40 @@ int getWeek(struct syslogTime *ts)
return weekNum;
}
/* getISOWeek - 1-53 week of the year */
int getISOWeek(struct syslogTime *ts, int *year)
{
int weekNum;
int curDow;
int curYearDay;
/* get current day in year, current day of week
* and the day of week of 1/1 */
curYearDay = getOrdinal(ts);
curDow = getWeekdayNbr(ts);
/* map from 0 - Sunday, 1, Monday to 1, Monday, 7 - Sunday */
if (curDow == 0) {
curDow = 7;
}
/* make ordinal in range 1-366 */
curYearDay++;
weekNum = (10 + curYearDay - curDow) / 7;
*year = ts->year;
if (weekNum == 0) {
/* this is actually W52 or W53 of previous year */
weekNum = weeksInYear[ts->year - 1 - 1969];
*year = ts->year - 1;
} else if (weekNum > weeksInYear[ts->year - 1969]) {
/* this is actually W01 of next year */
weekNum = 1;
*year = ts->year + 1;
}
return weekNum;
}
void
timeConvertToUTC(const struct syslogTime *const __restrict__ local,
struct syslogTime *const __restrict__ utc)

View File

@ -92,6 +92,7 @@ void applyDfltTZ(struct syslogTime *pTime, char *tz);
int getWeekdayNbr(struct syslogTime *ts);
int getOrdinal(struct syslogTime *ts);
int getWeek(struct syslogTime *ts);
int getISOWeek(struct syslogTime *ts, int *year);
void timeConvertToUTC(const struct syslogTime *const __restrict__ local, struct syslogTime *const __restrict__ utc);
time_t getTime(time_t *ttSeconds);
dateTimeFormat_t getDateTimeFormatFromStr(const char * const __restrict__ s);

View File

@ -1784,6 +1784,25 @@ getPRI(smsg_t * const pM)
}
static const char *
formatISOWeekOrYear(enum tplFormatTypes eFmt, struct syslogTime *pTm)
{
if(pTm->year >= 1970 && pTm->year <= 2099) {
int isoWeekYear;
int isoWeek;
isoWeek = getISOWeek(pTm, &isoWeekYear);
if (eFmt == tplFmtISOWeek) {
return two_digits[isoWeek];
} else {
return years[isoWeekYear - 1967];
}
} else {
return "YEAR OUT OF RANGE(1970-2099)";
}
}
const char *
getTimeReported(smsg_t * const pM, enum tplFormatTypes eFmt)
{
@ -1878,6 +1897,9 @@ getTimeReported(smsg_t * const pM, enum tplFormatTypes eFmt)
return daysInYear[getOrdinal(&pM->tTIMESTAMP)];
case tplFmtWeek:
return two_digits[getWeek(&pM->tTIMESTAMP)];
case tplFmtISOWeek:
case tplFmtISOWeekYear:
return formatISOWeekOrYear(eFmt, &pM->tTIMESTAMP);
}
return "INVALID eFmt OPTION!";
}
@ -1973,6 +1995,10 @@ static const char *getTimeUTC(struct syslogTime *const __restrict__ pTmIn,
case tplFmtWeek:
retbuf = strdup(two_digits[getWeek(pTm)]);
break;
case tplFmtISOWeek:
case tplFmtISOWeekYear:
retbuf = strdup(formatISOWeekOrYear(eFmt, pTm));
break;
}
if(retbuf == NULL) {
@ -2096,6 +2122,9 @@ getTimeGenerated(smsg_t *const __restrict__ pM,
return daysInYear[getOrdinal(pTm)];
case tplFmtWeek:
return two_digits[getWeek(pTm)];
case tplFmtISOWeek:
case tplFmtISOWeekYear:
return formatISOWeekOrYear(eFmt, pTm);
}
return "INVALID eFmt OPTION!";
}

View File

@ -724,6 +724,10 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe)
pTpe->data.field.eDateFormat = tplFmtOrdinal;
} else if (!strcmp((char*)Buf, "date-week")) {
pTpe->data.field.eDateFormat = tplFmtWeek;
} else if (!strcmp((char*)Buf, "date-iso-week")) {
pTpe->data.field.eDateFormat = tplFmtISOWeek;
} else if (!strcmp((char*)Buf, "date-iso-week-year")) {
pTpe->data.field.eDateFormat = tplFmtISOWeekYear;
} else if(!strcmp((char*)Buf, "date-utc")) {
pTpe->data.field.options.bDateInUTC = 1;
} else if(!strcmp((char*)Buf, "lowercase")) {

View File

@ -65,7 +65,8 @@ enum tplFormatTypes { tplFmtDefault = 0, tplFmtMySQLDate = 1,
tplFmtWDayName = 8, tplFmtYear = 9, tplFmtMonth = 10, tplFmtDay = 11,
tplFmtHour = 12, tplFmtMinute = 13, tplFmtSecond = 14,
tplFmtTZOffsHour = 15, tplFmtTZOffsMin = 16, tplFmtTZOffsDirection = 17,
tplFmtWDay = 18, tplFmtOrdinal = 19, tplFmtWeek = 20};
tplFmtWDay = 18, tplFmtOrdinal = 19, tplFmtWeek = 20,
tplFmtISOWeek = 21, tplFmtISOWeekYear = 22};
enum tplFormatCaseConvTypes { tplCaseConvNo = 0, tplCaseConvUpper = 1, tplCaseConvLower = 2 };
enum tplRegexType { TPL_REGEX_BRE = 0, /* posix BRE */
TPL_REGEX_ERE = 1 /* posix ERE */

View File

@ -172,6 +172,7 @@ TESTS += \
empty-hostname.sh \
timestamp-3164.sh \
timestamp-3339.sh \
timestamp-isoweek.sh \
timestamp-mysql.sh \
timestamp-pgsql.sh \
timestamp-subseconds.sh \
@ -1800,6 +1801,7 @@ EXTRA_DIST= \
proprepltest-rfctag.sh \
timestamp-3164.sh \
timestamp-3339.sh \
timestamp-isoweek.sh \
timestamp-mysql.sh \
timestamp-pgsql.sh \
timestamp-subseconds.sh \

24
tests/timestamp-isoweek.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
# add 2021-12-27 by Mattia Barbon, released under ASL 2.0
. ${srcdir:=.}/diag.sh init
generate_conf
add_conf '
template(name="outfmt" type="string" string="%timestamp:::date-iso-week-year%/%timestamp:::date-iso-week%\n")
:syslogtag, contains, "su" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
template="outfmt")
'
startup
injectmsg_literal "<34>1 1971-01-01T12:34:56.003Z mymachine.example.com su - ID47 - MSG"
injectmsg_literal "<34>1 2021-12-02T12:34:56.123456Z mymachine.example.com su - ID47 - MSG"
injectmsg_literal "<34>1 2099-12-31T12:34:56Z mymachine.example.com su - ID47 - MSG"
shutdown_when_empty
wait_shutdown
export EXPECTED='1970/53
2021/48
2099/53'
cmp_exact
exit_test