dovecot.chart.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # -*- coding: utf-8 -*-
  2. # Description: dovecot netdata python.d module
  3. # Author: Pawel Krupa (paulfantom)
  4. # SPDX-License-Identifier: GPL-3.0-or-later
  5. from bases.FrameworkServices.SocketService import SocketService
  6. UNIX_SOCKET = '/var/run/dovecot/stats'
  7. ORDER = [
  8. 'sessions',
  9. 'logins',
  10. 'commands',
  11. 'faults',
  12. 'context_switches',
  13. 'io',
  14. 'net',
  15. 'syscalls',
  16. 'lookup',
  17. 'cache',
  18. 'auth',
  19. 'auth_cache'
  20. ]
  21. CHARTS = {
  22. 'sessions': {
  23. 'options': [None, 'Dovecot Active Sessions', 'number', 'sessions', 'dovecot.sessions', 'line'],
  24. 'lines': [
  25. ['num_connected_sessions', 'active sessions', 'absolute']
  26. ]
  27. },
  28. 'logins': {
  29. 'options': [None, 'Dovecot Logins', 'number', 'logins', 'dovecot.logins', 'line'],
  30. 'lines': [
  31. ['num_logins', 'logins', 'absolute']
  32. ]
  33. },
  34. 'commands': {
  35. 'options': [None, 'Dovecot Commands', 'commands', 'commands', 'dovecot.commands', 'line'],
  36. 'lines': [
  37. ['num_cmds', 'commands', 'absolute']
  38. ]
  39. },
  40. 'faults': {
  41. 'options': [None, 'Dovecot Page Faults', 'faults', 'page faults', 'dovecot.faults', 'line'],
  42. 'lines': [
  43. ['min_faults', 'minor', 'absolute'],
  44. ['maj_faults', 'major', 'absolute']
  45. ]
  46. },
  47. 'context_switches': {
  48. 'options': [None, 'Dovecot Context Switches', 'switches', 'context switches', 'dovecot.context_switches',
  49. 'line'],
  50. 'lines': [
  51. ['vol_cs', 'voluntary', 'absolute'],
  52. ['invol_cs', 'involuntary', 'absolute']
  53. ]
  54. },
  55. 'io': {
  56. 'options': [None, 'Dovecot Disk I/O', 'KiB/s', 'disk', 'dovecot.io', 'area'],
  57. 'lines': [
  58. ['disk_input', 'read', 'incremental', 1, 1024],
  59. ['disk_output', 'write', 'incremental', -1, 1024]
  60. ]
  61. },
  62. 'net': {
  63. 'options': [None, 'Dovecot Network Bandwidth', 'kilobits/s', 'network', 'dovecot.net', 'area'],
  64. 'lines': [
  65. ['read_bytes', 'read', 'incremental', 8, 1000],
  66. ['write_bytes', 'write', 'incremental', -8, 1000]
  67. ]
  68. },
  69. 'syscalls': {
  70. 'options': [None, 'Dovecot Number of SysCalls', 'syscalls/s', 'system', 'dovecot.syscalls', 'line'],
  71. 'lines': [
  72. ['read_count', 'read', 'incremental'],
  73. ['write_count', 'write', 'incremental']
  74. ]
  75. },
  76. 'lookup': {
  77. 'options': [None, 'Dovecot Lookups', 'number/s', 'lookups', 'dovecot.lookup', 'stacked'],
  78. 'lines': [
  79. ['mail_lookup_path', 'path', 'incremental'],
  80. ['mail_lookup_attr', 'attr', 'incremental']
  81. ]
  82. },
  83. 'cache': {
  84. 'options': [None, 'Dovecot Cache Hits', 'hits/s', 'cache', 'dovecot.cache', 'line'],
  85. 'lines': [
  86. ['mail_cache_hits', 'hits', 'incremental']
  87. ]
  88. },
  89. 'auth': {
  90. 'options': [None, 'Dovecot Authentications', 'attempts', 'logins', 'dovecot.auth', 'stacked'],
  91. 'lines': [
  92. ['auth_successes', 'ok', 'absolute'],
  93. ['auth_failures', 'failed', 'absolute']
  94. ]
  95. },
  96. 'auth_cache': {
  97. 'options': [None, 'Dovecot Authentication Cache', 'number', 'cache', 'dovecot.auth_cache', 'stacked'],
  98. 'lines': [
  99. ['auth_cache_hits', 'hit', 'absolute'],
  100. ['auth_cache_misses', 'miss', 'absolute']
  101. ]
  102. }
  103. }
  104. class Service(SocketService):
  105. def __init__(self, configuration=None, name=None):
  106. SocketService.__init__(self, configuration=configuration, name=name)
  107. self.order = ORDER
  108. self.definitions = CHARTS
  109. self.host = None # localhost
  110. self.port = None # 24242
  111. self.unix_socket = UNIX_SOCKET
  112. self.request = 'EXPORT\tglobal\r\n'
  113. def _get_data(self):
  114. """
  115. Format data received from socket
  116. :return: dict
  117. """
  118. try:
  119. raw = self._get_raw_data()
  120. except (ValueError, AttributeError):
  121. return None
  122. if raw is None:
  123. self.debug('dovecot returned no data')
  124. return None
  125. data = raw.split('\n')[:2]
  126. desc = data[0].split('\t')
  127. vals = data[1].split('\t')
  128. ret = dict()
  129. for i, _ in enumerate(desc):
  130. try:
  131. ret[str(desc[i])] = int(vals[i])
  132. except ValueError:
  133. continue
  134. return ret or None