root/livinglogic.python.aplora/aplora.py @ 16:e4865b39c0d0

Revision 16:e4865b39c0d0, 4.2 KB (checked in by Walter Doerwald <walter@…>, 11 years ago)

Stop using cx_Oracle.Timestamp. Use ReST for documentation.

RevLine 
[16]1#!/usr/local/bin/python
2# -*- coding: utf-8 -*-
[0]3
[16]4## Copyright 2004-2008 by LivingLogic AG, Bayreuth/Germany.
5## Copyright 2004-2008 by Walter Dörwald
[0]6##
7## All Rights Reserved
8##
9## Permission to use, copy, modify, and distribute this software and its documentation
10## for any purpose and without fee is hereby granted, provided that the above copyright
11## notice appears in all copies and that both that copyright notice and this permission
12## notice appear in supporting documentation, and that the name of LivingLogic AG or
13## the author not be used in advertising or publicity pertaining to distribution of the
14## software without specific, written prior permission.
15##
16## LIVINGLOGIC AG AND THE AUTHOR DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17## INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
18## LIVINGLOGIC AG OR THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
19## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20## IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
21## IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23"""
24This script can be used with Apache's piped logging to log HTTP request
25to an Oracle database.
26"""
27
[16]28__docformat__ = "plaintext"
[0]29
30
31import os, datetime, cgi, Cookie, urlparse
32
33
34class Logger(object):
35    def __init__(self, oracle, connect, procname):
36        os.environ["ORACLE_HOME"] = oracle
37        import cx_Oracle
38        self.cx_Oracle = cx_Oracle
39        db = cx_Oracle.connect(connect)
40        self.c = db.cursor()
41        self.connect = connect
42        self.procname = procname
43
44    def findcoid(self, path, query):
45        # Find Content-Object-ID in URL
46        coid = None
47        pos1 = path.find("_id_")
48        if pos1 >= 0:
49            pos2 = path.find("_", pos1+4)
50            if pos2 >= 0:
51                coid = path[pos1+4:pos2]
52   
53        # Retry with a query parameter
54        if coid is None and query:
55            query = query[1:] # drop the ?
56            query = cgi.parse_qs(query)
57            if "id" in query:
58                coid = query["id"][0]
59        return coid
60   
61    def findsession(self, sessionin, sessionout, path):
62        if sessionout and sessionout != "-":
63            cookie = Cookie.SimpleCookie()
64            cookie.load(sessionout)
65            if "JSESSIONID" in cookie:
66                return cookie["JSESSIONID"].value
67        (scheme, server, path, params, query, frag) = urlparse.urlparse(path)
68        if params.startswith("jsessionid="):
69            return params[11:]
70        if sessionin and sessionin != "-":
71            return sessionin
72        return None
73
74    def run(self, stream):
75        while True:
76            line = stream.readline()
77            fields = [field.decode("string-escape").encode("latin-1") for field in line.rstrip("\n").split("\t")]
78
79            field = iter(fields)
80            instance = field.next()
81            try:
82                reqstart = int(field.next())
83            except ValueError:
84                reqstart = None
85            else:
86                reqstart = datetime.datetime.fromtimestamp(reqstart)
87            reqtime = 1e-6*float(field.next())
88            client = field.next()
89            useragent = field.next()
90            path = field.next()
91            query = field.next()
92            method = field.next()
93            status = int(field.next())
94            bytesin = int(field.next())
95            bytesout = int(field.next())
96            bytesbodyout = int(field.next())
97            referer = field.next()
98            contenttype = field.next()
99            sessionin = field.next()
100            sessionout = field.next()
[16]101
[0]102            (mimetype, options) = cgi.parse_header(contenttype)
103            charset = options.get("charset", None)
[16]104
[0]105            data = [
106                reqstart,
107                reqtime,
108                instance,
109                client,
110                useragent,
111                path+query,
112                method,
113                status,
114                bytesin,
115                bytesout,
116                bytesbodyout,
117                None, #req.content_encoding,
118                mimetype,
119                charset,
120                referer,
121                self.findsession(sessionin, sessionout, path),
122                self.findcoid(path, query),
123            ]
124            self.c.callproc(self.procname, data)
125
126
127if __name__ == "__main__":
128    import sys, optparse
129    p = optparse.OptionParser(usage="usage: %prog [options]", version="%%prog %s" % __version__)
130    p.add_option("-o", "--oracle", dest="oracle", help="Value for ORACLE_HOME", default="/oracle/Client")
131    p.add_option("-c", "--connect", dest="connect", help="Oracle connect string", default=None)
132    p.add_option("-p", "--procname", dest="procname", help="Name of insert procedure", default="log_insert")
133    (options, args) = p.parse_args()
134    logger = Logger(oracle=options.oracle, connect=options.connect, procname=options.procname)
135    logger.run(sys.stdin)
Note: See TracBrowser for help on using the browser.