config changes for logging: logs rotate and go to APPDATA, hud_config now goes in /fpdb/ if they must use it but logging.conf stays in /pyfpdb/. TODO: Some logging still into /fpdb/log/

This commit is contained in:
sqlcoder 2010-01-31 11:25:24 +00:00
parent cc5f77e950
commit 5e9486aa3d
8 changed files with 126 additions and 81 deletions

View File

@ -52,16 +52,19 @@ def get_default_config_path():
return config_path return config_path
def get_exec_path(): def get_exec_path():
"""Returns the path to the fpdb.(py|exe) file we are executing""" """Returns the path to the fpdb(dir|.exe) file we are executing"""
if hasattr(sys, "frozen"): # compiled by py2exe if hasattr(sys, "frozen"): # compiled by py2exe
return os.path.dirname(sys.executable) return os.path.dirname(sys.executable)
else: else:
return sys.path[0] return os.path.dirname(sys.path[0]) # should be path to /fpdb
def get_config(file_name, fallback = True): def get_config(file_name, fallback = True):
"""Looks in cwd and in self.default_config_path for a config file.""" """Looks in cwd and in self.default_config_path for a config file."""
exec_dir = get_exec_path() exec_dir = get_exec_path()
config_path = os.path.join(exec_dir, file_name) if file_name == 'logging.conf':
config_path = os.path.join(exec_dir, 'pyfpdb', file_name)
else:
config_path = os.path.join(exec_dir, file_name)
# print "config_path=", config_path # print "config_path=", config_path
if os.path.exists(config_path): # there is a file in the cwd if os.path.exists(config_path): # there is a file in the cwd
return config_path # so we use it return config_path # so we use it
@ -80,11 +83,7 @@ def get_config(file_name, fallback = True):
if os.path.exists(file_name + ".example"): if os.path.exists(file_name + ".example"):
try: try:
print "" print ""
if not os.path.isdir(default_dir): check_dir(default_dir)
msg = "Creating directory: '%s'" % (default_dir)
print msg
logging.info(msg)
os.mkdir(default_dir)
shutil.copyfile(file_name + ".example", config_path) shutil.copyfile(file_name + ".example", config_path)
msg = "No %s found in %s or %s\n" % (file_name, exec_dir, default_dir) \ msg = "No %s found in %s or %s\n" % (file_name, exec_dir, default_dir) \
+ "Config file has been created at %s.\n" % config_path \ + "Config file has been created at %s.\n" % config_path \
@ -104,11 +103,17 @@ def get_config(file_name, fallback = True):
sys.exit() sys.exit()
return file_name return file_name
def get_logger(file_name, config = "config", fallback = False): def get_logger(file_name, config = "config", fallback = False, log_dir=None):
conf = get_config(file_name, fallback = fallback) conf_file = get_config(file_name, fallback = fallback)
if conf: if conf_file:
try: try:
logging.config.fileConfig(conf) if log_dir is None:
log_dir = os.path.join(get_exec_path(), 'log')
check_dir(log_dir)
file = os.path.join(log_dir, 'logging.out')
file = file.replace('\\', '\\\\') # replace each \ with \\
# print " ="+file+" "+ str(type(file))+" len="+str(len(file))+"\n"
logging.config.fileConfig(conf_file, {"logFile":file})
log = logging.getLogger(config) log = logging.getLogger(config)
log.debug("%s logger initialised" % config) log.debug("%s logger initialised" % config)
return log return log
@ -120,8 +125,23 @@ def get_logger(file_name, config = "config", fallback = False):
log.debug("config logger initialised") log.debug("config logger initialised")
return log return log
def check_dir(path, create = True):
"""Check if a dir exists, optionally creates if not."""
if os.path.exists(path):
if os.path.isdir(path):
return path
else:
return False
if create:
msg = "Creating directory: '%s'" % (path)
print msg
log.info(msg)
os.mkdir(path)
else:
return False
# find a logging.conf file and set up logging # find a logging.conf file and set up logging
log = get_logger("logging.conf") log = get_logger("logging.conf", "config")
######################################################################## ########################################################################
# application wide consts # application wide consts
@ -421,7 +441,6 @@ class Tv:
class Config: class Config:
def __init__(self, file = None, dbname = ''): def __init__(self, file = None, dbname = ''):
# "file" is a path to an xml file with the fpdb/HUD configuration # "file" is a path to an xml file with the fpdb/HUD configuration
# we check the existence of "file" and try to recover if it doesn't exist # we check the existence of "file" and try to recover if it doesn't exist
@ -435,6 +454,13 @@ class Config:
if file is None: file = get_config("HUD_config.xml", True) if file is None: file = get_config("HUD_config.xml", True)
self.file = file
self.dir_self = get_exec_path()
self.dir_config = os.path.dirname(self.file)
self.dir_log = os.path.join(self.dir_config, 'log')
self.dir_database = os.path.join(self.dir_config, 'database')
log = get_logger("logging.conf", "config", log_dir=self.dir_log)
# Parse even if there was no real config file found and we are using the example # Parse even if there was no real config file found and we are using the example
# If using the example, we'll edit it later # If using the example, we'll edit it later
log.info("Reading configuration file %s" % file) log.info("Reading configuration file %s" % file)
@ -449,9 +475,6 @@ class Config:
sys.exit() sys.exit()
self.doc = doc self.doc = doc
self.file = file
self.dir = os.path.dirname(self.file)
self.dir_databases = os.path.join(self.dir, 'database')
self.supported_sites = {} self.supported_sites = {}
self.supported_games = {} self.supported_games = {}
self.supported_databases = {} # databaseName --> Database instance self.supported_databases = {} # databaseName --> Database instance

