Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am trying to log output from some shell scripts of mine to a file, and I want the timestamp prepended to each line. From what I understood, that's what logger(1) is for, but I don't want the output to go to /var/log/messages, and I can't see that this is possible using logger. I'm using Debian by the way.

What is the best way to do this?

—Oliver

share|improve this question
add comment

4 Answers

up vote 4 down vote accepted

logger's function is actually to shunt messages to syslog; default configs will prepend a timestamp and write the logs out to /var/log/messages, but that doesn't mean that logger's purpose is to prepend a timestamp.

One way to handle this would be to modify your syslog configs such that your messages routed via logger go to a special file - use the "-p" flag to logger to stipulate a facility.priority pair (perhaps one of the user[1..7] facilities), and configure your syslogd to log that facility to a special file.

Alternatively, you could whip up a quick shell function to simply prepend the timestamp:

Bodacious:~ james$ timestamp () {
> f=`date`
> echo $f $*
> }
You have new mail in /var/mail/james
Bodacious:~ james$ timestamp a line of logs
Tue 18 Jan 2011 22:40:24 EST a line of logs
Bodacious:~ james$ 

On my system, this is going to result in the shell forking /bin/date once per line of output. This is inefficient, but probably acceptable at small scales.

share|improve this answer
    
Thanks for a good answer :) This was my original idea, but I thought "there has to be a program out there that does this already"… but clearly not! Or not one that's commonly used anyhow. Out of curiosity, what are the "user[1..7] facilities" you refer to? –  obeattie Jan 18 '11 at 21:57
    
In attempting to provide an authoritative reference for my answer, I found out that I was a bit wrong. "Facilities" are one of the ways syslog segments the messages it processes. There are 23 facilities defined - mostly for types of log messages that were common when syslog was created (lpr, ftp, cron), a couple to be generic buckets (messages, system) - but there are 8 facilities called local0 through local7 (not user1 through user7 as I originally stated) intentionally designed for local uses. See RFC5424 for the full list of facilities –  James Polley May 2 '11 at 23:31
add comment

I needed something like that, and google got me here. Using something like syslog is definitely an overkill for just trying out to time something, and the printout-every-second is too inconvenient.

Here's a one-liner that seems to work fine:

cmd | { while read R; do echo "$(date +%s) $R"; done }

and a variant that prints the time it took to produce each line:

cmd | { T=$(date +%s); while read R; do T2=$(date +%s); echo "$((T2-T)) $R"; T=$T2; done }

(This is using seconds, probably not too hard to throw in %N in there, but at that level a shell solution is probably not the right tool anyway.)

share|improve this answer
add comment

You could use -t to tag each line, and then get your syslog server to filter to a different file based on that tag.

(Edited to take out incorrect reference to -f flag)

share|improve this answer
    
That's not what -f does. It uses the contents of the file as the message portion of the log entry. –  Dennis Williamson Jan 18 '11 at 14:44
    
My apologies! Misread the man page. However, the second part of the answer stands, so I've editted it to include just that. –  Niall Donegan Jan 18 '11 at 14:48
add comment

Using the answer from Command to prepend string to each line?, I found this the easiest solution:

cmd | sed "s/^/`date +'%a %b %d %k:%M:%S'` /"
share|improve this answer
    
No, this is broken: it appends the same date to all lines. –  Eli Barzilay Feb 8 '12 at 2:20
    
Well, it's broken if you want to run an entire log-generating process through it. I'm using it as I generate each line. –  Steve Bennett Feb 8 '12 at 4:40
    
If you're using it for a single line you don't need any pipe -- it's almost exactly the same as date +...; cmd. The only difference is that you get a newline from date which you can remove in the usual ways. –  Eli Barzilay Feb 8 '12 at 16:25
    
The usual ways being sed?:-) –  Steve Bennett Feb 9 '12 at 11:25
    
That would be one way ... but you're not using it. Your line uses backticks in a way that already swallows the newline. Here's a complete line that shows what I mean: echo -n "$(date +%s) "; cmd -- note that there are no pipes and no external subprocess other than date. –  Eli Barzilay Feb 9 '12 at 17:43
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.