Changeset 75:228a3120d62d in livinglogic.python.tipimaid

Show
Ignore:
Timestamp:
01/07/09 12:16:19 (10 years ago)
Author:
Nikolas Tautenhahn <nik@…>
Branch:
default
Message:

added option to create symlinks pointing to most recent log files, fixed a bug which caused a crash when liaalh was feeded an empty line

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • liaalh.py

    r63 r75  
    1616 
    1717class Buffer(object): 
    18     def __init__(self, pattern='', gzip_logs=None, buffertime=0, stream=sys.stdin, utcrotate=False): 
     18    def __init__(self, pattern='', gzip_logs=None, buffertime=0, stream=sys.stdin, utcrotate=False, symlinkpattern=None): 
    1919        self.pattern = pattern 
    2020        self.gzip_logs = gzip_logs 
     
    2929        self.updateutcoffset() 
    3030        self.handlevirtualhost = "%v" in pattern 
     31        self.symlinkpattern = symlinkpattern 
    3132        if buffertime > 0: 
    3233            self.run = self.run_buffered 
     
    3435            self.run = self.run_unbuffered 
    3536 
    36     def openfile(self, filename): 
     37    def openfile(self, filename, server): 
    3738        try: 
    3839            f = open(filename, "a", 1) 
     
    4344            else: 
    4445                raise 
     46        if self.symlinkpattern: 
     47            symlinkname = self.symlinkpattern.replace("%v", server) 
     48            try: 
     49                os.symlink(os.path.abspath(filename), symlinkname) 
     50            except OSError, exc: 
     51                if exc.errno == errno.ENOENT: 
     52                    os.makedirs(os.path.dirname(symlinkname)) 
     53                    os.symlink(os.path.abspath(filename), symlinkname) 
     54                elif exc.errno == errno.EEXIST: 
     55                    os.remove(symlinkname) 
     56                    os.symlink(os.path.abspath(filename), symlinkname) 
     57                else: 
     58                    raise 
    4559        if self.gzip_logs is not None: 
    4660            f = gzip.GzipFile(fileobj=f, compresslevel=self.gzip_logs) 
     
    6074                break 
    6175            if self.handlevirtualhost: 
    62                 yield line.split(None, 1) 
     76                ret = line.split(None, 1) 
     77                if ret == []: 
     78                    ret = [None, None] 
     79                yield ret 
    6380            else: 
    6481                yield (None, line) 
     
    7693                f.close() 
    7794                self.updateutcoffset() 
    78                 self.servers[server] = f = self.openfile(filename) 
     95                self.servers[server] = f = self.openfile(filename, server) 
    7996        else: 
    80             self.servers[server] = f = self.openfile(filename) 
     97            self.servers[server] = f = self.openfile(filename, server) 
    8198        f.write(line) 
    8299        f.flush() 
     
    85102        for (server, data) in self.readlines(): 
    86103            try: 
     104                if server is None and data is None: # got an empty line 
     105                    continue 
    87106                datestring = self.re_find_date.findall(data)[0] 
    88107                utclogdate = self.apachedate2utc(datestring) 
     
    99118            for (server, data) in self.readlines(): 
    100119                try: 
     120                    if server is None and data is None: # got an empty line 
     121                        continue 
    101122                    datestring = self.re_find_date.findall(data)[0] 
    102123                    utclogdate = self.apachedate2utc(datestring) 
     
    156177    p.add_option("-b", "--buffertime", dest="buffertime", type="int", action="store", help="Time in seconds for which log entries are buffered, default=0. Set to 0 to disable buffering", default=0) 
    157178    p.add_option("-u", "--utcrotate", dest="utcrotate", action="store_true", help="If set, UTC time determines the time for filenames and rotation. Otherwise local time is used.", default=False) 
     179    p.add_option("-s", "--symlink", dest="symlinkpattern", action="store", help="""Create a symlink pointing to the most recent log file (of each virtual host if you use %v). Needs a filename pattern for the symlink but only "%v" is allowed here as symlinks which include time/date data are useless, e.g. %v/access.log or symlinks/access-%v.log""", default=None) 
    158180    (options, args) = p.parse_args() 
    159181    if options.gzip is not None: 
     
    167189        sys.stderr.flush() 
    168190        return 1 
    169     buf = Buffer(pattern=args[0], gzip_logs=options.gzip, buffertime=options.buffertime, utcrotate=options.utcrotate) 
     191    if options.symlinkpattern is not None and "%v" in args[0] and ("%v" in options.symlinkpattern and options.symlinkpattern.count("%") > 1) or ("%v" not in options.symlinkpattern): 
     192        p.print_usage(sys.stderr) 
     193        sys.stderr.write("%s: If you split logfiles by virtual hosts you should use virtual hosts (%v) in the symlink-pattern as well. But you shouldn't use any patterns for time/date data.\n" % p.get_prog_name()) 
     194        sys.stderr.flush() 
     195        return 1 
     196 
     197    buf = Buffer(pattern=args[0], gzip_logs=options.gzip, buffertime=options.buffertime, utcrotate=options.utcrotate, symlinkpattern=options.symlinkpattern) 
    170198    buf.run() 
    171199