View File

@ -224,6 +224,7 @@ class Database:
def __init__(self, c, sql = None): def __init__(self, c, sql = None):
log = Configuration.get_logger("logging.conf", "db", log_dir=c.dir_log)
log.info("Creating Database instance, sql = %s" % sql) log.info("Creating Database instance, sql = %s" % sql)
self.config = c self.config = c
self.__connected = False self.__connected = False
@ -379,11 +380,11 @@ class Database:
log.warning("SQLite won't work well without 'sqlalchemy' installed.") log.warning("SQLite won't work well without 'sqlalchemy' installed.")
if database != ":memory:": if database != ":memory:":
if not os.path.isdir(self.config.dir_databases): if not os.path.isdir(self.config.dir_database):
print "Creating directory: '%s'" % (self.config.dir_databases) print "Creating directory: '%s'" % (self.config.dir_database)
log.info("Creating directory: '%s'" % (self.config.dir_databases)) log.info("Creating directory: '%s'" % (self.config.dir_database))
os.mkdir(self.config.dir_databases) os.mkdir(self.config.dir_database)
database = os.path.join(self.config.dir_databases, database) database = os.path.join(self.config.dir_database, database)
log.info("Connecting to SQLite: %(database)s" % {'database':database}) log.info("Connecting to SQLite: %(database)s" % {'database':database})
print "Connecting to SQLite: %(database)s" % {'database':database} print "Connecting to SQLite: %(database)s" % {'database':database}
self.connection = sqlite3.connect(database, detect_types=sqlite3.PARSE_DECLTYPES ) self.connection = sqlite3.connect(database, detect_types=sqlite3.PARSE_DECLTYPES )
@ -787,6 +788,7 @@ class Database:
def get_player_id(self, config, site, player_name): def get_player_id(self, config, site, player_name):
c = self.connection.cursor() c = self.connection.cursor()
print "get_player_id: player_name =", player_name, type(player_name)
p_name = Charset.to_utf8(player_name) p_name = Charset.to_utf8(player_name)
c.execute(self.sql.query['get_player_id'], (p_name, site)) c.execute(self.sql.query['get_player_id'], (p_name, site))
row = c.fetchone() row = c.fetchone()

View File

