Yann Weber 8 лет назад
Родитель
Сommit
8659e91f43

+ 8
- 2
globconf.d/loggers.ini Просмотреть файл

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

+ 12
- 8
lodel/logger.py Просмотреть файл

@@ -16,12 +16,15 @@ logger = logging.getLogger()
16 16
 
17 17
 # Setting options from Lodel.settings.Settings.logging
18 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 22
     #logging.captureWarnings(True) # Log warnings
21 23
 
22 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 29
 ##@brief Add an handler, identified by a name, to a given logger 
27 30
 #
@@ -38,10 +41,11 @@ def add_handler(name, logging_opt):
38 41
     logger = logging.getLogger()
39 42
     if name in handlers:
40 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 50
         handler = logging.handlers.RotatingFileHandler(
47 51
                                         logging_opt['filename'],
@@ -94,7 +98,7 @@ def log(lvl, msg, *args, **kwargs):
94 98
     extra = {
95 99
         '_pathname': os.path.relpath(
96 100
                                         caller[0],
97
-                                        start=Settings.lodel2_lib_path
101
+                                        start=Settings.lib_path
98 102
         ), # os.path.relpath add another small overhead
99 103
         '_lineno': caller[1],
100 104
         '_funcName': caller[2],

+ 0
- 1
lodel/plugin/plugins.py Просмотреть файл

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

+ 9
- 6
lodel/settings/__init__.py Просмотреть файл

@@ -34,11 +34,14 @@
34 34
 # </pre>
35 35
 #
36 36
 
37
+
38
+import warnings
37 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 Просмотреть файл

@@ -5,6 +5,7 @@ import os
5 5
 import configparser
6 6
 import copy
7 7
 import warnings
8
+import types # for dynamic bindings
8 9
 from collections import namedtuple
9 10
 
10 11
 from lodel.plugin.plugins import Plugins, PluginError
@@ -21,6 +22,7 @@ PYTHON_SYS_LIB_PATH = '/usr/local/lib/python{major}.{minor}/'.format(
21 22
 
22 23
                                                 major = sys.version_info.major,
23 24
                                                 minor = sys.version_info.minor)
25
+
24 26
 ##@brief Handles configuration load etc.
25 27
 #
26 28
 # To see howto bootstrap Settings and use it in lodel instance see 
@@ -71,7 +73,7 @@ class Settings(object):
71 73
     ##@brief Should be called only by the boostrap classmethod
72 74
     # @param conf_file str : Path to the global lodel2 configuration file
73 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 77
         self.__confs = dict()
76 78
         self.__conf_dir = conf_dir
77 79
         self.__load_bootstrap_conf(conf_file)
@@ -98,6 +100,14 @@ class Settings(object):
98 100
     ##@brief This method handlers Settings instance bootstraping
99 101
     def __bootstrap(self):
100 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 111
         plugins_opt_specs = lodel2_specs['lodel2']['plugins']
102 112
 
103 113
         # Init the settings loader
@@ -129,12 +139,16 @@ class Settings(object):
129 139
         res = copy.copy(specs.pop())
130 140
         for spec in specs:
131 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 144
                 if section not in res:
133 145
                     res[section] = dict()
134 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 149
                     if kname in res[section]:
136 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 152
         return res
139 153
     
140 154
     ##@brief Populate the Settings instance with options values fecthed with the loader from merged specs
@@ -152,11 +166,11 @@ class Settings(object):
152 166
             for section in loader.getsection(preffix, 'default'): #WARNING : hardcoded default section
153 167
                 specs[section] = copy.copy(specs[vsec])
154 168
             del(specs[vsec])
155
-        # Fetching valuds for sections
169
+        # Fetching values for sections
156 170
         for section in specs:
157 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 174
                 if section not in self.__confs:
161 175
                     self.__confs[section] = dict()
162 176
                 self.__confs[section][kname] = loader.getoption(section, kname, validator, default)
@@ -191,17 +205,17 @@ class Settings(object):
191 205
                     raise SettingsError("Duplicated key for '%s.%s'" % (section_name, kname))
192 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 211
         curname = 'root'
198
-        nodename = 'Root'
199
-        cur = self.__confs
212
+        nodename = 'Lodel2Settings'
213
+        cur = section_tree
200 214
         while True:
201
-            visited.append(cur)
215
+            visited.add(nodename)
202 216
             left = [    (kname, cur[kname])
203 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 220
             if len(left) == 0:
207 221
                 name, leaf = path.pop()
@@ -213,6 +227,7 @@ class Settings(object):
213 227
                 else:
214 228
                     path[-1][1][name] = self.__tree2namedtuple(leaf,typename)
215 229
                 nodename = '.'.join(nodename.split('.')[:-1])
230
+                cur = path[-1][1]
216 231
             else:
217 232
                 curname, cur = left[0]
218 233
                 path.append( (curname, cur) )

+ 0
- 1
lodel/settings/settings_loader.py Просмотреть файл

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

+ 10
- 4
lodel/settings/validator.py Просмотреть файл

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

+ 4
- 0
tests/loader_utils.py Просмотреть файл

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

Загрузка…
Отмена
Сохранить