Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/local/bin/python 

2# encoding: utf-8 

3""" 

4*Logger setup for python projects* 

5 

6:Author: 

7 David Young 

8 

9:Date Created: 

10 October 10, 2012 

11""" 

12from builtins import object 

13import os 

14import sys 

15import logging 

16from logging import handlers 

17 

18 

19def console_logger( 

20 level="WARNING" 

21): 

22 """ 

23 *Setup and return a console logger* 

24 

25 **Key Arguments:** 

26 - ``level`` -- the level of logging required 

27 

28 **Return:** 

29 - ``logger`` -- the console logger 

30 

31 **Usage:** 

32 .. code-block:: python  

33 

34 from fundamentals import logs 

35 log = logs.console_logger( 

36 level="DEBUG" 

37 ) 

38 log.debug("Testing console logger") 

39 """ 

40 ################ > IMPORTS ################ 

41 ## STANDARD LIB ## 

42 

43 import logging 

44 import logging.config 

45 ## THIRD PARTY ## 

46 import yaml 

47 try: 

48 yaml.warnings({'YAMLLoadWarning': False}) 

49 except: 

50 pass 

51 ## LOCAL APPLICATION ## 

52 

53 # SETUP LOGGING 

54 loggerConfig = """ 

55 version: 1 

56 formatters: 

57 console_style: 

58 format: '* %(asctime)s - %(levelname)s: %(pathname)s:%(funcName)s:%(lineno)d > %(message)s' 

59 datefmt: '%H:%M:%S' 

60 handlers: 

61 console: 

62 class: logging.StreamHandler 

63 level: """ + level + """ 

64 formatter: console_style 

65 stream: ext://sys.stdout 

66 root: 

67 level: """ + level + """ 

68 handlers: [console]""" 

69 

70 logging.config.dictConfig(yaml.load(loggerConfig)) 

71 logger = logging.getLogger(__name__) 

72 

73 return logger 

74 

75 

76def setup_dryx_logging(yaml_file): 

77 """ 

78 *setup dryx style python logging* 

79 

80 **Key Arguments:** 

81 - ``level`` -- the level of logging required 

82 

83 **Return:** 

84 - ``logger`` -- the console logger 

85 

86 **Usage:** 

87 .. code-block:: python  

88 

89 from fundamentals import logs 

90 log = logs.setup_dryx_logging( 

91 yaml_file="/Users/Dave/.config/fundamentals/fundamentals.yaml" 

92 ) 

93 log.error("test error") 

94 

95 Here is an example of the settings in the yaml file: 

96 

97 .. code-block:: yaml 

98 

99 version: 1 

100 

101 logging settings: 

102 formatters: 

103 file_style: 

104 format: '* %(asctime)s - %(name)s - %(levelname)s (%(pathname)s > %(funcName)s > %(lineno)d) - %(message)s ' 

105 datefmt: '%Y/%m/%d %H:%M:%S' 

106 console_style: 

107 format: '* %(asctime)s - %(levelname)s: %(pathname)s:%(funcName)s:%(lineno)d > %(message)s' 

108 datefmt: '%H:%M:%S' 

109 html_style: 

110 format: '<div id="row" class="%(levelname)s"><span class="date">%(asctime)s</span> <span class="label">file:</span><span class="filename">%(filename)s</span> <span class="label">method:</span><span class="funcName">%(funcName)s</span> <span class="label">line#:</span><span class="lineno">%(lineno)d</span> <span class="pathname">%(pathname)s</span> <div class="right"><span class="message">%(message)s</span><span class="levelname">%(levelname)s</span></div></div>' 

111 datefmt: '%Y-%m-%d <span class= "time">%H:%M <span class= "seconds">%Ss</span></span>' 

112 handlers: 

113 console: 

114 class: logging.StreamHandler 

115 level: DEBUG 

116 formatter: console_style 

117 stream: ext://sys.stdout 

118 file: 

119 class: logging.handlers.GroupWriteRotatingFileHandler 

120 level: WARNING 

121 formatter: file_style 

122 filename: /Users/Dave/.config/fundamentals/fundamentals.log 

123 mode: w+ 

124 maxBytes: 102400 

125 backupCount: 1 

126 root: 

127 level: WARNING 

128 handlers: [file,console] 

129 

130 """ 

131 import logging 

132 import logging.config 

133 import yaml 

134 try: 

135 from StringIO import StringIO 

136 except ImportError: 

137 from io import StringIO 

138 from os.path import expanduser 

139 

140 # IMPORT CUSTOM HANDLER THAT ALLOWS GROUP WRITING 

141 handlers.GroupWriteRotatingFileHandler = GroupWriteRotatingFileHandler 

142 

143 # GET CONTENT OF YAML FILE AND REPLACE ~ WITH HOME DIRECTORY PATH 

144 with open(yaml_file) as f: 

145 content = f.read() 

146 home = expanduser("~") 

147 content = content.replace("~/", home + "/") 

148 stream = StringIO(content) 

149 yamlContent = yaml.load(stream) 

150 stream.close() 

151 

152 # USE THE LOGGING SETTINGS SECTION OF THE SETTINGS DICTIONARY FILE IF THERE IS ONE 

153 # OTHERWISE ASSUME THE FILE CONTAINS ONLY LOGGING SETTINGS 

154 if "logging settings" in yamlContent: 

155 yamlContent = yamlContent["logging settings"] 

156 yamlContent["version"] = 1 

157 

158 logging.config.dictConfig(yamlContent) 

159 # SET THE ROOT LOGGER 

160 logger = logging.getLogger(__name__) 

161 

162 logging.captureWarnings(True) 

163 

164 return logger 

165 

166 

167class GroupWriteRotatingFileHandler(handlers.RotatingFileHandler): 

168 

169 """ 

170 *rotating file handler for logging* 

171 """ 

172 

173 def doRollover(self): 

174 """ 

175 *Override base class method to make the new log file group writable.* 

176 """ 

177 # Rotate the file first. 

178 handlers.RotatingFileHandler.doRollover(self) 

179 

180 # Add group write to the current permissions. 

181 currMode = os.stat(self.baseFilename).st_mode 

182 os.chmod(self.baseFilename, currMode | stat.S_IWGRP | 

183 stat.S_IRGRP | stat.S_IWOTH | stat.S_IROTH) 

184 

185 

186class GroupWriteRotatingFileHandler(handlers.RotatingFileHandler): 

187 

188 """ 

189 *rotating file handler for logging* 

190 """ 

191 

192 def _open(self): 

193 prevumask = os.umask(0) 

194 rtv = logging.handlers.RotatingFileHandler._open(self) 

195 os.umask(prevumask) 

196 return rtv 

197 

198 

199class emptyLogger(object): 

200 """ 

201 *A fake logger object so user can set ``log=False`` if required* 

202 

203 **Usage:** 

204 .. code-block:: python  

205 

206 if log == False: 

207 from fundamentals.logs import emptyLogger 

208 log = emptyLogger() 

209 """ 

210 

211 def info(self, argu): 

212 pass 

213 

214 def error(self, argu): 

215 pass 

216 

217 def debug(self, argu): 

218 pass 

219 

220 def critical(self, argu): 

221 pass 

222 

223 def warning(self, argu): 

224 pass