Commit 2b709b19d9a93a1f83d4605e81509bdb38367489
1 parent
720ccbfa
Exists in
master
and in
1 other branch
fixed several errors in logging and updated messages
all tornado code moved to serve.py disallowed topic restart (avoid regenerating questions)
Showing
7 changed files
with
129 additions
and
107 deletions
Show diff stats
aprendizations/learnapp.py
| ... | ... | @@ -79,7 +79,7 @@ class LearnApp(object): |
| 79 | 79 | |
| 80 | 80 | errors = 0 |
| 81 | 81 | for qref in self.factory: |
| 82 | - logger.debug(f'[sanity_check_questions] Checking "{qref}"...') | |
| 82 | + logger.debug(f'checking {qref}...') | |
| 83 | 83 | try: |
| 84 | 84 | q = self.factory[qref].generate() |
| 85 | 85 | except Exception: |
| ... | ... | @@ -208,7 +208,7 @@ class LearnApp(object): |
| 208 | 208 | finishtime=str(q['finish_time']), |
| 209 | 209 | student_id=uid, |
| 210 | 210 | topic_id=topic)) |
| 211 | - logger.debug(f'[check_answer] Saved "{q["ref"]}" into database') | |
| 211 | + logger.debug(f'db insert answer of {q["ref"]}') | |
| 212 | 212 | |
| 213 | 213 | if knowledge.topic_has_finished(): |
| 214 | 214 | # finished topic, save into database |
| ... | ... | @@ -222,7 +222,7 @@ class LearnApp(object): |
| 222 | 222 | .one_or_none() |
| 223 | 223 | if a is None: |
| 224 | 224 | # insert new studenttopic into database |
| 225 | - logger.debug('[check_answer] Database insert studenttopic') | |
| 225 | + logger.debug('db insert studenttopic') | |
| 226 | 226 | t = s.query(Topic).get(topic) |
| 227 | 227 | u = s.query(Student).get(uid) |
| 228 | 228 | # association object |
| ... | ... | @@ -231,14 +231,12 @@ class LearnApp(object): |
| 231 | 231 | u.topics.append(a) |
| 232 | 232 | else: |
| 233 | 233 | # update studenttopic in database |
| 234 | - logger.debug('[check_answer] Database update studenttopic') | |
| 234 | + logger.debug(f'db update studenttopic to level {level}') | |
| 235 | 235 | a.level = level |
| 236 | 236 | a.date = date |
| 237 | 237 | |
| 238 | 238 | s.add(a) |
| 239 | 239 | |
| 240 | - logger.debug(f'[check_answer] Saved topic "{topic}" into database') | |
| 241 | - | |
| 242 | 240 | return q, action |
| 243 | 241 | |
| 244 | 242 | # ------------------------------------------------------------------------ |
| ... | ... | @@ -347,7 +345,7 @@ class LearnApp(object): |
| 347 | 345 | # Buils dictionary of question factories |
| 348 | 346 | # ------------------------------------------------------------------------ |
| 349 | 347 | def make_factory(self) -> Dict[str, QFactory]: |
| 350 | - logger.info('Building questions factory...') | |
| 348 | + logger.info('Building questions factory:') | |
| 351 | 349 | factory = {} # {'qref': QFactory()} |
| 352 | 350 | g = self.deps |
| 353 | 351 | for tref in g.nodes(): | ... | ... |
aprendizations/main.py
| ... | ... | @@ -4,34 +4,17 @@ |
| 4 | 4 | import argparse |
| 5 | 5 | import logging |
| 6 | 6 | from os import environ, path |
| 7 | -import signal | |
| 8 | 7 | import ssl |
| 9 | 8 | import sys |
| 10 | 9 | |
| 11 | -# third party libraries | |
| 12 | -import tornado | |
| 13 | - | |
| 14 | 10 | # this project |
| 15 | 11 | from .learnapp import LearnApp, DatabaseUnusableError |
| 16 | -from .serve import WebApplication | |
| 12 | +from .serve import run_webserver | |
| 17 | 13 | from .tools import load_yaml |
| 18 | 14 | from . import APP_NAME, APP_VERSION |
| 19 | 15 | |
| 20 | 16 | |
| 21 | 17 | # ---------------------------------------------------------------------------- |
| 22 | -# Signal handler to catch Ctrl-C and abort server | |
| 23 | -# ---------------------------------------------------------------------------- | |
| 24 | -def signal_handler(signal, frame): | |
| 25 | - r = input(' --> Stop webserver? (yes/no) ').lower() | |
| 26 | - if r == 'yes': | |
| 27 | - tornado.ioloop.IOLoop.current().stop() | |
| 28 | - logging.critical('Webserver stopped.') | |
| 29 | - sys.exit(0) | |
| 30 | - else: | |
| 31 | - logging.info('Abort canceled...') | |
| 32 | - | |
| 33 | - | |
| 34 | -# ---------------------------------------------------------------------------- | |
| 35 | 18 | def parse_cmdline_arguments(): |
| 36 | 19 | argparser = argparse.ArgumentParser( |
| 37 | 20 | description='Server for online learning. Students and topics ' |
| ... | ... | @@ -91,7 +74,7 @@ def get_logger_config(debug=False): |
| 91 | 74 | 'version': 1, |
| 92 | 75 | 'formatters': { |
| 93 | 76 | 'standard': { |
| 94 | - 'format': '%(asctime)s | %(levelname)-10s | %(message)s', | |
| 77 | + 'format': '%(asctime)s | %(levelname)-8s | %(message)s', | |
| 95 | 78 | 'datefmt': '%Y-%m-%d %H:%M:%S', |
| 96 | 79 | }, |
| 97 | 80 | }, |
| ... | ... | @@ -115,14 +98,14 @@ def get_logger_config(debug=False): |
| 115 | 98 | 'handlers': ['default'], |
| 116 | 99 | 'level': level, |
| 117 | 100 | 'propagate': False, |
| 118 | - } for module in ['learnapp', 'models', 'factory', 'questions', | |
| 119 | - 'knowledge', 'tools']}) | |
| 101 | + } for module in ['learnapp', 'models', 'factory', 'tools', 'serve', | |
| 102 | + 'questions', 'student']}) | |
| 120 | 103 | |
| 121 | 104 | return load_yaml(config_file, default=default_config) |
| 122 | 105 | |
| 123 | 106 | |
| 124 | 107 | # ---------------------------------------------------------------------------- |
| 125 | -# Tornado web server | |
| 108 | +# Start application and webserver | |
| 126 | 109 | # ---------------------------------------------------------------------------- |
| 127 | 110 | def main(): |
| 128 | 111 | # --- Commandline argument parsing |
| ... | ... | @@ -144,34 +127,6 @@ def main(): |
| 144 | 127 | |
| 145 | 128 | logging.info('====================== Start Logging ======================') |
| 146 | 129 | |
| 147 | - # --- start application | |
| 148 | - logging.info('Starting App...') | |
| 149 | - try: | |
| 150 | - learnapp = LearnApp(arg.conffile, prefix=arg.prefix, db=arg.db, | |
| 151 | - check=arg.check) | |
| 152 | - except DatabaseUnusableError: | |
| 153 | - logging.critical('Failed to start application.') | |
| 154 | - print('--------------------------------------------------------------') | |
| 155 | - print('Could not find a usable database. Use one of the follwing ') | |
| 156 | - print('commands to initialize: ') | |
| 157 | - print(' ') | |
| 158 | - print(' initdb-aprendizations --admin # add admin ') | |
| 159 | - print(' initdb-aprendizations -a 86 "Max Smart" # add student ') | |
| 160 | - print(' initdb-aprendizations students.csv # add many students') | |
| 161 | - print('--------------------------------------------------------------') | |
| 162 | - sys.exit(1) | |
| 163 | - except Exception: | |
| 164 | - logging.critical('Failed to start application.') | |
| 165 | - sys.exit(1) | |
| 166 | - | |
| 167 | - # --- create web application | |
| 168 | - logging.info('Starting Web App (tornado)...') | |
| 169 | - try: | |
| 170 | - webapp = WebApplication(learnapp, debug=arg.debug) | |
| 171 | - except Exception: | |
| 172 | - logging.critical('Failed to start web application.') | |
| 173 | - sys.exit(1) | |
| 174 | - | |
| 175 | 130 | # --- get SSL certificates |
| 176 | 131 | if 'XDG_DATA_HOME' in environ: |
| 177 | 132 | certs_dir = path.join(environ['XDG_DATA_HOME'], 'certs') |
| ... | ... | @@ -197,34 +152,35 @@ def main(): |
| 197 | 152 | print(' ') |
| 198 | 153 | print(f' {certs_dir:<62}') |
| 199 | 154 | print(' ') |
| 155 | + print('(See README.md for more information) ') | |
| 200 | 156 | print('--------------------------------------------------------------') |
| 201 | 157 | sys.exit(1) |
| 158 | + else: | |
| 159 | + logging.info('SSL certificates loaded') | |
| 202 | 160 | |
| 203 | - # --- create webserver | |
| 161 | + # --- start application | |
| 204 | 162 | try: |
| 205 | - httpserver = tornado.httpserver.HTTPServer(webapp, ssl_options=ssl_ctx) | |
| 206 | - except ValueError: | |
| 207 | - logging.critical('Certificates cert.pem and privkey.pem not found') | |
| 163 | + learnapp = LearnApp(arg.conffile, prefix=arg.prefix, db=arg.db, | |
| 164 | + check=arg.check) | |
| 165 | + except DatabaseUnusableError: | |
| 166 | + logging.critical('Failed to start application.') | |
| 167 | + print('--------------------------------------------------------------') | |
| 168 | + print('Could not find a usable database. Use one of the follwing ') | |
| 169 | + print('commands to initialize: ') | |
| 170 | + print(' ') | |
| 171 | + print(' initdb-aprendizations --admin # add admin ') | |
| 172 | + print(' initdb-aprendizations -a 86 "Max Smart" # add student ') | |
| 173 | + print(' initdb-aprendizations students.csv # add many students') | |
| 174 | + print('--------------------------------------------------------------') | |
| 208 | 175 | sys.exit(1) |
| 209 | - | |
| 210 | - try: | |
| 211 | - httpserver.listen(arg.port) | |
| 212 | - except OSError: | |
| 213 | - logging.critical(f'Cannot bind port {arg.port}. Already in use?') | |
| 176 | + except Exception: | |
| 177 | + logging.critical('Failed to start application.') | |
| 214 | 178 | sys.exit(1) |
| 179 | + else: | |
| 180 | + logging.info('Backend application started') | |
| 215 | 181 | |
| 216 | - logging.info(f'Listening on port {arg.port}.') | |
| 217 | - | |
| 218 | - # --- run webserver | |
| 219 | - signal.signal(signal.SIGINT, signal_handler) | |
| 220 | - logging.info('Webserver running. (Ctrl-C to stop)') | |
| 221 | - | |
| 222 | - try: | |
| 223 | - tornado.ioloop.IOLoop.current().start() # running... | |
| 224 | - except Exception: | |
| 225 | - logging.critical('Webserver stopped.') | |
| 226 | - tornado.ioloop.IOLoop.current().stop() | |
| 227 | - raise | |
| 182 | + # --- run webserver forever | |
| 183 | + run_webserver(app=learnapp, ssl=ssl_ctx, port=arg.port, debug=arg.debug) | |
| 228 | 184 | |
| 229 | 185 | |
| 230 | 186 | # ---------------------------------------------------------------------------- | ... | ... |
aprendizations/questions.py
| ... | ... | @@ -461,7 +461,7 @@ class QFactory(object): |
| 461 | 461 | # i.e. a question object (radio, checkbox, ...). |
| 462 | 462 | # ----------------------------------------------------------------------- |
| 463 | 463 | def generate(self) -> Question: |
| 464 | - logger.debug(f'[QFactory.generate] "{self.question["ref"]}"...') | |
| 464 | + logger.debug(f'generating {self.question["ref"]}...') | |
| 465 | 465 | # Shallow copy so that script generated questions will not replace |
| 466 | 466 | # the original generators |
| 467 | 467 | q = self.question.copy() |
| ... | ... | @@ -492,7 +492,7 @@ class QFactory(object): |
| 492 | 492 | |
| 493 | 493 | # ----------------------------------------------------------------------- |
| 494 | 494 | async def generate_async(self) -> Question: |
| 495 | - logger.debug(f'[QFactory.generate_async] "{self.question["ref"]}"...') | |
| 495 | + logger.debug(f'generating {self.question["ref"]}...') | |
| 496 | 496 | # Shallow copy so that script generated questions will not replace |
| 497 | 497 | # the original generators |
| 498 | 498 | q = self.question.copy() |
| ... | ... | @@ -520,5 +520,5 @@ class QFactory(object): |
| 520 | 520 | logger.error(f'Invalid type "{q["type"]}" in "{q["ref"]}"') |
| 521 | 521 | raise |
| 522 | 522 | else: |
| 523 | - logger.debug(f'[generate_async] Done instance of {q["ref"]}') | |
| 523 | + logger.debug('ok') | |
| 524 | 524 | return qinstance | ... | ... |
aprendizations/serve.py
| ... | ... | @@ -6,6 +6,8 @@ import functools |
| 6 | 6 | import logging.config |
| 7 | 7 | import mimetypes |
| 8 | 8 | from os import path |
| 9 | +import signal | |
| 10 | +import sys | |
| 9 | 11 | import uuid |
| 10 | 12 | |
| 11 | 13 | # third party libraries |
| ... | ... | @@ -16,6 +18,9 @@ from tornado.escape import to_unicode |
| 16 | 18 | from .tools import md_to_html |
| 17 | 19 | from . import APP_NAME |
| 18 | 20 | |
| 21 | +# setup logger for this module | |
| 22 | +logger = logging.getLogger(__name__) | |
| 23 | + | |
| 19 | 24 | |
| 20 | 25 | # ---------------------------------------------------------------------------- |
| 21 | 26 | # Decorator used to restrict access to the administrator only |
| ... | ... | @@ -211,11 +216,11 @@ class FileHandler(BaseHandler): |
| 211 | 216 | with open(filepath, 'rb') as f: |
| 212 | 217 | data = f.read() |
| 213 | 218 | except FileNotFoundError: |
| 214 | - logging.error(f'File not found: {filepath}') | |
| 219 | + logger.error(f'File not found: {filepath}') | |
| 215 | 220 | except PermissionError: |
| 216 | - logging.error(f'No permission: {filepath}') | |
| 221 | + logger.error(f'No permission: {filepath}') | |
| 217 | 222 | except Exception: |
| 218 | - logging.error(f'Error reading: {filepath}') | |
| 223 | + logger.error(f'Error reading: {filepath}') | |
| 219 | 224 | raise |
| 220 | 225 | else: |
| 221 | 226 | self.set_header("Content-Type", content_type) |
| ... | ... | @@ -244,7 +249,7 @@ class QuestionHandler(BaseHandler): |
| 244 | 249 | # --- get question to render |
| 245 | 250 | @tornado.web.authenticated |
| 246 | 251 | def get(self): |
| 247 | - logging.debug('[QuestionHandler.get]') | |
| 252 | + logger.debug('[QuestionHandler.get]') | |
| 248 | 253 | user = self.current_user |
| 249 | 254 | q = self.learn.get_current_question(user) |
| 250 | 255 | |
| ... | ... | @@ -275,7 +280,7 @@ class QuestionHandler(BaseHandler): |
| 275 | 280 | # --- post answer, returns what to do next: shake, new_question, finished |
| 276 | 281 | @tornado.web.authenticated |
| 277 | 282 | async def post(self) -> None: |
| 278 | - logging.debug('[QuestionHandler.post]') | |
| 283 | + logger.debug('[QuestionHandler.post]') | |
| 279 | 284 | user = self.current_user |
| 280 | 285 | answer = self.get_body_arguments('answer') # list |
| 281 | 286 | |
| ... | ... | @@ -283,7 +288,7 @@ class QuestionHandler(BaseHandler): |
| 283 | 288 | answer_qid = self.get_body_arguments('qid')[0] |
| 284 | 289 | current_qid = self.learn.get_current_question_id(user) |
| 285 | 290 | if answer_qid != current_qid: |
| 286 | - logging.info(f'User {user} desynchronized questions') | |
| 291 | + logger.info(f'User {user} desynchronized questions') | |
| 287 | 292 | self.write({ |
| 288 | 293 | 'method': 'invalid', |
| 289 | 294 | 'params': { |
| ... | ... | @@ -349,6 +354,59 @@ class QuestionHandler(BaseHandler): |
| 349 | 354 | 'tries': q['tries'], |
| 350 | 355 | } |
| 351 | 356 | else: |
| 352 | - logging.error(f'Unknown action: {action}') | |
| 357 | + logger.error(f'Unknown action: {action}') | |
| 353 | 358 | |
| 354 | 359 | self.write(response) |
| 360 | + | |
| 361 | + | |
| 362 | +# ---------------------------------------------------------------------------- | |
| 363 | +# Signal handler to catch Ctrl-C and abort server | |
| 364 | +# ---------------------------------------------------------------------------- | |
| 365 | +def signal_handler(signal, frame): | |
| 366 | + r = input(' --> Stop webserver? (yes/no) ').lower() | |
| 367 | + if r == 'yes': | |
| 368 | + tornado.ioloop.IOLoop.current().stop() | |
| 369 | + logger.critical('Webserver stopped.') | |
| 370 | + sys.exit(0) | |
| 371 | + else: | |
| 372 | + logger.info('Abort canceled...') | |
| 373 | + | |
| 374 | + | |
| 375 | +# ---------------------------------------------------------------------------- | |
| 376 | +def run_webserver(app, ssl, port=8443, debug=False): | |
| 377 | + # --- create web application | |
| 378 | + try: | |
| 379 | + webapp = WebApplication(app, debug=debug) | |
| 380 | + except Exception: | |
| 381 | + logger.critical('Failed to start web application.') | |
| 382 | + sys.exit(1) | |
| 383 | + else: | |
| 384 | + logger.info('Web application started (tornado.web.Application)') | |
| 385 | + | |
| 386 | + # --- create tornado webserver | |
| 387 | + try: | |
| 388 | + httpserver = tornado.httpserver.HTTPServer(webapp, ssl_options=ssl) | |
| 389 | + except ValueError: | |
| 390 | + logger.critical('Certificates cert.pem and privkey.pem not found') | |
| 391 | + sys.exit(1) | |
| 392 | + else: | |
| 393 | + logger.debug('HTTP server started') | |
| 394 | + | |
| 395 | + try: | |
| 396 | + httpserver.listen(port) | |
| 397 | + except OSError: | |
| 398 | + logger.critical(f'Cannot bind port {port}. Already in use?') | |
| 399 | + sys.exit(1) | |
| 400 | + else: | |
| 401 | + logger.info(f'HTTP server listening on port {port}') | |
| 402 | + | |
| 403 | + # --- run webserver | |
| 404 | + signal.signal(signal.SIGINT, signal_handler) | |
| 405 | + logger.info('Webserver running. (Ctrl-C to stop)') | |
| 406 | + | |
| 407 | + try: | |
| 408 | + tornado.ioloop.IOLoop.current().start() # running... | |
| 409 | + except Exception: | |
| 410 | + logger.critical('Webserver stopped.') | |
| 411 | + tornado.ioloop.IOLoop.current().stop() | |
| 412 | + raise | ... | ... |
aprendizations/student.py
| ... | ... | @@ -63,7 +63,7 @@ class StudentState(object): |
| 63 | 63 | 'level': 0.0, # unlocked |
| 64 | 64 | 'date': datetime.now() |
| 65 | 65 | } |
| 66 | - logger.debug(f'[unlock_topics] Unlocked "{topic}".') | |
| 66 | + logger.debug(f'unlocked "{topic}"') | |
| 67 | 67 | # else: # lock this topic if deps do not satisfy min_level |
| 68 | 68 | # del self.state[topic] |
| 69 | 69 | |
| ... | ... | @@ -73,15 +73,16 @@ class StudentState(object): |
| 73 | 73 | # current_question: the current question to be presented |
| 74 | 74 | # ------------------------------------------------------------------------ |
| 75 | 75 | async def start_topic(self, topic: str): |
| 76 | - logger.debug(f'[start_topic] topic "{topic}"') | |
| 76 | + logger.debug(f'starting "{topic}"') | |
| 77 | 77 | |
| 78 | - # if self.current_topic == topic: | |
| 79 | - # logger.info('Restarting current topic is not allowed.') | |
| 80 | - # return | |
| 78 | + # avoid regenerating questions in the middle of the current topic | |
| 79 | + if self.current_topic == topic: | |
| 80 | + logger.info('Restarting current topic is not allowed.') | |
| 81 | + return | |
| 81 | 82 | |
| 82 | 83 | # do not allow locked topics |
| 83 | 84 | if self.is_locked(topic): |
| 84 | - logger.debug(f'[start_topic] topic "{topic}" is locked') | |
| 85 | + logger.debug(f'is locked "{topic}"') | |
| 85 | 86 | return |
| 86 | 87 | |
| 87 | 88 | # starting new topic |
| ... | ... | @@ -95,13 +96,13 @@ class StudentState(object): |
| 95 | 96 | questions = random.sample(t['questions'], k=k) |
| 96 | 97 | else: |
| 97 | 98 | questions = t['questions'][:k] |
| 98 | - logger.debug(f'[start_topic] questions: {", ".join(questions)}') | |
| 99 | + logger.debug(f'selected questions: {", ".join(questions)}') | |
| 99 | 100 | |
| 100 | 101 | self.questions = [await self.factory[ref].generate_async() |
| 101 | 102 | for ref in questions] |
| 102 | 103 | |
| 103 | 104 | n = len(self.questions) |
| 104 | - logger.debug(f'[start_topic] generated {n} questions') | |
| 105 | + logger.debug(f'generated {n} questions') | |
| 105 | 106 | |
| 106 | 107 | # get first question |
| 107 | 108 | self.next_question() |
| ... | ... | @@ -112,7 +113,7 @@ class StudentState(object): |
| 112 | 113 | # The current topic is unchanged. |
| 113 | 114 | # ------------------------------------------------------------------------ |
| 114 | 115 | def finish_topic(self): |
| 115 | - logger.debug(f'[finish_topic] current_topic {self.current_topic}') | |
| 116 | + logger.debug(f'finished {self.current_topic}') | |
| 116 | 117 | |
| 117 | 118 | self.state[self.current_topic] = { |
| 118 | 119 | 'date': datetime.now(), |
| ... | ... | @@ -129,13 +130,12 @@ class StudentState(object): |
| 129 | 130 | # - if wrong, counts number of tries. If exceeded, moves on. |
| 130 | 131 | # ------------------------------------------------------------------------ |
| 131 | 132 | async def check_answer(self, answer): |
| 132 | - logger.debug('[check_answer]') | |
| 133 | - | |
| 134 | 133 | q = self.current_question |
| 135 | 134 | q['answer'] = answer |
| 136 | 135 | q['finish_time'] = datetime.now() |
| 136 | + logger.debug(f'checking answer of {q["ref"]}...') | |
| 137 | 137 | await q.correct_async() |
| 138 | - logger.debug(f'[check_answer] Grade {q["grade"]:.2} in {q["ref"]}') | |
| 138 | + logger.debug(f'grade = {q["grade"]:.2}') | |
| 139 | 139 | |
| 140 | 140 | if q['grade'] > 0.999: |
| 141 | 141 | self.correct_answers += 1 |
| ... | ... | @@ -151,7 +151,7 @@ class StudentState(object): |
| 151 | 151 | else: |
| 152 | 152 | action = 'wrong' |
| 153 | 153 | if self.current_question['append_wrong']: |
| 154 | - logger.debug('[check_answer] Wrong, append new instance') | |
| 154 | + logger.debug('wrong answer, append new question') | |
| 155 | 155 | self.questions.append(self.factory[q['ref']].generate()) |
| 156 | 156 | self.next_question() |
| 157 | 157 | |
| ... | ... | @@ -172,7 +172,7 @@ class StudentState(object): |
| 172 | 172 | default_maxtries = self.deps.nodes[self.current_topic]['max_tries'] |
| 173 | 173 | maxtries = self.current_question.get('max_tries', default_maxtries) |
| 174 | 174 | self.current_question['tries'] = maxtries |
| 175 | - logger.debug(f'[next_question] "{self.current_question["ref"]}"') | |
| 175 | + logger.debug(f'current_question = {self.current_question["ref"]}') | |
| 176 | 176 | |
| 177 | 177 | return self.current_question # question or None |
| 178 | 178 | ... | ... |
config/logger-debug.yaml
| ... | ... | @@ -5,8 +5,8 @@ formatters: |
| 5 | 5 | void: |
| 6 | 6 | format: '' |
| 7 | 7 | standard: |
| 8 | - format: '%(asctime)s | %(levelname)-9s | %(name)-24s | %(thread)-15d | %(message)s' | |
| 9 | - datefmt: '%H:%M:%S' | |
| 8 | + format: '%(asctime)s | %(thread)-15d | %(levelname)-8s | %(module)-10s | %(funcName)-20s | %(message)s' | |
| 9 | + # datefmt: '%H:%M:%S' | |
| 10 | 10 | |
| 11 | 11 | handlers: |
| 12 | 12 | default: |
| ... | ... | @@ -25,7 +25,7 @@ loggers: |
| 25 | 25 | level: 'DEBUG' |
| 26 | 26 | propagate: false |
| 27 | 27 | |
| 28 | - 'aprendizations.knowledge': | |
| 28 | + 'aprendizations.student': | |
| 29 | 29 | handlers: ['default'] |
| 30 | 30 | level: 'DEBUG' |
| 31 | 31 | propagate: false |
| ... | ... | @@ -44,3 +44,8 @@ loggers: |
| 44 | 44 | handlers: ['default'] |
| 45 | 45 | level: 'DEBUG' |
| 46 | 46 | propagate: false |
| 47 | + | |
| 48 | + 'aprendizations.serve': | |
| 49 | + handlers: ['default'] | |
| 50 | + level: 'DEBUG' | |
| 51 | + propagate: false | ... | ... |
config/logger.yaml
| ... | ... | @@ -5,7 +5,7 @@ formatters: |
| 5 | 5 | void: |
| 6 | 6 | format: '' |
| 7 | 7 | standard: |
| 8 | - format: '%(asctime)s | %(thread)-15d | %(levelname)-9s | %(message)s' | |
| 8 | + format: '%(asctime)s | %(levelname)-8s | %(module)-10s | %(message)s' | |
| 9 | 9 | datefmt: '%Y-%m-%d %H:%M:%S' |
| 10 | 10 | |
| 11 | 11 | handlers: |
| ... | ... | @@ -25,7 +25,7 @@ loggers: |
| 25 | 25 | level: 'INFO' |
| 26 | 26 | propagate: false |
| 27 | 27 | |
| 28 | - 'aprendizations.knowledge': | |
| 28 | + 'aprendizations.student': | |
| 29 | 29 | handlers: ['default'] |
| 30 | 30 | level: 'INFO' |
| 31 | 31 | propagate: false |
| ... | ... | @@ -44,3 +44,8 @@ loggers: |
| 44 | 44 | handlers: ['default'] |
| 45 | 45 | level: 'INFO' |
| 46 | 46 | propagate: false |
| 47 | + | |
| 48 | + 'aprendizations.serve': | |
| 49 | + handlers: ['default'] | |
| 50 | + level: 'INFO' | |
| 51 | + propagate: false | ... | ... |