@ -51,10 +51,8 @@ import gobject
# FreePokerTools modules # FreePokerTools modules
import Configuration import Configuration
print "start logging"
log = Configuration.get_logger("logging.conf", config = 'hud') log = Configuration.get_logger("logging.conf", config = 'hud')
log.debug("%s logger initialized." % "dud") log.debug("%s logger initialized." % "hud")
print "logging started"
import Database import Database
@ -68,36 +66,40 @@ elif os.name == 'nt':
import Hud import Hud
log = Configuration.get_logger("logging.conf")
class HUD_main(object): class HUD_main(object):
"""A main() object to own both the read_stdin thread and the gui.""" """A main() object to own both the read_stdin thread and the gui."""
# This class mainly provides state for controlling the multiple HUDs. # This class mainly provides state for controlling the multiple HUDs.
def __init__(self, db_name = 'fpdb'): def __init__(self, db_name = 'fpdb'):
self.db_name = db_name try:
self.log = log print "HUD_main: starting ..."
self.config = Configuration.Config(file=options.config, dbname=options.dbname) self.db_name = db_name
self.hud_dict = {} self.config = Configuration.Config(file=options.config, dbname=options.dbname)
self.hud_params = self.config.get_hud_ui_parameters() log = Configuration.get_logger("logging.conf", "hud", log_dir=self.config.dir_log)
log.debug("starting ...")
self.hud_dict = {}
self.hud_params = self.config.get_hud_ui_parameters()
# a thread to read stdin # a thread to read stdin
gobject.threads_init() # this is required gobject.threads_init() # this is required
thread.start_new_thread(self.read_stdin, ()) # starts the thread thread.start_new_thread(self.read_stdin, ()) # starts the thread
# a main window
self.main_window = gtk.Window()
self.main_window.connect("destroy", self.destroy)
self.vb = gtk.VBox()
self.label = gtk.Label('Closing this window will exit from the HUD.')
self.vb.add(self.label)
self.main_window.add(self.vb)
self.main_window.set_title("HUD Main Window")
self.main_window.show_all()
except:
log.debug("commit "+str(i)+" failed: info=" + str(sys.exc_info())
+ " value=" + str(sys.exc_value))
# a main window
self.main_window = gtk.Window()
self.main_window.connect("destroy", self.destroy)
self.vb = gtk.VBox()
self.label = gtk.Label('Closing this window will exit from the HUD.')
self.vb.add(self.label)
self.main_window.add(self.vb)
self.main_window.set_title("HUD Main Window")
self.main_window.show_all()
def destroy(self, *args): # call back for terminating the main eventloop def destroy(self, *args): # call back for terminating the main eventloop
self.log.info("Terminating normally.") log.info("Terminating normally.")
gtk.main_quit() gtk.main_quit()
def kill_hud(self, event, table): def kill_hud(self, event, table):
@ -205,7 +207,7 @@ class HUD_main(object):
t0 = time.time() t0 = time.time()
t1 = t2 = t3 = t4 = t5 = t6 = t0 t1 = t2 = t3 = t4 = t5 = t6 = t0
new_hand_id = string.rstrip(new_hand_id) new_hand_id = string.rstrip(new_hand_id)
self.log.debug("Received hand no %s" % new_hand_id) log.debug("Received hand no %s" % new_hand_id)
if new_hand_id == "": # blank line means quit if new_hand_id == "": # blank line means quit
self.destroy() self.destroy()
break # this thread is not always killed immediately with gtk.main_quit() break # this thread is not always killed immediately with gtk.main_quit()
@ -217,7 +219,7 @@ class HUD_main(object):
(table_name, max, poker_game, type, site_id, site_name, num_seats, tour_number, tab_number) = \ (table_name, max, poker_game, type, site_id, site_name, num_seats, tour_number, tab_number) = \
self.db_connection.get_table_info(new_hand_id) self.db_connection.get_table_info(new_hand_id)
except Exception, err: except Exception, err:
self.log.error("db error: skipping %s" % new_hand_id) log.error("db error: skipping %s" % new_hand_id)
continue continue
t1 = time.time() t1 = time.time()
@ -276,7 +278,7 @@ class HUD_main(object):
if type == "tour": if type == "tour":
table_name = "%s %s" % (tour_number, tab_number) table_name = "%s %s" % (tour_number, tab_number)
# sys.stderr.write("HUD create: table name "+table_name+" not found, skipping.\n") # sys.stderr.write("HUD create: table name "+table_name+" not found, skipping.\n")
self.log.error("HUD create: table name %s not found, skipping." % table_name) log.error("HUD create: table name %s not found, skipping." % table_name)
else: else:
tablewindow.max = max tablewindow.max = max
tablewindow.site = site_name tablewindow.site = site_name

28
pyfpdb/Hand.py Normal file → Executable file
View File

