dovecot.chart.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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', 'line'],
  49. 'lines': [
  50. ['vol_cs', 'voluntary', 'absolute'],
  51. ['invol_cs', 'involuntary', 'absolute']
  52. ]
  53. },
  54. 'io': {
  55. 'options': [None, 'Dovecot Disk I/O', 'KiB/s', 'disk', 'dovecot.io', 'area'],
  56. 'lines': [
  57. ['disk_input', 'read', 'incremental', 1, 1024],
  58. ['disk_output', 'write', 'incremental', -1, 1024]
  59. ]
  60. },
  61. 'net': {
  62. 'options': [None, 'Dovecot Network Bandwidth', 'kilobits/s', 'network', 'dovecot.net', 'area'],
  63. 'lines': [
  64. ['read_bytes', 'read', 'incremental', 8, 1000],
  65. ['write_bytes', 'write', 'incremental', -8, 1000]
  66. ]
  67. },
  68. 'syscalls': {
  69. 'options': [None, 'Dovecot Number of SysCalls', 'syscalls/s', 'system', 'dovecot.syscalls', 'line'],
  70. 'lines': [
  71. ['read_count', 'read', 'incremental'],
  72. ['write_count', 'write', 'incremental']
  73. ]
  74. },
  75. 'lookup': {
  76. 'options': [None, 'Dovecot Lookups', 'number/s', 'lookups', 'dovecot.lookup', 'stacked'],
  77. 'lines': [
  78. ['mail_lookup_path', 'path', 'incremental'],
  79. ['mail_lookup_attr', 'attr', 'incremental']
  80. ]
  81. },
  82. 'cache': {
  83. 'options': [None, 'Dovecot Cache Hits', 'hits/s', 'cache', 'dovecot.cache', 'line'],
  84. 'lines': [
  85. ['mail_cache_hits', 'hits', 'incremental']
  86. ]
  87. },
  88. 'auth': {
  89. 'options': [None, 'Dovecot Authentications', 'attempts', 'logins', 'dovecot.auth', 'stacked'],
  90. 'lines': [
  91. ['auth_successes', 'ok', 'absolute'],
  92. ['auth_failures', 'failed', 'absolute']
  93. ]
  94. },
  95. 'auth_cache': {
  96. 'options': [None, 'Dovecot Authentication Cache', 'number', 'cache', 'dovecot.auth_cache', 'stacked'],
  97. 'lines': [
  98. ['auth_cache_hits', 'hit', 'absolute'],
  99. ['auth_cache_misses', 'miss', 'absolute']
  100. ]
  101. }
  102. }
  103. class Service(SocketService):
  104. def __init__(self, configuration=None, name=None):
  105. SocketService.__init__(self, configuration=configuration, name=name)
  106. self.order = ORDER
  107. self.definitions = CHARTS
  108. self.host = None # localhost
  109. self.port = None # 24242
  110. self.unix_socket = UNIX_SOCKET
  111. self.request = 'EXPORT\tglobal\r\n'
  112. def _get_data(self):
  113. """
  114. Format data received from socket
  115. :return: dict
  116. """
  117. try:
  118. raw = self._get_raw_data()
  119. except (ValueError, AttributeError):
  120. return None
  121. if raw is None:
  122. self.debug('dovecot returned no data')
  123. return None
  124. data = raw.split('\n')[:2]
  125. desc = data[0].split('\t')
  126. vals = data[1].split('\t')
  127. ret = dict()
  128. for i, _ in enumerate(desc):
  129. try:
  130. ret[str(desc[i])] = int(vals[i])
  131. except ValueError:
  132. continue
  133. return ret or None