Package virtualization :: Module batching_log_notifier
[hide private]
[frames] | no frames]

Source Code for Module virtualization.batching_log_notifier

  1  # 
  2  # Copyright (c) 2008--2013 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU General Public License, 
  5  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  6  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  8  # along with this software; if not, see 
  9  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 10  # 
 11  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 12  # granted to use or replicate Red Hat trademarks that are incorporated 
 13  # in this software or its documentation. 
 14  # 
 15   
 16  # 
 17  # This module provides the BatchingLogNotifier class, which has the ability to 
 18  # queue up log messages and periodically forward them in a batch to the server. 
 19  # 
 20   
 21  from threading import Thread, Event, Lock 
 22   
 23  ############################################################################### 
 24  # Constants 
 25  ############################################################################### 
 26   
 27  POLL_INTERVAL = 5  # Seconds 
 28   
 29  ############################################################################### 
 30  # BatchingLogNotifier Class 
 31  ############################################################################### 
 32   
33 -class BatchingLogNotifier:
34
35 - def __init__(self, batch_notify_handler):
36 self.__log_message_queue = LockableLogMessageQueue() 37 self.__notify_thread = NotifyThread(self.__log_message_queue, 38 batch_notify_handler)
39
40 - def add_log_message(self, log_message):
41 self.__log_message_queue.lock() 42 try: 43 self.__log_message_queue.add(log_message) 44 finally: 45 self.__log_message_queue.unlock()
46
47 - def start(self):
48 self.__notify_thread.start()
49
50 - def stop(self):
51 self.__notify_thread.stop() 52 if self.__notify_thread.isAlive(): 53 self.__notify_thread.join()
54 55 ############################################################################### 56 # LogQueue Class 57 ############################################################################### 58
59 -class LockableLogMessageQueue:
60
61 - def __init__(self):
62 self.__log_message_queue = [] 63 self.__queue_lock = Lock()
64
65 - def lock(self):
66 self.__queue_lock.acquire()
67
68 - def unlock(self):
69 self.__queue_lock.release()
70
71 - def add(self, log_message):
72 self.__log_message_queue.append(log_message)
73
74 - def pop(self):
75 first_item = self.__log_message_queue[0] 76 self.__log_message_queue.remove(first_item) 77 return first_item
78
79 - def is_empty(self):
80 return len(self.__log_message_queue) == 0
81 82 ############################################################################### 83 # BatchNotifyHandler Class 84 ############################################################################### 85
86 -class BatchNotifyHandler:
87 """ 88 This class provides a generic mechanism for processing logging callbacks. 89 This is just a stub class, which should be inherited by anyone who wants 90 to respond to logging events. 91 """ 92
93 - def __init__(self):
94 pass
95
96 - def batch_began():
97 pass
98
99 - def log_message_discovered(log_message):
100 pass
101
102 - def batch_ended():
103 pass
104 105 ############################################################################### 106 # NotifyThread Class 107 ############################################################################### 108
109 -class NotifyThread(Thread):
110 111 ########################################################################### 112 # Public Interface 113 ########################################################################### 114
115 - def __init__(self, log_message_queue, batch_notify_handler):
116 Thread.__init__(self) 117 self.__log_message_queue = log_message_queue 118 self.__batch_notify_handler = batch_notify_handler 119 self.__stop_event = Event()
120
121 - def run(self):
122 # First, clear the stop event in case it was already set. 123 self.__stop_event.clear() 124 125 # Enter the main loop, flushing the queue every interval. 126 while not self.__stop_event.isSet(): 127 self.__flush_log_message_queue() 128 self.__stop_event.wait(POLL_INTERVAL) 129 130 # We've been signaled to stop, but flush the queue one more time before 131 # exiting. 132 self.__flush_log_message_queue()
133
134 - def stop(self):
135 self.__stop_event.set()
136 137 ########################################################################### 138 # Helper Methods 139 ########################################################################### 140
142 self.__log_message_queue.lock() 143 try: 144 if not self.__log_message_queue.is_empty(): 145 self.__batch_notify_handler.batch_began() 146 while not self.__log_message_queue.is_empty(): 147 log_message = self.__log_message_queue.pop() 148 self.__batch_notify_handler.log_message_discovered( 149 log_message) 150 self.__batch_notify_handler.batch_ended() 151 finally: 152 self.__log_message_queue.unlock()
153 154 if __name__ == "__main__": 155 notifier = BatchingLogNotifier() 156 notifier.start() 157