Move all the logging to log.py and prefix all the log names with "erynrl"
This commit is contained in:
parent
5d4e0cff3d
commit
ce63c825b0
8 changed files with 126 additions and 102 deletions
|
@ -1,21 +1,16 @@
|
|||
# Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import logging
|
||||
import logging.config
|
||||
import os.path
|
||||
import sys
|
||||
import tcod
|
||||
from . import log
|
||||
from .engine import Configuration, Engine
|
||||
from .events import EventHandler
|
||||
from .geometry import Size
|
||||
|
||||
LOG = logging.getLogger('main')
|
||||
|
||||
CONSOLE_WIDTH, CONSOLE_HEIGHT = 80, 50
|
||||
MAP_WIDTH, MAP_HEIGHT = 80, 45
|
||||
|
||||
FONT = 'terminal16x16_gs_ro.png'
|
||||
|
||||
def parse_args(argv, *a, **kw):
|
||||
|
@ -24,23 +19,6 @@ def parse_args(argv, *a, **kw):
|
|||
args = parser.parse_args(argv)
|
||||
return args
|
||||
|
||||
def init_logging(args):
|
||||
'''Set up the logging system by (preferrably) reading a logging configuration file.'''
|
||||
logging_config_path = find_logging_config()
|
||||
if logging_config_path:
|
||||
with open(logging_config_path, encoding='utf-8') as logging_config_file:
|
||||
logging_config = json.load(logging_config_file)
|
||||
logging.config.dictConfig(logging_config)
|
||||
LOG.info('Found logging configuration at %s', logging_config_path)
|
||||
else:
|
||||
root_logger = logging.getLogger('')
|
||||
root_logger.setLevel(logging.DEBUG if args.debug else logging.INFO)
|
||||
|
||||
stderr_handler = logging.StreamHandler()
|
||||
stderr_handler.setFormatter(logging.Formatter("%(asctime)s %(name)s: %(message)s"))
|
||||
|
||||
root_logger.addHandler(stderr_handler)
|
||||
|
||||
def walk_up_directories_of_path(path):
|
||||
while path and path != '/':
|
||||
path = os.path.dirname(path)
|
||||
|
@ -51,38 +29,26 @@ def find_fonts_directory():
|
|||
for parent_dir in walk_up_directories_of_path(__file__):
|
||||
possible_fonts_dir = os.path.join(parent_dir, 'fonts')
|
||||
if os.path.isdir(possible_fonts_dir):
|
||||
LOG.info('Found fonts dir %s', possible_fonts_dir)
|
||||
log.ROOT.info('Found fonts dir %s', possible_fonts_dir)
|
||||
break
|
||||
else:
|
||||
return None
|
||||
|
||||
return possible_fonts_dir
|
||||
|
||||
def find_logging_config():
|
||||
'''Walk up the filesystem from this script to find a logging_config.json'''
|
||||
for parent_dir in walk_up_directories_of_path(__file__):
|
||||
possible_logging_config_file = os.path.join(parent_dir, 'logging_config.json')
|
||||
if os.path.isfile(possible_logging_config_file):
|
||||
LOG.info('Found logging config file %s', possible_logging_config_file)
|
||||
break
|
||||
else:
|
||||
return None
|
||||
|
||||
return possible_logging_config_file
|
||||
|
||||
def main(argv):
|
||||
args = parse_args(argv[1:], prog=argv[0])
|
||||
|
||||
init_logging(args)
|
||||
log.init()
|
||||
|
||||
fonts_directory = find_fonts_directory()
|
||||
if not fonts_directory:
|
||||
LOG.error("Couldn't find a fonts/ directory")
|
||||
log.ROOT.error("Couldn't find a fonts/ directory")
|
||||
return -1
|
||||
|
||||
font = os.path.join(fonts_directory, FONT)
|
||||
if not os.path.isfile(font):
|
||||
LOG.error("Font file %s doesn't exist", font)
|
||||
log.ROOT.error("Font file %s doesn't exist", font)
|
||||
return -1
|
||||
|
||||
tileset = tcod.tileset.load_tilesheet(font, 16, 16, tcod.tileset.CHARMAP_CP437)
|
||||
|
|
|
@ -18,18 +18,16 @@ Action : Base class of all actions
|
|||
WaitAction
|
||||
'''
|
||||
|
||||
import logging
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from . import items
|
||||
from . import log
|
||||
from .geometry import Direction
|
||||
from .object import Actor, Item
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .engine import Engine
|
||||
|
||||
LOG = logging.getLogger('actions')
|
||||
|
||||
class ActionResult:
|
||||
'''The result of an Action.
|
||||
|
||||
|
@ -158,12 +156,12 @@ class BumpAction(MoveAction):
|
|||
else:
|
||||
entity_occupying_position = None
|
||||
|
||||
LOG.debug('Bumping %s into %s (in_bounds:%s walkable:%s overlaps:%s)',
|
||||
self.actor,
|
||||
new_position,
|
||||
position_is_in_bounds,
|
||||
position_is_walkable,
|
||||
entity_occupying_position)
|
||||
log.ACTIONS.debug('Bumping %s into %s (in_bounds:%s walkable:%s overlaps:%s)',
|
||||
self.actor,
|
||||
new_position,
|
||||
position_is_in_bounds,
|
||||
position_is_walkable,
|
||||
entity_occupying_position)
|
||||
|
||||
if not position_is_in_bounds or not position_is_walkable:
|
||||
return self.failure()
|
||||
|
@ -180,7 +178,7 @@ class WalkAction(MoveAction):
|
|||
def perform(self, engine: 'Engine') -> ActionResult:
|
||||
new_position = self.actor.position + self.direction
|
||||
|
||||
LOG.debug('Moving %s to %s', self.actor, new_position)
|
||||
log.ACTIONS.debug('Moving %s to %s', self.actor, new_position)
|
||||
self.actor.position = new_position
|
||||
|
||||
return self.success()
|
||||
|
@ -201,13 +199,13 @@ class MeleeAction(MoveAction):
|
|||
|
||||
damage = self.actor.fighter.attack_power - self.target.fighter.defense
|
||||
if damage > 0 and self.target:
|
||||
LOG.debug('%s attacks %s for %d damage!', self.actor, self.target, damage)
|
||||
log.ACTIONS.debug('%s attacks %s for %d damage!', self.actor, self.target, damage)
|
||||
self.target.fighter.hit_points -= damage
|
||||
else:
|
||||
LOG.debug('%s attacks %s but does no damage!', self.actor, self.target)
|
||||
log.ACTIONS.debug('%s attacks %s but does no damage!', self.actor, self.target)
|
||||
|
||||
if self.target.fighter.is_dead:
|
||||
LOG.info('%s is dead!', self.target)
|
||||
log.ACTIONS.info('%s is dead!', self.target)
|
||||
return ActionResult(self, alternate=DieAction(self.target))
|
||||
|
||||
return self.success()
|
||||
|
@ -216,18 +214,18 @@ class WaitAction(Action):
|
|||
'''Wait a turn'''
|
||||
|
||||
def perform(self, engine: 'Engine') -> ActionResult:
|
||||
LOG.debug('%s is waiting a turn', self.actor)
|
||||
log.ACTIONS.debug('%s is waiting a turn', self.actor)
|
||||
return self.success()
|
||||
|
||||
class DieAction(Action):
|
||||
'''Kill an Actor'''
|
||||
|
||||
def perform(self, engine: 'Engine') -> ActionResult:
|
||||
LOG.debug('%s dies', self.actor)
|
||||
log.ACTIONS.debug('%s dies', self.actor)
|
||||
engine.entities.remove(self.actor)
|
||||
|
||||
if self.actor.yields_corpse_on_death:
|
||||
LOG.debug('%s leaves a corpse behind', self.actor)
|
||||
log.ACTIONS.debug('%s leaves a corpse behind', self.actor)
|
||||
corpse = Item(kind=items.Corpse, name=f'{self.actor.name} Corpse', position=self.actor.position)
|
||||
return ActionResult(self, alternate=DropItemAction(self.actor, corpse))
|
||||
|
||||
|
|
14
erynrl/ai.py
14
erynrl/ai.py
|
@ -1,12 +1,12 @@
|
|||
# Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
import logging
|
||||
import random
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
|
||||
import numpy as np
|
||||
import tcod
|
||||
|
||||
from . import log
|
||||
from .actions import Action, BumpAction, WaitAction
|
||||
from .components import Component
|
||||
from .geometry import Direction, Point
|
||||
|
@ -15,8 +15,6 @@ from .object import Entity
|
|||
if TYPE_CHECKING:
|
||||
from .engine import Engine
|
||||
|
||||
LOG = logging.getLogger('ai')
|
||||
|
||||
class AI(Component):
|
||||
def __init__(self, entity: Entity) -> None:
|
||||
super().__init__()
|
||||
|
@ -34,7 +32,7 @@ class HostileEnemy(AI):
|
|||
radius=self.entity.sight_radius)
|
||||
|
||||
if engine.map.visible[tuple(self.entity.position)]:
|
||||
LOG.debug("AI for %s", self.entity)
|
||||
log.AI.debug("AI for %s", self.entity)
|
||||
|
||||
hero_position = engine.hero.position
|
||||
hero_is_visible = visible_tiles[hero_position.x, hero_position.y]
|
||||
|
@ -46,13 +44,13 @@ class HostileEnemy(AI):
|
|||
entity_position = self.entity.position
|
||||
|
||||
if engine.map.visible[tuple(self.entity.position)]:
|
||||
LOG.debug('|-> Path to hero %s', path_to_hero)
|
||||
log.AI.debug('|-> Path to hero %s', path_to_hero)
|
||||
|
||||
next_position = path_to_hero.pop(0) if len(path_to_hero) > 1 else hero_position
|
||||
direction_to_next_position = entity_position.direction_to_adjacent_point(next_position)
|
||||
|
||||
if engine.map.visible[tuple(self.entity.position)]:
|
||||
LOG.info('`-> Hero is visible to %s, bumping %s (%s)', self.entity, direction_to_next_position, next_position)
|
||||
log.AI.info('`-> Hero is visible to %s, bumping %s (%s)', self.entity, direction_to_next_position, next_position)
|
||||
|
||||
return BumpAction(self.entity, direction_to_next_position)
|
||||
else:
|
||||
|
@ -68,13 +66,13 @@ class HostileEnemy(AI):
|
|||
tile_is_walkable = engine.map.tile_is_walkable(new_position)
|
||||
if not overlaps_existing_entity and tile_is_walkable:
|
||||
if engine.map.visible[tuple(self.entity.position)]:
|
||||
LOG.info('Hero is NOT visible to %s, bumping %s randomly', self.entity, direction)
|
||||
log.AI.info('Hero is NOT visible to %s, bumping %s randomly', self.entity, direction)
|
||||
action = BumpAction(self.entity, direction)
|
||||
break
|
||||
else:
|
||||
# If this entity somehow can't move anywhere, just wait
|
||||
if engine.map.visible[tuple(self.entity.position)]:
|
||||
LOG.info("Hero is NOT visible to %s and it can't move anywhere, waiting", self.entity)
|
||||
log.AI.info("Hero is NOT visible to %s and it can't move anywhere, waiting", self.entity)
|
||||
action = WaitAction(self.entity)
|
||||
|
||||
return action
|
||||
|
|
|
@ -2,21 +2,19 @@
|
|||
|
||||
'''Defines the core game engine.'''
|
||||
|
||||
import logging
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import MutableSet
|
||||
|
||||
import tcod
|
||||
|
||||
from . import log
|
||||
from . import monsters
|
||||
from .ai import HostileEnemy
|
||||
from .geometry import Size
|
||||
from .map import Map
|
||||
from .object import Entity, Hero, Monster
|
||||
|
||||
LOG = logging.getLogger('engine')
|
||||
|
||||
@dataclass
|
||||
class Configuration:
|
||||
map_size: Size
|
||||
|
@ -66,7 +64,7 @@ class Engine:
|
|||
else:
|
||||
monster = Monster(monsters.Orc, ai_class=HostileEnemy, position=random_start_position)
|
||||
|
||||
LOG.info('Spawning %s', monster)
|
||||
log.ENGINE.info('Spawning %s', monster)
|
||||
self.entities.add(monster)
|
||||
|
||||
self.update_field_of_view()
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
'''Defines event handling mechanisms.'''
|
||||
|
||||
import logging
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
import tcod
|
||||
|
||||
from . import log
|
||||
from .actions import Action, ActionResult, ExitAction, RegenerateRoomsAction, BumpAction, WaitAction
|
||||
from .geometry import Direction
|
||||
from .object import Actor
|
||||
|
@ -14,9 +14,6 @@ from .object import Actor
|
|||
if TYPE_CHECKING:
|
||||
from .engine import Engine
|
||||
|
||||
LOG = logging.getLogger('events')
|
||||
ACTIONS_TREE_LOG = logging.getLogger('actions.tree')
|
||||
|
||||
class EventHandler(tcod.event.EventDispatch[Action]):
|
||||
'''Handler of `tcod` events'''
|
||||
|
||||
|
@ -35,11 +32,11 @@ class EventHandler(tcod.event.EventDispatch[Action]):
|
|||
|
||||
# Unhandled event. Ignore it.
|
||||
if not action:
|
||||
LOG.debug('Unhandled event: %s', event)
|
||||
log.EVENTS.debug('Unhandled event: %s', event)
|
||||
return
|
||||
|
||||
ACTIONS_TREE_LOG.info('Processing Hero Actions')
|
||||
ACTIONS_TREE_LOG.info('|-> %s', action.actor)
|
||||
log.ACTIONS_TREE.info('Processing Hero Actions')
|
||||
log.ACTIONS_TREE.info('|-> %s', action.actor)
|
||||
|
||||
result = self.perform_action_until_done(action)
|
||||
|
||||
|
@ -54,7 +51,7 @@ class EventHandler(tcod.event.EventDispatch[Action]):
|
|||
self.engine.entities,
|
||||
key=lambda e: e.position.euclidean_distance_to(hero_position))
|
||||
|
||||
ACTIONS_TREE_LOG.info('Processing Entity Actions')
|
||||
log.ACTIONS_TREE.info('Processing Entity Actions')
|
||||
|
||||
for i, ent in enumerate(entities):
|
||||
if not isinstance(ent, Actor):
|
||||
|
@ -65,7 +62,7 @@ class EventHandler(tcod.event.EventDispatch[Action]):
|
|||
continue
|
||||
|
||||
if self.engine.map.visible[tuple(ent.position)]:
|
||||
ACTIONS_TREE_LOG.info('%s-> %s', '|' if i < len(entities) - 1 else '`', ent)
|
||||
log.ACTIONS_TREE.info('%s-> %s', '|' if i < len(entities) - 1 else '`', ent)
|
||||
|
||||
action = ent_ai.act(self.engine)
|
||||
self.perform_action_until_done(action)
|
||||
|
@ -76,17 +73,17 @@ class EventHandler(tcod.event.EventDispatch[Action]):
|
|||
'''Perform the given action and any alternate follow-up actions until the action chain is done.'''
|
||||
result = action.perform(self.engine)
|
||||
|
||||
if ACTIONS_TREE_LOG.isEnabledFor(logging.INFO) and self.engine.map.visible[tuple(action.actor.position)]:
|
||||
if log.ACTIONS_TREE.isEnabledFor(log.INFO) and self.engine.map.visible[tuple(action.actor.position)]:
|
||||
if result.alternate:
|
||||
alternate_string = f'{result.alternate.__class__.__name__}[{result.alternate.actor.symbol}]'
|
||||
else:
|
||||
alternate_string = str(result.alternate)
|
||||
ACTIONS_TREE_LOG.info('| %s-> %s => success=%s done=%s alternate=%s',
|
||||
'|' if not result.success or not result.done else '`',
|
||||
action,
|
||||
result.success,
|
||||
result.done,
|
||||
alternate_string)
|
||||
log.ACTIONS_TREE.info('| %s-> %s => success=%s done=%s alternate=%s',
|
||||
'|' if not result.success or not result.done else '`',
|
||||
action,
|
||||
result.success,
|
||||
result.done,
|
||||
alternate_string)
|
||||
|
||||
while not result.done:
|
||||
action = result.alternate
|
||||
|
@ -94,12 +91,12 @@ class EventHandler(tcod.event.EventDispatch[Action]):
|
|||
|
||||
result = action.perform(self.engine)
|
||||
|
||||
if ACTIONS_TREE_LOG.isEnabledFor(logging.INFO) and self.engine.map.visible[tuple(action.actor.position)]:
|
||||
if log.ACTIONS_TREE.isEnabledFor(log.INFO) and self.engine.map.visible[tuple(action.actor.position)]:
|
||||
if result.alternate:
|
||||
alternate_string = f'{result.alternate.__class__.__name__}[{result.alternate.actor.symbol}]'
|
||||
else:
|
||||
alternate_string = str(result.alternate)
|
||||
ACTIONS_TREE_LOG.info('| %s-> %s => success=%s done=%s alternate=%s',
|
||||
log.ACTIONS_TREE.info('| %s-> %s => success=%s done=%s alternate=%s',
|
||||
'|' if not result.success or not result.done else '`',
|
||||
action,
|
||||
result.success,
|
||||
|
|
69
erynrl/log.py
Normal file
69
erynrl/log.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
# Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
'''
|
||||
Initializes and sets up
|
||||
'''
|
||||
|
||||
import json
|
||||
import logging
|
||||
import logging.config
|
||||
import os.path
|
||||
|
||||
# These are re-imports so clients of this module don't have to also import logging
|
||||
# pylint: disable=unused-import
|
||||
from logging import CRITICAL, DEBUG, ERROR, FATAL, INFO, NOTSET, WARN, WARNING
|
||||
|
||||
def _log_name(*components):
|
||||
return '.'.join(['erynrl'] + list(components))
|
||||
|
||||
ROOT = logging.getLogger(_log_name())
|
||||
AI = logging.getLogger(_log_name('ai'))
|
||||
ACTIONS = logging.getLogger(_log_name('actions'))
|
||||
ACTIONS_TREE = logging.getLogger(_log_name('actions', 'tree'))
|
||||
ENGINE = logging.getLogger(_log_name('engine'))
|
||||
EVENTS = logging.getLogger(_log_name('events'))
|
||||
MAP = logging.getLogger(_log_name('map'))
|
||||
|
||||
def walk_up_directories_of_path(path):
|
||||
'''Walk up a path, yielding each directory, until the root of the filesystem is found'''
|
||||
while path and path != '/':
|
||||
if os.path.isdir(path):
|
||||
yield path
|
||||
path = os.path.dirname(path)
|
||||
|
||||
def find_logging_config():
|
||||
'''Walk up the filesystem from this script to find a logging_config.json'''
|
||||
for parent_dir in walk_up_directories_of_path(__file__):
|
||||
possible_logging_config_file = os.path.join(parent_dir, 'logging_config.json')
|
||||
if os.path.isfile(possible_logging_config_file):
|
||||
ROOT.info('Found logging config file %s', possible_logging_config_file)
|
||||
break
|
||||
else:
|
||||
return None
|
||||
|
||||
return possible_logging_config_file
|
||||
|
||||
def init(config_file=None):
|
||||
'''
|
||||
Set up the logging system by (preferrably) reading a logging configuration file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
config_file : str
|
||||
Path to a file containing a Python logging configuration in JSON
|
||||
'''
|
||||
logging_config_path = config_file if config_file else find_logging_config()
|
||||
|
||||
if os.path.isfile(logging_config_path):
|
||||
with open(logging_config_path, encoding='utf-8') as logging_config_file:
|
||||
logging_config = json.load(logging_config_file)
|
||||
logging.config.dictConfig(logging_config)
|
||||
ROOT.info('Found logging configuration at %s', logging_config_path)
|
||||
else:
|
||||
root_logger = logging.getLogger('')
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
|
||||
stderr_handler = logging.StreamHandler()
|
||||
stderr_handler.setFormatter(logging.Formatter("%(asctime)s %(name)s: %(message)s"))
|
||||
|
||||
root_logger.addHandler(stderr_handler)
|
|
@ -1,6 +1,5 @@
|
|||
# Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
import logging
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import Iterator, List, Optional
|
||||
|
@ -8,11 +7,10 @@ from typing import Iterator, List, Optional
|
|||
import numpy as np
|
||||
import tcod
|
||||
|
||||
from . import log
|
||||
from .geometry import Direction, Point, Rect, Size
|
||||
from .tile import Empty, Floor, Shroud, Wall
|
||||
|
||||
LOG = logging.getLogger('map')
|
||||
|
||||
class Map:
|
||||
def __init__(self, size: Size):
|
||||
self.size = size
|
||||
|
@ -120,7 +118,7 @@ class RoomsAndCorridorsGenerator(MapGenerator):
|
|||
node_bounds = self.__rect_from_bsp_node(node)
|
||||
|
||||
if node.children:
|
||||
LOG.debug(node_bounds)
|
||||
log.MAP.debug(node_bounds)
|
||||
|
||||
left_room: RectangularRoom = getattr(node.children[0], room_attrname)
|
||||
right_room: RectangularRoom = getattr(node.children[1], room_attrname)
|
||||
|
@ -128,8 +126,8 @@ class RoomsAndCorridorsGenerator(MapGenerator):
|
|||
left_room_bounds = left_room.bounds
|
||||
right_room_bounds = right_room.bounds
|
||||
|
||||
LOG.debug(' left: %s, %s', node.children[0], left_room_bounds)
|
||||
LOG.debug('right: %s, %s', node.children[1], right_room_bounds)
|
||||
log.MAP.debug(' left: %s, %s', node.children[0], left_room_bounds)
|
||||
log.MAP.debug('right: %s, %s', node.children[1], right_room_bounds)
|
||||
|
||||
start_point = left_room_bounds.midpoint
|
||||
end_point = right_room_bounds.midpoint
|
||||
|
@ -140,16 +138,16 @@ class RoomsAndCorridorsGenerator(MapGenerator):
|
|||
else:
|
||||
corner = Point(start_point.x, end_point.y)
|
||||
|
||||
LOG.debug('Digging a tunnel between %s and %s with corner %s', start_point, end_point, corner)
|
||||
LOG.debug('|-> start: %s', left_room_bounds)
|
||||
LOG.debug('`-> end: %s', right_room_bounds)
|
||||
log.MAP.debug('Digging a tunnel between %s and %s with corner %s', start_point, end_point, corner)
|
||||
log.MAP.debug('|-> start: %s', left_room_bounds)
|
||||
log.MAP.debug('`-> end: %s', right_room_bounds)
|
||||
|
||||
for x, y in tcod.los.bresenham(tuple(start_point), tuple(corner)).tolist():
|
||||
tiles[x, y] = Floor
|
||||
for x, y in tcod.los.bresenham(tuple(corner), tuple(end_point)).tolist():
|
||||
tiles[x, y] = Floor
|
||||
else:
|
||||
LOG.debug('%s (room) %s', node_bounds, node)
|
||||
log.MAP.debug('%s (room) %s', node_bounds, node)
|
||||
|
||||
# Generate a room size between minimum_room_size and maximum_room_size. The minimum value is
|
||||
# straight-forward, but the maximum value needs to be clamped between minimum_room_size and the size of
|
||||
|
@ -162,7 +160,7 @@ class RoomsAndCorridorsGenerator(MapGenerator):
|
|||
node.y + self.rng.randint(1, max(1, node.height - size.height - 1)))
|
||||
bounds = Rect(origin, size)
|
||||
|
||||
LOG.debug('`-> %s', bounds)
|
||||
log.MAP.debug('`-> %s', bounds)
|
||||
|
||||
room = RectangularRoom(bounds)
|
||||
setattr(node, room_attrname, room)
|
||||
|
|
|
@ -15,30 +15,30 @@
|
|||
}
|
||||
},
|
||||
"loggers": {
|
||||
"ai": {
|
||||
"erynrl.ai": {
|
||||
"level": "ERROR",
|
||||
"handlers": ["console"],
|
||||
"propagate": false
|
||||
},
|
||||
"actions": {
|
||||
"erynrl.actions": {
|
||||
"level": "INFO",
|
||||
"handlers": ["console"]
|
||||
},
|
||||
"actions.movement": {
|
||||
"erynrl.actions.movement": {
|
||||
"level": "ERROR",
|
||||
"handlers": ["console"]
|
||||
},
|
||||
"actions.tree": {
|
||||
"erynrl.actions.tree": {
|
||||
"level": "INFO",
|
||||
"handlers": ["console"],
|
||||
"propagate": false
|
||||
},
|
||||
"events": {
|
||||
"erynrl.events": {
|
||||
"level": "WARN",
|
||||
"handlers": ["console"],
|
||||
"propagate": false
|
||||
},
|
||||
"visible": {
|
||||
"erynrl.visible": {
|
||||
"level": "DEBUG",
|
||||
"handlers": ["console"]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue