elasticsearch.chart.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. # -*- coding: utf-8 -*-
  2. # Description: elastic search node stats netdata python.d module
  3. # Author: ilyam8
  4. # SPDX-License-Identifier: GPL-3.0-or-later
  5. import json
  6. import threading
  7. from collections import namedtuple
  8. from socket import gethostbyname, gaierror
  9. try:
  10. from queue import Queue
  11. except ImportError:
  12. from Queue import Queue
  13. from bases.FrameworkServices.UrlService import UrlService
  14. # default module values (can be overridden per job in `config`)
  15. update_every = 5
  16. METHODS = namedtuple('METHODS', ['get_data', 'url', 'run'])
  17. NODE_STATS = [
  18. 'indices.search.fetch_current',
  19. 'indices.search.fetch_total',
  20. 'indices.search.query_current',
  21. 'indices.search.query_total',
  22. 'indices.search.query_time_in_millis',
  23. 'indices.search.fetch_time_in_millis',
  24. 'indices.indexing.index_total',
  25. 'indices.indexing.index_current',
  26. 'indices.indexing.index_time_in_millis',
  27. 'indices.refresh.total',
  28. 'indices.refresh.total_time_in_millis',
  29. 'indices.flush.total',
  30. 'indices.flush.total_time_in_millis',
  31. 'indices.translog.operations',
  32. 'indices.translog.size_in_bytes',
  33. 'indices.translog.uncommitted_operations',
  34. 'indices.translog.uncommitted_size_in_bytes',
  35. 'indices.segments.count',
  36. 'indices.segments.terms_memory_in_bytes',
  37. 'indices.segments.stored_fields_memory_in_bytes',
  38. 'indices.segments.term_vectors_memory_in_bytes',
  39. 'indices.segments.norms_memory_in_bytes',
  40. 'indices.segments.points_memory_in_bytes',
  41. 'indices.segments.doc_values_memory_in_bytes',
  42. 'indices.segments.index_writer_memory_in_bytes',
  43. 'indices.segments.version_map_memory_in_bytes',
  44. 'indices.segments.fixed_bit_set_memory_in_bytes',
  45. 'jvm.gc.collectors.young.collection_count',
  46. 'jvm.gc.collectors.old.collection_count',
  47. 'jvm.gc.collectors.young.collection_time_in_millis',
  48. 'jvm.gc.collectors.old.collection_time_in_millis',
  49. 'jvm.mem.heap_used_percent',
  50. 'jvm.mem.heap_used_in_bytes',
  51. 'jvm.mem.heap_committed_in_bytes',
  52. 'jvm.buffer_pools.direct.count',
  53. 'jvm.buffer_pools.direct.used_in_bytes',
  54. 'jvm.buffer_pools.direct.total_capacity_in_bytes',
  55. 'jvm.buffer_pools.mapped.count',
  56. 'jvm.buffer_pools.mapped.used_in_bytes',
  57. 'jvm.buffer_pools.mapped.total_capacity_in_bytes',
  58. 'thread_pool.bulk.queue',
  59. 'thread_pool.bulk.rejected',
  60. 'thread_pool.write.queue',
  61. 'thread_pool.write.rejected',
  62. 'thread_pool.index.queue',
  63. 'thread_pool.index.rejected',
  64. 'thread_pool.search.queue',
  65. 'thread_pool.search.rejected',
  66. 'thread_pool.merge.queue',
  67. 'thread_pool.merge.rejected',
  68. 'indices.fielddata.memory_size_in_bytes',
  69. 'indices.fielddata.evictions',
  70. 'breakers.fielddata.tripped',
  71. 'http.current_open',
  72. 'transport.rx_size_in_bytes',
  73. 'transport.tx_size_in_bytes',
  74. 'process.max_file_descriptors',
  75. 'process.open_file_descriptors'
  76. ]
  77. CLUSTER_STATS = [
  78. 'nodes.count.data',
  79. 'nodes.count.master',
  80. 'nodes.count.total',
  81. 'nodes.count.coordinating_only',
  82. 'nodes.count.ingest',
  83. 'indices.docs.count',
  84. 'indices.query_cache.hit_count',
  85. 'indices.query_cache.miss_count',
  86. 'indices.store.size_in_bytes',
  87. 'indices.count',
  88. 'indices.shards.total'
  89. ]
  90. HEALTH_STATS = [
  91. 'number_of_nodes',
  92. 'number_of_data_nodes',
  93. 'number_of_pending_tasks',
  94. 'number_of_in_flight_fetch',
  95. 'active_shards',
  96. 'relocating_shards',
  97. 'unassigned_shards',
  98. 'delayed_unassigned_shards',
  99. 'initializing_shards',
  100. 'active_shards_percent_as_number'
  101. ]
  102. LATENCY = {
  103. 'query_latency': {
  104. 'total': 'indices_search_query_total',
  105. 'spent_time': 'indices_search_query_time_in_millis'
  106. },
  107. 'fetch_latency': {
  108. 'total': 'indices_search_fetch_total',
  109. 'spent_time': 'indices_search_fetch_time_in_millis'
  110. },
  111. 'indexing_latency': {
  112. 'total': 'indices_indexing_index_total',
  113. 'spent_time': 'indices_indexing_index_time_in_millis'
  114. },
  115. 'flushing_latency': {
  116. 'total': 'indices_flush_total',
  117. 'spent_time': 'indices_flush_total_time_in_millis'
  118. }
  119. }
  120. # charts order (can be overridden if you want less charts, or different order)
  121. ORDER = [
  122. 'search_performance_total',
  123. 'search_performance_current',
  124. 'search_performance_time',
  125. 'search_latency',
  126. 'index_performance_total',
  127. 'index_performance_current',
  128. 'index_performance_time',
  129. 'index_latency',
  130. 'index_translog_operations',
  131. 'index_translog_size',
  132. 'index_segments_count',
  133. 'index_segments_memory_writer',
  134. 'index_segments_memory',
  135. 'jvm_mem_heap',
  136. 'jvm_mem_heap_bytes',
  137. 'jvm_buffer_pool_count',
  138. 'jvm_direct_buffers_memory',
  139. 'jvm_mapped_buffers_memory',
  140. 'jvm_gc_count',
  141. 'jvm_gc_time',
  142. 'host_metrics_file_descriptors',
  143. 'host_metrics_http',
  144. 'host_metrics_transport',
  145. 'thread_pool_queued',
  146. 'thread_pool_rejected',
  147. 'fielddata_cache',
  148. 'fielddata_evictions_tripped',
  149. 'cluster_health_status',
  150. 'cluster_health_nodes',
  151. 'cluster_health_pending_tasks',
  152. 'cluster_health_flight_fetch',
  153. 'cluster_health_shards',
  154. 'cluster_stats_nodes',
  155. 'cluster_stats_query_cache',
  156. 'cluster_stats_docs',
  157. 'cluster_stats_store',
  158. 'cluster_stats_indices',
  159. 'cluster_stats_shards_total',
  160. ]
  161. CHARTS = {
  162. 'search_performance_total': {
  163. 'options': [None, 'Queries And Fetches', 'events/s', 'search performance',
  164. 'elastic.search_performance_total', 'stacked'],
  165. 'lines': [
  166. ['indices_search_query_total', 'queries', 'incremental'],
  167. ['indices_search_fetch_total', 'fetches', 'incremental']
  168. ]
  169. },
  170. 'search_performance_current': {
  171. 'options': [None, 'Queries and Fetches In Progress', 'events', 'search performance',
  172. 'elastic.search_performance_current', 'stacked'],
  173. 'lines': [
  174. ['indices_search_query_current', 'queries', 'absolute'],
  175. ['indices_search_fetch_current', 'fetches', 'absolute']
  176. ]
  177. },
  178. 'search_performance_time': {
  179. 'options': [None, 'Time Spent On Queries And Fetches', 'seconds', 'search performance',
  180. 'elastic.search_performance_time', 'stacked'],
  181. 'lines': [
  182. ['indices_search_query_time_in_millis', 'query', 'incremental', 1, 1000],
  183. ['indices_search_fetch_time_in_millis', 'fetch', 'incremental', 1, 1000]
  184. ]
  185. },
  186. 'search_latency': {
  187. 'options': [None, 'Query And Fetch Latency', 'milliseconds', 'search performance', 'elastic.search_latency', 'stacked'],
  188. 'lines': [
  189. ['query_latency', 'query', 'absolute', 1, 1000],
  190. ['fetch_latency', 'fetch', 'absolute', 1, 1000]
  191. ]
  192. },
  193. 'index_performance_total': {
  194. 'options': [None, 'Indexed Documents, Index Refreshes, Index Flushes To Disk', 'events/s',
  195. 'indexing performance', 'elastic.index_performance_total', 'stacked'],
  196. 'lines': [
  197. ['indices_indexing_index_total', 'indexed', 'incremental'],
  198. ['indices_refresh_total', 'refreshes', 'incremental'],
  199. ['indices_flush_total', 'flushes', 'incremental']
  200. ]
  201. },
  202. 'index_performance_current': {
  203. 'options': [None, 'Number Of Documents Currently Being Indexed', 'currently indexed',
  204. 'indexing performance', 'elastic.index_performance_current', 'stacked'],
  205. 'lines': [
  206. ['indices_indexing_index_current', 'documents', 'absolute']
  207. ]
  208. },
  209. 'index_performance_time': {
  210. 'options': [None, 'Time Spent On Indexing, Refreshing, Flushing', 'seconds', 'indexing performance',
  211. 'elastic.index_performance_time', 'stacked'],
  212. 'lines': [
  213. ['indices_indexing_index_time_in_millis', 'indexing', 'incremental', 1, 1000],
  214. ['indices_refresh_total_time_in_millis', 'refreshing', 'incremental', 1, 1000],
  215. ['indices_flush_total_time_in_millis', 'flushing', 'incremental', 1, 1000]
  216. ]
  217. },
  218. 'index_latency': {
  219. 'options': [None, 'Indexing And Flushing Latency', 'milliseconds', 'indexing performance',
  220. 'elastic.index_latency', 'stacked'],
  221. 'lines': [
  222. ['indexing_latency', 'indexing', 'absolute', 1, 1000],
  223. ['flushing_latency', 'flushing', 'absolute', 1, 1000]
  224. ]
  225. },
  226. 'index_translog_operations': {
  227. 'options': [None, 'Translog Operations', 'operations', 'translog',
  228. 'elastic.index_translog_operations', 'area'],
  229. 'lines': [
  230. ['indices_translog_operations', 'total', 'absolute'],
  231. ['indices_translog_uncommitted_operations', 'uncommited', 'absolute']
  232. ]
  233. },
  234. 'index_translog_size': {
  235. 'options': [None, 'Translog Size', 'MiB', 'translog',
  236. 'elastic.index_translog_size', 'area'],
  237. 'lines': [
  238. ['indices_translog_size_in_bytes', 'total', 'absolute', 1, 1048567],
  239. ['indices_translog_uncommitted_size_in_bytes', 'uncommited', 'absolute', 1, 1048567]
  240. ]
  241. },
  242. 'index_segments_count': {
  243. 'options': [None, 'Total Number Of Indices Segments', 'segments', 'indices segments',
  244. 'elastic.index_segments_count', 'line'],
  245. 'lines': [
  246. ['indices_segments_count', 'segments', 'absolute']
  247. ]
  248. },
  249. 'index_segments_memory_writer': {
  250. 'options': [None, 'Index Writer Memory Usage', 'MiB', 'indices segments',
  251. 'elastic.index_segments_memory_writer', 'area'],
  252. 'lines': [
  253. ['indices_segments_index_writer_memory_in_bytes', 'total', 'absolute', 1, 1048567]
  254. ]
  255. },
  256. 'index_segments_memory': {
  257. 'options': [None, 'Indices Segments Memory Usage', 'MiB', 'indices segments',
  258. 'elastic.index_segments_memory', 'stacked'],
  259. 'lines': [
  260. ['indices_segments_terms_memory_in_bytes', 'terms', 'absolute', 1, 1048567],
  261. ['indices_segments_stored_fields_memory_in_bytes', 'stored fields', 'absolute', 1, 1048567],
  262. ['indices_segments_term_vectors_memory_in_bytes', 'term vectors', 'absolute', 1, 1048567],
  263. ['indices_segments_norms_memory_in_bytes', 'norms', 'absolute', 1, 1048567],
  264. ['indices_segments_points_memory_in_bytes', 'points', 'absolute', 1, 1048567],
  265. ['indices_segments_doc_values_memory_in_bytes', 'doc values', 'absolute', 1, 1048567],
  266. ['indices_segments_version_map_memory_in_bytes', 'version map', 'absolute', 1, 1048567],
  267. ['indices_segments_fixed_bit_set_memory_in_bytes', 'fixed bit set', 'absolute', 1, 1048567]
  268. ]
  269. },
  270. 'jvm_mem_heap': {
  271. 'options': [None, 'JVM Heap Percentage Currently in Use', 'percentage', 'memory usage and gc',
  272. 'elastic.jvm_heap', 'area'],
  273. 'lines': [
  274. ['jvm_mem_heap_used_percent', 'inuse', 'absolute']
  275. ]
  276. },
  277. 'jvm_mem_heap_bytes': {
  278. 'options': [None, 'JVM Heap Commit And Usage', 'MiB', 'memory usage and gc',
  279. 'elastic.jvm_heap_bytes', 'area'],
  280. 'lines': [
  281. ['jvm_mem_heap_committed_in_bytes', 'commited', 'absolute', 1, 1048576],
  282. ['jvm_mem_heap_used_in_bytes', 'used', 'absolute', 1, 1048576]
  283. ]
  284. },
  285. 'jvm_buffer_pool_count': {
  286. 'options': [None, 'JVM Buffers', 'pools', 'memory usage and gc',
  287. 'elastic.jvm_buffer_pool_count', 'line'],
  288. 'lines': [
  289. ['jvm_buffer_pools_direct_count', 'direct', 'absolute'],
  290. ['jvm_buffer_pools_mapped_count', 'mapped', 'absolute']
  291. ]
  292. },
  293. 'jvm_direct_buffers_memory': {
  294. 'options': [None, 'JVM Direct Buffers Memory', 'MiB', 'memory usage and gc',
  295. 'elastic.jvm_direct_buffers_memory', 'area'],
  296. 'lines': [
  297. ['jvm_buffer_pools_direct_used_in_bytes', 'used', 'absolute', 1, 1048567],
  298. ['jvm_buffer_pools_direct_total_capacity_in_bytes', 'total capacity', 'absolute', 1, 1048567]
  299. ]
  300. },
  301. 'jvm_mapped_buffers_memory': {
  302. 'options': [None, 'JVM Mapped Buffers Memory', 'MiB', 'memory usage and gc',
  303. 'elastic.jvm_mapped_buffers_memory', 'area'],
  304. 'lines': [
  305. ['jvm_buffer_pools_mapped_used_in_bytes', 'used', 'absolute', 1, 1048567],
  306. ['jvm_buffer_pools_mapped_total_capacity_in_bytes', 'total capacity', 'absolute', 1, 1048567]
  307. ]
  308. },
  309. 'jvm_gc_count': {
  310. 'options': [None, 'Garbage Collections', 'events/s', 'memory usage and gc', 'elastic.gc_count', 'stacked'],
  311. 'lines': [
  312. ['jvm_gc_collectors_young_collection_count', 'young', 'incremental'],
  313. ['jvm_gc_collectors_old_collection_count', 'old', 'incremental']
  314. ]
  315. },
  316. 'jvm_gc_time': {
  317. 'options': [None, 'Time Spent On Garbage Collections', 'milliseconds', 'memory usage and gc',
  318. 'elastic.gc_time', 'stacked'],
  319. 'lines': [
  320. ['jvm_gc_collectors_young_collection_time_in_millis', 'young', 'incremental'],
  321. ['jvm_gc_collectors_old_collection_time_in_millis', 'old', 'incremental']
  322. ]
  323. },
  324. 'thread_pool_queued': {
  325. 'options': [None, 'Number Of Queued Threads In Thread Pool', 'queued threads', 'queues and rejections',
  326. 'elastic.thread_pool_queued', 'stacked'],
  327. 'lines': [
  328. ['thread_pool_bulk_queue', 'bulk', 'absolute'],
  329. ['thread_pool_write_queue', 'write', 'absolute'],
  330. ['thread_pool_index_queue', 'index', 'absolute'],
  331. ['thread_pool_search_queue', 'search', 'absolute'],
  332. ['thread_pool_merge_queue', 'merge', 'absolute']
  333. ]
  334. },
  335. 'thread_pool_rejected': {
  336. 'options': [None, 'Rejected Threads In Thread Pool', 'rejected threads', 'queues and rejections',
  337. 'elastic.thread_pool_rejected', 'stacked'],
  338. 'lines': [
  339. ['thread_pool_bulk_rejected', 'bulk', 'absolute'],
  340. ['thread_pool_write_rejected', 'write', 'absolute'],
  341. ['thread_pool_index_rejected', 'index', 'absolute'],
  342. ['thread_pool_search_rejected', 'search', 'absolute'],
  343. ['thread_pool_merge_rejected', 'merge', 'absolute']
  344. ]
  345. },
  346. 'fielddata_cache': {
  347. 'options': [None, 'Fielddata Cache', 'MiB', 'fielddata cache', 'elastic.fielddata_cache', 'line'],
  348. 'lines': [
  349. ['indices_fielddata_memory_size_in_bytes', 'cache', 'absolute', 1, 1048576]
  350. ]
  351. },
  352. 'fielddata_evictions_tripped': {
  353. 'options': [None, 'Fielddata Evictions And Circuit Breaker Tripped Count', 'events/s',
  354. 'fielddata cache', 'elastic.fielddata_evictions_tripped', 'line'],
  355. 'lines': [
  356. ['indices_fielddata_evictions', 'evictions', 'incremental'],
  357. ['indices_fielddata_tripped', 'tripped', 'incremental']
  358. ]
  359. },
  360. 'cluster_health_nodes': {
  361. 'options': [None, 'Nodes Statistics', 'nodes', 'cluster health API',
  362. 'elastic.cluster_health_nodes', 'area'],
  363. 'lines': [
  364. ['number_of_nodes', 'nodes', 'absolute'],
  365. ['number_of_data_nodes', 'data_nodes', 'absolute'],
  366. ]
  367. },
  368. 'cluster_health_pending_tasks': {
  369. 'options': [None, 'Tasks Statistics', 'tasks', 'cluster health API',
  370. 'elastic.cluster_health_pending_tasks', 'line'],
  371. 'lines': [
  372. ['number_of_pending_tasks', 'pending_tasks', 'absolute'],
  373. ]
  374. },
  375. 'cluster_health_flight_fetch': {
  376. 'options': [None, 'In Flight Fetches Statistics', 'fetches', 'cluster health API',
  377. 'elastic.cluster_health_flight_fetch', 'line'],
  378. 'lines': [
  379. ['number_of_in_flight_fetch', 'in_flight_fetch', 'absolute']
  380. ]
  381. },
  382. 'cluster_health_status': {
  383. 'options': [None, 'Cluster Status', 'status', 'cluster health API',
  384. 'elastic.cluster_health_status', 'area'],
  385. 'lines': [
  386. ['status_green', 'green', 'absolute'],
  387. ['status_red', 'red', 'absolute'],
  388. ['status_foo1', None, 'absolute'],
  389. ['status_foo2', None, 'absolute'],
  390. ['status_foo3', None, 'absolute'],
  391. ['status_yellow', 'yellow', 'absolute']
  392. ]
  393. },
  394. 'cluster_health_shards': {
  395. 'options': [None, 'Shards Statistics', 'shards', 'cluster health API',
  396. 'elastic.cluster_health_shards', 'stacked'],
  397. 'lines': [
  398. ['active_shards', 'active_shards', 'absolute'],
  399. ['relocating_shards', 'relocating_shards', 'absolute'],
  400. ['unassigned_shards', 'unassigned', 'absolute'],
  401. ['delayed_unassigned_shards', 'delayed_unassigned', 'absolute'],
  402. ['initializing_shards', 'initializing', 'absolute'],
  403. ['active_shards_percent_as_number', 'active_percent', 'absolute']
  404. ]
  405. },
  406. 'cluster_stats_nodes': {
  407. 'options': [None, 'Nodes Statistics', 'nodes', 'cluster stats API',
  408. 'elastic.cluster_nodes', 'area'],
  409. 'lines': [
  410. ['nodes_count_data', 'data', 'absolute'],
  411. ['nodes_count_master', 'master', 'absolute'],
  412. ['nodes_count_total', 'total', 'absolute'],
  413. ['nodes_count_ingest', 'ingest', 'absolute'],
  414. ['nodes_count_coordinating_only', 'coordinating_only', 'absolute']
  415. ]
  416. },
  417. 'cluster_stats_query_cache': {
  418. 'options': [None, 'Query Cache Statistics', 'queries', 'cluster stats API',
  419. 'elastic.cluster_query_cache', 'stacked'],
  420. 'lines': [
  421. ['indices_query_cache_hit_count', 'hit', 'incremental'],
  422. ['indices_query_cache_miss_count', 'miss', 'incremental']
  423. ]
  424. },
  425. 'cluster_stats_docs': {
  426. 'options': [None, 'Docs Statistics', 'docs', 'cluster stats API',
  427. 'elastic.cluster_docs', 'line'],
  428. 'lines': [
  429. ['indices_docs_count', 'docs', 'absolute']
  430. ]
  431. },
  432. 'cluster_stats_store': {
  433. 'options': [None, 'Store Statistics', 'MiB', 'cluster stats API',
  434. 'elastic.cluster_store', 'line'],
  435. 'lines': [
  436. ['indices_store_size_in_bytes', 'size', 'absolute', 1, 1048567]
  437. ]
  438. },
  439. 'cluster_stats_indices': {
  440. 'options': [None, 'Indices Statistics', 'indices', 'cluster stats API',
  441. 'elastic.cluster_indices', 'line'],
  442. 'lines': [
  443. ['indices_count', 'indices', 'absolute'],
  444. ]
  445. },
  446. 'cluster_stats_shards_total': {
  447. 'options': [None, 'Total Shards Statistics', 'shards', 'cluster stats API',
  448. 'elastic.cluster_shards_total', 'line'],
  449. 'lines': [
  450. ['indices_shards_total', 'shards', 'absolute']
  451. ]
  452. },
  453. 'host_metrics_transport': {
  454. 'options': [None, 'Cluster Communication Transport Metrics', 'kilobit/s', 'host metrics',
  455. 'elastic.host_transport', 'area'],
  456. 'lines': [
  457. ['transport_rx_size_in_bytes', 'in', 'incremental', 8, 1000],
  458. ['transport_tx_size_in_bytes', 'out', 'incremental', -8, 1000]
  459. ]
  460. },
  461. 'host_metrics_file_descriptors': {
  462. 'options': [None, 'Available File Descriptors In Percent', 'percentage', 'host metrics',
  463. 'elastic.host_descriptors', 'area'],
  464. 'lines': [
  465. ['file_descriptors_used', 'used', 'absolute', 1, 10]
  466. ]
  467. },
  468. 'host_metrics_http': {
  469. 'options': [None, 'Opened HTTP Connections', 'connections', 'host metrics',
  470. 'elastic.host_http_connections', 'line'],
  471. 'lines': [
  472. ['http_current_open', 'opened', 'absolute', 1, 1]
  473. ]
  474. }
  475. }
  476. class Service(UrlService):
  477. def __init__(self, configuration=None, name=None):
  478. UrlService.__init__(self, configuration=configuration, name=name)
  479. self.order = ORDER
  480. self.definitions = CHARTS
  481. self.host = self.configuration.get('host')
  482. self.port = self.configuration.get('port', 9200)
  483. self.url = '{scheme}://{host}:{port}'.format(
  484. scheme=self.configuration.get('scheme', 'http'),
  485. host=self.host,
  486. port=self.port,
  487. )
  488. self.latency = dict()
  489. self.methods = list()
  490. def check(self):
  491. if not all([self.host,
  492. self.port,
  493. isinstance(self.host, str),
  494. isinstance(self.port, (str, int))]):
  495. self.error('Host is not defined in the module configuration file')
  496. return False
  497. # Hostname -> ip address
  498. try:
  499. self.host = gethostbyname(self.host)
  500. except gaierror as error:
  501. self.error(str(error))
  502. return False
  503. # Create URL for every Elasticsearch API
  504. self.methods = [METHODS(get_data=self._get_node_stats,
  505. url=self.url + '/_nodes/_local/stats',
  506. run=self.configuration.get('node_stats', True)),
  507. METHODS(get_data=self._get_cluster_health,
  508. url=self.url + '/_cluster/health',
  509. run=self.configuration.get('cluster_health', True)),
  510. METHODS(get_data=self._get_cluster_stats,
  511. url=self.url + '/_cluster/stats',
  512. run=self.configuration.get('cluster_stats', True))]
  513. # Remove disabled API calls from 'avail methods'
  514. return UrlService.check(self)
  515. def _get_data(self):
  516. threads = list()
  517. queue = Queue()
  518. result = dict()
  519. for method in self.methods:
  520. if not method.run:
  521. continue
  522. th = threading.Thread(target=method.get_data,
  523. args=(queue, method.url))
  524. th.start()
  525. threads.append(th)
  526. for thread in threads:
  527. thread.join()
  528. result.update(queue.get())
  529. return result or None
  530. def _get_cluster_health(self, queue, url):
  531. """
  532. Format data received from http request
  533. :return: dict
  534. """
  535. raw_data = self._get_raw_data(url)
  536. if not raw_data:
  537. return queue.put(dict())
  538. data = self.json_reply(raw_data)
  539. if not data:
  540. return queue.put(dict())
  541. to_netdata = fetch_data_(raw_data=data,
  542. metrics=HEALTH_STATS)
  543. to_netdata.update({'status_green': 0, 'status_red': 0, 'status_yellow': 0,
  544. 'status_foo1': 0, 'status_foo2': 0, 'status_foo3': 0})
  545. current_status = 'status_' + data['status']
  546. to_netdata[current_status] = 1
  547. return queue.put(to_netdata)
  548. def _get_cluster_stats(self, queue, url):
  549. """
  550. Format data received from http request
  551. :return: dict
  552. """
  553. raw_data = self._get_raw_data(url)
  554. if not raw_data:
  555. return queue.put(dict())
  556. data = self.json_reply(raw_data)
  557. if not data:
  558. return queue.put(dict())
  559. to_netdata = fetch_data_(raw_data=data,
  560. metrics=CLUSTER_STATS)
  561. return queue.put(to_netdata)
  562. def _get_node_stats(self, queue, url):
  563. """
  564. Format data received from http request
  565. :return: dict
  566. """
  567. raw_data = self._get_raw_data(url)
  568. if not raw_data:
  569. return queue.put(dict())
  570. data = self.json_reply(raw_data)
  571. if not data:
  572. return queue.put(dict())
  573. node = list(data['nodes'].keys())[0]
  574. to_netdata = fetch_data_(raw_data=data['nodes'][node],
  575. metrics=NODE_STATS)
  576. # Search, index, flush, fetch performance latency
  577. for key in LATENCY:
  578. try:
  579. to_netdata[key] = self.find_avg(total=to_netdata[LATENCY[key]['total']],
  580. spent_time=to_netdata[LATENCY[key]['spent_time']],
  581. key=key)
  582. except KeyError:
  583. continue
  584. if 'process_open_file_descriptors' in to_netdata and 'process_max_file_descriptors' in to_netdata:
  585. to_netdata['file_descriptors_used'] = round(float(to_netdata['process_open_file_descriptors'])
  586. / to_netdata['process_max_file_descriptors'] * 1000)
  587. return queue.put(to_netdata)
  588. def json_reply(self, reply):
  589. try:
  590. return json.loads(reply)
  591. except ValueError as err:
  592. self.error(err)
  593. return None
  594. def find_avg(self, total, spent_time, key):
  595. if key not in self.latency:
  596. self.latency[key] = dict(total=total,
  597. spent_time=spent_time)
  598. return 0
  599. if self.latency[key]['total'] != total:
  600. latency = float(spent_time - self.latency[key]['spent_time'])\
  601. / float(total - self.latency[key]['total']) * 1000
  602. self.latency[key]['total'] = total
  603. self.latency[key]['spent_time'] = spent_time
  604. return latency
  605. self.latency[key]['spent_time'] = spent_time
  606. return 0
  607. def fetch_data_(raw_data, metrics):
  608. data = dict()
  609. for metric in metrics:
  610. value = raw_data
  611. metrics_list = metric.split('.')
  612. try:
  613. for m in metrics_list:
  614. value = value[m]
  615. except KeyError:
  616. continue
  617. data['_'.join(metrics_list)] = value
  618. return data