Search Postgresql Archives

Re: Current log files when rotating?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



$ 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 <gsmith@xxxxxxxxxxxxx> 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 gsmith@xxxxxxxxxxxxx http://www.gregsmith.com Baltimore, MD

--
Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux