Log messages routed to stdout/stderr as appropriate.
This also uses a dedicated logger instead of passing everything to the root logger. `overviewer_core` still needs to be updated to reflect this. Additionally, `logger.configure` has been simplified.
This commit is contained in:
@@ -42,6 +42,8 @@ from overviewer_core import configParser, tileset, assetmanager, dispatcher
|
|||||||
from overviewer_core import cache
|
from overviewer_core import cache
|
||||||
from overviewer_core import observer
|
from overviewer_core import observer
|
||||||
|
|
||||||
|
LOG = logging.getLogger('overviewer')
|
||||||
|
|
||||||
helptext = """
|
helptext = """
|
||||||
%prog [--rendermodes=...] [options] <World> <Output Dir>
|
%prog [--rendermodes=...] [options] <World> <Output Dir>
|
||||||
%prog --config=<config file> [options]"""
|
%prog --config=<config file> [options]"""
|
||||||
@@ -146,14 +148,14 @@ def main():
|
|||||||
from overviewer_core.textures import Textures
|
from overviewer_core.textures import Textures
|
||||||
tex = Textures()
|
tex = Textures()
|
||||||
|
|
||||||
logging.info("Looking for a few common texture files...")
|
LOG.info("Looking for a few common texture files...")
|
||||||
try:
|
try:
|
||||||
f = tex.find_file("assets/minecraft/textures/blocks/sandstone_top.png", verbose=True)
|
f = tex.find_file("assets/minecraft/textures/blocks/sandstone_top.png", verbose=True)
|
||||||
f = tex.find_file("assets/minecraft/textures/blocks/grass_top.png", verbose=True)
|
f = tex.find_file("assets/minecraft/textures/blocks/grass_top.png", verbose=True)
|
||||||
f = tex.find_file("assets/minecraft/textures/blocks/diamond_ore.png", verbose=True)
|
f = tex.find_file("assets/minecraft/textures/blocks/diamond_ore.png", verbose=True)
|
||||||
f = tex.find_file("assets/minecraft/textures/blocks/planks_oak.png", verbose=True)
|
f = tex.find_file("assets/minecraft/textures/blocks/planks_oak.png", verbose=True)
|
||||||
except IOError:
|
except IOError:
|
||||||
logging.error("Could not find any texture files.")
|
LOG.error("Could not find any texture files.")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
@@ -173,7 +175,7 @@ def main():
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
# more helpful message for users who know what they're doing
|
# more helpful message for users who know what they're doing
|
||||||
logging.error("You must either specify --config or give me a world directory and output directory")
|
LOG.error("You must either specify --config or give me a world directory and output directory")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
list_worlds()
|
list_worlds()
|
||||||
return 1
|
return 1
|
||||||
@@ -190,12 +192,12 @@ def main():
|
|||||||
print("worlds['myworld'] = %r" % args[0])
|
print("worlds['myworld'] = %r" % args[0])
|
||||||
print("outputdir = %r" % (args[1] if len(args) > 1 else "/path/to/output"))
|
print("outputdir = %r" % (args[1] if len(args) > 1 else "/path/to/output"))
|
||||||
print()
|
print()
|
||||||
logging.error("Cannot specify both --config AND a world + output directory on the command line.")
|
LOG.error("Cannot specify both --config AND a world + output directory on the command line.")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if not options.config and len(args) < 2:
|
if not options.config and len(args) < 2:
|
||||||
logging.error("You must specify both the world directory and an output directory")
|
LOG.error("You must specify both the world directory and an output directory")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 1
|
return 1
|
||||||
if not options.config and len(args) > 2:
|
if not options.config and len(args) > 2:
|
||||||
@@ -205,10 +207,10 @@ def main():
|
|||||||
if not os.path.exists(args[start]):
|
if not os.path.exists(args[start]):
|
||||||
for end in range(start+1, len(args)+1):
|
for end in range(start+1, len(args)+1):
|
||||||
if os.path.exists(" ".join(args[start:end])):
|
if os.path.exists(" ".join(args[start:end])):
|
||||||
logging.warning("It looks like you meant to specify \"%s\" as your world dir or your output\n\
|
LOG.warning("It looks like you meant to specify \"%s\" as your world dir or your output\n\
|
||||||
dir but you forgot to put quotes around the directory, since it contains spaces." % " ".join(args[start:end]))
|
dir but you forgot to put quotes around the directory, since it contains spaces." % " ".join(args[start:end]))
|
||||||
return 1
|
return 1
|
||||||
logging.error("Too many command line arguments")
|
LOG.error("Too many command line arguments")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -220,8 +222,8 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
if not options.config:
|
if not options.config:
|
||||||
# No config file mode.
|
# No config file mode.
|
||||||
worldpath, destdir = map(os.path.expanduser, args)
|
worldpath, destdir = map(os.path.expanduser, args)
|
||||||
logging.debug("Using %r as the world directory", worldpath)
|
LOG.debug("Using %r as the world directory", worldpath)
|
||||||
logging.debug("Using %r as the output directory", destdir)
|
LOG.debug("Using %r as the output directory", destdir)
|
||||||
|
|
||||||
mw_parser.set_config_item("worlds", {'world': worldpath})
|
mw_parser.set_config_item("worlds", {'world': worldpath})
|
||||||
mw_parser.set_config_item("outputdir", destdir)
|
mw_parser.set_config_item("outputdir", destdir)
|
||||||
@@ -242,7 +244,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
if options.rendermodes:
|
if options.rendermodes:
|
||||||
logging.error("You cannot specify --rendermodes if you give a config file. Configure your rendermodes in the config file instead")
|
LOG.error("You cannot specify --rendermodes if you give a config file. Configure your rendermodes in the config file instead")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -251,7 +253,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
mw_parser.parse(os.path.expanduser(options.config))
|
mw_parser.parse(os.path.expanduser(options.config))
|
||||||
except configParser.MissingConfigException as e:
|
except configParser.MissingConfigException as e:
|
||||||
# this isn't a "bug", so don't print scary traceback
|
# this isn't a "bug", so don't print scary traceback
|
||||||
logging.error(str(e))
|
LOG.error(str(e))
|
||||||
util.nice_exit(1)
|
util.nice_exit(1)
|
||||||
|
|
||||||
# Add in the command options here, perhaps overriding values specified in
|
# Add in the command options here, perhaps overriding values specified in
|
||||||
@@ -264,16 +266,16 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
config = mw_parser.get_validated_config()
|
config = mw_parser.get_validated_config()
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
if options.verbose:
|
if options.verbose:
|
||||||
logging.exception("An error was encountered with your configuration. See the info below.")
|
LOG.exception("An error was encountered with your configuration. See the info below.")
|
||||||
else: # no need to print scary traceback! just
|
else: # no need to print scary traceback! just
|
||||||
logging.error("An error was encountered with your configuration.")
|
LOG.error("An error was encountered with your configuration.")
|
||||||
logging.error(str(ex))
|
LOG.error(str(ex))
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if options.check_terrain: # we are already in the "if configfile" branch
|
if options.check_terrain: # we are already in the "if configfile" branch
|
||||||
logging.info("Looking for a few common texture files...")
|
LOG.info("Looking for a few common texture files...")
|
||||||
for render_name, render in config['renders'].iteritems():
|
for render_name, render in config['renders'].iteritems():
|
||||||
logging.info("Looking at render %r", render_name)
|
LOG.info("Looking at render %r", render_name)
|
||||||
|
|
||||||
# find or create the textures object
|
# find or create the textures object
|
||||||
texopts = util.dict_subset(render, ["texturepath"])
|
texopts = util.dict_subset(render, ["texturepath"])
|
||||||
@@ -287,8 +289,8 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
# Final validation steps and creation of the destination directory
|
# Final validation steps and creation of the destination directory
|
||||||
logging.info("Welcome to Minecraft Overviewer!")
|
LOG.info("Welcome to Minecraft Overviewer!")
|
||||||
logging.debug("Current log level: {0}".format(logging.getLogger().level))
|
LOG.debug("Current log level: {0}".format(LOG.level))
|
||||||
|
|
||||||
# Override some render configdict options depending on one-time command line
|
# Override some render configdict options depending on one-time command line
|
||||||
# modifiers
|
# modifiers
|
||||||
@@ -297,26 +299,26 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
bool(options.checktiles) +
|
bool(options.checktiles) +
|
||||||
bool(options.notilechecks)
|
bool(options.notilechecks)
|
||||||
) > 1:
|
) > 1:
|
||||||
logging.error("You cannot specify more than one of --forcerender, "+
|
LOG.error("You cannot specify more than one of --forcerender, "+
|
||||||
"--check-tiles, and --no-tile-checks. These options conflict.")
|
"--check-tiles, and --no-tile-checks. These options conflict.")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 1
|
return 1
|
||||||
if options.forcerender:
|
if options.forcerender:
|
||||||
logging.info("Forcerender mode activated. ALL tiles will be rendered")
|
LOG.info("Forcerender mode activated. ALL tiles will be rendered")
|
||||||
for render in config['renders'].itervalues():
|
for render in config['renders'].itervalues():
|
||||||
render['renderchecks'] = 2
|
render['renderchecks'] = 2
|
||||||
elif options.checktiles:
|
elif options.checktiles:
|
||||||
logging.info("Checking all tiles for updates manually.")
|
LOG.info("Checking all tiles for updates manually.")
|
||||||
for render in config['renders'].itervalues():
|
for render in config['renders'].itervalues():
|
||||||
render['renderchecks'] = 1
|
render['renderchecks'] = 1
|
||||||
elif options.notilechecks:
|
elif options.notilechecks:
|
||||||
logging.info("Disabling all tile mtime checks. Only rendering tiles "+
|
LOG.info("Disabling all tile mtime checks. Only rendering tiles "+
|
||||||
"that need updating since last render")
|
"that need updating since last render")
|
||||||
for render in config['renders'].itervalues():
|
for render in config['renders'].itervalues():
|
||||||
render['renderchecks'] = 0
|
render['renderchecks'] = 0
|
||||||
|
|
||||||
if not config['renders']:
|
if not config['renders']:
|
||||||
logging.error("You must specify at least one render in your config file. See the docs if you're having trouble")
|
LOG.error("You must specify at least one render in your config file. See the docs if you're having trouble")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
@@ -327,7 +329,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
try:
|
try:
|
||||||
worldpath = config['worlds'][render['world']]
|
worldpath = config['worlds'][render['world']]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.error("Render %s's world is '%s', but I could not find a corresponding entry in the worlds dictionary.",
|
LOG.error("Render %s's world is '%s', but I could not find a corresponding entry in the worlds dictionary.",
|
||||||
rname, render['world'])
|
rname, render['world'])
|
||||||
return 1
|
return 1
|
||||||
render['worldname_orig'] = render['world']
|
render['worldname_orig'] = render['world']
|
||||||
@@ -344,23 +346,23 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
try:
|
try:
|
||||||
renderLink = config['renders'][x]
|
renderLink = config['renders'][x]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.error("Render %s's overlay is '%s', but I could not find a corresponding entry in the renders dictionary.",
|
LOG.error("Render %s's overlay is '%s', but I could not find a corresponding entry in the renders dictionary.",
|
||||||
rname, x)
|
rname, x)
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
logging.error("Render %s's overlay contains itself.", rname)
|
LOG.error("Render %s's overlay contains itself.", rname)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
destdir = config['outputdir']
|
destdir = config['outputdir']
|
||||||
if not destdir:
|
if not destdir:
|
||||||
logging.error("You must specify the output directory in your config file.")
|
LOG.error("You must specify the output directory in your config file.")
|
||||||
logging.error("e.g. outputdir = '/path/to/outputdir'")
|
LOG.error("e.g. outputdir = '/path/to/outputdir'")
|
||||||
return 1
|
return 1
|
||||||
if not os.path.exists(destdir):
|
if not os.path.exists(destdir):
|
||||||
try:
|
try:
|
||||||
os.mkdir(destdir)
|
os.mkdir(destdir)
|
||||||
except OSError:
|
except OSError:
|
||||||
logging.exception("Could not create the output directory.")
|
LOG.exception("Could not create the output directory.")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
@@ -372,7 +374,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
# If we've been asked to update web assets, do that and then exit
|
# If we've been asked to update web assets, do that and then exit
|
||||||
if options.update_web_assets:
|
if options.update_web_assets:
|
||||||
assetMrg.output_noconfig()
|
assetMrg.output_noconfig()
|
||||||
logging.info("Web assets have been updated")
|
LOG.info("Web assets have been updated")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# The changelist support.
|
# The changelist support.
|
||||||
@@ -382,7 +384,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
path = render['changelist']
|
path = render['changelist']
|
||||||
if path not in changelists:
|
if path not in changelists:
|
||||||
out = open(path, "w")
|
out = open(path, "w")
|
||||||
logging.debug("Opening changelist %s (%s)", out, out.fileno())
|
LOG.debug("Opening changelist %s (%s)", out, out.fileno())
|
||||||
changelists[path] = out
|
changelists[path] = out
|
||||||
else:
|
else:
|
||||||
out = changelists[path]
|
out = changelists[path]
|
||||||
@@ -404,7 +406,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
|
|
||||||
renders = config['renders']
|
renders = config['renders']
|
||||||
for render_name, render in renders.iteritems():
|
for render_name, render in renders.iteritems():
|
||||||
logging.debug("Found the following render thing: %r", render)
|
LOG.debug("Found the following render thing: %r", render)
|
||||||
|
|
||||||
# find or create the world object
|
# find or create the world object
|
||||||
try:
|
try:
|
||||||
@@ -424,13 +426,13 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
tex = texcache[texopts_key]
|
tex = texcache[texopts_key]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logging.debug("Asking for regionset %r" % render['dimension'][1])
|
LOG.debug("Asking for regionset %r" % render['dimension'][1])
|
||||||
rset = w.get_regionset(render['dimension'][1])
|
rset = w.get_regionset(render['dimension'][1])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
logging.error("Sorry, I can't find anything to render! Are you sure there are .mca files in the world directory?")
|
LOG.error("Sorry, I can't find anything to render! Are you sure there are .mca files in the world directory?")
|
||||||
return 1
|
return 1
|
||||||
if rset == None: # indicates no such dimension was found:
|
if rset == None: # indicates no such dimension was found:
|
||||||
logging.error("Sorry, you requested dimension '%s' for %s, but I couldn't find it", render['dimension'][0], render_name)
|
LOG.error("Sorry, you requested dimension '%s' for %s, but I couldn't find it", render['dimension'][0], render_name)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
#################
|
#################
|
||||||
@@ -450,7 +452,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
# object
|
# object
|
||||||
if (render['northdirection'] > 0):
|
if (render['northdirection'] > 0):
|
||||||
rset = world.RotatedRegionSet(rset, render['northdirection'])
|
rset = world.RotatedRegionSet(rset, render['northdirection'])
|
||||||
logging.debug("Using RegionSet %r", rset)
|
LOG.debug("Using RegionSet %r", rset)
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
# Do the final prep and create the TileSet object
|
# Do the final prep and create the TileSet object
|
||||||
@@ -484,13 +486,13 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
|
|||||||
assetMrg.finalize(tilesets)
|
assetMrg.finalize(tilesets)
|
||||||
|
|
||||||
for out in changelists.itervalues():
|
for out in changelists.itervalues():
|
||||||
logging.debug("Closing %s (%s)", out, out.fileno())
|
LOG.debug("Closing %s (%s)", out, out.fileno())
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
if config['processes'] == 1:
|
if config['processes'] == 1:
|
||||||
logging.debug("Final cache stats:")
|
LOG.debug("Final cache stats:")
|
||||||
for c in caches:
|
for c in caches:
|
||||||
logging.debug("\t%s: %s hits, %s misses", c.__class__.__name__, c.hits, c.misses)
|
LOG.debug("\t%s: %s hits, %s misses", c.__class__.__name__, c.hits, c.misses)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -533,10 +535,10 @@ if __name__ == "__main__":
|
|||||||
util.nice_exit(ret)
|
util.nice_exit(ret)
|
||||||
except textures.TextureException as e:
|
except textures.TextureException as e:
|
||||||
# this isn't a "bug", so don't print scary traceback
|
# this isn't a "bug", so don't print scary traceback
|
||||||
logging.error(str(e))
|
LOG.error(str(e))
|
||||||
util.nice_exit(1)
|
util.nice_exit(1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception("""An error has occurred. This may be a bug. Please let us know!
|
LOG.exception("""An error has occurred. This may be a bug. Please let us know!
|
||||||
See http://docs.overviewer.org/en/latest/index.html#help
|
See http://docs.overviewer.org/en/latest/index.html#help
|
||||||
|
|
||||||
This is the error that occurred:""")
|
This is the error that occurred:""")
|
||||||
|
|||||||
@@ -51,6 +51,15 @@ HIGHLIGHT = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class InverseLevelFilter(object):
|
||||||
|
|
||||||
|
def __init__(self, max_level=logging.WARN):
|
||||||
|
self.max_level = max_level
|
||||||
|
|
||||||
|
def filter(self, record):
|
||||||
|
return record.levelno < self.max_level
|
||||||
|
|
||||||
|
|
||||||
class WindowsOutputStream(object):
|
class WindowsOutputStream(object):
|
||||||
"""A file-like object that proxies sys.stderr and interprets simple ANSI
|
"""A file-like object that proxies sys.stderr and interprets simple ANSI
|
||||||
escape codes for color, translating them to the appropriate Windows calls.
|
escape codes for color, translating them to the appropriate Windows calls.
|
||||||
@@ -265,36 +274,33 @@ def configure(loglevel=logging.INFO, verbose=False, simple=False):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger('overviewer')
|
||||||
|
logger.setLevel(loglevel)
|
||||||
|
|
||||||
|
if not logger.handlers:
|
||||||
|
# No handlers have been configure yet... (probably the first call of
|
||||||
|
# logger.configure)
|
||||||
|
is_windows = platform.system() == 'Windows'
|
||||||
outstream = sys.stdout
|
outstream = sys.stdout
|
||||||
if simple:
|
errstream = sys.stderr
|
||||||
formatter = DumbFormatter(verbose)
|
errformatter = DumbFormatter(verbose)
|
||||||
|
outformatter = DumbFormatter(verbose)
|
||||||
|
|
||||||
elif platform.system() == 'Windows':
|
if is_windows:
|
||||||
# Our custom output stream processor knows how to deal with select ANSI
|
|
||||||
# color escape sequences
|
|
||||||
outstream = WindowsOutputStream(outstream)
|
outstream = WindowsOutputStream(outstream)
|
||||||
formatter = ANSIColorFormatter(verbose)
|
errstream = WindowsOutputStream(errstream)
|
||||||
|
|
||||||
elif outstream.isatty():
|
if (is_windows or outstream.isatty()) and not simple:
|
||||||
# terminal logging with ANSI color
|
# Our custom output stream processor knows how to deal with select
|
||||||
formatter = ANSIColorFormatter(verbose)
|
# ANSI color escape sequences
|
||||||
|
errformatter = ANSIColorFormatter(verbose)
|
||||||
|
outformatter = ANSIColorFormatter(verbose)
|
||||||
|
|
||||||
else:
|
out_handler = logging.StreamHandler(outstream)
|
||||||
# Let's not assume anything. Just text.
|
out_handler.setFormatter(outformatter)
|
||||||
formatter = DumbFormatter(verbose)
|
out_handler.addFilter(InverseLevelFilter(max_level=logging.WARN))
|
||||||
|
err_handler = logging.StreamHandler(errstream)
|
||||||
if hasattr(logger, 'overviewerHandler'):
|
err_handler.setLevel(logging.WARN)
|
||||||
# we have already set up logging so just replace the formatter
|
err_handler.setFormatter(errformatter)
|
||||||
# this time with the new values
|
logger.addHandler(out_handler)
|
||||||
logger.overviewerHandler.setFormatter(formatter)
|
logger.addHandler(err_handler)
|
||||||
logger.setLevel(loglevel)
|
|
||||||
|
|
||||||
else:
|
|
||||||
# Save our handler here so we can tell which handler was ours if the
|
|
||||||
# function is called again
|
|
||||||
logger.overviewerHandler = logging.StreamHandler(outstream)
|
|
||||||
logger.overviewerHandler.setFormatter(formatter)
|
|
||||||
logger.addHandler(logger.overviewerHandler)
|
|
||||||
logger.setLevel(loglevel)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user