Browse Source

Fixing settings & logger

Yann Weber 9 years ago
parent
commit
8659e91f43

+ 8
- 2
globconf.d/loggers.ini View File

1
-[lodel2.logging.default]
1
+[lodel2.logging.stderr]
2
+level = INFO
3
+context = False
4
+
5
+[lodel2.logging.logfile]
2
 level = DEBUG
6
 level = DEBUG
3
 context = True
7
 context = True
4
-filename = -
8
+filename = /tmp/lodel2.log
9
+maxbytes = 4096
10
+backupcount = 1

+ 12
- 8
lodel/logger.py View File

16
 
16
 
17
 # Setting options from Lodel.settings.Settings.logging
17
 # Setting options from Lodel.settings.Settings.logging
18
 def __init_from_settings():
18
 def __init_from_settings():
19
-    # Disabled, because the custom format raises error (enable to give the _ preffixed arguments to logger resulting into a KeyError exception )
19
+    # capture warning disabled, because the custom format raises error (unable
20
+    # to give the _ preffixed arguments to logger resulting into a KeyError
21
+    # exception )
20
     #logging.captureWarnings(True) # Log warnings
22
     #logging.captureWarnings(True) # Log warnings
21
 
23
 
22
     logger.setLevel(logging.DEBUG)
24
     logger.setLevel(logging.DEBUG)
23
-    for name, logging_opt in Settings.logging.items():
24
-        add_handler(name, logging_opt)
25
+    for name in Settings.logging._fields:
26
+        add_handler(name, getattr(Settings.logging, name))
27
+    
25
 
28
 
26
 ##@brief Add an handler, identified by a name, to a given logger 
29
 ##@brief Add an handler, identified by a name, to a given logger 
27
 #
30
 #
38
     logger = logging.getLogger()
41
     logger = logging.getLogger()
39
     if name in handlers:
42
     if name in handlers:
40
         raise KeyError("A handler named '%s' allready exists")
43
         raise KeyError("A handler named '%s' allready exists")
41
-
42
-    if 'filename' in logging_opt:
43
-        maxBytes = (1024 * 10) if 'maxBytes' not in logging_opt else logging_opt['maxBytes']
44
-        backupCount = 10 if 'backupCount' not in logging_opt else logging_opt['backupCount']
44
+    
45
+    logging_opt = logging_opt._asdict()
46
+    if 'filename' in logging_opt and logging_opt['filename'] is not None:
47
+        maxBytes = (1024 * 10) if 'maxbytes' not in logging_opt else logging_opt['maxbytes']
48
+        backupCount = 10 if 'backupcount' not in logging_opt else logging_opt['backupcount']
45
 
49
 
