Commit 2b709b19d9a93a1f83d4605e81509bdb38367489

Authored by Miguel Barão
1 parent 720ccbfa
Exists in master and in 1 other branch dev

fixed several errors in logging and updated messages

all tornado code moved to serve.py
disallowed topic restart (avoid regenerating questions)
aprendizations/learnapp.py
@@ -79,7 +79,7 @@ class LearnApp(object): @@ -79,7 +79,7 @@ class LearnApp(object):
79 79
80 errors = 0 80 errors = 0
81 for qref in self.factory: 81 for qref in self.factory:
82 - logger.debug(f'[sanity_check_questions] Checking "{qref}"...') 82 + logger.debug(f'checking {qref}...')
83 try: 83 try:
84 q = self.factory[qref].generate() 84 q = self.factory[qref].generate()
85 except Exception: 85 except Exception:
@@ -208,7 +208,7 @@ class LearnApp(object): @@ -208,7 +208,7 @@ class LearnApp(object):
208 finishtime=str(q['finish_time']), 208 finishtime=str(q['finish_time']),
209 student_id=uid, 209 student_id=uid,
210 topic_id=topic)) 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 if knowledge.topic_has_finished(): 213 if knowledge.topic_has_finished():
214 # finished topic, save into database 214 # finished topic, save into database
@@ -222,7 +222,7 @@ class LearnApp(object): @@ -222,7 +222,7 @@ class LearnApp(object):
222 .one_or_none() 222 .one_or_none()
223 if a is None: 223 if a is None:
224 # insert new studenttopic into database 224 # insert new studenttopic into database
225 - logger.debug('[check_answer] Database insert studenttopic') 225 + logger.debug('db insert studenttopic')
226 t = s.query(Topic).get(topic) 226 t = s.query(Topic).get(topic)
227 u = s.query(Student).get(uid) 227 u = s.query(Student).get(uid)
228 # association object 228 # association object
@@ -231,14 +231,12 @@ class LearnApp(object): @@ -231,14 +231,12 @@ class LearnApp(object):
231 u.topics.append(a) 231 u.topics.append(a)
232 else: 232 else:
233 # update studenttopic in database 233 # update studenttopic in database
234 - logger.debug('[check_answer] Database update studenttopic') 234 + logger.debug(f'db update studenttopic to level {level}')
235 a.level = level 235 a.level = level
236 a.date = date 236 a.date = date
237 237
238 s.add(a) 238 s.add(a)
239 239
240 - logger.debug(f'[check_answer] Saved topic "{topic}" into database')  
241 -  
242 return q, action 240 return q, action
243 241
244 # ------------------------------------------------------------------------ 242 # ------------------------------------------------------------------------
@@ -347,7 +345,7 @@ class LearnApp(object): @@ -347,7 +345,7 @@ class LearnApp(object):
347 # Buils dictionary of question factories 345 # Buils dictionary of question factories
348 # ------------------------------------------------------------------------ 346 # ------------------------------------------------------------------------
349 def make_factory(self) -> Dict[str, QFactory]: 347 def make_factory(self) -> Dict[str, QFactory]:
350 - logger.info('Building questions factory...') 348 + logger.info('Building questions factory:')
351 factory = {} # {'qref': QFactory()} 349 factory = {} # {'qref': QFactory()}
352 g = self.deps 350 g = self.deps
353 for tref in g.nodes(): 351 for tref in g.nodes():
aprendizations/main.py
@@ -4,34 +4,17 @@ @@ -4,34 +4,17 @@
4 import argparse 4 import argparse
5 import logging 5 import logging
6 from os import environ, path 6 from os import environ, path
7 -import signal  
8 import ssl 7 import ssl
9 import sys 8 import sys
10 9
11 -# third party libraries  
12 -import tornado  
13 -  
14 # this project 10 # this project
15 from .learnapp import LearnApp, DatabaseUnusableError 11 from .learnapp import LearnApp, DatabaseUnusableError
16 -from .serve import WebApplication 12 +from .serve import run_webserver
17 from .tools import load_yaml 13 from .tools import load_yaml
18 from . import APP_NAME, APP_VERSION 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 def parse_cmdline_arguments(): 18 def parse_cmdline_arguments():
36 argparser = argparse.ArgumentParser( 19 argparser = argparse.ArgumentParser(
37 description='Server for online learning. Students and topics ' 20 description='Server for online learning. Students and topics '
@@ -91,7 +74,7 @@ def get_logger_config(debug=False): @@ -91,7 +74,7 @@ def get_logger_config(debug=False):
91 'version': 1, 74 'version': 1,
92 'formatters': { 75 'formatters': {
93 'standard': { 76 'standard': {
94 - 'format': '%(asctime)s | %(levelname)-10s | %(message)s', 77 + 'format': '%(asctime)s | %(levelname)-8s | %(message)s',
95 'datefmt': '%Y-%m-%d %H:%M:%S', 78 'datefmt': '%Y-%m-%d %H:%M:%S',
96 }, 79 },
97 }, 80 },
@@ -115,14 +98,14 @@ def get_logger_config(debug=False): @@ -115,14 +98,14 @@ def get_logger_config(debug=False):
115 'handlers': ['default'], 98 'handlers': ['default'],
116 'level': level, 99 'level': level,
117 'propagate': False, 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 return load_yaml(config_file, default=default_config) 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 def main(): 110 def main():
128 # --- Commandline argument parsing 111 # --- Commandline argument parsing
@@ -144,34 +127,6 @@ def main(): @@ -144,34 +127,6 @@ def main():
144 127
145 logging.info('====================== Start Logging ======================') 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 # --- get SSL certificates 130 # --- get SSL certificates
176 if 'XDG_DATA_HOME' in environ: 131 if 'XDG_DATA_HOME' in environ:
177 certs_dir = path.join(environ['XDG_DATA_HOME'], 'certs') 132 certs_dir = path.join(environ['XDG_DATA_HOME'], 'certs')
@@ -197,34 +152,35 @@ def main(): @@ -197,34 +152,35 @@ def main():
197 print(' ') 152 print(' ')
198 print(f' {certs_dir:<62}') 153 print(f' {certs_dir:<62}')
199 print(' ') 154 print(' ')
  155 + print('(See README.md for more information) ')
200 print('--------------------------------------------------------------') 156 print('--------------------------------------------------------------')
201 sys.exit(1) 157 sys.exit(1)
  158 + else:
  159 + logging.info('SSL certificates loaded')
202 160
203 - # --- create webserver 161 + # --- start application
204 try: 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 sys.exit(1) 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 sys.exit(1) 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,7 +461,7 @@ class QFactory(object):
461 # i.e. a question object (radio, checkbox, ...). 461 # i.e. a question object (radio, checkbox, ...).
462 # ----------------------------------------------------------------------- 462 # -----------------------------------------------------------------------
463 def generate(self) -> Question: 463 def generate(self) -> Question:
464 - logger.debug(f'[QFactory.generate] "{self.question["ref"]}"...') 464 + logger.debug(f'generating {self.question["ref"]}...')
465 # Shallow copy so that script generated questions will not replace 465 # Shallow copy so that script generated questions will not replace
466 # the original generators 466 # the original generators
467 q = self.question.copy() 467 q = self.question.copy()
@@ -492,7 +492,7 @@ class QFactory(object): @@ -492,7 +492,7 @@ class QFactory(object):
492 492
493 # ----------------------------------------------------------------------- 493 # -----------------------------------------------------------------------
494 async def generate_async(self) -> Question: 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 # Shallow copy so that script generated questions will not replace 496 # Shallow copy so that script generated questions will not replace
497 # the original generators 497 # the original generators
498 q = self.question.copy() 498 q = self.question.copy()
@@ -520,5 +520,5 @@ class QFactory(object): @@ -520,5 +520,5 @@ class QFactory(object):
520 logger.error(f'Invalid type "{q["type"]}" in "{q["ref"]}"') 520 logger.error(f'Invalid type "{q["type"]}" in "{q["ref"]}"')
521 raise 521 raise
522 else: 522 else:
523 - logger.debug(f'[generate_async] Done instance of {q["ref"]}') 523 + logger.debug('ok')
524 return qinstance 524 return qinstance
aprendizations/serve.py
@@ -6,6 +6,8 @@ import functools @@ -6,6 +6,8 @@ import functools
6 import logging.config 6 import logging.config
7 import mimetypes 7 import mimetypes
8 from os import path 8 from os import path
  9 +import signal
  10 +import sys
9 import uuid 11 import uuid
10 12
11 # third party libraries 13 # third party libraries
@@ -16,6 +18,9 @@ from tornado.escape import to_unicode @@ -16,6 +18,9 @@ from tornado.escape import to_unicode
16 from .tools import md_to_html 18 from .tools import md_to_html
17 from . import APP_NAME 19 from . import APP_NAME
18 20
  21 +# setup logger for this module
  22 +logger = logging.getLogger(__name__)
  23 +
19 24
20 # ---------------------------------------------------------------------------- 25 # ----------------------------------------------------------------------------
21 # Decorator used to restrict access to the administrator only 26 # Decorator used to restrict access to the administrator only
@@ -211,11 +216,11 @@ class FileHandler(BaseHandler): @@ -211,11 +216,11 @@ class FileHandler(BaseHandler):
211 with open(filepath, 'rb') as f: 216 with open(filepath, 'rb') as f:
212 data = f.read() 217 data = f.read()
213 except FileNotFoundError: 218 except FileNotFoundError:
214 - logging.error(f'File not found: {filepath}') 219 + logger.error(f'File not found: {filepath}')
215 except PermissionError: 220 except PermissionError:
216 - logging.error(f'No permission: {filepath}') 221 + logger.error(f'No permission: {filepath}')
217 except Exception: 222 except Exception:
218 - logging.error(f'Error reading: {filepath}') 223 + logger.error(f'Error reading: {filepath}')
219 raise 224 raise
220 else: 225 else:
221 self.set_header("Content-Type", content_type) 226 self.set_header("Content-Type", content_type)
@@ -244,7 +249,7 @@ class QuestionHandler(BaseHandler): @@ -244,7 +249,7 @@ class QuestionHandler(BaseHandler):
244 # --- get question to render 249 # --- get question to render
245 @tornado.web.authenticated 250 @tornado.web.authenticated
246 def get(self): 251 def get(self):
247 - logging.debug('[QuestionHandler.get]') 252 + logger.debug('[QuestionHandler.get]')
248 user = self.current_user 253 user = self.current_user
249 q = self.learn.get_current_question(user) 254 q = self.learn.get_current_question(user)
250 255
@@ -275,7 +280,7 @@ class QuestionHandler(BaseHandler): @@ -275,7 +280,7 @@ class QuestionHandler(BaseHandler):
275 # --- post answer, returns what to do next: shake, new_question, finished 280 # --- post answer, returns what to do next: shake, new_question, finished
276 @tornado.web.authenticated 281 @tornado.web.authenticated
277 async def post(self) -> None: 282 async def post(self) -> None:
278 - logging.debug('[QuestionHandler.post]') 283 + logger.debug('[QuestionHandler.post]')
279 user = self.current_user 284 user = self.current_user
280 answer = self.get_body_arguments('answer') # list 285 answer = self.get_body_arguments('answer') # list
281 286
@@ -283,7 +288,7 @@ class QuestionHandler(BaseHandler): @@ -283,7 +288,7 @@ class QuestionHandler(BaseHandler):
283 answer_qid = self.get_body_arguments('qid')[0] 288 answer_qid = self.get_body_arguments('qid')[0]
284 current_qid = self.learn.get_current_question_id(user) 289 current_qid = self.learn.get_current_question_id(user)
285 if answer_qid != current_qid: 290 if answer_qid != current_qid:
286 - logging.info(f'User {user} desynchronized questions') 291 + logger.info(f'User {user} desynchronized questions')
287 self.write({ 292 self.write({
288 'method': 'invalid', 293 'method': 'invalid',
289 'params': { 294 'params': {
@@ -349,6 +354,59 @@ class QuestionHandler(BaseHandler): @@ -349,6 +354,59 @@ class QuestionHandler(BaseHandler):
349 'tries': q['tries'], 354 'tries': q['tries'],
350 } 355 }
351 else: 356 else:
352 - logging.error(f'Unknown action: {action}') 357 + logger.error(f'Unknown action: {action}')
353 358
354 self.write(response) 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,7 +63,7 @@ class StudentState(object):
63 'level': 0.0, # unlocked 63 'level': 0.0, # unlocked
64 'date': datetime.now() 64 'date': datetime.now()
65 } 65 }
66 - logger.debug(f'[unlock_topics] Unlocked "{topic}".') 66 + logger.debug(f'unlocked "{topic}"')
67 # else: # lock this topic if deps do not satisfy min_level 67 # else: # lock this topic if deps do not satisfy min_level
68 # del self.state[topic] 68 # del self.state[topic]
69 69
@@ -73,15 +73,16 @@ class StudentState(object): @@ -73,15 +73,16 @@ class StudentState(object):
73 # current_question: the current question to be presented 73 # current_question: the current question to be presented
74 # ------------------------------------------------------------------------ 74 # ------------------------------------------------------------------------
75 async def start_topic(self, topic: str): 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 # do not allow locked topics 83 # do not allow locked topics
83 if self.is_locked(topic): 84 if self.is_locked(topic):
84 - logger.debug(f'[start_topic] topic "{topic}" is locked') 85 + logger.debug(f'is locked "{topic}"')
85 return 86 return
86 87
87 # starting new topic 88 # starting new topic
@@ -95,13 +96,13 @@ class StudentState(object): @@ -95,13 +96,13 @@ class StudentState(object):
95 questions = random.sample(t['questions'], k=k) 96 questions = random.sample(t['questions'], k=k)
96 else: 97 else:
97 questions = t['questions'][:k] 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 self.questions = [await self.factory[ref].generate_async() 101 self.questions = [await self.factory[ref].generate_async()
101 for ref in questions] 102 for ref in questions]
102 103
103 n = len(self.questions) 104 n = len(self.questions)
104 - logger.debug(f'[start_topic] generated {n} questions') 105 + logger.debug(f'generated {n} questions')
105 106
106 # get first question 107 # get first question
107 self.next_question() 108 self.next_question()
@@ -112,7 +113,7 @@ class StudentState(object): @@ -112,7 +113,7 @@ class StudentState(object):
112 # The current topic is unchanged. 113 # The current topic is unchanged.
113 # ------------------------------------------------------------------------ 114 # ------------------------------------------------------------------------
114 def finish_topic(self): 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 self.state[self.current_topic] = { 118 self.state[self.current_topic] = {
118 'date': datetime.now(), 119 'date': datetime.now(),
@@ -129,13 +130,12 @@ class StudentState(object): @@ -129,13 +130,12 @@ class StudentState(object):
129 # - if wrong, counts number of tries. If exceeded, moves on. 130 # - if wrong, counts number of tries. If exceeded, moves on.
130 # ------------------------------------------------------------------------ 131 # ------------------------------------------------------------------------
131 async def check_answer(self, answer): 132 async def check_answer(self, answer):
132 - logger.debug('[check_answer]')  
133 -  
134 q = self.current_question 133 q = self.current_question
135 q['answer'] = answer 134 q['answer'] = answer
136 q['finish_time'] = datetime.now() 135 q['finish_time'] = datetime.now()
  136 + logger.debug(f'checking answer of {q["ref"]}...')
137 await q.correct_async() 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 if q['grade'] > 0.999: 140 if q['grade'] > 0.999:
141 self.correct_answers += 1 141 self.correct_answers += 1
@@ -151,7 +151,7 @@ class StudentState(object): @@ -151,7 +151,7 @@ class StudentState(object):
151 else: 151 else:
152 action = 'wrong' 152 action = 'wrong'
153 if self.current_question['append_wrong']: 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 self.questions.append(self.factory[q['ref']].generate()) 155 self.questions.append(self.factory[q['ref']].generate())
156 self.next_question() 156 self.next_question()
157 157
@@ -172,7 +172,7 @@ class StudentState(object): @@ -172,7 +172,7 @@ class StudentState(object):
172 default_maxtries = self.deps.nodes[self.current_topic]['max_tries'] 172 default_maxtries = self.deps.nodes[self.current_topic]['max_tries']
173 maxtries = self.current_question.get('max_tries', default_maxtries) 173 maxtries = self.current_question.get('max_tries', default_maxtries)
174 self.current_question['tries'] = maxtries 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 return self.current_question # question or None 177 return self.current_question # question or None
178 178
config/logger-debug.yaml
@@ -5,8 +5,8 @@ formatters: @@ -5,8 +5,8 @@ formatters:
5 void: 5 void:
6 format: '' 6 format: ''
7 standard: 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 handlers: 11 handlers:
12 default: 12 default:
@@ -25,7 +25,7 @@ loggers: @@ -25,7 +25,7 @@ loggers:
25 level: 'DEBUG' 25 level: 'DEBUG'
26 propagate: false 26 propagate: false
27 27
28 - 'aprendizations.knowledge': 28 + 'aprendizations.student':
29 handlers: ['default'] 29 handlers: ['default']
30 level: 'DEBUG' 30 level: 'DEBUG'
31 propagate: false 31 propagate: false
@@ -44,3 +44,8 @@ loggers: @@ -44,3 +44,8 @@ loggers:
44 handlers: ['default'] 44 handlers: ['default']
45 level: 'DEBUG' 45 level: 'DEBUG'
46 propagate: false 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,7 +5,7 @@ formatters:
5 void: 5 void:
6 format: '' 6 format: ''
7 standard: 7 standard:
8 - format: '%(asctime)s | %(thread)-15d | %(levelname)-9s | %(message)s' 8 + format: '%(asctime)s | %(levelname)-8s | %(module)-10s | %(message)s'
9 datefmt: '%Y-%m-%d %H:%M:%S' 9 datefmt: '%Y-%m-%d %H:%M:%S'
10 10
11 handlers: 11 handlers:
@@ -25,7 +25,7 @@ loggers: @@ -25,7 +25,7 @@ loggers:
25 level: 'INFO' 25 level: 'INFO'
26 propagate: false 26 propagate: false
27 27
28 - 'aprendizations.knowledge': 28 + 'aprendizations.student':
29 handlers: ['default'] 29 handlers: ['default']
30 level: 'INFO' 30 level: 'INFO'
31 propagate: false 31 propagate: false
@@ -44,3 +44,8 @@ loggers: @@ -44,3 +44,8 @@ loggers:
44 handlers: ['default'] 44 handlers: ['default']
45 level: 'INFO' 45 level: 'INFO'
46 propagate: false 46 propagate: false
  47 +
  48 + 'aprendizations.serve':
  49 + handlers: ['default']
  50 + level: 'INFO'
  51 + propagate: false