1 # Copyright 2018 ke liang <lokyse@163.com>.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
18 from logging import config
19 from typing import Dict, Optional, Any
20 from deprecated import deprecated
21 from warnings import warn
23 from watchdog.observers import Observer
24 from watchdog.events import FileSystemEventHandler, FileSystemEvent
26 from onaplogging.utils.tools import yaml_to_dict
29 __all__ = ['patch_loggingYaml'] # rename after the deprecated name changed
32 class FileEventHandlers(FileSystemEventHandler):
33 """Handler of the events in the file system.
35 Use it to keep and eye on files in the file system.
38 watchdog.events.FileSystemEventHandler
40 filepath : The path to the file to be monitored.
41 current_config : Defaults to None.
43 filepath : The path to the file to be monitored.
52 def current_config(self):
54 return self.currentConfig # deprecated, replace with _current_config
57 def filepath(self, value):
59 self._filepath = value
61 @current_config.setter
62 def current_config(self, value):
63 # type: (Dict) -> Dict
64 self.currentConfig = value
66 def __init__(self, filepath): # type: (str)
67 warn("Attribute currentConfig will be replaced with property"
68 "current_config. Use current_config instead.")
70 FileSystemEventHandler.__init__(self)
72 self.filepath = filepath
73 self.current_config = None
75 def on_modified(self, event):
76 # type: (FileSystemEvent) -> None
77 """Configuration file actualizer.
79 When an event occurs in the file system the hadnler's filepath
80 is taken to update the configuration file. If the actualization
81 of the config file fails it will keep the old config file.
84 event : Represents an event on the file system.
86 Exception : If the actualization of the config file fails.
89 if event.src_path == self.filepath:
91 new_config = yaml_to_dict(self.filepath)
92 print("Reloading logging configuration file %s "
95 config.dictConfig(new_config)
96 self.current_config = new_config
100 print("Reuse the old configuration to avoid this"
101 "exception terminate program")
103 if self.current_config:
104 config.dictConfig(self.current_config)
107 def _yamlConfig(filepath=None, watchDog=None):
108 # type: (Optional[str], Optional[Any]) -> None
109 """YAML configuration file loader.
111 Use it to monitor a file status in a directory. The watchdog can monitor
112 a YAML file status looking for modifications. If the watchdog is provided
113 start observing the directory. The new configuration file is saved as
114 current for the later reuse.
117 filepath : The path to the file to be monitored. Defaults to None.
118 watchDog : Monitors a YAML file identifier status. Defaults to None.
121 OSError : If the requested file in the filepath is not a file.
122 Exception : If watchdog observer setup or YAML coversion fails.
125 is_file = os.path.isfile(filepath)
128 raise OSError("%s is not a file" % (filepath))
130 dirpath = os.path.dirname(filepath)
134 dictConfig = yaml_to_dict(filepath)
135 # Dev note: Will send a notify then we could reload logging config
137 observer = Observer()
138 event_handler = FileEventHandlers(filepath)
139 observer.schedule(event_handler=event_handler,
142 observer.setDaemon(True)
145 config.dictConfig(dictConfig)
148 event_handler.currentConfig = dictConfig
151 traceback.print_exc()
154 def patch_logging_yaml():
156 """YAML configuration patch.
158 Adds the YAML configuration file loader
159 to logging.config module during runtime.
161 config.yamlConfig = _yamlConfig
164 @deprecated(reason="Will be removed. Call patch_logging_yaml() instead.")
165 def patch_loggingYaml():
166 """See patch_logging_yaml()"""