Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F141074542
D14918.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D14918.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D14918: Add option -Z to syslogd(8) to use ISO 8601 timestamps
Attached
Detach File
Event Timeline
Log In to Comment