$ cat dbscripts/logtail.py #!/usr/bin/env python """ usage: logtail [-d pathname][-n] -d pathname Use pathname instead of /var/lib/postgresql/8.2/main/pg_log -n Just print the current log file name and exit -l List the log file names -p [files] Run the files through pager """
import os, time, sys, getopt, signal class LogTail: """Logfile tailer for rotated log files. Initially purpouse was to keep tail on PostgreSQL logs, but can be used with any application that satisfies these assumptions: * All log files reside in the same directory. * We can find last log file by sorting the file list alphabetically. * When log is switched, we start tailing from the last file - assume that there will be no gaps (sufficiently large files). """ def __init__(self,logpath): """Initialize the logtailer, open the initial log file.""" self.logpath = logpath self.logfile = None self.logf = None self.probesleft = 2 self.first = True def getfilenames(self): """Return the sorted list of log file names""" files = [] for f in os.listdir(self.logpath): if f.startswith("postgresql-20"): files.append(os.path.join(self.logpath, f)) files.sort() return files def getlogname(self): """Return the name of current logfile.""" files = self.getfilenames() if files: return files[-1] return None def readline(self): """Read single line from logfile, switch to next file if current file is exhausted.""" while True: # If not already open, keep trying until it becomes available while not self.logf: self.logfile = self.getlogname() if not self.logfile: # initial log file not found time.sleep(1) continue try: self.logf = open(self.logfile) self.probesleft = 2 except IOError, msg: time.sleep(1) if self.first: # seek to EOF of first file self.first = False self.logf.seek(0, 2) line = self.logf.readline() if line: return line self.logf.seek(0, 1) # reset EOF condition for next attempt if self.logfile != self.getlogname(): self.probesleft -= 1 if not self.probesleft: self.logf = None else: time.sleep(0.2) def __iter__(self): """Initialize iterator""" return self def next(self): """Iterator wrapper for readline()""" return self.readline() def view_file(logpath, args): """Run the specified files through pager""" lt = LogTail(logpath) if not args: args = [ lt.getlogname() ] logfiles = lt.getfilenames() for f in args: if not f in logfiles or not os.path.exists(f): print f, "is not a postgres log file." sys.exit(1) signal.signal(signal.SIGINT, signal.SIG_IGN) os.environ["LESSSECURE"] = "1" os.spawnv(os.P_WAIT, "/usr/bin/less", [ "less", "-n" ] + args) def usage(): print __doc__ sys.exit(1) def main(): logpath = "/var/lib/postgresql/8.2/main/pg_log" try: opts, args = getopt.getopt(sys.argv[1:], "nlpd:h") except getopt.error, msg: print msg usage() for opt,arg in opts: if opt == "-n": # list current file print LogTail(logpath).getlogname() sys.exit(0) elif opt == "-l": # list the log files for f in LogTail(logpath).getfilenames(): print f sys.exit(0) elif opt == "-p": # run the file through pager view_file(logpath, args) sys.exit(0) elif opt == "-d": logpath = arg; elif opt == "-h": usage() try: for line in LogTail(logpath): sys.stdout.write(line) sys.stdout.flush() except KeyboardInterrupt: pass if __name__ == "__main__": main() On Mon, Nov 10, 2008 at 8:46 PM, Greg Smith <[EMAIL PROTECTED]> wrote: > Let's say you're using logging_collector and you've put some %-escapes into > log_filename for daily log rotation. Perhaps it's daily rotation with this > pattern: > > log_filename = 'postgresql-%Y-%m-%d.log' > > Is there any good way to ask the server what log file name it's currently > writing to? I was trying to write something that does a "tail" on the > current log, and was hoping there was a simple way to figure out which file > that goes against. Looking for the latest timestamp or running strftime > would both work I guess, those just seemed a little heavy (was hoping for an > "alias"-sized answer) to figure out something that the server certainly > knows. > > -- > * Greg Smith [EMAIL PROTECTED] http://www.gregsmith.com Baltimore, MD > > -- > Sent via pgsql-general mailing list (pgsql-general@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-general >