squid.chart.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # -*- coding: utf-8 -*-
  2. # Description: squid netdata python.d module
  3. # Author: Pawel Krupa (paulfantom)
  4. from bases.FrameworkServices.SocketService import SocketService
  5. # default module values (can be overridden per job in `config`)
  6. # update_every = 2
  7. priority = 60000
  8. retries = 60
  9. # charts order (can be overridden if you want less charts, or different order)
  10. ORDER = ['clients_net', 'clients_requests', 'servers_net', 'servers_requests']
  11. CHARTS = {
  12. 'clients_net': {
  13. 'options': [None, "Squid Client Bandwidth", "kilobits/s", "clients", "squid.clients_net", "area"],
  14. 'lines': [
  15. ["client_http_kbytes_in", "in", "incremental", 8, 1],
  16. ["client_http_kbytes_out", "out", "incremental", -8, 1],
  17. ["client_http_hit_kbytes_out", "hits", "incremental", -8, 1]
  18. ]},
  19. 'clients_requests': {
  20. 'options': [None, "Squid Client Requests", "requests/s", "clients", "squid.clients_requests", 'line'],
  21. 'lines': [
  22. ["client_http_requests", "requests", "incremental"],
  23. ["client_http_hits", "hits", "incremental"],
  24. ["client_http_errors", "errors", "incremental", -1, 1]
  25. ]},
  26. 'servers_net': {
  27. 'options': [None, "Squid Server Bandwidth", "kilobits/s", "servers", "squid.servers_net", "area"],
  28. 'lines': [
  29. ["server_all_kbytes_in", "in", "incremental", 8, 1],
  30. ["server_all_kbytes_out", "out", "incremental", -8, 1]
  31. ]},
  32. 'servers_requests': {
  33. 'options': [None, "Squid Server Requests", "requests/s", "servers", "squid.servers_requests", 'line'],
  34. 'lines': [
  35. ["server_all_requests", "requests", "incremental"],
  36. ["server_all_errors", "errors", "incremental", -1, 1]
  37. ]}
  38. }
  39. class Service(SocketService):
  40. def __init__(self, configuration=None, name=None):
  41. SocketService.__init__(self, configuration=configuration, name=name)
  42. self._keep_alive = True
  43. self.request = ""
  44. self.host = "localhost"
  45. self.port = 3128
  46. self.order = ORDER
  47. self.definitions = CHARTS
  48. def _get_data(self):
  49. """
  50. Get data via http request
  51. :return: dict
  52. """
  53. response = self._get_raw_data()
  54. data = dict()
  55. try:
  56. raw = ""
  57. for tmp in response.split('\r\n'):
  58. if tmp.startswith("sample_time"):
  59. raw = tmp
  60. break
  61. if raw.startswith('<'):
  62. self.error("invalid data received")
  63. return None
  64. for row in raw.split('\n'):
  65. if row.startswith(("client", "server.all")):
  66. tmp = row.split("=")
  67. data[tmp[0].replace('.', '_').strip(' ')] = int(tmp[1])
  68. except (ValueError, AttributeError, TypeError):
  69. self.error("invalid data received")
  70. return None
  71. if not data:
  72. self.error("no data received")
  73. return None
  74. return data
  75. def _check_raw_data(self, data):
  76. header = data[:1024].lower()
  77. if "connection: keep-alive" in header:
  78. self._keep_alive = True
  79. else:
  80. self._keep_alive = False
  81. if data[-7:] == "\r\n0\r\n\r\n" and "transfer-encoding: chunked" in header: # HTTP/1.1 response
  82. self.debug("received full response from squid")
  83. return True
  84. self.debug("waiting more data from squid")
  85. return False
  86. def check(self):
  87. """
  88. Parse essential configuration, autodetect squid configuration (if needed), and check if data is available
  89. :return: boolean
  90. """
  91. self._parse_config()
  92. # format request
  93. req = self.request.decode()
  94. if not req.startswith("GET"):
  95. req = "GET " + req
  96. if not req.endswith(" HTTP/1.1\r\n\r\n"):
  97. req += " HTTP/1.1\r\n\r\n"
  98. self.request = req.encode()
  99. if self._get_data() is not None:
  100. return True
  101. else:
  102. return False