46
         handler = logging.handlers.RotatingFileHandler(
50
         handler = logging.handlers.RotatingFileHandler(
47
                                         logging_opt['filename'],
51
                                         logging_opt['filename'],
94
     extra = {
98
     extra = {
95
         '_pathname': os.path.relpath(
99
         '_pathname': os.path.relpath(
96
                                         caller[0],
100
                                         caller[0],
97
-                                        start=Settings.lodel2_lib_path
101
+                                        start=Settings.lib_path
98
         ), # os.path.relpath add another small overhead
102
         ), # os.path.relpath add another small overhead
99
         '_lineno': caller[1],
103
         '_lineno': caller[1],
100
         '_funcName': caller[2],
104
         '_funcName': caller[2],

+ 0
- 1
lodel/plugin/plugins.py View File

45
         path = None
45
         path = None
46
         for cur_path in cls._plugin_directories:
46
         for cur_path in cls._plugin_directories:
47
             plugin_path = os.path.join(cur_path, plugin_name)+'/'
47
             plugin_path = os.path.join(cur_path, plugin_name)+'/'
48
-            print(plugin_path)
49
             if os.path.isdir(plugin_path):
48
             if os.path.isdir(plugin_path):
50
                 return plugin_path
49
                 return plugin_path
51
         raise NameError("No plugin named '%s'" % plugin_name)
50
         raise NameError("No plugin named '%s'" % plugin_name)

+ 9
- 6
lodel/settings/__init__.py View File

34
 # </pre>
34
 # </pre>
35
 #
35
 #
36
 
36
 
37
+
38
+import warnings
37
 from lodel.settings.settings import Settings as SettingsHandler
39
 from lodel.settings.settings import Settings as SettingsHandler
38
 
40
 
39
-##@brief Bootstraped instance
40
-settings = SettingsHandler.bootstrap()
41
-if settings is not None:
42
-    ##@brief Exposed variable that represents configurations values in a
43
-    # namedtuple tree
44
-    Settings = settings.confs
41
+settings = SettingsHandler.instance
42
+
43
+if settings is None:
44
+    Settings = None
45
+else:
46
+    Settings = settings.confs.lodel2
47
+

+ 26
- 11
lodel/settings/settings.py View File

5
 import configparser
5
 import configparser
6
 import copy
6
 import copy
7
 import warnings
7
 import warnings
8
+import types # for dynamic bindings
8
 from collections import namedtuple
9
 from collections import namedtuple
9
 
10
 
10
 from lodel.plugin.plugins import Plugins, PluginError
11
 from lodel.plugin.plugins import Plugins, PluginError
21
 
22
 
22
                                                 major = sys.version_info.major,
23
                                                 major = sys.version_info.major,
23
                                                 minor = sys.version_info.minor)
24
                                                 minor = sys.version_info.minor)
25
+
24
 ##@brief Handles configuration load etc.
26
 ##@brief Handles configuration load etc.
25
 #
27
 #
26
 # To see howto bootstrap Settings and use it in lodel instance see 
28
 # To see howto bootstrap Settings and use it in lodel instance see 
71
     ##@brief Should be called only by the boostrap classmethod
73
     ##@brief Should be called only by the boostrap classmethod
72
     # @param conf_file str : Path to the global lodel2 configuration file
74
     # @param conf_file str : Path to the global lodel2 configuration file
73
     # @param conf_dir str : Path to the conf directory
75
     # @param conf_dir str : Path to the conf directory
74
-    def __init__(self, conf_file = '/etc/lodel2/lodel2.conf', conf_dir = 'conf.d'):
76
+    def __init__(self, conf_file, conf_dir):
75
         self.__confs = dict()
77
         self.__confs = dict()
76
         self.__conf_dir = conf_dir
78
         self.__conf_dir = conf_dir
77
         self.__load_bootstrap_conf(conf_file)
79
         self.__load_bootstrap_conf(conf_file)
98
     ##@brief This method handlers Settings instance bootstraping
100
     ##@brief This method handlers Settings instance bootstraping
99
     def __bootstrap(self):
101
     def __bootstrap(self):
100
         lodel2_specs = LODEL2_CONF_SPECS
102
         lodel2_specs = LODEL2_CONF_SPECS
103
+        for section in lodel2_specs:
104
+            if section.lower() != section:
105
+                raise SettingsError("Only lower case are allowed in section name (thank's ConfigParser...)")
106
+            for kname in lodel2_specs[section]:
107
+                if kname.lower() != kname:
108
+                    raise SettingsError("Only lower case are allowed in section name (thank's ConfigParser...)")
109
+                
110
+                
101
         plugins_opt_specs = lodel2_specs['lodel2']['plugins']
111
         plugins_opt_specs = lodel2_specs['lodel2']['plugins']
102
 
112
 
103
         # Init the settings loader
113
         # Init the settings loader
129
         res = copy.copy(specs.pop())
139
         res = copy.copy(specs.pop())
130
         for spec in specs:
140
         for spec in specs:
131
             for section in spec:
141
             for section in spec:
142
+                if section.lower() != section:
143
+                    raise SettingsError("Only lower case are allowed in section name (thank's ConfigParser...)")
132
                 if section not in res:
144
                 if section not in res:
133
                     res[section] = dict()
145
                     res[section] = dict()
134
                 for kname in spec[section]:
146
                 for kname in spec[section]:
147
+                    if kname.lower() != kname:
148
+                        raise SettingsError("Only lower case are allowed in section name (thank's ConfigParser...)")
135
                     if kname in res[section]:
149
                     if kname in res[section]:
136
                         raise SettingsError("Duplicated key '%s' in section '%s'" % (kname, section))
150
                         raise SettingsError("Duplicated key '%s' in section '%s'" % (kname, section))
137
-                    res[section][kname] = copy.copy(spec[section][kname])
151
+                    res[section.lower()][kname] = copy.copy(spec[section][kname])
138
         return res
152
         return res
139
     
153
     
140
     ##@brief Populate the Settings instance with options values fecthed with the loader from merged specs
154
     ##@brief Populate the Settings instance with options values fecthed with the loader from merged specs
152
             for section in loader.getsection(preffix, 'default'): #WARNING : hardcoded default section
166
             for section in loader.getsection(preffix, 'default'): #WARNING : hardcoded default section
153
                 specs[section] = copy.copy(specs[vsec])
167
                 specs[section] = copy.copy(specs[vsec])
154
             del(specs[vsec])
168
             del(specs[vsec])
155
-        # Fetching valuds for sections
169
+        # Fetching values for sections
156
         for section in specs:
170
         for section in specs:
157
             for kname in specs[section]:
171
             for kname in specs[section]:
158
-                validator = specs[section][kname][0]
159
-                default = specs[section][kname][1]
172
+                validator = specs[section][kname][1]
173
+                default = specs[section][kname][0]
160
                 if section not in self.__confs:
174
                 if section not in self.__confs:
161
                     self.__confs[section] = dict()
175
                     self.__confs[section] = dict()
162
                 self.__confs[section][kname] = loader.getoption(section, kname, validator, default)
176
                 self.__confs[section][kname] = loader.getoption(section, kname, validator, default)
191
                     raise SettingsError("Duplicated key for '%s.%s'" % (section_name, kname))
205
                     raise SettingsError("Duplicated key for '%s.%s'" % (section_name, kname))
192
                 cur[kname] = kval
206
                 cur[kname] = kval
193
 
207
 
194
-        path = [ ('root', self.__confs) ]
195
-        visited = list()
208
+        path = [ ('root', section_tree) ]
209
+        visited = set()
196
         
210
         
197
         curname = 'root'
211
         curname = 'root'
198
-        nodename = 'Root'
199
-        cur = self.__confs
212
+        nodename = 'Lodel2Settings'
213
+        cur = section_tree
200
         while True:
214
         while True:
201
-            visited.append(cur)
215
+            visited.add(nodename)
202
             left = [    (kname, cur[kname])
216
             left = [    (kname, cur[kname])
203
                         for kname in cur
217
                         for kname in cur
204
-                        if cur[kname] not in visited and isinstance(cur[kname], dict)
218
+                        if nodename+'.'+kname.title() not in visited and isinstance(cur[kname], dict)
205
                     ]
219
                     ]
206
             if len(left) == 0:
220
             if len(left) == 0:
207
                 name, leaf = path.pop()
221
                 name, leaf = path.pop()
213
                 else:
227
                 else:
214
                     path[-1][1][name] = self.__tree2namedtuple(leaf,typename)
228
                     path[-1][1][name] = self.__tree2namedtuple(leaf,typename)
215
                 nodename = '.'.join(nodename.split('.')[:-1])
229
                 nodename = '.'.join(nodename.split('.')[:-1])
230
+                cur = path[-1][1]
216
             else:
231
             else:
217
                 curname, cur = left[0]
232
                 curname, cur = left[0]
218
                 path.append( (curname, cur) )
233
                 path.append( (curname, cur) )

+ 0
- 1
lodel/settings/settings_loader.py View File

37
                             conf[sect][param] = config[sect][param]
37
                             conf[sect][param] = config[sect][param]
38
                             if sect != 'DEFAULT': self.__conf_sv[sect + ':' + param]=f_ini
38
                             if sect != 'DEFAULT': self.__conf_sv[sect + ':' + param]=f_ini
39
                         else:
39
                         else:
40
-                            print(conf)
41
                             raise SettingsError("Key attribute already defined : %s " % sect + '.' + param + ' dans ' + f_ini + ' et ' + self.__conf_sv[sect + ':' + param])                        
40
                             raise SettingsError("Key attribute already defined : %s " % sect + '.' + param + ' dans ' + f_ini + ' et ' + self.__conf_sv[sect + ':' + param])                        
42
                 else:
41
                 else:
43
                     opts={}
42
                     opts={}

+ 10
- 4
lodel/settings/validator.py View File

12
 # @note to get a list of registered default validators just run
12
 # @note to get a list of registered default validators just run
13
 # <pre>$ python scripts/settings_validator.py</pre>
13
 # <pre>$ python scripts/settings_validator.py</pre>
14
 
14
 
15
+##@brief Exception class that should be raised when a validation fails
15
 class SettingsValidationError(Exception):
16
 class SettingsValidationError(Exception):
16
     pass
17
     pass
17
 
18
 
122
     if not isinstance(value, str):
123
     if not isinstance(value, str):
123
         raise SettingsValidationError("A string was expected but got '%s' " % value)
124
         raise SettingsValidationError("A string was expected but got '%s' " % value)
124
     if value == '-':
125
     if value == '-':
125
-        return sys.stderr
126
+        return None
126
     return value
127
     return value
127
 
128
 
128
 ##@brief Boolean value validator callback
129
 ##@brief Boolean value validator callback
129
 def boolean_val(value):
130
 def boolean_val(value):
130
-    if not (value is True) and not (value is False):
131
+    if value.strip().lower() == 'true' or value.strip() == '1':
132
+        value = True
133
+    elif value.strip().lower() == 'false' or value.strip() == '0':
134
+        value = False
135
+    else:
131
         raise SettingsValidationError("A boolean was expected but got '%s' " % value)
136
         raise SettingsValidationError("A boolean was expected but got '%s' " % value)
132
     return bool(value)
137
     return bool(value)
133
 
138
 
141
     valids = ['DEBUG', 'INFO', 'SECURITY', 'ERROR', 'CRITICAL']
146
     valids = ['DEBUG', 'INFO', 'SECURITY', 'ERROR', 'CRITICAL']
142
     if value.upper() not in valids:
147
     if value.upper() not in valids:
143
         raise SettingsValidationError("The value '%s' is not a valid loglevel")
148
         raise SettingsValidationError("The value '%s' is not a valid loglevel")
149
+    return value.upper()
144
 
150
 
145
 #
151
 #
146
 #   Default validators registration
152
 #   Default validators registration
212
                         SettingValidator('bool')),
218
                         SettingValidator('bool')),
213
         'filename': (   None,
219
         'filename': (   None,
214
                         SettingValidator('errfile', none_is_valid = True)),
220
                         SettingValidator('errfile', none_is_valid = True)),
215
-        'backupCount': (    None,
221
+        'backupcount': (    None,
216
                             SettingValidator('int', none_is_valid = True)),
222
                             SettingValidator('int', none_is_valid = True)),
217
-        'maxBytes': (   None,
223
+        'maxbytes': (   None,
218
                         SettingValidator('int', none_is_valid = True)),
224
                         SettingValidator('int', none_is_valid = True)),
219
     }
225
     }
220
 }
226
 }

+ 4
- 0
tests/loader_utils.py View File

4
 # This file should be imported in every tests files
4
 # This file should be imported in every tests files
5
 #
5
 #
6
 
6
 
7
+import imp
8
+import lodel.settings
7
 from lodel.settings.settings import Settings
9
 from lodel.settings.settings import Settings
8
 Settings.bootstrap(conf_file = 'settings_local.ini', conf_dir = 'globconf.d')
10
 Settings.bootstrap(conf_file = 'settings_local.ini', conf_dir = 'globconf.d')
11
+
12
+imp.reload(lodel.settings)

Loading…
Cancel
Save