[ale] line timestamp command

Horkan Smith ale at horkan.net
Thu Nov 14 13:59:03 EST 2013


Interesting.  I'd not noticed that behavior, thanks for pointing it out!

I think the reason we're seeing the timestamp come out is the call to fflush() - which means I could also fix this by adding:

      fputc(ch, outstream);
      lastch = ch;

+     if ('\n' == lastch) {
+        fflush(outstream);
+     }

   }

Which in turn would mean I could probably drop the fflush() after the timestamp.

I'm not sure which is the 'better' solution, as they both seem to work.  Any thoughts?

thanks!
   horkan

On Thu, Nov 14, 2013 at 08:59:05AM -0500, Ed Cashin wrote:
> 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/

> _______________________________________________
> 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


More information about the Ale mailing list