worker.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. {% extends "base.html" %}
  2. {% block navbar %}
  3. {% module Template("navbar.html", active_tab="workers", absolute_url=absolute_url) %}
  4. {% end %}
  5. {% block container %}
  6. <div class="container-fluid">
  7. <div class="row-fluid">
  8. <div class="span12">
  9. <div class="page-header">
  10. <h1 id="workername">{{ worker.name }}</h1>
  11. </div>
  12. <div class="tabbable">
  13. <ul class="nav nav-tabs">
  14. <li class="active"><a href="#tab-pool" data-toggle="tab">Pool</a></li>
  15. <li><a href="#tab-broker" data-toggle="tab">Broker</a></li>
  16. <li><a href="#tab-queues" data-toggle="tab">Queues</a></li>
  17. <li><a href="#tab-tasks" data-toggle="tab">Tasks</a></li>
  18. <li><a href="#tab-limits" data-toggle="tab">Limits</a></li>
  19. <li><a href="#tab-config" data-toggle="tab">Config</a></li>
  20. </ul>
  21. <div class="tab-content">
  22. <div class="tab-pane active" id="tab-pool">
  23. <div class="row-fluid">
  24. <div class="span6">
  25. <table class="table table-bordered table-striped">
  26. <caption>Worker pool options</caption>
  27. <tbody>
  28. {% for name,value in worker.stats['pool'].items() %}
  29. <tr>
  30. <td>{{ humanize(name) }}</td>
  31. <td>{{ humanize(value) }}</td>
  32. </tr>
  33. {% end %}
  34. <tr>
  35. <td>Worker PID</td>
  36. <td>{{ worker.stats.get('pid', '')}}</td>
  37. </tr>
  38. </tbody>
  39. </table>
  40. </div>
  41. <div class="span6">
  42. <div class="form-horizontal">
  43. <fieldset>
  44. <legend>Pool size control</legend>
  45. <div class="control-group">
  46. <label class="control-label" for="pool-size">Pool size</label>
  47. <div class="controls">
  48. <div class="input-append">
  49. <select class="input-mini" id="pool-size">
  50. <option>1</option>
  51. <option>2</option>
  52. <option>3</option>
  53. <option>4</option>
  54. <option>5</option>
  55. </select>
  56. <button class="btn" type="button" onclick="flower.on_pool_grow(event)">Grow</button>
  57. <button class="btn" type="button" onclick="flower.on_pool_shrink(event)">Shrink</button>
  58. </div>
  59. </div>
  60. </div>
  61. <div class="control-group">
  62. <label class="control-label" for="min-autoscale">Min/Max autoscale</label>
  63. <div class="controls">
  64. <div class="input-append">
  65. <input class="input-mini" id="min-autoscale" size="6" type="text">
  66. <input class="input-mini" id="max-autoscale" size="6" type="text">
  67. <button class="btn" type="button" onclick="flower.on_pool_autoscale(event)">Apply</button>
  68. </div>
  69. </div>
  70. </div>
  71. </fieldset>
  72. </div>
  73. </div>
  74. </div>
  75. {% if worker.stats.get('autoscaler', None) %}
  76. <div class="row-fluid">
  77. <div class="span6">
  78. <table class="table table-bordered table-striped">
  79. <caption>Autoscaler options</caption>
  80. <tbody>
  81. {% for name,value in worker.stats['autoscaler'].items() %}
  82. <tr>
  83. <td>{{ humanize(name) }}</td>
  84. <td>{{ humanize(value) }}</td>
  85. </tr>
  86. {% end %}
  87. </tbody>
  88. </table>
  89. </div>
  90. </div>
  91. {% end %}
  92. </div> <!-- end pool tab -->
  93. <div class="tab-pane" id="tab-broker">
  94. <div class="span6">
  95. <table class="table table-bordered table-striped">
  96. <caption>Broker options</caption>
  97. <tbody>
  98. {% for name,value in (worker.stats.get('consumer', None) or worker.stats)['broker'].items() %}
  99. <tr>
  100. <td>{{ humanize(name) }}</td>
  101. <td>{{ value }}</td>
  102. </tr>
  103. {% end %}
  104. </tbody>
  105. </table>
  106. </div>
  107. </div> <!-- end broker tab -->
  108. <div class="tab-pane" id="tab-queues">
  109. <h3>Active <small>queues being consumed from</small></h3>
  110. <div class="control-group">
  111. <div class="controls">
  112. <div class="input-append">
  113. <input class="span2" id="add-consumer-name" size="16" type="text">
  114. <button class="btn" type="button" onclick="flower.on_add_consumer(event)">Add Consumer</button>
  115. </div>
  116. </div>
  117. </div>
  118. <table class="table table-bordered table-striped">
  119. <thead>
  120. <tr>
  121. <th>Name</th>
  122. <th>Exclusive</th>
  123. <!-- <th>Exchange</th> -->
  124. <th>Durable</th>
  125. <th>Routing key</th>
  126. <th>No ACK</th>
  127. <th>Alias</th>
  128. <th>Queue arguments</th>
  129. <th>Binding arguments</th>
  130. <th>Auto delete</th>
  131. <th style="width: 125px;"></th>
  132. </tr>
  133. </thead>
  134. <tbody>
  135. {% for queue in worker.active_queues %}
  136. <tr>
  137. <td>{{ queue['name'] }}</td>
  138. <td>{{ queue['exclusive'] }}</td>
  139. <!-- <td>{{ queue['exchange'] }}</td> -->
  140. <td>{{ queue['durable'] }}</td>
  141. <td>{{ queue['routing_key'] }}</td>
  142. <td>{{ queue['no_ack'] }}</td>
  143. <td>{{ queue['alias'] }}</td>
  144. <td>{{ queue['queue_arguments'] }}</td>
  145. <td>{{ queue['binding_arguments'] }}</td>
  146. <td>{{ queue['auto_delete'] }}</td>
  147. <td><button class="btn btn-danger" onclick="flower.on_cancel_consumer(event)">Cancel Consumer</button></td>
  148. </tr>
  149. {% end %}
  150. </tbody>
  151. </table>
  152. </div> <!-- end queues tab -->
  153. <div class="tab-pane" id="tab-tasks">
  154. <h2>Processed <small>number of completed tasks</small></h2>
  155. <table class="table table-bordered table-striped">
  156. <tbody>
  157. {% for name,value in worker.stats['total'].items() %}
  158. <tr>
  159. <td>{{ name }}</td>
  160. <td>{{ value }}</td>
  161. </tr>
  162. {% end %}
  163. </tbody>
  164. </table>
  165. <h2>Active <small>currently executing tasks</small></h2>
  166. <table class="table table-bordered table-striped">
  167. <thead>
  168. <tr>
  169. <th>Name</th>
  170. <th>UUID</th>
  171. <th>Start time</th>
  172. <th>Ack</th>
  173. <th>PID</th>
  174. <th>args</th>
  175. <th>kwargs</th>
  176. </tr>
  177. </tr>
  178. </tr>
  179. </thead>
  180. <tbody>
  181. {% for task in worker.active_tasks %}
  182. <tr>
  183. <td>{{ task['name'] }}</td>
  184. <td><a href="{{ absolute_url('/task/' + task['id']) }}">{{ task['id'] }}</a></td>
  185. <td>{{ humanize(task['time_start'], type='time') }}</td>
  186. <td>{{ task['acknowledged'] }}</td>
  187. <td>{{ task['worker_pid'] }}</td>
  188. <td>{{ task['args'] }}</td>
  189. <td>{{ task['kwargs'] }}</td>
  190. </tr>
  191. {% end %}
  192. </tbody>
  193. </table>
  194. <h2>Scheduled <small>scheduled (eta/countdown/retry) tasks</small></h2>
  195. <table class="table table-bordered table-striped">
  196. <thead>
  197. <tr>
  198. <th>Name</th>
  199. <th>UUID</th>
  200. <th>args</th>
  201. <th>kwargs</th>
  202. </tr>
  203. </thead>
  204. <tbody>
  205. {% for task in worker.scheduled_tasks %}
  206. <tr>
  207. <td>{{ task['request']['name'] }}</td>
  208. <td><a href="{{ absolute_url('/task/' + task['request']['id']) }}">{{ task['request']['id'] }}</a></td>
  209. <td>{{ task['request']['args'] }}</td>
  210. <td>{{ task['request']['kwargs'] }}</td>
  211. </tr>
  212. {% end %}
  213. </tbody>
  214. </table>
  215. <h2>Reserved <small>tasks that have been received, but are still waiting to be executed</small></h2>
  216. <table class="table table-bordered table-striped">
  217. <thead>
  218. <tr>
  219. <th>Name</th>
  220. <th>UUID</th>
  221. <th>args</th>
  222. <th>kwargs</th>
  223. </tr>
  224. </thead>
  225. <tbody>
  226. {% for task in worker.reserved_tasks %}
  227. <tr>
  228. <td>{{ task['name'] }}</td>
  229. <td><a href="{{ absolute_url('/task/' + task['id']) }}">{{ task['id'] }}</a></td>
  230. <td>{{ task['args'] }}</td>
  231. <td>{{ task['kwargs'] }}</td>
  232. </tr>
  233. {% end %}
  234. </tbody>
  235. </table>
  236. <h2>Revoked <small>cancelled tasks</small></h2>
  237. <table class="table table-bordered table-striped">
  238. <thead>
  239. <tr>
  240. <th>Name</th>
  241. <th>ID</th>
  242. <th>args</th>
  243. <th>kwargs</th>
  244. </tr>
  245. </thead>
  246. <tbody>
  247. {% for task in worker.revoked_tasks %}
  248. <tr>
  249. <td></td>
  250. <td><a href="{{ absolute_url('/task/' + task) }}">{{ task }}</a></td>
  251. <td></td>
  252. <td></td>
  253. </tr>
  254. {% end %}
  255. </tbody>
  256. </table>
  257. </div> <!-- end tasks tab -->
  258. <div class="tab-pane" id="tab-limits">
  259. <h3>Task limits</h3>
  260. <table class="table table-bordered table-striped">
  261. <thead>
  262. <tr>
  263. <th>Task name</th>
  264. <th>Rate limit</th>
  265. <th>Timeouts</th>
  266. </tr>
  267. </thead>
  268. {% for taskname in worker.registered_tasks %}
  269. <tr>
  270. <td>{{ taskname }}</td>
  271. <td>
  272. <div class="control-group">
  273. <div class="controls">
  274. <div class="input-append">
  275. <input class="input-small" type="text">
  276. <button class="btn" type="button" onclick="flower.on_task_rate_limit(event)">Apply</button>
  277. </div>
  278. </div>
  279. </div>
  280. </td>
  281. <td>
  282. <div class="control-group">
  283. <div class="controls">
  284. <div class="input-append">
  285. <input class="input-small" type="text">
  286. <button class="btn" type="button" onclick="flower.on_task_timeout(event)">Soft</button>
  287. <button class="btn" type="button" onclick="flower.on_task_timeout(event)">Hard</button>
  288. </div>
  289. </div>
  290. </div>
  291. </td>
  292. </tr>
  293. {% end %}
  294. </table>
  295. </div> <!-- end limits tab -->
  296. <div class="tab-pane" id="tab-config">
  297. <div class="span8">
  298. <table class="table table-bordered table-striped">
  299. <caption>Configuration options</caption>
  300. <tbody>
  301. {% for name,value in sorted(worker.conf.items()) %}
  302. {% if value is not None %}
  303. <tr>
  304. <td><a href="http://docs.celeryproject.org/en/latest/configuration.html#{{ name.lower().replace('_', '-') }}" target="_blank">{{ name }}</a></td>
  305. <td>{{ value }}</td>
  306. </tr>
  307. {% end %}
  308. {% end %}
  309. </tbody>
  310. </table>
  311. </div>
  312. </div> <!-- end config tab -->
  313. </div>
  314. </div>
  315. </div>
  316. <div>
  317. {% end %}