Page MenuHomeFreeBSD

D14918.diff
No OneTemporary

D14918.diff

Index: usr.sbin/syslogd/syslogd.8
===================================================================
--- usr.sbin/syslogd/syslogd.8
+++ usr.sbin/syslogd/syslogd.8
@@ -36,7 +36,7 @@
.Nd log systems messages
.Sh SYNOPSIS
.Nm
-.Op Fl 468ACcdFHkNnosTuv
+.Op Fl 468ACcdFHkNnosTuvZ
.Op Fl a Ar allowed_peer
.Op Fl b Ar bind_address
.Op Fl f Ar config_file
@@ -333,6 +333,10 @@
If specified more than once,
the names of the facility and priority are logged with each locally-written
message.
+.It Fl Z
+Generate timestamps in ISO 8601 format.
+This includes the year and the timezone, and all logging is done
+in UTC.
.El
.Pp
The
Index: usr.sbin/syslogd/syslogd.c
===================================================================
--- usr.sbin/syslogd/syslogd.c
+++ usr.sbin/syslogd/syslogd.c
@@ -71,7 +71,7 @@
*/
/* Maximum number of characters in time of last occurrence */
-#define MAXDATELEN 16
+#define MAXDATELEN 33
#define MAXLINE 1024 /* maximum line length */
#define MAXSVLINE MAXLINE /* maximum saved line length */
#define DEFUPRI (LOG_USER|LOG_NOTICE)
@@ -309,6 +309,7 @@
static int MarkSeq; /* mark sequence number */
static int NoBind; /* don't bind() as suggested by RFC 3164 */
static int SecureMode; /* when true, receive only unix domain socks */
+static int ZuluTime = 0; /* display date and time in UTC ISO format */
#ifdef INET6
static int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */
#else
@@ -352,7 +353,7 @@
static void fprintlog(struct filed *, int, const char *);
static void init(int);
static void logerror(const char *);
-static void logmsg(int, const char *, const char *, const char *, int);
+static void logmsg(int, char [], const char *, const char *, int);
static void log_deadchild(pid_t, int, const char *);
static void markit(void);
static int socksetup(struct peer *);
@@ -460,7 +461,7 @@
if (madvise(NULL, 0, MADV_PROTECT) != 0)
dprintf("madvise() failed: %s\n", strerror(errno));
- while ((ch = getopt(argc, argv, "468Aa:b:cCdf:FHkl:m:nNop:P:sS:Tuv"))
+ while ((ch = getopt(argc, argv, "468Aa:b:cCdf:FHkl:m:nNop:P:sS:TuvZ"))
!= -1)
switch (ch) {
#ifdef INET
@@ -601,6 +602,9 @@
case 'v': /* log facility and priority */
LogFacPri++;
break;
+ case 'Z': /* time stamps in UTC ISO format */
+ ZuluTime = 1;
+ break;
default:
usage();
}
@@ -843,7 +847,7 @@
{
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
- "usage: syslogd [-468ACcdFHknosTuv] [-a allowed_peer]",
+ "usage: syslogd [-468ACcdFHknosTuvZ] [-a allowed_peer]",
" [-b bind_address] [-f config_file]",
" [-l [mode:]path] [-m mark_interval]",
" [-P pid_file] [-p log_socket]",
@@ -858,7 +862,7 @@
static void
parsemsg(const char *from, char *msg)
{
- const char *timestamp;
+ char timestamp[MAXDATELEN];
char *q;
long n;
int i, c, pri, msglen;
@@ -901,26 +905,87 @@
pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri));
/*
- * The TIMESTAMP field is the local time and is in the format of
+ * If the "-Z" option was not used when invoking syslogd,
+ * the TIMESTAMP field is the local time and is in the format of
* "Mmm dd hh:mm:ss" (without the quote marks).
- * A single space character MUST follow the TIMESTAMP field.
+ * If the "-Z" option was given when invoking syslogd,
+ * the TIMESTAMP field is in UTC and is in the ISO 8601 format of
+ * "YYYY-MM-DDThh:mm:ss[.mmm]Z" (without the quote marks).
+ * A single space character MUST follow the TIMESTAMP field.
*
* XXXGL: the check can be improved.
*/
+ timestamp[0] = '\0';
msg += i + 1;
msglen = strlen(msg);
- if (msglen < MAXDATELEN || msg[3] != ' ' || msg[6] != ' ' ||
- msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') {
+ if (msglen >= 16 && msg[3] == ' ' && msg[6] == ' ' &&
+ msg[9] == ':' && msg[12] == ':' && msg[15] == ' ') {
+ /* BSD syslog TIMESTAMP, RFC 3164 */
+ strlcpy(timestamp, msg, 16);
+ msg += 16;
+ msglen -= 16;
+ if (ZuluTime)
+ RemoteAddDate = 1;
+ } else if (msglen >= 20 &&
+ isdigit(msg[0]) && isdigit(msg[1]) && isdigit(msg[2]) &&
+ isdigit(msg[3]) && msg[4] == '-' &&
+ isdigit(msg[5]) && isdigit(msg[6]) && msg[7] == '-' &&
+ isdigit(msg[8]) && isdigit(msg[9]) && msg[10] == 'T' &&
+ isdigit(msg[11]) && isdigit(msg[12]) && msg[13] == ':' &&
+ isdigit(msg[14]) && isdigit(msg[15]) && msg[16] == ':' &&
+ isdigit(msg[17]) && isdigit(msg[18]) && (msg[19] == '.' ||
+ msg[19] == 'Z' || msg[19] == '+' || msg[19] == '-')) {
+ /* FULL-DATE "T" FULL-TIME, RFC 5424 */
+ strlcpy(timestamp, msg, sizeof(timestamp));
+ msg += 19;
+ msglen -= 19;
+ i = 0;
+ if (msglen >= 3 && msg[0] == '.' && isdigit(msg[1])) {
+ /* TIME-SECFRAC */
+ msg += 2;
+ msglen -= 2;
+ i += 2;
+ while(i < 7 && msglen >= 1 && isdigit(msg[0])) {
+ msg++;
+ msglen--;
+ i++;
+ }
+ }
+ if (msglen >= 2 && msg[0] == 'Z' && msg[1] == ' ') {
+ /* "Z" */
+ timestamp[20+i] = '\0';
+ msg += 2;
+ msglen -= 2;
+ } else if (msglen >= 7 &&
+ (msg[0] == '+' || msg[0] == '-') &&
+ isdigit(msg[1]) && isdigit(msg[2]) &&
+ msg[3] == ':' &&
+ isdigit(msg[4]) && isdigit(msg[5]) &&
+ msg[6] == ' ') {
+ /* TIME-NUMOFFSET */
+ timestamp[25+i] = '\0';
+ msg += 7;
+ msglen -= 7;
+ } else {
+ /* invalid time format, roll back */
+ msg -= 19 + i;
+ msglen += 19 + i;
+ dprintf("Invalid TIMESTAMP from %s: %s\n", from, msg);
+ RemoteAddDate = 1;
+ }
+ } else if (msglen >= 2 && msg[0] == '-' && msg[1] == ' ') {
+ /* NILVALUE, RFC 5424 */
+ msg += 2;
+ msglen -= 2;
+ dprintf("No TIMESTAMP included from %s: %s\n", from, msg);
+ RemoteAddDate = 1;
+ } else {
dprintf("Invalid TIMESTAMP from %s: %s\n", from, msg);
- return;
+ RemoteAddDate = 1;
}
- if (!RemoteAddDate)
- timestamp = msg;
- else
- timestamp = NULL;
- msg += MAXDATELEN;
- msglen -= MAXDATELEN;
+ if (RemoteAddDate)
+ *timestamp = '\0';
/*
* A single space character MUST also follow the HOSTNAME field.
@@ -1046,7 +1111,7 @@
logmsg(pri, NULL, p, LocalHostName, flags);
}
-static time_t now;
+static struct timeval now;
/*
* Match a program or host name against a specification.
@@ -1098,21 +1163,38 @@
* the priority.
*/
static void
-logmsg(int pri, const char *timestamp, const char *msg, const char *from,
+logmsg(int pri, char *timestamp, const char *msg, const char *from,
int flags)
{
struct filed *f;
int i, fac, msglen, prilev;
char prog[NAME_MAX+1];
char buf[MAXLINE+1];
+ char nowtimestamp[MAXDATELEN] = "";
dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n",
pri, flags, from, msg);
- (void)time(&now);
- if (timestamp == NULL)
- timestamp = ctime(&now) + 4;
+ (void)gettimeofday(&now, NULL);
+ if (timestamp == NULL || timestamp[0] == '\0') {
+ if (ZuluTime) {
+ struct tm *tm;
+ size_t l;
+ tm = gmtime(&now.tv_sec);
+ l = strftime(nowtimestamp, sizeof(nowtimestamp), "%FT%T", tm);
+ /*
+ * Use only millisecond precision as some time has
+ * passed since syslog(3) was called.
+ */
+ snprintf(nowtimestamp + l, sizeof(nowtimestamp) - l,
+ ".%03ldZ", now.tv_usec / 1000);
+ } else
+ strlcpy(nowtimestamp, ctime(&now.tv_sec) + 4, 16);
+
+ timestamp = nowtimestamp;
+ }
+
/* extract facility and priority level */
if (flags & MARK)
fac = LOG_NFACILITIES;
@@ -1182,7 +1264,8 @@
continue;
/* don't output marks to recently written files */
- if ((flags & MARK) && (now - f->f_time) < MarkInterval / 2)
+ if ((flags & MARK) &&
+ (now.tv_sec - f->f_time) < MarkInterval / 2)
continue;
/*
@@ -1196,7 +1279,7 @@
sizeof(f->f_lasttime));
f->f_prevcount++;
dprintf("msg repeated %d times, %ld sec of %d\n",
- f->f_prevcount, (long)(now - f->f_time),
+ f->f_prevcount, (long)(now.tv_sec - f->f_time),
repeatinterval[f->f_repeatcount]);
/*
* If domark would have logged this by now,
@@ -1204,7 +1287,7 @@
* but back off so we'll flush less often
* in the future.
*/
- if (now > REPEATTIME(f)) {
+ if (now.tv_sec > REPEATTIME(f)) {
fprintlog(f, flags, (char *)NULL);
BACKOFF(f);
}
@@ -1259,7 +1342,7 @@
if (f->f_type == F_WALL) {
/* The time displayed is not synchornized with the other log
* destinations (like messages). Following fragment was using
- * ctime(&now), which was updating the time every 30 sec.
+ * ctime(&now.tv_sec), which was updating the time every 30 sec.
* With f_lasttime, time is synchronized correctly.
*/
iov[0] = (struct iovec){
@@ -1361,7 +1444,7 @@
};
}
dprintf("Logging to %s", TypeNames[f->f_type]);
- f->f_time = now;
+ f->f_time = now.tv_sec;
switch (f->f_type) {
case F_UNUSED:
@@ -1389,11 +1472,11 @@
/* check for local vs remote messages */
if (strcasecmp(f->f_prevhost, LocalHostName))
l = snprintf(line, sizeof line - 1,
- "<%d>%.15s Forwarded from %s: %s",
+ "<%d>%.32s Forwarded from %s: %s",
f->f_prevpri, (char *)iov[0].iov_base,
f->f_prevhost, (char *)iov[5].iov_base);
else
- l = snprintf(line, sizeof line - 1, "<%d>%.15s %s",
+ l = snprintf(line, sizeof line - 1, "<%d>%.32s %s",
f->f_prevpri, (char *)iov[0].iov_base,
(char *)iov[5].iov_base);
if (l < 0)
@@ -2362,7 +2445,7 @@
struct filed *f;
struct deadq_entry *dq, *dq0;
- now = time((time_t *)NULL);
+ (void)gettimeofday(&now, NULL);
MarkSeq += TIMERINTVL;
if (MarkSeq >= MarkInterval) {
logmsg(LOG_INFO, NULL, "-- MARK --", LocalHostName, MARK);
@@ -2370,7 +2453,7 @@
}
STAILQ_FOREACH(f, &fhead, next) {
- if (f->f_prevcount && now >= REPEATTIME(f)) {
+ if (f->f_prevcount && now.tv_sec >= REPEATTIME(f)) {
dprintf("flush %s: repeated %d times, %d sec.\n",
TypeNames[f->f_type], f->f_prevcount,
repeatinterval[f->f_repeatcount]);

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 1, 1:15 PM (17 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27437048
Default Alt Text
D14918.diff (9 KB)

Event Timeline