icecast.chart.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # -*- coding: utf-8 -*-
  2. # Description: icecast netdata python.d module
  3. # Author: Ilya Mashchenko (ilyam8)
  4. # SPDX-License-Identifier: GPL-3.0-or-later
  5. import json
  6. from bases.FrameworkServices.UrlService import UrlService
  7. ORDER = [
  8. 'listeners',
  9. ]
  10. CHARTS = {
  11. 'listeners': {
  12. 'options': [None, 'Number Of Listeners', 'listeners', 'listeners', 'icecast.listeners', 'line'],
  13. 'lines': [
  14. ]
  15. }
  16. }
  17. class Source:
  18. def __init__(self, idx, data):
  19. self.name = 'source_{0}'.format(idx)
  20. self.is_active = data.get('stream_start') and data.get('server_name')
  21. self.listeners = data['listeners']
  22. class Service(UrlService):
  23. def __init__(self, configuration=None, name=None):
  24. UrlService.__init__(self, configuration=configuration, name=name)
  25. self.order = ORDER
  26. self.definitions = CHARTS
  27. self.url = self.configuration.get('url')
  28. self._manager = self._build_manager()
  29. def check(self):
  30. """
  31. Add active sources to the "listeners" chart
  32. :return: bool
  33. """
  34. sources = self.get_sources()
  35. if not sources:
  36. return None
  37. active_sources = 0
  38. for idx, raw_source in enumerate(sources):
  39. if Source(idx, raw_source).is_active:
  40. active_sources += 1
  41. dim_id = 'source_{0}'.format(idx)
  42. dim = 'source {0}'.format(idx)
  43. self.definitions['listeners']['lines'].append([dim_id, dim])
  44. return bool(active_sources)
  45. def _get_data(self):
  46. """
  47. Get number of listeners for every source
  48. :return: dict
  49. """
  50. sources = self.get_sources()
  51. if not sources:
  52. return None
  53. data = dict()
  54. for idx, raw_source in enumerate(sources):
  55. source = Source(idx, raw_source)
  56. data[source.name] = source.listeners
  57. return data
  58. def get_sources(self):
  59. """
  60. Format data received from http request and return list of sources
  61. :return: list
  62. """
  63. raw_data = self._get_raw_data()
  64. if not raw_data:
  65. return None
  66. try:
  67. data = json.loads(raw_data)
  68. except ValueError as error:
  69. self.error('JSON decode error:', error)
  70. return None
  71. sources = data['icestats'].get('source')
  72. if not sources:
  73. return None
  74. return sources if isinstance(sources, list) else [sources]