[ale] line timestamp command

Ed Cashin ecashin at noserose.net
Thu Nov 14 08:59:05 EST 2013


Hi, Horkan.

That reminds me of an issue I encountered when writing this kind of C
program.  If you put it in a pipe line, so that the C library's standard
I/O subsystem can't see that stdout is a terminal, like this, where I add
cat,

  ecashin at atala horkan$ { echo test; sleep 2; echo test; } | ./a.out | cat

... then the output doesn't come out as some users might expect---delays
are introduced while stdio waits for more output to buffer.  In this case,
the timestamp appears right away, but its message only appears when the
second timestamped message does.

You can tell stdio to line-buffer the output and get consistent behavior in
cases where this matters---i.e., where a human might be watching and
wondering, "Where the heck is my output?"  :)

  ecashin at atala horkan$ gcc -Wall ts.c
  ecashin at atala horkan$ { echo test; sleep 2; echo test; } | ./a.out | cat
  Thu Nov 14 08:47:23 2013: test
  Thu Nov 14 08:47:25 2013: test
  ecashin at atala horkan$ diff -u ts.c.orig ts.c
  --- ts.c.orig   2013-11-14 08:44:08.000000000 -0500
  +++ ts.c        2013-11-14 08:47:15.000000000 -0500
  @@ -48,6 +48,8 @@
      int ch;
      int lastch;

  +   setlinebuf(stdout);
  +
      /* the ctime() man page says ctime is asctime(localtime(&t)) */
      /* the localtime() man page suggests calling tzset before using
localtime(),
         if you want to be portable */
  @@ -72,4 +74,6 @@
         lastch = ch;

      }
  +
  +   return 0;
   }
  ecashin at atala horkan$

I could swear that many years ago, that (setvbuf stuff) didn't work for me
on Linux, but who knows.

On Wed, Nov 13, 2013 at 7:43 AM, Horkan Smith <ale at horkan.net> wrote:

> While I was procrastinating on something else....
>
> -----begin-----
>
> /* add_timestamp.c */
> /* This messy, poorly commented code was authored by Horkan Smith, and I
> hearby release it into the public domain. No warranties expressed or
> implied. */
>
> /* Copy stdin to stdout, printing the current time at the start of each
> line. */
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <time.h>
>
>
> /* dump the current time to 'outstream' using 'ctime()' format w/out
> newline */
> void showtime (FILE *outstream) {
>
>    time_t t;
>    char *p;
>    int len;
>
>    /* current time */
>    t = time(NULL);
>
>    /* shouldn't ever happen w/ a NULL ptr arg, but it doesn't hurt. */
>    if ( ((time_t) -1) == t ) {
>      perror("\ntime(NULL)");
>      exit(-1);
>    }
>
>    /* return a pointer to a string version of current time */
>    /* note: not thread safe - use ctime_r() if you use threads! */
>    p = ctime(&t);
>
>    /* We've got to get rid of the newline at the end */
>    len = strlen(p) -1;
>
>    if ((len >= 0) && (*(p + len) == '\n')) {
>       *(p + len) = (char) 0;
>    }
>
>    /* could use printf, but sometimes it'll link smaller this way. */
>    fputs(p, outstream); fputc(':', outstream); fputc(' ', outstream);
>
> }
>
> int main (int argc, char *argv[], char *envp[]) {
>
>    FILE *instream = stdin;
>    FILE *outstream = stdout;
>    int ch;
>    int lastch;
>
>    /* the ctime() man page says ctime is asctime(localtime(&t)) */
>    /* the localtime() man page suggests calling tzset before using
> localtime(),
>       if you want to be portable */
>    tzset();
>
>
>    /* main loop,
>          get a char
>          if the last one was a newline, write the timestamp
>          write the char out
>     */
>
>    lastch = '\n';
>    while (EOF != (ch = fgetc(instream))) {
>
>       if ('\n' == lastch) {
>          showtime(outstream);
>          fflush(outstream);
>       }
>
>       fputc(ch, outstream);
>       lastch = ch;
>
>    }
> }
>
> ------end------
>
> On Tue, Nov 12, 2013 at 01:34:22PM -0500, Scott Plante wrote:
> > Does anyone happen to know of a command line tool that will read lines
> from standard input and write them to std out, pre-pending a timestamp? I
> have a process that emits messages to std out periodically as it processes
> and I'd like to write that to a log file, but with a time at the start of
> the line. I could do it with a script but a nice little command would be
> better, if it exists.
> >
> >
> > I'm looking for something that would perform the function of this
> script, maybe with an option for format:
> >
> >
> > while read line;
> > do
> > echo $(date +"%D %T") "$line";
> > done
> >
> >
> >
> > Scott
>
> > _______________________________________________
> > Ale mailing list
> > Ale at ale.org
> > http://mail.ale.org/mailman/listinfo/ale
> > See JOBS, ANNOUNCE and SCHOOLS lists at
> > http://mail.ale.org/mailman/listinfo
>
>
> --
> Horkan Smith
> 678-777-3263 cell, ale at horkan.net
> _______________________________________________
> Ale mailing list
> Ale at ale.org
> http://mail.ale.org/mailman/listinfo/ale
> See JOBS, ANNOUNCE and SCHOOLS lists at
> http://mail.ale.org/mailman/listinfo
>



-- 
  Ed Cashin <ecashin at noserose.net>
  http://noserose.net/e/
  http://www.coraid.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.ale.org/pipermail/ale/attachments/20131114/a9d61862/attachment.html>


More information about the Ale mailing list