summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@eurephia.org>2020-07-29 15:29:12 +0200
committerDavid Sommerseth <dazo@eurephia.org>2020-07-30 17:03:42 +0200
commit421c0a73bc8e8cfed0f1188bd886e741dff1076a (patch)
tree710c4ac2ba8d150842ab65291d93563e5955c031
parent11d95327f1ead107139c500734ef95f4ae05a6d2 (diff)
downloadlogactio-421c0a73bc8e8cfed0f1188bd886e741dff1076a.tar.gz
logactio-421c0a73bc8e8cfed0f1188bd886e741dff1076a.tar.xz
logactio-421c0a73bc8e8cfed0f1188bd886e741dff1076a.zip
Migrate to Python 3
Signed-off-by: David Sommerseth <dazo@eurephia.org>
-rw-r--r--LogActio/Logger.py2
-rw-r--r--LogActio/ReporterQueue.py6
-rw-r--r--LogActio/Reporters/HTTPreporter.py6
-rw-r--r--LogActio/Reporters/IPTipset.py65
-rw-r--r--LogActio/Reporters/QpidReporter.py12
-rw-r--r--LogActio/Reporters/SMTPreporter.py20
-rw-r--r--LogActio/Reporters/__init__.py4
-rw-r--r--LogActio/ThresholdWatch.py15
-rw-r--r--LogActio/__init__.py40
-rw-r--r--docs/Makefile2
-rw-r--r--docs/source/conf.py8
-rwxr-xr-xlogactio8
-rw-r--r--rpm/SPECS/logactio.spec15
-rwxr-xr-xrpm/mk-rpm.sh2
-rw-r--r--setup.py4
15 files changed, 97 insertions, 112 deletions
diff --git a/LogActio/Logger.py b/LogActio/Logger.py
index 52bd5e8..e5943cd 100644
--- a/LogActio/Logger.py
+++ b/LogActio/Logger.py
@@ -86,7 +86,7 @@ class Logger(object):
def Log(self, lvl, msg):
if lvl <= self.__verblevel:
- self.__logger._log(lvl, msg)
+ self.__logger._log(lvl, msg.rstrip())
def Close(self):
diff --git a/LogActio/ReporterQueue.py b/LogActio/ReporterQueue.py
index 077bbe4..6c7bdaa 100644
--- a/LogActio/ReporterQueue.py
+++ b/LogActio/ReporterQueue.py
@@ -25,8 +25,8 @@
# are deemed to be part of the source code.
#
-import threading, Queue
-import Message
+import threading, queue
+import LogActio.Message as Message
class ReporterQueue(object):
@@ -34,7 +34,7 @@ class ReporterQueue(object):
self.__thread = None
self.__qname = qname
self.__description = descr
- self.__queue = Queue.Queue()
+ self.__queue = queue.Queue()
self.__thread = threading.Thread(target=processor)
diff --git a/LogActio/Reporters/HTTPreporter.py b/LogActio/Reporters/HTTPreporter.py
index 3e5150c..2213e11 100644
--- a/LogActio/Reporters/HTTPreporter.py
+++ b/LogActio/Reporters/HTTPreporter.py
@@ -44,10 +44,10 @@ class HTTPreporter(ReporterQueue.ReporterQueue):
"""
def __init__(self, config, logger = None):
- if not config.has_key("url"):
+ if "url" not in config:
raise Exception("HTTPreporter is not configured with a URL")
- self.__method = config.has_key("method") and config["method"] or "GET"
+ self.__method = "method" in config and config["method"] or "GET"
self.__url = config["url"]
self.__log = logger and logger or self.__logfnc
@@ -61,7 +61,7 @@ class HTTPreporter(ReporterQueue.ReporterQueue):
self.__processqueue)
def __logfnc(self, lvl, msg):
- print "%s" % msg
+ print("%s" % msg)
sys.stdout.flush()
diff --git a/LogActio/Reporters/IPTipset.py b/LogActio/Reporters/IPTipset.py
index cd676b9..a628574 100644
--- a/LogActio/Reporters/IPTipset.py
+++ b/LogActio/Reporters/IPTipset.py
@@ -91,35 +91,36 @@ class IPTipset(LogActio.ReporterQueue.ReporterQueue):
self.__iptchains = False
self.__iptchainsjump = False
self.__iptchaininserts = False
+ self.__ipset_save = False
- if not config.has_key("ipset-name"):
+ if "ipset-name" not in config:
raise Exception("IPTipset is missing in ipset name")
else:
self.__ipsetname = config["ipset-name"]
- if config.has_key("ipset-create"):
+ if "ipset-create" in config:
create = config["ipset-create"].lower()
self.__create = (create == "true" or create == "1") and True or False
- if self.__create and config.has_key("ipset-hashsize"):
+ if self.__create and "ipset-hashsize" in config:
self.__hashsize = str(config["ipset-hashsize"])
- if self.__create and config.has_key("ipset-timeout"):
+ if self.__create and "ipset-timeout" in config:
self.__timeout = str(config["ipset-timeout"])
- if self.__create and config.has_key("ipset-counters"):
+ if self.__create and "ipset-counters" in config:
counters = config["ipset-counters"].lower()
self.__counters = (counters == "true" or counters == "1") and True or False
- if config.has_key("iptables-chains"):
+ if "iptables-chains" in config:
self.__iptchains = [v.strip() for v in config["iptables-chains"].split(",")]
- if not config.has_key("iptables-jump"):
+ if "iptables-jump" not in config:
raise Exception("IPTipset needs the iptables-jump variable when iptables-chains is set")
self.__iptchainsjump = config["iptables-jump"]
- if config.has_key("iptables-insert-points"):
+ if "iptables-insert-points" in config:
self.__iptchaininserts = {}
for inspoint in config["iptables-insert-points"].split(","):
(chain, point) = inspoint.split(":")
self.__iptchaininserts[chain.strip()] = str(point)
- if config.has_key("ipset-save"):
+ if "ipset-save" in config:
self.__ipset_save = config["ipset-save"]
# Prepare this object, ipset and iptables
@@ -139,14 +140,14 @@ class IPTipset(LogActio.ReporterQueue.ReporterQueue):
def __logfnc(self, lvl, msg):
- print "%s" % msg
+ print("%s" % msg)
sys.stdout.flush()
def __parse_cmd_log(self, cmd, logfp):
logfp.seek(0)
for line in logfp:
- self.__log(3, "[IPTipset] %s: %s" % (cmd, line))
+ self.__log(3, "[IPTipset] %s: %s" % (cmd, line.decode('utf-8')))
def __call_ipset(self, mode, args = None):
@@ -160,17 +161,15 @@ class IPTipset(LogActio.ReporterQueue.ReporterQueue):
else:
args = ["ipset", mode, self.__ipsetname, args]
- nullfp = os.open("/dev/null", os.O_RDWR)
- tmplog = tempfile.SpooledTemporaryFile(mode="rw+b")
+ tmplog = tempfile.SpooledTemporaryFile(mode="w+b")
self.__log(4, "[IPTipset] Executing: %s" % " ".join(args))
- cmd = subprocess.Popen(args, stdin=nullfp, stdout=tmplog, stderr=tmplog)
+ cmd = subprocess.Popen(args, stdin=subprocess.DEVNULL, stdout=tmplog, stderr=tmplog)
res = cmd.wait()
self.__parse_cmd_log("ipset:%s" % mode, tmplog)
# Clean up
tmplog.close()
del tmplog
- os.close(nullfp);
return res
@@ -192,7 +191,7 @@ class IPTipset(LogActio.ReporterQueue.ReporterQueue):
if s[0] != 'add':
continue
self.__call_ipset(s[0], s[2:])
- except IOError, e:
+ except IOError as e:
# Ignore "No such file or directory", as the file may not exist
if e.errno != 2:
raise e
@@ -200,19 +199,17 @@ class IPTipset(LogActio.ReporterQueue.ReporterQueue):
def __save_ipset_state(self):
args = ["ipset", "save", self.__ipsetname]
- nullfp = os.open("/dev/null", os.O_RDWR)
f = open(self.__ipset_save, "w")
self.__log(4, "[IPTipset]: Saving state - Executing %s" % " ".join(args))
- subprocess.Popen(args, stdin=nullfp, stdout=f)
+ subprocess.Popen(args, stdin=subprocess.DEVNULL, stdout=f)
f.close()
def __parse_already_registered(self):
args = ["ipset", "save", self.__ipsetname]
- nullfp = os.open("/dev/null", os.O_RDWR)
- tmplog = tempfile.SpooledTemporaryFile(mode="rw+b")
+ tmplog = tempfile.SpooledTemporaryFile(mode="w+b")
self.__log(4, "[IPTipset] Executing: %s" % " ".join(args))
- cmd = subprocess.Popen(args, stdin=nullfp, stdout=tmplog, stderr=tmplog)
+ cmd = subprocess.Popen(args, stdin=subprocess.DEVNULL, stdout=tmplog, stderr=tmplog)
cmd.wait()
# Process all "add" lines which matches our ipset set name
@@ -220,25 +217,21 @@ class IPTipset(LogActio.ReporterQueue.ReporterQueue):
rg = re.compile("^add (.*) \b((?:[0-9]{1,3}\.){3}[0-9]{1,3})\b")
retlist = []
for line in tmplog:
- m = rg.match(line.strip())
+ m = rg.match(line.strip().decode('utf-8'))
if m:
rgm = m.groups()
if rgm[0] == self.__ipsetname:
retlist.append(rgm[1])
tmplog.close()
del tmplog
- os.close(nullfp)
- del nullfp
return retlist
def __prepare_iptables(self):
- nullfp = os.open("/dev/null", os.O_RDWR)
-
for chain in self.__iptchains:
# Prepare iptables command line
args = False
- if self.__iptchaininserts and self.__iptchaininserts.has_key(chain):
+ if self.__iptchaininserts and chain in self.__iptchaininserts:
args = ["iptables", "-I", chain, self.__iptchaininserts[chain],
"-m", "set", "--match-set", self.__ipsetname,
"-j", self.__iptchainsjump]
@@ -248,26 +241,20 @@ class IPTipset(LogActio.ReporterQueue.ReporterQueue):
"-j", self.__iptchainsjump]
# Call iptables and wait for it to complete and log the output
- tmplog = tempfile.SpooledTemporaryFile(mode="rw+b")
+ tmplog = tempfile.SpooledTemporaryFile(mode="w+b")
self.__log(4, "[IPTipset] Executing: %s" % " ".join(args))
- cmd = subprocess.Popen(args, stdin=nullfp, stdout=tmplog, stderr=tmplog)
+ cmd = subprocess.Popen(args, stdin=subprocess.DEVNULL, stdout=tmplog, stderr=tmplog)
cmd.wait()
self.__parse_cmd_log("iptables:%s" % chain, tmplog)
tmplog.close()
del tmplog
- # Clean up
- os.close(nullfp)
- del nullfp
-
def __cleanup_iptables(self):
- nullfp = os.open("/dev/null", os.O_RDWR)
-
for chain in self.__iptchains:
# Prepare iptables command line
args = False
- if self.__iptchaininserts and self.__iptchaininserts.has_key(chain):
+ if self.__iptchaininserts and chain in self.__iptchaininserts:
args = ["iptables", "-D", chain, self.__iptchaininserts[chain],
"-m", "set", "--match-set", self.__ipsetname,
"-j", self.__iptchainsjump]
@@ -277,17 +264,15 @@ class IPTipset(LogActio.ReporterQueue.ReporterQueue):
"-j", self.__iptchainsjump]
# Call iptables and wait for it to complete and log the output
- tmplog = tempfile.SpooledTemporaryFile(mode="rw+b")
+ tmplog = tempfile.SpooledTemporaryFile(mode="w+b")
self.__log(4, "[IPTipset] Executing: %s" % " ".join(args))
- cmd = subprocess.Popen(args, stdin=nullfp, stdout=tmplog, stderr=tmplog)
+ cmd = subprocess.Popen(args, stdin=subprocess.DEVNULL, stdout=tmplog, stderr=tmplog)
cmd.wait()
self.__parse_cmd_log("iptables:%s" % chain, tmplog)
tmplog.close()
del tmplog
# Clean up
- os.close(nullfp)
- del nullfp
time.sleep(5) # Allow iptables to complete its job before indicating we're done
diff --git a/LogActio/Reporters/QpidReporter.py b/LogActio/Reporters/QpidReporter.py
index 6c05df5..de63680 100644
--- a/LogActio/Reporters/QpidReporter.py
+++ b/LogActio/Reporters/QpidReporter.py
@@ -49,16 +49,16 @@ class QpidReporter(LogActio.ReporterQueue.ReporterQueue):
"""
def __init__(self, config, logger = None):
- if not config.has_key("broker"):
+ if "broker" not in config:
raise Exception("QpidReporter is not configured with a broker host/address")
- if not config.has_key("routing_key"):
+ if "routing_key" not in config:
raise Exception("QpidReporter is not configured with a Qpid routing key")
- if not config.has_key("exchange"):
+ if "exchange" not in config:
raise Exception("QpidReporter is not configured with a Qpid exchange")
self.__log = logger and logger or self.__logfnc
self.__broker = config["broker"]
- self.__port = config.has_key("port") and config["port"] or 5672
+ self.__port = "port" in config and config["port"] or 5672
self.__routkey = config["routing_key"]
self.__exchange = config["exchange"]
@@ -68,7 +68,7 @@ class QpidReporter(LogActio.ReporterQueue.ReporterQueue):
self.__processqueue)
def __logfnc(self, lvl, msg):
- print "%s" % msg
+ print("%s" % msg)
sys.stdout.flush()
@@ -103,7 +103,7 @@ class QpidReporter(LogActio.ReporterQueue.ReporterQueue):
qpidsess.message_transfer(self.__exchange, message=qm)
mcount += 1
del qm
- except Exception, e:
+ except Exception as e:
self.__log(0, "** ERROR ** QpidReporter failed: %s" % str(e))
qpidsess.close(timeout=30)
diff --git a/LogActio/Reporters/SMTPreporter.py b/LogActio/Reporters/SMTPreporter.py
index 802a36a..3438dc0 100644
--- a/LogActio/Reporters/SMTPreporter.py
+++ b/LogActio/Reporters/SMTPreporter.py
@@ -48,22 +48,22 @@ class SMTPreporter(ReporterQueue.ReporterQueue):
"""
def __init__(self, config, logger = None):
- if not config.has_key("sender"):
+ if "sender" not in config:
raise Exception("SMTPreporter is not configured with a sender address")
- if not config.has_key("recipients"):
+ if "recipients" not in config:
raise Exception("SMTPreporter is not configured with any recipients")
- if not config.has_key("smtp_host"):
+ if "smtp_host" not in config:
raise Exception("SMTPreporter is not configured with SMTP host")
self.__log = logger and logger or self.__logfnc
self.__sender = config["sender"]
self.__recipients = config["recipients"].split(",")
- self.__subjprefix = config.has_key("subject_prefix") and config["subject_prefix"] or None
+ self.__subjprefix = "subject_prefix" in config and config["subject_prefix"] or None
self.__smtphost = config["smtp_host"]
- self.__smtpport = config.has_key("smtp_port") and (int(config["smtp_port"])) or 25
- self.__smtpuser = config.has_key("smtp_username") and config["smtp_username"] or None
- self.__smtppass = config.has_key("smtp_password") and config["smtp_password"] or None
- self.__sslmode = config.has_key("sslmode") and config["sslmode"] or None
+ self.__smtpport = "smtp_port" in config and (int(config["smtp_port"])) or 25
+ self.__smtpuser = "smtp_username" in config and config["smtp_username"] or None
+ self.__smtppass = "smtp_password" in config and config["smtp_password"] or None
+ self.__sslmode = "sslmode" in config and config["sslmode"] or None
if (self.__smtpuser and not self.__smtppass) or (not self.__smtpuser and self.__smtppass):
raise Exception("SMTPreporter must have both smtp_username and smtp_password")
@@ -78,7 +78,7 @@ class SMTPreporter(ReporterQueue.ReporterQueue):
def __logfnc(self, lvl, msg):
- print "%s" % msg
+ print("%s" % msg)
sys.stdout.flush()
@@ -122,7 +122,7 @@ class SMTPreporter(ReporterQueue.ReporterQueue):
smtp.sendmail(self.__sender, self.__recipients, msg.as_string())
self.__log(1, "Report sent to: %s" % ", ".join(self.__recipients))
smtp.quit()
- except Exception, e:
+ except Exception as e:
self.__log(0, "** ERROR ** SMTPreporter failed: %s" % str(e))
diff --git a/LogActio/Reporters/__init__.py b/LogActio/Reporters/__init__.py
index 7d47ab7..08a48af 100644
--- a/LogActio/Reporters/__init__.py
+++ b/LogActio/Reporters/__init__.py
@@ -31,7 +31,7 @@ from LogActio import Message, ReporterQueue
class DefaultReporter(ReporterQueue.ReporterQueue):
def __init__(self, config, logger = None):
- self.__alertprefix = config.has_key('prefix') and config['prefix'] or "---> "
+ self.__alertprefix = 'prefix' in config and config['prefix'] or "---> "
self.__log = logger
ReporterQueue.ReporterQueue.__init__(self,
"DefaultReporter",
@@ -52,7 +52,7 @@ class DefaultReporter(ReporterQueue.ReporterQueue):
elif( msg.MessageType() == Message.MSG_SEND ):
if not self.__log:
- print "[DefaultReporter] %s" % msg
+ print("[DefaultReporter] %s" % msg)
sys.stdout.flush()
else:
self.__log(0, "[DefaultReporter] %s" % msg)
diff --git a/LogActio/ThresholdWatch.py b/LogActio/ThresholdWatch.py
index 2fd7403..d5a5ee4 100644
--- a/LogActio/ThresholdWatch.py
+++ b/LogActio/ThresholdWatch.py
@@ -30,7 +30,7 @@ import hashlib, time
class ThresholdType_Rule(object):
def __init__(self, params):
- if not params.has_key("threshold"):
+ if "threshold" not in params:
raise ValueError("Missing required 'threshold' parameter")
self.__threshold = int(params["threshold"])
@@ -82,7 +82,8 @@ class ThresholdType_Exact(object):
self.__ratelimit = params["ratelimit"] and int(params["ratelimit"]) or None
def __gen_hash(self, regexmatch):
- return hashlib.sha384("|".join(regexmatch)).hexdigest()
+ v = "|".join(regexmatch)
+ return hashlib.sha384(v.encode('utf-8')).hexdigest()
def CheckThreshold(self, alert, regexmatch):
@@ -95,7 +96,7 @@ class ThresholdType_Exact(object):
# Check if we have a regexmatch on this from earlier checks
rghash = self.__gen_hash(regexmatch)
- if self.__matchedgroups.has_key(rghash):
+ if rghash in self.__matchedgroups:
lastevent = self.__matchedgroups[rghash]
lastevent["count"] += 1
@@ -105,14 +106,14 @@ class ThresholdType_Exact(object):
and (self.__ratelimit is None or now > (lastevent["lastsent"] + self.__ratelimit)))
try:
- if (self.__timeframe and lastevent.has_key('lastseen')
+ if (self.__timeframe and 'lastseen' in lastevent
and (lastevent["lastseen"] > 0)
and (now >= (lastevent["lastseen"] + self.__timeframe))):
# If the time-frame have timed out, reset it
self.__lastseen = 0
else:
self.__lastseen = now
- except KeyError, e:
+ except KeyError as e:
self.__lastseen = now
else:
@@ -129,7 +130,7 @@ class ThresholdType_Exact(object):
def ClearTimeTrackers(self, regexmatch):
rghash = self.__gen_hash(regexmatch)
- if self.__matchedgroups.has_key(rghash):
+ if rghash in self.__matchedgroups:
self.__matchedgroups[rghash]["lasteen"] = 0
self.__matchedgroups[rghash]["lastsent"] = 0
@@ -140,7 +141,7 @@ class ThresholdType_Exact(object):
def GetCurrentCount(self, regexmatch):
rghash = self.__gen_hash(regexmatch)
- if self.__matchedgroups.has_key(rghash):
+ if rghash in self.__matchedgroups:
return self.__matchedgroups[rghash]["count"]
else:
return 0
diff --git a/LogActio/__init__.py b/LogActio/__init__.py
index b969232..d7f66c6 100644
--- a/LogActio/__init__.py
+++ b/LogActio/__init__.py
@@ -25,8 +25,8 @@
# are deemed to be part of the source code.
#
-import sys, os, re, time, ConfigParser, threading, signal
-import ReporterQueue
+import sys, os, re, time, configparser, threading, signal
+import LogActio.ReporterQueue
from LogActio.ThresholdWatch import ThresholdWatch
from LogActio.Reporters import DefaultReporter
@@ -72,7 +72,7 @@ class WatcherThread(threading.Thread):
# Start reporter modules declared in rules
for r in self.__rules:
- if r.has_key("reporters") and r["reporters"] is not None:
+ if ("reporters" in r) and (r["reporters"] is not None):
for rep in r["reporters"]:
rep._Start()
@@ -125,7 +125,7 @@ class WatcherThread(threading.Thread):
# Send the alert event to be processed, prioritise the
# rule specific reporter over the default reporter
- rep = alert.has_key("reporters") and alert["reporters"] or self.__reporters
+ rep = ("reporters" in alert) and alert["reporters"] or self.__reporters
for r in rep:
r.ProcessEvent(self.__logfile, alert["prefix"], regexmatch,
alert["threshold"].GetCurrentCount(regexmatch)+1, alert["threshold"].GetThreshold())
@@ -154,7 +154,7 @@ class WatcherThread(threading.Thread):
# Shutdown rule specific reporters
for r in self.__rules:
- if r.has_key("reporters") and r["reporters"] is not None:
+ if ("reporters" in r) and (r["reporters"] is not None):
for rep in r["reporters"]:
rep._Shutdown()
@@ -167,11 +167,11 @@ class WatcherThread(threading.Thread):
class LogActio(object):
def __init__(self, cfgfile, daemon=False, pidfile=None, logger=None, stdout="/dev/null"):
try:
- self.__cfg = ConfigParser.ConfigParser()
+ self.__cfg = configparser.ConfigParser()
res = self.__cfg.read(cfgfile)
if len(res) == 0:
raise Exception("Could not load the configuration file '%s'" % cfgfile)
- except Exception, e:
+ except Exception as e:
raise e
self.__watchthreads = []
@@ -191,14 +191,14 @@ class LogActio(object):
self.__daemonise(stdout)
if self.__pidfilename:
- self.__pidfp = os.open(self.__pidfilename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0600)
+ self.__pidfp = os.open(self.__pidfilename, 'w')
os.write(self.__pidfp, "%i" % os.getpid())
self.__parse_cfg()
def __logfnc(self, lvl, msg):
- print "[%i] %s" % (lvl, msg)
+ print("[%i] %s" % (lvl, msg))
def __daemonise(self, redir_stdout):
@@ -206,7 +206,7 @@ class LogActio(object):
pid = os.fork()
if pid > 0:
sys.exit(0)
- except OSError, e:
+ except OSError as e:
sys.stderr.write("Failed to daemonise [step 1]: %s\n" % str(e))
sys.exit(1)
@@ -218,7 +218,7 @@ class LogActio(object):
pid = os.fork()
if pid > 0:
sys.exit(0)
- except OSError, e:
+ except OSError as e:
sys.stderr.write("Failed to daemonise [step 2]: %s\n" % str(e))
sys.exit(1)
@@ -241,7 +241,7 @@ class LogActio(object):
for entry in [rr for rr in self.__cfg.sections() if repre.match(rr)]:
repname = repre.match(entry).groups()[0]
- if __reporters.has_key(repname):
+ if repname in __reporters:
raise Exception("The %s reporter has already been configured" % repname)
# Get configuration for reporter
@@ -249,10 +249,10 @@ class LogActio(object):
for k,v in self.__cfg.items(entry):
repcfg[k] = v
- if repcfg.has_key("module"):
+ if "module" in repcfg:
# import this reporter module, but only if it is unkown
extmodule = repcfg["module"]
- if not self.__ext_modules.has_key(extmodule):
+ if extmodule not in self.__ext_modules:
self.__ext_modules[extmodule] = __import__("LogActio.Reporters.%s" % extmodule,
fromlist="LogActio.Reporters")
else:
@@ -268,7 +268,7 @@ class LogActio(object):
del repcfg
self.__log(2, "Configured reporter %s: %s" % (repname, __reporters[repname].GetName()))
- if not __reporters.has_key("Default"):
+ if "Default" not in __reporters:
__reporters["Default"] = DefaultReporter({}, self.__log)
self.__log(1, "Available reporter modules: %s" % ", ".join(__reporters.keys()))
@@ -289,7 +289,7 @@ class LogActio(object):
# Extract the poll time
try:
polltime = self.__cfg.get(entry, "polltime")
- except ConfigParser.NoOptionError:
+ except configparser.NoOptionError:
polltime = None
# Extract the default reporters to use for this log file
@@ -298,9 +298,9 @@ class LogActio(object):
repnames = self.__cfg.get(entry, "reporters")
for repname in [n.strip() for n in repnames.split(",")]:
defreps.append(__reporters[repname])
- except ConfigParser.NoOptionError:
+ except configparser.NoOptionError:
depreps = [__reporters["Default"]]
- except KeyError, e:
+ except KeyError as e:
raise Exception("No reporters are configured as '%s'" % repname)
# Create a new thread which will watch this particular log file
@@ -327,10 +327,10 @@ class LogActio(object):
repnames = self.__cfg.get(entry, "reporters")
for repname in [n.strip() for n in repnames.split(",")]:
rulereps.append(__reporters[repname])
- except ConfigParser.NoOptionError:
+ except configparser.NoOptionError:
# If nothing was found, that's okay
reps = None
- except KeyError, e:
+ except KeyError as e:
raise Exception("No reporters are configured as '%s'" % repname)
# Add the rule to the proper WatchThread
diff --git a/docs/Makefile b/docs/Makefile
index e97cb5f..0375493 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -3,7 +3,7 @@
# You can set these variables from the command line.
SPHINXOPTS =
-SPHINXBUILD = sphinx-build
+SPHINXBUILD = sphinx-build-3
PAPER =
BUILDDIR = build
diff --git a/docs/source/conf.py b/docs/source/conf.py
index deae582..5033a0d 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -42,16 +42,16 @@ master_doc = 'index'
# General information about the project.
project = u'logactio'
-copyright = u'2012-2015, David Sommerseth'
+copyright = u'2012-2020, David Sommerseth'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-version = '1.0'
+version = '1.2'
# The full version, including alpha/beta/rc tags.
-release = '1.0'
+release = '1.2'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -223,7 +223,7 @@ man_pages = [
epub_title = u'logactio'
epub_author = u'David Sommerseth'
epub_publisher = u'David Sommerseth'
-epub_copyright = u'2012-2015, David Sommerseth'
+epub_copyright = u'2012-2020, David Sommerseth'
# The language of the text. It defaults to the language option
# or en if the language is not set.
diff --git a/logactio b/logactio
index 8983dfc..0f682cd 100755
--- a/logactio
+++ b/logactio
@@ -1,9 +1,9 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
#
# logactio - simple framework for doing configured action on certain
# log file events
#
-# Copyright 2012 - 2015 David Sommerseth <dazo@eurephia.org>
+# Copyright 2012 - 2020 David Sommerseth <dazo@eurephia.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -75,9 +75,9 @@ if __name__ == '__main__':
main = LogActio(opts.cfg, opts.daemon, opts.pidfile, logger.Log, opts.stdoutredir)
main.Run()
sys.exit(0)
- except Exception, e:
+ except Exception as e:
if opts.trace:
import traceback
traceback.print_exc(file=sys.stdout)
else:
- print "** ERROR ** %s" % str(e)
+ print("** ERROR ** %s" % str(e))
diff --git a/rpm/SPECS/logactio.spec b/rpm/SPECS/logactio.spec
index ce848f5..1274385 100644
--- a/rpm/SPECS/logactio.spec
+++ b/rpm/SPECS/logactio.spec
@@ -1,6 +1,3 @@
-%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
-%{!?python_ver: %define python_ver %(%{__python} -c "import sys ; print sys.version[:3]")}
-
Summary: A simple log tracker which acts on certain events
Name: logactio
Version: 1.1
@@ -23,6 +20,8 @@ BuildArch: noarch
%define systemd_avail 1
%endif
+Requires: python(abi) >= 3.6
+
%if 0%{systemd_avail} == 1
Requires(post): systemd
Requires(preun): systemd
@@ -37,7 +36,7 @@ Requires(preun): initscripts
%if 0%{rhel} <= 6
BuildRequires: python-sphinx10
%else
-BuildRequires: python-sphinx
+BuildRequires: python3-sphinx
%endif
@@ -50,7 +49,7 @@ in Python and can easily be extended with specific actions.
%setup -q
%build
-%{__python} setup.py build
+%py3_build
pushd docs
%if 0%{rhel} > 6
make text man
@@ -64,7 +63,7 @@ popd
rm -rf %{buildroot}
# Install logactio code
-%{__python} setup.py install --root=%{buildroot}
+%py3_install
# Install man pages
mkdir -p %{buildroot}/%{_mandir}/man7
@@ -116,8 +115,8 @@ fi
%doc COPYING docs/build/text/configuration.txt docs/build/text/starting.txt
%{_mandir}/man7/*.gz
%{_bindir}/logactio
-%{python_sitelib}/LogActio
-%{python_sitelib}/*.egg-info
+%{python3_sitelib}/LogActio
+%{python3_sitelib}/*.egg-info
%config(noreplace) /etc/sysconfig/%{name}
%if 0%{systemd_avail} == 1
%{_unitdir}/%{name}.service
diff --git a/rpm/mk-rpm.sh b/rpm/mk-rpm.sh
index 9e50672..2280d4f 100755
--- a/rpm/mk-rpm.sh
+++ b/rpm/mk-rpm.sh
@@ -11,7 +11,7 @@
exit 1
fi
- python2 setup.py sdist --formats=bztar
+ python3 setup.py sdist --formats=bztar
cp dist/logactio-*.tar.bz2 rpm/SOURCES
cp init/sysv/logactio rpm/SOURCES/logactio.sysv
cp init/systemd/logactio* rpm/SOURCES/
diff --git a/setup.py b/setup.py
index 0f8a687..89de76a 100644
--- a/setup.py
+++ b/setup.py
@@ -1,9 +1,9 @@
-#!/usr/bin/python2
+#!/usr/bin/python3
from distutils.sysconfig import get_python_lib
from distutils.core import setup
from os.path import join
-import commands, sys
+import sys
# Get PYTHONLIB with no prefix so --prefix installs work.
PYTHONLIB = join(get_python_lib(standard_lib=1, prefix=''), 'site-packages')