.Dd March 22, 2006 .Dt COPYTOLOG 1 .Os NetBSD 1.4T .Sh NAME .Nm copytolog .Nd copy output to a logfile, making rotation easy .Sh SYNOPSIS .Ar ... | .Nm .Op Fl options .Ar logfile .Sh DESCRIPTION .Nm reads from its standard input, accumulating input into lines. When a line is complete (ie, when a newline is read), it opens the .Ar logfile named, appends the line, and closes it. The idea is that instead of running .D1 somedaemon >> logfile (which causes the logfile to be held open, so that you have to kill and restart the daemon in order to rotate the logfile), you can do .D1 somedaemon | copytolog logfile and then the logfile will never be held open for more than a brief moment while .Nm writes to it. .Pp To cut down on syscall overhead, if multiple lines are available on the standard input at once, .Nm will write them all at once, instead of opening and closing the file for each one. (It does this only when multiple lines are available at the same time; it will not hold onto one line, delaying in the hope that another line will become available.) .Pp There is an internal buffer limit; if an input line is so huge that this buffer fills without a newline being seen, .Nm will write the partial line anyway, writing the rest of the line when it becomes available. .Pp There is also a timeout: when .Nm has a partial line, if nothing is read for some time, it will write the partial line anyway (and write the rest when it becomes available). .Pp .Nm blocks all signals it can. Its normal mode of exiting is to read EOF on its standard input; when this happens, it exits. All other things that can cause it to exit produce an explanatory message on stderr and a nonzero exit code. These things are: startup failures (such as bad arguments); an error (as opposed to EOF) when reading from its stdin; and unexpected error returns from syscalls such as .Xr select 2 or (if enabled) .Xr flock 2 . The only abnormal exits that won't produce messages are due to signals like SIGKILL that cannot be caught, or more arcane ways of killing the process such as attaching with .Xr ptrace 2 and forcing an exit. .Pp If .Nm cannot open/create the output logfile, it will complain to stderr and retry the open (approximately once a minute, in the absence of other activity), buffering log data meanwhile. As soon as the open succeeds, it will dump all accumulated log data. .Nm generates another complaint to stderr each time the error returned by .Xr open 2 changes (as long as the same failure is returned, .Nm does not generate repeated messages). If the buffer overflows while it is in this state, the oldest data is thrown away to make room for the new, and if and when the open finally succeeds, a synthetic line is generated saying that log data was lost. If it reads EOF while in this mode, it does not exit until it manages to successfully dump its buffered data. .Pp If .Nm gets an error attempting to write to the logfile, it produces a complaint to stderr. When this happens, the log data it is attempting to write are buffered and the write is retried later. .Pp The following options are understood: .Bl -tag -width indent -compact -offset indent .It Fl timefmt Ar fmt Generate timestamps. .Ar fmt is a .Xr strftime 3 format, with the additional note that .Sq %f generates a two-digit fractional second value, that is, hundredths of a second. The timestamp is obtained from .Xr gettimeofday 2 , called immediately after the .Xr read 2 that returned the first byte of the line (which may not be the same as the one that returned the last byte of the line). Timestamps are generated only immediately after newlines; in particular, when flushing a partial line due to a timeout, no new timestamp is generated when the rest of the line is read. .It Fl timestamp Like .Fl timefmt with the argument .Sq "%Y%m%d%H%M%S.%f " , that is, generates timestamps of the form .D1 YYYYMMDDhhmmss.hh (where the hh is hundredths of a second). .It Fl mode Ar mode .It Fl perm Ar mode These specify the mode bits with which to create .Ar logfile , when it is found to be nonexistent and .Nm wants to write to it. The value is passed directly as the third argument to .Xr open 2 ; in particular, it will be modified by the current umask (see .Xr umask 2 ) . The argument is always taken as octal; a leading zero is unnecessary (but harmless if present). .It Fl bufsize Ar nbytes Specifies the size in bytes of the internal buffer referred to above. .It Fl timeout Ar ms Specifies the value (in milliseconds) of the timeout referred to above. Specifying -1 disables the timeout behaviour; other negative values are errors. .It Fl logfile Ar logfile Equivalent to specifying the .Ar logfile pathname on the command line without an option, but disambiguates in cases where the argument begins (or may begin) with a dash. .It Fl flock .It Fl fcntl Specify that .Nm is to lock the logfile around writes. .Fl flock uses .Xr flock 2 with argument .Dv LOCK_EX ; .Fl fcntl uses .Xr fcntl 2 ' Ns s .Dv F_SETLKW operation with type .Dv F_WRLCK , applied to the entire file .Pf ( Dv l_start=0 .Dv l_len=0 ) . .Nm always does blocking locks; if the attempt to get the lock blocks, .Nm will not read further input while waiting. .El .Pp All the options have reasonable defaults. At this writing, they are: .Bl -tag -width indent -compact -offset indent .It Fl timestamp By default timestamps are not generated. .It Fl mode 0666. .It Fl bufsize 8192. .It Fl timeout 1000 (ie, one second). .El There is no default for .Ar logfile ; a logfile must be specified, either with .Fl logfile or directly on the command line with no option. .Sh AUTHOR der Mouse, .Aq mouse@rodents.montreal.qc.ca .