log.py
Go to the documentation of this file.
1 # Copyright 2017 Mycroft AI Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 #
15 import inspect
16 import logging
17 import sys
18 
19 from os.path import isfile
20 
21 from mycroft.util.json_helper import load_commented_json, merge_dict
22 from mycroft.configuration.locations import SYSTEM_CONFIG, USER_CONFIG
23 
24 
25 def getLogger(name="MYCROFT"):
26  """Depreciated. Use LOG instead"""
27  return logging.getLogger(name)
28 
29 
31  @classmethod
32  def method(cls, *args, **kwargs):
33  cls._log(fn, *args, **kwargs)
34 
35  method.__func__.__doc__ = fn.__doc__
36  return method
37 
38 
39 class LOG:
40  """
41  Custom logger class that acts like logging.Logger
42  The logger name is automatically generated by the module of the caller
43 
44  Usage:
45  >>> LOG.debug('My message: %s', debug_str)
46  13:12:43.673 - :<module>:1 - DEBUG - My message: hi
47  >>> LOG('custom_name').debug('Another message')
48  13:13:10.462 - custom_name - DEBUG - Another message
49  """
50 
51  _custom_name = None
52  handler = None
53  level = None
54 
55  # Copy actual logging methods from logging.Logger
56  # Usage: LOG.debug(message)
57  debug = _make_log_method(logging.Logger.debug)
58  info = _make_log_method(logging.Logger.info)
59  warning = _make_log_method(logging.Logger.warning)
60  error = _make_log_method(logging.Logger.error)
61  exception = _make_log_method(logging.Logger.exception)
62 
63  @classmethod
64  def init(cls):
65  confs = [SYSTEM_CONFIG, USER_CONFIG]
66  config = {}
67  for conf in confs:
68  try:
69  merge_dict(config,
70  load_commented_json(conf) if isfile(conf) else {})
71  except Exception as e:
72  print('couldn\'t load {}: {}'.format(conf, str(e)))
73 
74  cls.level = logging.getLevelName(config.get('log_level', 'INFO'))
75  fmt = '%(asctime)s.%(msecs)03d - ' \
76  '%(name)s - %(levelname)s - %(message)s'
77  datefmt = '%H:%M:%S'
78  formatter = logging.Formatter(fmt, datefmt)
79  cls.handler = logging.StreamHandler(sys.stdout)
80  cls.handler.setFormatter(formatter)
81 
82  # Enable logging in external modules
83  cls.create_logger('').setLevel(cls.level)
84 
85  @classmethod
86  def create_logger(cls, name):
87  logger = logging.getLogger(name)
88  logger.propagate = False
89  logger.addHandler(cls.handler)
90  return logger
91 
92  def __init__(self, name):
93  LOG._custom_name = name
94 
95  @classmethod
96  def _log(cls, func, *args, **kwargs):
97  if cls._custom_name is not None:
98  name = cls._custom_name
99  cls._custom_name = None
100  else:
101  # Stack:
102  # [0] - _log()
103  # [1] - debug(), info(), warning(), or error()
104  # [2] - caller
105  stack = inspect.stack()
106 
107  # Record:
108  # [0] - frame object
109  # [1] - filename
110  # [2] - line number
111  # [3] - function
112  # ...
113  record = stack[2]
114  mod = inspect.getmodule(record[0])
115  module_name = mod.__name__ if mod else ''
116  name = module_name + ':' + record[3] + ':' + str(record[2])
117  func(cls.create_logger(name), *args, **kwargs)
118 
119 
120 LOG.init()
def _log(cls, func, args, kwargs)
Definition: log.py:96
def __init__(self, name)
Definition: log.py:92
def create_logger(cls, name)
Definition: log.py:86
def init(cls)
Definition: log.py:64
def load_commented_json(filename)
Definition: json_helper.py:35
def getLogger(name="MYCROFT")
Definition: log.py:25
def _make_log_method(fn)
Definition: log.py:30
def merge_dict(base, delta)
Definition: json_helper.py:18


mycroft_ros
Author(s):
autogenerated on Mon Apr 26 2021 02:35:40