Coverage for conflog/config.py: 100%

50 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-10 04:36 +0000

1"""A module for managing logging configurations. 

2""" 

3 

4from typing import Union 

5import logging 

6from .loaders import environ_loader, ini_loader, json_loader, xml_loader, yaml_loader 

7 

8LEVELS = { 

9 "debug": logging.DEBUG, 

10 "warning": logging.WARNING, 

11 "info": logging.INFO, 

12 "error": logging.ERROR, 

13 "critical": logging.CRITICAL, 

14} 

15 

16DEFAULT_HANDLERS = "stream" 

17DEFAULT_DATEFMT = "%d-%b-%y %H:%M:%S" 

18DEFAULT_FILENAME = "conflog.log" 

19DEFAULT_FILEMODE = "w" 

20DEFAULT_FORMAT = "%(asctime)s --> %(name)s - %(levelname)s - %(message)s" 

21DEFAULT_LEVEL = "info" 

22DEFAULT_EXTRAS = {} 

23 

24 

25class Config: 

26 """A class for managing logging configurations.""" 

27 

28 def __init__( 

29 self, conf_files: Union[None, list] = None, conf_dict: Union[None, list] = None 

30 ): 

31 """Initialise config by loading and merging 

32 the configuration options from files and environment 

33 variables, with optional configuration dictionary overwriting 

34 everything being specified. 

35 """ 

36 

37 self.conf = {} 

38 

39 # Load configurations from files 

40 for conf_file in conf_files or []: 

41 

42 curr_conf = {} 

43 

44 if conf_file.endswith(".ini"): 

45 curr_conf = ini_loader.load(conf_file) 

46 elif conf_file.endswith(".json"): 

47 curr_conf = json_loader.load(conf_file) 

48 elif conf_file.endswith(".xml"): 

49 curr_conf = xml_loader.load(conf_file) 

50 elif conf_file.endswith(".yaml"): 

51 curr_conf = yaml_loader.load(conf_file) 

52 

53 self.conf = {**self.conf, **curr_conf} 

54 

55 # Load configurations from environment variables 

56 # Environment variables configuration overwrites all configuration 

57 # files supplied 

58 self.conf = {**self.conf, **environ_loader.load()} 

59 

60 # Overwrite everything if configuration dictionary is supplied 

61 if conf_dict: 

62 self.conf = {**self.conf, **conf_dict} 

63 

64 def get_handlers(self) -> str: 

65 """Get handlers. 

66 Handlers is a comma separated value of the handler 

67 types to be used. 

68 If handlers is not specified, default to 'stream'. 

69 Currently supported handlers are 'stream' and 'file'. 

70 """ 

71 return self.conf.get("handlers", DEFAULT_HANDLERS).split(",") 

72 

73 def get_datefmt(self) -> str: 

74 """Get date format. 

75 If date format is not specified, default to '%d-%b-%y %H:%M:%S'. 

76 """ 

77 return self.conf.get("datefmt", DEFAULT_DATEFMT) 

78 

79 def get_filename(self) -> str: 

80 """Get log filename. 

81 If log filename is not specified, default to 'conflog.log'. 

82 """ 

83 return self.conf.get("filename", DEFAULT_FILENAME) 

84 

85 def get_filemode(self) -> str: 

86 """Get file mode. 

87 If file mode is not specified, default to 'w'. 

88 """ 

89 return self.conf.get("filemode", DEFAULT_FILEMODE) 

90 

91 def get_format(self) -> str: 

92 """Get log format. 

93 If log format is not specified, default to 

94 '%(asctime)s --> %(name)s - %(levelname)s - %(message)s'. 

95 """ 

96 return self.conf.get("format", DEFAULT_FORMAT) 

97 

98 def get_level(self) -> int: 

99 """Get log level. 

100 If log level is not specified, default to 'info'. 

101 """ 

102 level = self.conf.get("level", DEFAULT_LEVEL) 

103 return LEVELS[level.lower()] 

104 

105 def get_extras(self) -> dict: 

106 """Get extras. 

107 Extras is a dictionary of extra message parameters 

108 to be added to the log. 

109 If extras is not specified, default to an empty dictionary. 

110 """ 

111 extras = self.conf.get("extras", DEFAULT_EXTRAS) 

112 if isinstance(extras, str): 

113 _extras = {} 

114 for pair in extras.split(","): 

115 key, value = pair.split("=") 

116 _extras[key] = value 

117 extras = _extras 

118 return extras