Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

usage.py 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. """
  2. """
  3. # Created on 2014.03.15
  4. #
  5. # Author: Giovanni Cannata
  6. #
  7. # Copyright 2013 - 2018 Giovanni Cannata
  8. #
  9. # This file is part of ldap3.
  10. #
  11. # ldap3 is free software: you can redistribute it and/or modify
  12. # it under the terms of the GNU Lesser General Public License as published
  13. # by the Free Software Foundation, either version 3 of the License, or
  14. # (at your option) any later version.
  15. #
  16. # ldap3 is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU Lesser General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU Lesser General Public License
  22. # along with ldap3 in the COPYING and COPYING.LESSER files.
  23. # If not, see <http://www.gnu.org/licenses/>.
  24. from datetime import datetime, timedelta
  25. from os import linesep
  26. from .exceptions import LDAPMetricsError
  27. from ..utils.log import log, log_enabled, ERROR, BASIC
  28. class ConnectionUsage(object):
  29. """
  30. Collect statistics on connection usage
  31. """
  32. def reset(self):
  33. self.open_sockets = 0
  34. self.closed_sockets = 0
  35. self.wrapped_sockets = 0
  36. self.bytes_transmitted = 0
  37. self.bytes_received = 0
  38. self.messages_transmitted = 0
  39. self.messages_received = 0
  40. self.operations = 0
  41. self.abandon_operations = 0
  42. self.add_operations = 0
  43. self.bind_operations = 0
  44. self.compare_operations = 0
  45. self.delete_operations = 0
  46. self.extended_operations = 0
  47. self.modify_operations = 0
  48. self.modify_dn_operations = 0
  49. self.search_operations = 0
  50. self.unbind_operations = 0
  51. self.referrals_received = 0
  52. self.referrals_followed = 0
  53. self.referrals_connections = 0
  54. self.restartable_failures = 0
  55. self.restartable_successes = 0
  56. self.servers_from_pool = 0
  57. if log_enabled(BASIC):
  58. log(BASIC, 'reset usage metrics')
  59. def __init__(self):
  60. self.initial_connection_start_time = None
  61. self.open_socket_start_time = None
  62. self.connection_stop_time = None
  63. self.last_transmitted_time = None
  64. self.last_received_time = None
  65. self.open_sockets = 0
  66. self.closed_sockets = 0
  67. self.wrapped_sockets = 0
  68. self.bytes_transmitted = 0
  69. self.bytes_received = 0
  70. self.messages_transmitted = 0
  71. self.messages_received = 0
  72. self.operations = 0
  73. self.abandon_operations = 0
  74. self.add_operations = 0
  75. self.bind_operations = 0
  76. self.compare_operations = 0
  77. self.delete_operations = 0
  78. self.extended_operations = 0
  79. self.modify_operations = 0
  80. self.modify_dn_operations = 0
  81. self.search_operations = 0
  82. self.unbind_operations = 0
  83. self.referrals_received = 0
  84. self.referrals_followed = 0
  85. self.referrals_connections = 0
  86. self.restartable_failures = 0
  87. self.restartable_successes = 0
  88. self.servers_from_pool = 0
  89. if log_enabled(BASIC):
  90. log(BASIC, 'instantiated Usage object')
  91. def __repr__(self):
  92. r = 'Connection Usage:' + linesep
  93. r += ' Time: [elapsed: ' + str(self.elapsed_time) + ']' + linesep
  94. r += ' Initial start time: ' + (str(self.initial_connection_start_time.isoformat()) if self.initial_connection_start_time else '') + linesep
  95. r += ' Open socket time: ' + (str(self.open_socket_start_time.isoformat()) if self.open_socket_start_time else '') + linesep
  96. r += ' Last transmitted time: ' + (str(self.last_transmitted_time.isoformat()) if self.last_transmitted_time else '') + linesep
  97. r += ' Last received time: ' + (str(self.last_received_time.isoformat()) if self.last_received_time else '') + linesep
  98. r += ' Close socket time: ' + (str(self.connection_stop_time.isoformat()) if self.connection_stop_time else '') + linesep
  99. r += ' Server:' + linesep
  100. r += ' Servers from pool: ' + str(self.servers_from_pool) + linesep
  101. r += ' Sockets open: ' + str(self.open_sockets) + linesep
  102. r += ' Sockets closed: ' + str(self.closed_sockets) + linesep
  103. r += ' Sockets wrapped: ' + str(self.wrapped_sockets) + linesep
  104. r += ' Bytes: ' + str(self.bytes_transmitted + self.bytes_received) + linesep
  105. r += ' Transmitted: ' + str(self.bytes_transmitted) + linesep
  106. r += ' Received: ' + str(self.bytes_received) + linesep
  107. r += ' Messages: ' + str(self.messages_transmitted + self.messages_received) + linesep
  108. r += ' Transmitted: ' + str(self.messages_transmitted) + linesep
  109. r += ' Received: ' + str(self.messages_received) + linesep
  110. r += ' Operations: ' + str(self.operations) + linesep
  111. r += ' Abandon: ' + str(self.abandon_operations) + linesep
  112. r += ' Bind: ' + str(self.bind_operations) + linesep
  113. r += ' Add: ' + str(self.add_operations) + linesep
  114. r += ' Compare: ' + str(self.compare_operations) + linesep
  115. r += ' Delete: ' + str(self.delete_operations) + linesep
  116. r += ' Extended: ' + str(self.extended_operations) + linesep
  117. r += ' Modify: ' + str(self.modify_operations) + linesep
  118. r += ' ModifyDn: ' + str(self.modify_dn_operations) + linesep
  119. r += ' Search: ' + str(self.search_operations) + linesep
  120. r += ' Unbind: ' + str(self.unbind_operations) + linesep
  121. r += ' Referrals: ' + linesep
  122. r += ' Received: ' + str(self.referrals_received) + linesep
  123. r += ' Followed: ' + str(self.referrals_followed) + linesep
  124. r += ' Connections: ' + str(self.referrals_connections) + linesep
  125. r += ' Restartable tries: ' + str(self.restartable_failures + self.restartable_successes) + linesep
  126. r += ' Failed restarts: ' + str(self.restartable_failures) + linesep
  127. r += ' Successful restarts: ' + str(self.restartable_successes) + linesep
  128. return r
  129. def __str__(self):
  130. return self.__repr__()
  131. def __iadd__(self, other):
  132. if not isinstance(other, ConnectionUsage):
  133. raise LDAPMetricsError('unable to add to ConnectionUsage')
  134. self.open_sockets += other.open_sockets
  135. self.closed_sockets += other.closed_sockets
  136. self.wrapped_sockets += other.wrapped_sockets
  137. self.bytes_transmitted += other.bytes_transmitted
  138. self.bytes_received += other.bytes_received
  139. self.messages_transmitted += other.messages_transmitted
  140. self.messages_received += other.messages_received
  141. self.operations += other.operations
  142. self.abandon_operations += other.abandon_operations
  143. self.add_operations += other.add_operations
  144. self.bind_operations += other.bind_operations
  145. self.compare_operations += other.compare_operations
  146. self.delete_operations += other.delete_operations
  147. self.extended_operations += other.extended_operations
  148. self.modify_operations += other.modify_operations
  149. self.modify_dn_operations += other.modify_dn_operations
  150. self.search_operations += other.search_operations
  151. self.unbind_operations += other.unbind_operations
  152. self.referrals_received += other.referrals_received
  153. self.referrals_followed += other.referrals_followed
  154. self.referrals_connections += other.referrals_connections
  155. self.restartable_failures += other.restartable_failures
  156. self.restartable_successes += other.restartable_successes
  157. self.servers_from_pool += other.servers_from_pool
  158. return self
  159. def update_transmitted_message(self, message, length):
  160. self.last_transmitted_time = datetime.now()
  161. self.bytes_transmitted += length
  162. self.operations += 1
  163. self.messages_transmitted += 1
  164. if message['type'] == 'abandonRequest':
  165. self.abandon_operations += 1
  166. elif message['type'] == 'addRequest':
  167. self.add_operations += 1
  168. elif message['type'] == 'bindRequest':
  169. self.bind_operations += 1
  170. elif message['type'] == 'compareRequest':
  171. self.compare_operations += 1
  172. elif message['type'] == 'delRequest':
  173. self.delete_operations += 1
  174. elif message['type'] == 'extendedReq':
  175. self.extended_operations += 1
  176. elif message['type'] == 'modifyRequest':
  177. self.modify_operations += 1
  178. elif message['type'] == 'modDNRequest':
  179. self.modify_dn_operations += 1
  180. elif message['type'] == 'searchRequest':
  181. self.search_operations += 1
  182. elif message['type'] == 'unbindRequest':
  183. self.unbind_operations += 1
  184. else:
  185. if log_enabled(ERROR):
  186. log(ERROR, 'unable to collect usage for unknown message type <%s>', message['type'])
  187. raise LDAPMetricsError('unable to collect usage for unknown message type')
  188. def update_received_message(self, length):
  189. self.last_received_time = datetime.now()
  190. self.bytes_received += length
  191. self.messages_received += 1
  192. def start(self, reset=True):
  193. if reset:
  194. self.reset()
  195. self.open_socket_start_time = datetime.now()
  196. self.connection_stop_time = None
  197. if not self.initial_connection_start_time:
  198. self.initial_connection_start_time = self.open_socket_start_time
  199. if log_enabled(BASIC):
  200. log(BASIC, 'start collecting usage metrics')
  201. def stop(self):
  202. if self.open_socket_start_time:
  203. self.connection_stop_time = datetime.now()
  204. if log_enabled(BASIC):
  205. log(BASIC, 'stop collecting usage metrics')
  206. @property
  207. def elapsed_time(self):
  208. if self.connection_stop_time:
  209. return self.connection_stop_time - self.open_socket_start_time
  210. else:
  211. return (datetime.now() - self.open_socket_start_time) if self.open_socket_start_time else timedelta(0)