@ -28,12 +28,14 @@ from decimal import Decimal
import operator import operator
import time,datetime import time,datetime
from copy import deepcopy from copy import deepcopy
from Exceptions import *
import pprint import pprint
import Configuration
from Exceptions import *
import DerivedStats import DerivedStats
import Card import Card
log = logging.getLogger("parser") log = Configuration.get_logger("logging.conf", "parser")
class Hand(object): class Hand(object):
@ -46,7 +48,9 @@ class Hand(object):
SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7, 'Absolute':8, 'PartyPoker':9, 'Partouche':10, 'Carbon':11 } SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7, 'Absolute':8, 'PartyPoker':9, 'Partouche':10, 'Carbon':11 }
def __init__(self, sitename, gametype, handText, builtFrom = "HHC"): def __init__(self, config, sitename, gametype, handText, builtFrom = "HHC"):
self.config = config
log = Configuration.get_logger("logging.conf", "db", log_dir=self.config.dir_log)
self.sitename = sitename self.sitename = sitename
self.siteId = self.SITEIDS[sitename] self.siteId = self.SITEIDS[sitename]
self.stats = DerivedStats.DerivedStats(self) self.stats = DerivedStats.DerivedStats(self)
@ -617,7 +621,8 @@ Map the tuple self.gametype onto the pokerstars string describing it
class HoldemOmahaHand(Hand): class HoldemOmahaHand(Hand):
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC", handid=None): def __init__(self, config, hhc, sitename, gametype, handText, builtFrom = "HHC", handid=None):
self.config = config
if gametype['base'] != 'hold': if gametype['base'] != 'hold':
pass # or indeed don't pass and complain instead pass # or indeed don't pass and complain instead
log.debug("HoldemOmahaHand") log.debug("HoldemOmahaHand")
@ -625,7 +630,7 @@ class HoldemOmahaHand(Hand):
self.holeStreets = ['PREFLOP'] self.holeStreets = ['PREFLOP']
self.communityStreets = ['FLOP', 'TURN', 'RIVER'] self.communityStreets = ['FLOP', 'TURN', 'RIVER']
self.actionStreets = ['BLINDSANTES','PREFLOP','FLOP','TURN','RIVER'] self.actionStreets = ['BLINDSANTES','PREFLOP','FLOP','TURN','RIVER']
Hand.__init__(self, sitename, gametype, handText, builtFrom = "HHC") Hand.__init__(self, self.config, sitename, gametype, handText, builtFrom = "HHC")
self.sb = gametype['sb'] self.sb = gametype['sb']
self.bb = gametype['bb'] self.bb = gametype['bb']
@ -916,7 +921,8 @@ class HoldemOmahaHand(Hand):
print >>fh, "\n\n" print >>fh, "\n\n"
class DrawHand(Hand): class DrawHand(Hand):
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC"): def __init__(self, config, hhc, sitename, gametype, handText, builtFrom = "HHC"):
self.config = config
if gametype['base'] != 'draw': if gametype['base'] != 'draw':
pass # or indeed don't pass and complain instead pass # or indeed don't pass and complain instead
self.streetList = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE'] self.streetList = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
@ -924,7 +930,7 @@ class DrawHand(Hand):
self.holeStreets = ['DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE'] self.holeStreets = ['DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
self.actionStreets = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE'] self.actionStreets = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
self.communityStreets = [] self.communityStreets = []
Hand.__init__(self, sitename, gametype, handText) Hand.__init__(self, self.config, sitename, gametype, handText)
self.sb = gametype['sb'] self.sb = gametype['sb']
self.bb = gametype['bb'] self.bb = gametype['bb']
# Populate the draw hand. # Populate the draw hand.
@ -1108,7 +1114,8 @@ class DrawHand(Hand):
class StudHand(Hand): class StudHand(Hand):
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC"): def __init__(self, config, hhc, sitename, gametype, handText, builtFrom = "HHC"):
self.config = config
if gametype['base'] != 'stud': if gametype['base'] != 'stud':
pass # or indeed don't pass and complain instead pass # or indeed don't pass and complain instead
@ -1118,7 +1125,7 @@ class StudHand(Hand):
self.streetList = ['BLINDSANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH'] # a list of the observed street names in order self.streetList = ['BLINDSANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH'] # a list of the observed street names in order
self.holeStreets = ['THIRD','FOURTH','FIFTH','SIXTH','SEVENTH'] self.holeStreets = ['THIRD','FOURTH','FIFTH','SIXTH','SEVENTH']
Hand.__init__(self, sitename, gametype, handText) Hand.__init__(self, self.config, sitename, gametype, handText)
self.sb = gametype['sb'] self.sb = gametype['sb']
self.bb = gametype['bb'] self.bb = gametype['bb']
#Populate the StudHand #Populate the StudHand
@ -1511,7 +1518,8 @@ limit 1""", {'handid':handid})
#TODO: siteid should be in hands table - we took the scenic route through players here. #TODO: siteid should be in hands table - we took the scenic route through players here.
res = c.fetchone() res = c.fetchone()
gametype = {'category':res[1],'base':res[2],'type':res[3],'limitType':res[4],'hilo':res[5],'sb':res[6],'bb':res[7], 'currency':res[10]} gametype = {'category':res[1],'base':res[2],'type':res[3],'limitType':res[4],'hilo':res[5],'sb':res[6],'bb':res[7], 'currency':res[10]}
h = HoldemOmahaHand(hhc = None, sitename=res[0], gametype = gametype, handText=None, builtFrom = "DB", handid=handid) c = Configuration.Config()
h = HoldemOmahaHand(config = c, hhc = None, sitename=res[0], gametype = gametype, handText=None, builtFrom = "DB", handid=handid)
cards = map(Card.valueSuitFromCard, res[11:16] ) cards = map(Card.valueSuitFromCard, res[11:16] )
if cards[0]: if cards[0]:
h.setCommunityCards('FLOP', cards[0:3]) h.setCommunityCards('FLOP', cards[0:3])

19
pyfpdb/HandHistoryConverter.py Normal file → Executable file
View File

@ -16,8 +16,6 @@
#In the "official" distribution you can find the license in #In the "official" distribution you can find the license in
#agpl-3.0.txt in the docs folder of the package. #agpl-3.0.txt in the docs folder of the package.
import Hand
import Tourney
import re import re
import sys import sys
import traceback import traceback
@ -31,13 +29,16 @@ import operator
from xml.dom.minidom import Node from xml.dom.minidom import Node
import time import time
import datetime import datetime
import Hand
import Tourney
from Exceptions import FpdbParseError from Exceptions import FpdbParseError
import Configuration import Configuration
import gettext import gettext
gettext.install('fpdb') gettext.install('fpdb')
log = Configuration.get_logger("logging.conf") log = Configuration.get_logger("logging.conf", "parser")
import pygtk import pygtk
import gtk import gtk
@ -57,12 +58,14 @@ class HandHistoryConverter():
codepage = "cp1252" codepage = "cp1252"
def __init__(self, in_path = '-', out_path = '-', follow=False, index=0, autostart=True, starsArchive=False): def __init__(self, config, in_path = '-', out_path = '-', follow=False, index=0, autostart=True, starsArchive=False):
"""\ """\
in_path (default '-' = sys.stdin) in_path (default '-' = sys.stdin)
out_path (default '-' = sys.stdout) out_path (default '-' = sys.stdout)
follow : whether to tail -f the input""" follow : whether to tail -f the input"""
self.config = config
log = Configuration.get_logger("logging.conf", "parser", log_dir=self.config.dir_log)
log.info("HandHistory init - %s subclass, in_path '%s'; out_path '%s'" % (self.sitename, in_path, out_path) ) log.info("HandHistory init - %s subclass, in_path '%s'; out_path '%s'" % (self.sitename, in_path, out_path) )
self.index = index self.index = index
@ -283,11 +286,11 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
if l in self.readSupportedGames(): if l in self.readSupportedGames():
if gametype['base'] == 'hold': if gametype['base'] == 'hold':
log.debug("hand = Hand.HoldemOmahaHand(self, self.sitename, gametype, handtext)") log.debug("hand = Hand.HoldemOmahaHand(self, self.sitename, gametype, handtext)")
hand = Hand.HoldemOmahaHand(self, self.sitename, gametype, handText) hand = Hand.HoldemOmahaHand(self.config, self, self.sitename, gametype, handText)
elif gametype['base'] == 'stud': elif gametype['base'] == 'stud':
hand = Hand.StudHand(self, self.sitename, gametype, handText) hand = Hand.StudHand(self.config, self, self.sitename, gametype, handText)
elif gametype['base'] == 'draw': elif gametype['base'] == 'draw':
hand = Hand.DrawHand(self, self.sitename, gametype, handText) hand = Hand.DrawHand(self.config, self, self.sitename, gametype, handText)
else: else:
log.info("Unsupported game type: %s" % gametype) log.info("Unsupported game type: %s" % gametype)
@ -417,7 +420,7 @@ or None if we fail to get the info """
list.pop() #Last entry is empty list.pop() #Last entry is empty
for l in list: for l in list:
# print "'" + l + "'" # print "'" + l + "'"
hands = hands + [Hand.Hand(self.sitename, self.gametype, l)] hands = hands + [Hand.Hand(self.config, self.sitename, self.gametype, l)]
# TODO: This looks like it could be replaced with a list comp.. ? # TODO: This looks like it could be replaced with a list comp.. ?
return hands return hands

View File

@ -695,6 +695,7 @@ class fpdb:
def load_profile(self): def load_profile(self):
"""Loads profile from the provided path name.""" """Loads profile from the provided path name."""
self.config = Configuration.Config(file=options.config, dbname=options.dbname) self.config = Configuration.Config(file=options.config, dbname=options.dbname)
log = Configuration.get_logger("logging.conf", "fpdb", log_dir=self.config.dir_log)
self.settings = {} self.settings = {}
self.settings['global_lock'] = self.lock self.settings['global_lock'] = self.lock
if (os.sep=="/"): if (os.sep=="/"):

3
pyfpdb/fpdb_import.py Normal file → Executable file
View File

@ -65,6 +65,7 @@ class Importer:
self.config = config self.config = config
self.sql = sql self.sql = sql
log = Configuration.get_logger("logging.conf", "importer", log_dir=self.config.dir_log)
self.filelist = {} self.filelist = {}
self.dirlist = {} self.dirlist = {}
self.siteIds = {} self.siteIds = {}
@ -429,7 +430,7 @@ class Importer:
idx = self.pos_in_file[file] idx = self.pos_in_file[file]
else: else:
self.pos_in_file[file] = 0 self.pos_in_file[file] = 0
hhc = obj(in_path = file, out_path = out_path, index = idx, starsArchive = self.settings['starsArchive']) hhc = obj(self.config, in_path = file, out_path = out_path, index = idx, starsArchive = self.settings['starsArchive'])
if hhc.getStatus(): if hhc.getStatus():
handlist = hhc.getProcessedHands() handlist = hhc.getProcessedHands()
self.pos_in_file[file] = hhc.getLastCharacterRead() self.pos_in_file[file] = hhc.getLastCharacterRead()

31
pyfpdb/logging.conf Normal file → Executable file
View File

@ -1,64 +1,69 @@
[loggers] [loggers]
keys=root,parser,importer,config,db keys=root,fpdb,logview,parser,importer,config,db,hud
[handlers] [handlers]
keys=consoleHandler,fileHandler keys=consoleHandler,rotatingFileHandler
[formatters] [formatters]
keys=fileFormatter,stderrFormatter keys=fileFormatter,stderrFormatter
[logger_root] [logger_root]
level=INFO level=INFO
handlers=consoleHandler,fileHandler handlers=consoleHandler,rotatingFileHandler
[logger_fpdb] [logger_fpdb]
level=INFO level=INFO
handlers=consoleHandler,fileHandler handlers=consoleHandler,rotatingFileHandler
qualname=fpdb qualname=fpdb
propagate=0 propagate=0
[logger_logview] [logger_logview]
level=INFO level=INFO
handlers=consoleHandler,fileHandler handlers=consoleHandler,rotatingFileHandler
qualname=logview qualname=logview
propagate=0 propagate=0
[logger_parser] [logger_parser]
level=INFO level=INFO
handlers=consoleHandler,fileHandler handlers=consoleHandler,rotatingFileHandler
qualname=parser qualname=parser
propagate=0 propagate=0
[logger_importer] [logger_importer]
level=DEBUG level=DEBUG
handlers=consoleHandler,fileHandler handlers=consoleHandler,rotatingFileHandler
qualname=importer qualname=importer
propagate=0 propagate=0
[logger_config] [logger_config]
level=INFO level=INFO
handlers=consoleHandler,fileHandler handlers=consoleHandler,rotatingFileHandler
qualname=config qualname=config
propagate=0 propagate=0
[logger_db] [logger_db]
level=DEBUG level=DEBUG
handlers=consoleHandler,fileHandler handlers=consoleHandler,rotatingFileHandler
qualname=db qualname=db
propagate=0 propagate=0
[logger_hud]
level=DEBUG
handlers=consoleHandler,rotatingFileHandler
qualname=hud
propagate=0
[handler_consoleHandler] [handler_consoleHandler]
class=StreamHandler class=StreamHandler
level=ERROR level=ERROR
formatter=stderrFormatter formatter=stderrFormatter
args=(sys.stderr,) args=(sys.stderr,)
[handler_fileHandler] [handler_rotatingFileHandler]
class=FileHandler class=handlers.RotatingFileHandler
level=DEBUG level=DEBUG
formatter=fileFormatter formatter=fileFormatter
args=('logging.out', 'a') args=('%(logFile)s', 'a', 50000, 5)
[formatter_fileFormatter] [formatter_fileFormatter]
format=%(asctime)s - %(name)-12s %(levelname)-8s %(message)s format=%(asctime)s - %(name)-12s %(levelname)-8s %(message)s