monitoring_controller.rb 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. class MonitoringController < ApplicationController
  3. prepend_before_action -> { authentication_check(permission: 'admin.monitoring') }, except: [:health_check, :status]
  4. skip_before_action :verify_csrf_token
  5. =begin
  6. Resource:
  7. GET /api/v1/monitoring/health_check?token=XXX
  8. Response:
  9. {
  10. "healthy": true,
  11. "message": "success",
  12. }
  13. {
  14. "healthy": false,
  15. "message": "authentication of XXX failed; issue #2",
  16. "issues": ["authentication of XXX failed", "issue #2"],
  17. }
  18. Test:
  19. curl http://localhost/api/v1/monitoring/health_check?token=XXX
  20. =end
  21. def health_check
  22. token_or_permission_check
  23. issues = []
  24. # channel check
  25. Channel.where(active: true).each { |channel|
  26. next if (channel.status_in.empty? || channel.status_in == 'ok') && (channel.status_out.empty? || channel.status_out == 'ok')
  27. if channel.status_in == 'error'
  28. message = "Channel: #{channel.area} in "
  29. %w(host user uid).each { |key|
  30. next if !channel.options[key] || channel.options[key].empty?
  31. message += "key:#{channel.options[key]};"
  32. }
  33. issues.push "#{message} #{channel.last_log_in}"
  34. end
  35. next if channel.status_out != 'error'
  36. message = "Channel: #{channel.area} out "
  37. %w(host user uid).each { |key|
  38. next if !channel.options[key] || channel.options[key].empty?
  39. message += "key:#{channel.options[key]};"
  40. }
  41. issues.push "#{message} #{channel.last_log_out}"
  42. }
  43. # unprocessable mail check
  44. directory = "#{Rails.root}/tmp/unprocessable_mail"
  45. if File.exist?(directory)
  46. count = 0
  47. Dir.glob("#{directory}/*.eml") { |_entry|
  48. count += 1
  49. }
  50. if count.nonzero?
  51. issues.push "unprocessable mails: #{count}"
  52. end
  53. end
  54. # scheduler check
  55. Scheduler.where(active: true).where.not(last_run: nil).each { |scheduler|
  56. next if scheduler.period <= 300
  57. next if scheduler.last_run + scheduler.period.seconds > Time.zone.now - 5.minutes
  58. issues.push 'scheduler not running'
  59. break
  60. }
  61. if Scheduler.where(active: true, last_run: nil).count == Scheduler.where(active: true).count
  62. issues.push 'scheduler not running'
  63. end
  64. token = Setting.get('monitoring_token')
  65. if issues.empty?
  66. result = {
  67. healthy: true,
  68. message: 'success',
  69. token: token,
  70. }
  71. render json: result
  72. return
  73. end
  74. result = {
  75. healthy: false,
  76. message: issues.join(';'),
  77. issues: issues,
  78. token: token,
  79. }
  80. render json: result
  81. end
  82. =begin
  83. Resource:
  84. GET /api/v1/monitoring/status?token=XXX
  85. Response:
  86. {
  87. "agents": 8123,
  88. "last_login": "2016-11-21T14:14:14Z",
  89. "counts": {
  90. "users": 12313,
  91. "tickets": 23123,
  92. "ticket_articles": 131451,
  93. },
  94. "last_created_at": {
  95. "users": "2016-11-21T14:14:14Z",
  96. "tickets": "2016-11-21T14:14:14Z",
  97. "ticket_articles": "2016-11-21T14:14:14Z",
  98. },
  99. }
  100. Test:
  101. curl http://localhost/api/v1/monitoring/status?token=XXX
  102. =end
  103. def status
  104. token_or_permission_check
  105. last_login = nil
  106. last_login_user = User.where('last_login IS NOT NULL').order(last_login: :desc).limit(1).first
  107. if last_login_user
  108. last_login = last_login_user.last_login
  109. end
  110. status = {
  111. counts: {},
  112. last_created_at: {},
  113. last_login: last_login,
  114. agents: User.with_permissions('ticket.agent').count,
  115. }
  116. map = {
  117. users: User,
  118. groups: Group,
  119. overviews: Overview,
  120. tickets: Ticket,
  121. ticket_articles: Ticket::Article,
  122. }
  123. map.each { |key, class_name|
  124. status[:counts][key] = class_name.count
  125. last = class_name.last
  126. status[:last_created_at][key] = if last
  127. last.created_at
  128. end
  129. }
  130. render json: status
  131. end
  132. def token
  133. access_check
  134. token = SecureRandom.urlsafe_base64(40)
  135. Setting.set('monitoring_token', token)
  136. result = {
  137. token: token,
  138. }
  139. render json: result, status: :created
  140. end
  141. private
  142. def token_or_permission_check
  143. user = authentication_check_only(permission: 'admin.monitoring')
  144. return if user
  145. return if Setting.get('monitoring_token') == params[:token]
  146. raise Exceptions::NotAuthorized
  147. end
  148. def access_check
  149. return if Permission.find_by(name: 'admin.monitoring', active: true)
  150. raise Exceptions::NotAuthorized
  151. end
  152. end