[logging] Add new "log timestamp precision" command for subsecond timestamps

2007-04-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu>

	* command.c: (config_write_host) Save "log timestamp precision"
	  if not default value.
	  (show_logging) Show configured timestamp precision.
	  (config_log_timestamp_precision) Enable configuration of timestamp
	  precision.
	  (no_config_log_timestamp_precision) Restore default timestamp
	  precision.
	  (cmd_init) Install new timestamp precision commands.
	* log.h: (struct zlog) New timestamp_precision field.
	  (quagga_timestamp) New function to generate a timestamp with the
	  desired precision.
	  (struct timestamp_control) Declare a structure for use in avoiding
	  repeated duplicate calls to quagga_timestamp.
	* log.c: (quagga_timestamp) New function to generate a timestamp
	  of the desired precision.
	  (time_print) Call quagga_timestamp if the time hasn't already been
	  calculated.
	  (vzlog) Initialize a timestamp_control structure and pass it to
	  time_print and vty_log.
	  (zlog_backtrace) Fix 64-bit problem: cannot print size_t with %u.
	* vty.h: Must now include "log.h".
	  (vty_log) Takes an additional struct timestamp_control argument.
	* vty.c: (vty_log_out) Use new struct timestamp_control and new
	  quagga_timestamp function to print timestamps of the desired
	  precision.
	  (vty_time_print) Use new quagga_timestamp function.
	  (vty_log) Accept new struct timestamp_control argument and pass it
	  down to vty_log_out.
diff --git a/lib/vty.c b/lib/vty.c
index 4288e15..6cb8b48 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -149,17 +149,22 @@
 
 static int
 vty_log_out (struct vty *vty, const char *level, const char *proto_str,
-	     const char *format, va_list va)
+	     const char *format, struct timestamp_control *ctl, va_list va)
 {
   int ret;
   int len;
   char buf[1024];
-  struct tm *tm;
 
-  if ((tm = localtime(&recent_time.tv_sec)) != NULL)
-    len = strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S ", tm);
-  else
-    len = 0;
+  if (!ctl->already_rendered)
+    {
+      ctl->len = quagga_timestamp(ctl->precision, ctl->buf, sizeof(ctl->buf));
+      ctl->already_rendered = 1;
+    }
+  if (ctl->len+1 >= sizeof(buf))
+    return -1;
+  memcpy(buf, ctl->buf, len = ctl->len);
+  buf[len++] = ' ';
+  buf[len] = '\0';
 
   if (level)
     ret = snprintf(buf+len, sizeof(buf)-len, "%s: %s: ", level, proto_str);
@@ -199,19 +204,11 @@
 void
 vty_time_print (struct vty *vty, int cr)
 {
-  time_t clock;
-  struct tm *tm;
-#define TIME_BUF 25
-  char buf [TIME_BUF];
-  int ret;
+  char buf [25];
   
-  time (&clock);
-  tm = localtime (&clock);
-
-  ret = strftime (buf, TIME_BUF, "%Y/%m/%d %H:%M:%S", tm);
-  if (ret == 0)
+  if (quagga_timestamp(0, buf, sizeof(buf)) == 0)
     {
-      zlog (NULL, LOG_INFO, "strftime error");
+      zlog (NULL, LOG_INFO, "quagga_timestamp error");
       return;
     }
   if (cr)
@@ -2417,7 +2414,7 @@
 /* Small utility function which output log to the VTY. */
 void
 vty_log (const char *level, const char *proto_str,
-	 const char *format, va_list va)
+	 const char *format, struct timestamp_control *ctl, va_list va)
 {
   unsigned int i;
   struct vty *vty;
@@ -2431,7 +2428,7 @@
 	{
 	  va_list ac;
 	  va_copy(ac, va);
-	  vty_log_out (vty, level, proto_str, format, ac);
+	  vty_log_out (vty, level, proto_str, format, ctl, ac);
 	  va_end(ac);
 	}
 }