pgbus 0.17.1 → 0.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -0
  3. data/README.md +48 -13
  4. data/app/controllers/concerns/pgbus/job_listing.rb +37 -0
  5. data/app/controllers/concerns/pgbus/process_listing.rb +17 -0
  6. data/app/controllers/pgbus/application_controller.rb +5 -2
  7. data/app/controllers/pgbus/batches_controller.rb +4 -1
  8. data/app/controllers/pgbus/dashboard_controller.rb +20 -6
  9. data/app/controllers/pgbus/dead_letter_controller.rb +27 -3
  10. data/app/controllers/pgbus/events_controller.rb +52 -3
  11. data/app/controllers/pgbus/insights_controller.rb +19 -1
  12. data/app/controllers/pgbus/jobs_controller.rb +45 -26
  13. data/app/controllers/pgbus/locks_controller.rb +7 -2
  14. data/app/controllers/pgbus/outbox_controller.rb +4 -1
  15. data/app/controllers/pgbus/processes_controller.rb +3 -1
  16. data/app/controllers/pgbus/queues_controller.rb +16 -4
  17. data/app/controllers/pgbus/recurring_tasks_controller.rb +5 -7
  18. data/app/frontend/pgbus/modules/charts.js +119 -77
  19. data/app/frontend/pgbus/style.css +1 -1
  20. data/app/frontend/pgbus/tailwind.css +18 -0
  21. data/app/helpers/pgbus/application_helper.rb +155 -113
  22. data/app/helpers/pgbus/button_helper.rb +88 -0
  23. data/app/helpers/pgbus/dashboard_helper.rb +157 -0
  24. data/app/helpers/pgbus/events_helper.rb +40 -0
  25. data/app/helpers/pgbus/insights_helper.rb +39 -0
  26. data/app/helpers/pgbus/processes_helper.rb +79 -0
  27. data/app/views/pgbus/batches/_batches_table.html.erb +16 -13
  28. data/app/views/pgbus/batches/show.html.erb +3 -4
  29. data/app/views/pgbus/dashboard/_processes_table.html.erb +11 -11
  30. data/app/views/pgbus/dashboard/_queue_health.html.erb +42 -51
  31. data/app/views/pgbus/dashboard/_queues_table.html.erb +18 -16
  32. data/app/views/pgbus/dashboard/_recent_failures.html.erb +16 -12
  33. data/app/views/pgbus/dashboard/_stats_cards.html.erb +70 -36
  34. data/app/views/pgbus/dashboard/show.html.erb +1 -1
  35. data/app/views/pgbus/dead_letter/_error.html.erb +13 -0
  36. data/app/views/pgbus/dead_letter/_messages_table.html.erb +37 -96
  37. data/app/views/pgbus/dead_letter/_row.html.erb +75 -0
  38. data/app/views/pgbus/dead_letter/index.html.erb +6 -9
  39. data/app/views/pgbus/dead_letter/show.html.erb +37 -21
  40. data/app/views/pgbus/events/_list.html.erb +55 -0
  41. data/app/views/pgbus/events/_processed_table.html.erb +45 -0
  42. data/app/views/pgbus/events/_replay.html.erb +10 -0
  43. data/app/views/pgbus/events/_row.html.erb +162 -0
  44. data/app/views/pgbus/events/_tabs.html.erb +13 -0
  45. data/app/views/pgbus/events/index.html.erb +27 -48
  46. data/app/views/pgbus/events/show.html.erb +25 -7
  47. data/app/views/pgbus/insights/_chart_card.html.erb +21 -0
  48. data/app/views/pgbus/insights/_latency_table.html.erb +20 -0
  49. data/app/views/pgbus/insights/_status_table.html.erb +19 -0
  50. data/app/views/pgbus/insights/_throughput_table.html.erb +18 -0
  51. data/app/views/pgbus/insights/show.html.erb +83 -100
  52. data/app/views/pgbus/jobs/_list.html.erb +64 -0
  53. data/app/views/pgbus/jobs/_row.html.erb +107 -0
  54. data/app/views/pgbus/jobs/_tabs.html.erb +14 -0
  55. data/app/views/pgbus/jobs/index.html.erb +10 -10
  56. data/app/views/pgbus/jobs/show.html.erb +18 -20
  57. data/app/views/pgbus/locks/_concurrency.html.erb +25 -23
  58. data/app/views/pgbus/locks/_uniqueness.html.erb +20 -22
  59. data/app/views/pgbus/outbox/index.html.erb +30 -27
  60. data/app/views/pgbus/processes/_processes_table.html.erb +6 -25
  61. data/app/views/pgbus/processes/_row.html.erb +48 -0
  62. data/app/views/pgbus/processes/_status.html.erb +4 -0
  63. data/app/views/pgbus/queues/_queues_list.html.erb +28 -32
  64. data/app/views/pgbus/queues/show.html.erb +69 -118
  65. data/app/views/pgbus/recurring_tasks/_tasks_table.html.erb +75 -76
  66. data/app/views/pgbus/recurring_tasks/index.html.erb +1 -1
  67. data/app/views/pgbus/recurring_tasks/show.html.erb +45 -51
  68. data/app/views/pgbus/shared/_empty_row.html.erb +2 -0
  69. data/app/views/pgbus/shared/_pager.html.erb +34 -0
  70. data/config/i18n-tasks.yml +11 -2
  71. data/config/locales/da.yml +405 -113
  72. data/config/locales/de.yml +405 -113
  73. data/config/locales/en.yml +405 -113
  74. data/config/locales/es.yml +404 -112
  75. data/config/locales/fi.yml +404 -112
  76. data/config/locales/fr.yml +406 -114
  77. data/config/locales/it.yml +405 -113
  78. data/config/locales/ja.yml +405 -113
  79. data/config/locales/nb.yml +405 -113
  80. data/config/locales/nl.yml +405 -113
  81. data/config/locales/pt.yml +406 -114
  82. data/config/locales/sv.yml +404 -112
  83. data/lib/generators/pgbus/templates/initializer.rb.erb +4 -0
  84. data/lib/pgbus/active_job/executor.rb +16 -6
  85. data/lib/pgbus/cli/dlq.rb +32 -5
  86. data/lib/pgbus/client.rb +4 -2
  87. data/lib/pgbus/configuration.rb +47 -2
  88. data/lib/pgbus/dead_letter_header.rb +129 -0
  89. data/lib/pgbus/doctor.rb +8 -4
  90. data/lib/pgbus/event_bus/handler.rb +18 -11
  91. data/lib/pgbus/event_bus/registry.rb +6 -0
  92. data/lib/pgbus/failed_event_recorder.rb +34 -0
  93. data/lib/pgbus/instrumentation.rb +2 -1
  94. data/lib/pgbus/mcp/base_tool.rb +25 -0
  95. data/lib/pgbus/mcp/tools/concurrency_tool.rb +23 -4
  96. data/lib/pgbus/mcp/tools/dlq_detail_tool.rb +4 -2
  97. data/lib/pgbus/mcp/tools/dlq_tool.rb +10 -4
  98. data/lib/pgbus/mcp/tools/locks_tool.rb +23 -5
  99. data/lib/pgbus/mcp/tools/recurring_tool.rb +33 -4
  100. data/lib/pgbus/outbox/poller.rb +1 -1
  101. data/lib/pgbus/process/consumer.rb +53 -3
  102. data/lib/pgbus/process/dispatcher.rb +1 -1
  103. data/lib/pgbus/process/supervisor.rb +32 -11
  104. data/lib/pgbus/process/worker.rb +45 -8
  105. data/lib/pgbus/recurring/scheduler.rb +2 -1
  106. data/lib/pgbus/version.rb +1 -1
  107. data/lib/pgbus/web/data_source/dashboard_signals.rb +170 -0
  108. data/lib/pgbus/web/data_source/dead_letter.rb +142 -0
  109. data/lib/pgbus/web/data_source/event_list.rb +161 -0
  110. data/lib/pgbus/web/data_source/job_list.rb +323 -0
  111. data/lib/pgbus/web/data_source/list_counts.rb +80 -0
  112. data/lib/pgbus/web/data_source/process_list.rb +69 -0
  113. data/lib/pgbus/web/data_source/queue_summary.rb +122 -0
  114. data/lib/pgbus/web/data_source.rb +132 -254
  115. data/lib/pgbus/web/dead_letter_reason.rb +81 -0
  116. data/lib/pgbus/web/event_state.rb +71 -0
  117. data/lib/pgbus/web/health_app.rb +7 -3
  118. data/lib/pgbus/web/health_verdict.rb +78 -0
  119. data/lib/pgbus/web/insights_charts.rb +84 -0
  120. data/lib/pgbus/web/job_state.rb +111 -0
  121. data/lib/pgbus/web/process_activity.rb +97 -0
  122. data/lib/pgbus/web/process_state.rb +187 -0
  123. data/lib/pgbus/web/queue_summary.rb +104 -0
  124. data/lib/pgbus/web/time_format.rb +128 -0
  125. metadata +43 -4
  126. data/app/views/pgbus/events/_pending_table.html.erb +0 -169
  127. data/app/views/pgbus/jobs/_enqueued_table.html.erb +0 -118
  128. data/app/views/pgbus/jobs/_failed_table.html.erb +0 -76
@@ -41,6 +41,7 @@ fr:
41
41
  title: Processus actifs
42
42
  queue_health:
43
43
  dead_tuples: Tuples mortes
44
+ empty: Aucune table de file à mesurer pour l'instant
44
45
  headers:
45
46
  bloat: Bloat
46
47
  dead: Mortes
@@ -60,14 +61,34 @@ fr:
60
61
  one: "%{count} table nécessite un vacuum"
61
62
  other: "%{count} tables nécessitent un vacuum"
62
63
  title: Santé des files d'attente
64
+ words:
65
+ bloat:
66
+ critical: "%{ratio} sur %{table} — les lectures ralentissent ; lancez un vacuum maintenant (critique au-delà de %{critical}, alerte au-delà de %{warn})"
67
+ none: Rien à mesurer pour l'instant
68
+ ok: "%{ratio} sur %{table} — correct (alerte au-delà de %{warn}, critique au-delà de %{critical})"
69
+ warn: "%{ratio} sur %{table} — vacuum à prévoir (alerte au-delà de %{warn}, critique au-delà de %{critical})"
70
+ dead_tuples:
71
+ ok: Correct — alerte au-delà de %{limit} lignes mortes
72
+ warn: Au-delà de %{limit} — l'autovacuum est en retard ; le tableau ci-dessous montre où
73
+ transaction:
74
+ critical: Plus de %{critical} — le vacuum ne peut pas récupérer de lignes avant sa fin ; repérez-la dans pg_stat_activity (alerte à %{warn} ; le verdict de santé se dégrade après %{verdict})
75
+ none: Aucune transaction ouverte — le vacuum peut récupérer toutes les lignes mortes (alerte à %{warn}, alarme à %{critical} ; le verdict de santé se dégrade après %{verdict})
76
+ ok: Correct — alerte à %{warn}, alarme à %{critical} ; le verdict de santé se dégrade après %{verdict}
77
+ warn: Plus de %{warn} — une longue transaction empêche le vacuum de récupérer des lignes (alarme à %{critical} ; le verdict de santé se dégrade après %{verdict})
78
+ vacuum:
79
+ critical: Plus de %{critical} — l'autovacuum n'atteint pas ces tables ; vérifiez ses réglages (alerte après %{warn})
80
+ ok: Correct — alerte après %{warn}, critique après %{critical}
81
+ unknown: Jamais passé en vacuum, ou statistiques indisponibles
82
+ warn: Plus de %{warn} — l'autovacuum prend peut-être du retard (critique après %{critical})
63
83
  worst_bloat: Pire Bloat
64
84
  queues_table:
65
85
  empty: Aucune file d'attente trouvée
66
86
  headers:
67
87
  depth: Profondeur
68
- oldest_claimable: Plus ancien disponible (s)
88
+ oldest_claimable: Plus ancien disponible
69
89
  parked: Différés
70
90
  queue: File d'attente
91
+ status: Statut
71
92
  total: Total
72
93
  visible: Visible
73
94
  title: Files d'attente
@@ -75,7 +96,9 @@ fr:
75
96
  recent_failures:
76
97
  empty: Aucune erreur
77
98
  headers:
99
+ attempt: Tentative
78
100
  error: Erreur
101
+ job: Job
79
102
  queue: File d'attente
80
103
  when: Quand
81
104
  title: Échecs récents
@@ -83,19 +106,72 @@ fr:
83
106
  show:
84
107
  title: Tableau de bord
85
108
  stats_cards:
109
+ dead_lettered: En dead-letter
110
+ dlq_newest_html: 'le plus récent : %{error_class} dans %{job} %{ago}'
111
+ dlq_newest_legacy_html: 'le plus récent : %{job} %{ago} — aucune raison enregistrée'
112
+ dlq_newest_no_error_html: 'le plus récent : %{job} %{ago} — aucune erreur enregistrée'
113
+ dlq_none: Rien en dead-letter
114
+ dlq_see_why: ouvrez la page dead-letter pour voir pourquoi chacun est mort
86
115
  enqueued: Enregistré
87
- failed_dlq: Échoué / DLQ
88
- failed_dlq_labels: Échoués / Dead Lettered
116
+ enqueued_detail: "%{claimable} disponibles maintenant · %{waiting} planifiés, en cours ou en nouvelle tentative"
117
+ enqueued_paused:
118
+ one: "%{count} dans des files en pause"
119
+ other: "%{count} dans des files en pause"
89
120
  parked_jobs: Jobs en attente
90
121
  parked_jobs_oldest: le plus ancien %{age}
91
122
  processes: Processus
123
+ processes_detail: "%{healthy} sains · %{stalled} bloqués · %{stale} obsolètes"
124
+ processes_none: Rien ne tourne — aucun job n'est pris en charge
125
+ processes_stale: les processus obsolètes ont cessé d'émettre leur heartbeat ; leurs jobs en cours sont relancés à l'expiration de leur délai de visibilité
92
126
  queues: Files d'attente
127
+ queues_detail: "%{paused} en pause · %{dlq} en dead-letter"
128
+ queues_undrained:
129
+ one: "%{count} contient des jobs que rien ne vide"
130
+ other: "%{count} contiennent des jobs que rien ne vide"
93
131
  recurring: Récurrent
132
+ recurring_detail: Tâches que le planificateur met en file selon leur calendrier
133
+ retrying: Nouvel essai
134
+ retrying_due:
135
+ one: "%{count} à relancer maintenant"
136
+ other: "%{count} à relancer maintenant"
137
+ retrying_newest: erreur la plus récente %{error_class}
138
+ retrying_next_html: prochaine tentative %{time}
139
+ retrying_none: Rien n'est en nouvel essai
94
140
  throughput: Débit
95
- throughput_unit: msg/s
96
- view_tasks: Voir les tâches
97
- visible: visible
141
+ throughput_detail: tâches/min sur les %{minutes} dernières min
142
+ throughput_unavailable: nécessite les statistiques de jobs (rails g pgbus:add_job_stats)
143
+ verdict:
144
+ links:
145
+ dlq: Dead letters
146
+ processes: Processus
147
+ look_at: 'À examiner :'
148
+ meaning:
149
+ degraded: Quelque chose demande de l'attention, mais les jobs circulent encore. /readyz répond toujours prêt.
150
+ ok: Chaque file contenant du travail est vidée et chaque processus émet son heartbeat. /readyz répond prêt.
151
+ stalled: Des jobs attendent et rien ne les prend en charge. /readyz répond non prêt (503).
152
+ statuses:
153
+ degraded: DEGRADED
154
+ ok: OK
155
+ stalled: STALLED
156
+ title: 'Santé : %{status}'
157
+ unavailable: Verdict de santé indisponible — les contrôles sous-jacents n'ont pas pu être lus ; consultez le journal
98
158
  dead_letter:
159
+ detail:
160
+ backtrace: Backtrace (premières lignes)
161
+ died: 'Mort :'
162
+ dlq: 'File de lettres mortes :'
163
+ error_from_attempt: Erreur de la tentative %{attempt} ; les tentatives %{from}–%{to} n'ont enregistré aucune erreur.
164
+ source: 'Déplacé par :'
165
+ sources:
166
+ consumer: consommateur d'événements
167
+ worker: worker de jobs
168
+ why: Pourquoi il est mort
169
+ filters:
170
+ all: Toutes
171
+ clear_error_class: Retirer le filtre
172
+ error_class: 'Erreur : %{error_class}'
173
+ filter_error_class: Afficher uniquement %{error_class}
174
+ label: Filtrer les lettres mortes
99
175
  index:
100
176
  discard_all: Tout rejeter
101
177
  discard_all_confirm: Rejeter définitivement tous les messages DLQ ?
@@ -115,11 +191,13 @@ fr:
115
191
  empty: La file d'attente des messages morts est vide
116
192
  full_json_payload: Charge utile JSON complète
117
193
  headers:
118
- enqueued: Enregistré
194
+ actions: Actions
195
+ attempts: Tentatives
196
+ died: Mort
119
197
  id: ID
120
- job_class: Classe de tâche
121
- reads: Lectures
122
- source_queue: File d'attente source
198
+ job: Job
199
+ reason: Raison
200
+ source_queue: File source
123
201
  headers_section: En-têtes
124
202
  job_id: 'ID de la tâche :'
125
203
  metadata: Métadonnées
@@ -131,6 +209,16 @@ fr:
131
209
  visible_at: 'Visible à :'
132
210
  retry: Réessayer
133
211
  total_label: messages dans la file de lettres mortes
212
+ view: Voir
213
+ reasons:
214
+ error_earlier_attempt_html: 'Tentatives épuisées. Dernière erreur enregistrée, de la tentative %{error_attempt} : %{error_class}: %{error_message}'
215
+ error_html: 'Tentatives épuisées. Dernière erreur : %{error_class}: %{error_message}'
216
+ event_no_error_html: Le handler a échoué sur %{attempts} livraisons (max %{max}) — aucune erreur du handler n'a été enregistrée
217
+ no_error_recorded_html: "%{max} tentatives dépassées après %{attempts} lectures — aucune erreur enregistrée ; chaque tentative échouée a planté avant de pouvoir la signaler"
218
+ not_recorded_html: Raison non enregistrée (déplacé en DLQ avant pgbus %{version})
219
+ retried_before:
220
+ one: Déjà relancé depuis la DLQ une fois.
221
+ other: Déjà relancé depuis la DLQ %{count} fois.
134
222
  show:
135
223
  back: Retour à la DLQ
136
224
  context: Contexte
@@ -138,8 +226,10 @@ fr:
138
226
  discard_confirm: Ignorer définitivement ?
139
227
  headers: En-têtes
140
228
  labels:
229
+ attempts: Tentatives
230
+ died: Mort
231
+ dlq: File de lettres mortes
141
232
  enqueued_at: Mis en file à
142
- read_count: Nombre de lectures
143
233
  source_queue: File source
144
234
  visibility_timeout: Délai de visibilité
145
235
  not_found: Message non trouvé
@@ -163,6 +253,7 @@ fr:
163
253
  mark_handled_failed: Impossible de marquer l'événement comme traité.
164
254
  marked_handled: Événement marqué comme traité.
165
255
  none_selected: Aucun événement sélectionné.
256
+ payload_redacted: 'Non enregistré : le payload contient encore des valeurs masquées ([FILTERED]) qui remplaceraient les vraies.'
166
257
  payload_update_failed: Impossible de mettre à jour la charge utile. Vérifiez que le JSON est valide.
167
258
  payload_updated: Charge utile mise à jour et événement réenregistré.
168
259
  replay_failed: Événement non trouvé ou impossible à rejouer.
@@ -170,56 +261,118 @@ fr:
170
261
  reroute_failed: Impossible de rediriger l'événement.
171
262
  rerouted: Événement redirigé vers le gestionnaire cible.
172
263
  index:
173
- discard_selected: Jeter la sélection
174
- discard_selected_confirm: Jeter les événements sélectionnés ?
175
- pending_empty: Aucun événement en attente
176
- pending_headers:
177
- enqueued: Enregistré
178
- handler_queue: File du gestionnaire
179
- id: ID
180
- reads: Lectures
181
- routing_key: Clé de routage
182
264
  pending_title: Événements en attente
183
- processed_empty: Aucun événement traité pour le moment
184
- processed_headers:
185
- event_id: ID de l'événement
186
- handler: Gestionnaire
187
- processed_at: Traité à
188
265
  processed_title: Événements traités
266
+ subscribers:
267
+ covered: Consommé par un consumer en cours d'exécution
268
+ uncovered: Aucun consumer en cours d'exécution ne couvre ce modèle
269
+ unknown: Couverture des consumers inconnue
270
+ view_pending: Voir les événements en attente
189
271
  subscribers_empty: Aucun abonné enregistré
190
272
  subscribers_headers:
273
+ consumer: Consumer
191
274
  handler: Gestionnaire
192
275
  pattern: Modèle
276
+ pending: En attente
193
277
  queue: File d'attente
194
278
  subscribers_title: Abonnés enregistrés
195
279
  title: Événements
196
- pending_table:
197
- arguments: Charge utile
280
+ list:
198
281
  context: Contexte
199
282
  discard: Jeter
200
283
  discard_confirm: Jeter cet événement ? Il sera archivé.
284
+ discard_failure_confirm: Abandonner cet événement en échec ? Son message n'est plus dans la file.
285
+ discard_selected: Jeter la sélection
286
+ discard_selected_confirm: Jeter les événements sélectionnés ?
201
287
  edit_payload: Modifier & Réessayer
202
288
  edit_payload_confirm: Mettre à jour la charge utile et réenregistrer cet événement ?
203
289
  edit_payload_label: 'Charge utile JSON :'
290
+ empty:
291
+ all: Aucun événement en attente
292
+ ready: Aucun événement en attente de traitement
293
+ retrying: Aucun événement en attente de nouvelle tentative
294
+ running: Aucun événement en cours de traitement
295
+ scheduled: Aucun événement planifié
204
296
  event_id: 'ID de l''événement :'
205
297
  full_json_payload: Charge utile JSON complète
298
+ headers:
299
+ actions: Actions
300
+ attempts: Tentatives
301
+ event: Événement
302
+ handler: Gestionnaire
303
+ id: ID
304
+ reason: Prochaine exécution / Raison
305
+ state: État
206
306
  headers_section: En-têtes
207
307
  mark_handled: Marquer comme traité
208
- mark_handled_confirm: Marquer cet événement comme traité ? Il sera archivé et ignoré lors du relecture.
308
+ mark_handled_confirm: Marquer cet événement comme traité ? Son message est archivé et le handler ne l'exécute pas.
209
309
  metadata: Métadonnées
210
310
  metadata_labels:
311
+ enqueued: 'Mis en file :'
211
312
  last_read: 'Dernière lecture :'
313
+ published: 'Publié :'
212
314
  read_count: 'Nombre de lectures :'
213
315
  visible_at: 'Visible à :'
316
+ payload: Charge utile
317
+ reasons:
318
+ handling_html: En cours de traitement par %{handler} — réclamé %{ago} · le bail expire %{time}
319
+ lease_expired_html: Bail expiré (le consumer est probablement mort) — nouvelle livraison à %{handler}, tentative %{attempt}
320
+ no_consumer_for_queue_html: Aucun consumer en cours d'exécution n'est abonné à %{pattern} (%{handler})
321
+ no_consumers_html: Aucun consumer sain en cours d'exécution
322
+ orphaned_html: Échec avec %{error} dans %{handler} — le message n'est plus dans la file
323
+ paused_html: File en pause
324
+ retrying_dlq_html: "%{handler} tentative %{attempt}/%{max} en échec : %{error} — la prochaine lecture le déplace vers la DLQ"
325
+ retrying_due_html: "%{handler} tentative %{attempt}/%{max} en échec : %{error} — prochaine tentative maintenant"
326
+ retrying_html: "%{handler} tentative %{attempt}/%{max} en échec : %{error} — prochaine tentative %{time}"
327
+ scheduled_html: Planifié — traité par %{handler} %{time}
328
+ waiting_html: 'En attente — %{count} devant · suivant : %{handler}'
329
+ waiting_unknown_html: En attente de %{handler}
214
330
  reroute: Rediriger
215
331
  reroute_confirm: Rediriger cet événement vers un autre gestionnaire ?
216
332
  reroute_label: 'Gestionnaire cible :'
333
+ states:
334
+ ready: Prêt
335
+ retrying: Nouvel essai
336
+ running: En traitement
337
+ scheduled: Planifié
338
+ tabs:
339
+ all: Tous
340
+ ready: Prêts
341
+ retrying: Nouvel essai
342
+ running: En traitement
343
+ scheduled: Planifiés
344
+ tabs_label: États des événements
345
+ view_failure: Voir l'échec
346
+ processed:
347
+ empty: Aucun événement traité pour le moment
348
+ headers:
349
+ actions: Actions
350
+ event_id: ID de l'événement
351
+ handler: Gestionnaire
352
+ reason: Raison
353
+ state: État
354
+ reasons:
355
+ abandoned_html: Le claim s'est tu %{ago} — la prochaine livraison relance le handler
356
+ completed_html: Terminé %{ago}
357
+ completed_legacy_html: Enregistré %{ago} (claim en une phase ; mettre à niveau avec pgbus:add_processed_event_completion)
358
+ handling_html: En traitement — claim rafraîchi %{ago}
359
+ replay: Rejouer
360
+ replay_confirm: Relivrer cet événement à son handler sous un nouvel ID d'événement ? Le handler s'exécute à nouveau.
361
+ replay_unavailable:
362
+ no_handler: Le handler n'est plus enregistré
363
+ not_archived: N'est plus dans l'archive
364
+ states:
365
+ abandoned: Silencieux
366
+ completed: Terminé
367
+ handling: En traitement
217
368
  show:
218
369
  back: Retour aux événements
219
370
  labels:
371
+ completed_at: Terminé le
220
372
  event_id: ID de l'événement
221
373
  handler: Gestionnaire
222
374
  processed_at: Traité à
375
+ state: État
223
376
  not_found: Événement non trouvé
224
377
  title: Événement %{event_id}
225
378
  helpers:
@@ -231,6 +384,7 @@ fr:
231
384
  bulk_select_row: Sélectionner %{id}
232
385
  bulk_selected: sélectionné
233
386
  pagination:
387
+ label: Pagination
234
388
  next: Suivant
235
389
  previous: Précédent
236
390
  showing: Affichage de %{from}–%{to} sur %{total}
@@ -245,24 +399,50 @@ fr:
245
399
  healthy: Sain
246
400
  stale: Obsolète
247
401
  stalled: Bloqué
402
+ time:
403
+ absolute_format: "%Y-%m-%d %H:%M:%S %Z"
404
+ clock_format: "%H:%M"
405
+ future: dans %{distance}
406
+ now: maintenant
407
+ past: il y a %{distance}
408
+ range:
409
+ days:
410
+ one: "%{count} jour"
411
+ other: "%{count} jours"
412
+ hours:
413
+ one: "%{count} heure"
414
+ other: "%{count} heures"
415
+ minutes:
416
+ one: "%{count} minute"
417
+ other: "%{count} minutes"
418
+ units:
419
+ days: "%{count}j"
420
+ hours: "%{count}h"
421
+ milliseconds: "%{count}ms"
422
+ minutes: "%{count}min"
423
+ seconds: "%{count}s"
248
424
  insights:
249
425
  show:
250
426
  charts:
251
- failed_to_load: Échec du chargement des données du graphique
252
- latency: Latence de la file d'attente (ms)
427
+ captions:
428
+ latency: Les jobs ont attendu %{avg} en moyenne avant d'être pris par un worker, p95 %{p95}
429
+ status: "%{success} réussies, %{failed} échouées, %{dead_lettered} en dead-letter"
430
+ throughput_html: "%{total} tâches sur les derniers %{range}, pic de %{peak} tâches/min %{at}"
431
+ data_table: Tableau de données
432
+ latency: Latence de la file d'attente
253
433
  latency_avg: Moyenne
254
434
  latency_p95: P95
255
435
  no_data: Pas encore de données
256
436
  series_name: Tâches/min
257
437
  status_distribution: Répartition du statut
258
- throughput: Débit (tâches/min)
438
+ throughput: Débit
259
439
  description_html: Indicateurs de performance professionnelle pour les derniers %{range}
260
440
  latency_by_queue:
261
441
  empty: Pas encore de données de latence
262
442
  headers:
263
- avg: Moyenne (ms)
443
+ avg: Moyenne
264
444
  count: Nombre
265
- p95: P95 (ms)
445
+ p95: P95
266
446
  queue: File d'attente
267
447
  title: Latence par file d'attente
268
448
  live_streams:
@@ -282,6 +462,10 @@ fr:
282
462
  job_class: Classe de tâche
283
463
  max: Max
284
464
  title: Classes de travail les plus lentes (durée moyenne)
465
+ statuses:
466
+ dead_lettered: En dead-letter
467
+ failed: Échoués
468
+ success: Réussis
285
469
  streams:
286
470
  summary:
287
471
  active: Actif
@@ -310,6 +494,20 @@ fr:
310
494
  p99_latency: Latence P99
311
495
  succeeded: Réussi
312
496
  total_jobs: Total des travaux
497
+ tables:
498
+ captions:
499
+ latency_minute: Latence de la file d'attente par minute
500
+ latency_step: Latence de la file d'attente par %{step}
501
+ status: Jobs par statut final
502
+ throughput_minute: Jobs par minute
503
+ throughput_step: Jobs par %{step}
504
+ headers:
505
+ avg: Moyenne
506
+ from: Depuis
507
+ highest_p95: P95 le plus élevé
508
+ jobs: Jobs
509
+ share: Part
510
+ status: Statut
313
511
  time_ranges:
314
512
  1h: 1h
315
513
  24h: 24h
@@ -317,60 +515,87 @@ fr:
317
515
  7d: 7j
318
516
  title: Aperçus
319
517
  jobs:
320
- enqueued_table:
518
+ index:
519
+ discard_all: Tout ignorer
520
+ discard_all_confirm: Ignorer tous les travaux échoués ?
521
+ discard_all_enqueued_notice: "%{count} travaux en file d'attente supprimés et verrous libérés."
522
+ discard_selected: Supprimer la sélection
523
+ discard_selected_confirm: Supprimer les éléments sélectionnés ?
524
+ discarded_selected:
525
+ one: 1 élément sélectionné supprimé.
526
+ other: "%{count} éléments sélectionnés supprimés."
527
+ none_selected: Aucun élément sélectionné.
528
+ retry_all: Tout réessayer
529
+ retry_all_confirm: Réessayer tous les travaux échoués ?
530
+ title: Travaux
531
+ list:
321
532
  arguments: Arguments
322
- discard: Rejeter
323
- discard_all: Tout supprimer
324
- discard_all_confirm: Supprimer tous les travaux en file d'attente et libérer leurs verrous ? Cette action est irréversible.
325
- discard_confirm: Rejeter ce message ?
326
- empty: Aucun travail en file d'attente
533
+ discard: Ignorer
534
+ discard_all_enqueued: Abandonner tous les jobs en file
535
+ discard_all_enqueued_confirm: Supprimer tous les travaux en file d'attente et libérer leurs verrous ? Cette action est irréversible.
536
+ discard_confirm: Ignorer ce travail ?
537
+ empty:
538
+ all: Aucun job
539
+ blocked: Aucun job bloqué par une limite de concurrence
540
+ ready: Aucun job en attente d'exécution
541
+ retrying: Aucun job en attente d'un nouvel essai
542
+ running: Aucun job en cours
543
+ scheduled: Aucun job planifié
327
544
  full_json_payload: Charge utile JSON complète
328
545
  headers:
329
- enqueued: En file d'attente
546
+ actions: Actions
547
+ attempts: Tentatives
330
548
  id: ID
331
- job_class: Classe de travail
549
+ job: Job
332
550
  queue: File d'attente
333
- reads: Lectures
551
+ reason: Prochaine exécution / Raison
552
+ state: État
334
553
  headers_section: En-têtes
335
554
  job_id: 'ID du travail :'
336
555
  metadata: Métadonnées
337
556
  metadata_labels:
557
+ concurrency_key: 'Clé de concurrence :'
558
+ enqueued: 'Mis en file :'
338
559
  last_read: 'Dernière lecture :'
339
560
  locale: 'Langue :'
340
561
  priority: 'Priorité :'
341
- queue: 'File d''attente :'
342
562
  scheduled: 'Planifié :'
343
563
  timezone: 'Fuseau horaire :'
344
564
  visible_at: 'Visible à :'
565
+ reasons:
566
+ blocked_html: En attente d'un créneau de concurrence sur %{key} (occupés %{held}/%{limit}) · mis en attente %{ago}
567
+ blocked_no_slots_html: En attente d'un créneau de concurrence sur %{key} · mis en attente %{ago}
568
+ lease_expired_html: Bail expiré (le worker est probablement mort) — nouvelle livraison, tentative %{attempt}
569
+ no_workers_html: Aucun worker sain en cours d'exécution
570
+ not_drained_html: Aucun worker ne traite cette file
571
+ orphaned_html: Échec avec %{error} — le message n'est plus dans la file
572
+ paused_html: File en pause
573
+ retrying_dlq_html: 'La tentative %{attempt}/%{max} a échoué : %{error} — la prochaine lecture le déplace vers la DLQ'
574
+ retrying_due_html: 'La tentative %{attempt}/%{max} a échoué : %{error} — prochaine tentative maintenant'
575
+ retrying_html: 'La tentative %{attempt}/%{max} a échoué : %{error} — prochaine tentative %{time}'
576
+ running_html: Réclamé %{ago} · le bail expire %{time}
577
+ scheduled_html: Planifié — s'exécute %{time}
578
+ waiting_html: En attente — %{count} devant
579
+ waiting_priority_html: En attente — %{count} devant à cette priorité
580
+ waiting_unknown_html: En attente de prise en charge
345
581
  retry: Réessayer
346
582
  retry_confirm: Réinitialiser le délai de visibilité et réessayer ?
347
- title: Travaux en file d'attente
348
- failed_table:
349
- discard: Ignorer
350
- discard_confirm: Ignorer ce travail ?
351
- empty: Aucun travail échoué
352
- headers:
353
- actions: Actions
354
- error: Erreur
355
- failed: Échoué
356
- id: ID
357
- queue: File d'attente
358
- retries: Reprises
359
- retry: Réessayer
360
- title: Travaux échoués
361
- index:
362
- discard_all: Tout ignorer
363
- discard_all_confirm: Ignorer tous les travaux échoués ?
364
- discard_all_enqueued_notice: "%{count} travaux en file d'attente supprimés et verrous libérés."
365
- discard_selected: Supprimer la sélection
366
- discard_selected_confirm: Supprimer les éléments sélectionnés ?
367
- discarded_selected:
368
- one: 1 élément sélectionné supprimé.
369
- other: "%{count} éléments sélectionnés supprimés."
370
- none_selected: Aucun élément sélectionné.
371
- retry_all: Tout réessayer
372
- retry_all_confirm: Réessayer tous les travaux échoués ?
373
- title: Travaux
583
+ states:
584
+ blocked: Bloqué
585
+ ready: Prêt
586
+ retrying: Nouvel essai
587
+ running: En cours
588
+ scheduled: Planifié
589
+ tabs:
590
+ all: Tous
591
+ blocked: Bloqués
592
+ ready: Prêts
593
+ retrying: Nouvel essai
594
+ running: En cours
595
+ scheduled: Planifiés
596
+ tabs_label: États des jobs
597
+ view_failure: Voir l'échec
598
+ view_locks: Voir les verrous
374
599
  show:
375
600
  back: Retour aux travaux
376
601
  backtrace: Trace de la pile
@@ -423,6 +648,7 @@ fr:
423
648
  other: Supprimer les %{count} jobs en attente derrière cette clé ? Ils ne s'exécuteront jamais.
424
649
  empty: Aucune clé de concurrence utilisée
425
650
  headers:
651
+ actions: Actions
426
652
  in_use: Occupé
427
653
  key: Clé
428
654
  lease: Bail
@@ -456,6 +682,7 @@ fr:
456
682
  discard_selected_confirm: Supprimer les verrous sélectionnés ?
457
683
  empty: Aucun verrou actif
458
684
  headers:
685
+ actions: Actions
459
686
  age: Âge
460
687
  lock_key: Clé de verrou
461
688
  msg_id: ID du message
@@ -483,8 +710,6 @@ fr:
483
710
  pending: En attente
484
711
  published: Publié
485
712
  stats:
486
- no_age: "—"
487
- oldest_age: "%{seconds}s"
488
713
  oldest_unpublished: Plus ancien non publié
489
714
  total: Total
490
715
  unpublished: Non publié
@@ -493,18 +718,76 @@ fr:
493
718
  index:
494
719
  title: Processus
495
720
  processes_table:
721
+ capsule: capsule %{capsule} · processus %{process}
496
722
  empty: Aucun processus en cours d'exécution
497
723
  headers:
498
- hostname: Nom d'hôte
499
- kind: Type
500
- last_heartbeat: Dernier battement de cœur
501
- metadata: Métadonnées
502
- pid: PID
724
+ activity: Activité
725
+ heartbeat: Battement
726
+ process: Processus
727
+ recycle: Recyclage
503
728
  status: Statut
504
- rates:
505
- dequeued: retirés
506
- failed: échoués
507
- processed: traités
729
+ no_raw_metadata: Aucune autre métadonnée
730
+ raw_metadata: Autres métadonnées
731
+ started: Démarré
732
+ under_supervisor: sous le superviseur %{pid}
733
+ uptime: actif depuis %{duration}
734
+ state:
735
+ activity:
736
+ buffered: "%{number} en tampon"
737
+ busy_slots: "%{busy}/%{capacity} slots occupés"
738
+ busy_threads: "%{busy}/%{capacity} threads occupés"
739
+ consumes: Consomme %{topics}
740
+ drains: Vide %{queues}
741
+ drains_all: Vide toutes les files
742
+ failed_rate: "%{rate} échecs/s"
743
+ handled: "%{number} traités"
744
+ maintenance: Lance la maintenance toutes les %{interval} (jobs planifiés, processus morts, archives)
745
+ outbox: Publie les entrées de l'outbox
746
+ rate: "%{rate} jobs/s"
747
+ schedule:
748
+ one: Exécute %{count} tâche récurrente, vérifie toutes les %{interval}
749
+ other: Exécute %{count} tâches récurrentes, vérifie toutes les %{interval}
750
+ slots:
751
+ one: "%{count} slot"
752
+ other: "%{count} slots"
753
+ supervises: Supervise %{children}
754
+ supervises_none: Ne supervise aucun processus sur cet hôte
755
+ threads:
756
+ one: "%{count} thread"
757
+ other: "%{count} threads"
758
+ kinds:
759
+ consumer:
760
+ one: "%{count} consommateur"
761
+ other: "%{count} consommateurs"
762
+ dispatcher:
763
+ one: dispatcher
764
+ other: "%{count} dispatchers"
765
+ outbox_poller:
766
+ one: poller d'outbox
767
+ other: "%{count} pollers d'outbox"
768
+ scheduler:
769
+ one: planificateur
770
+ other: "%{count} planificateurs"
771
+ worker:
772
+ one: "%{count} worker"
773
+ other: "%{count} workers"
774
+ next:
775
+ stale_reaped: probablement mort ; retiré au prochain passage du dispatcher (sous %{within})
776
+ stale_unreaped: probablement mort ; aucun dispatcher vivant pour le retirer
777
+ stalled_maintenance: les jobs planifiés, le nettoyage des processus morts et la compaction des archives n'avancent plus
778
+ stalled_schedule: les tâches récurrentes ne sont plus mises en file
779
+ stalled_standalone: aucun superviseur pour le redémarrer
780
+ stalled_supervised: le watchdog du superviseur le redémarre
781
+ reasons:
782
+ healthy_detection_off_html: Battement %{ago} (limite %{limit}) · détection de blocage désactivée
783
+ healthy_heartbeat_html: Battement %{ago} (limite %{limit})
784
+ healthy_loop_html: Boucle avancée %{ago} (limite %{limit})
785
+ stale_html: Aucun battement depuis %{age} (limite %{limit})
786
+ stalled_html: Boucle avancée pour la dernière fois %{ago} (limite %{limit})
787
+ recycle:
788
+ jobs: "%{done} / %{limit} jobs"
789
+ lifetime: actif depuis %{uptime} / %{limit}
790
+ memory: "%{used} / %{limit} Mo"
508
791
  queues:
509
792
  destroy:
510
793
  success: File d'attente %{name} supprimée.
@@ -517,59 +800,70 @@ fr:
517
800
  headers:
518
801
  actions: Actions
519
802
  depth: Profondeur
520
- newest: Le plus récent (s)
521
- oldest_claimable: Plus ancien disponible (s)
803
+ newest: Le plus récent
804
+ oldest_claimable: Plus ancien disponible
522
805
  parked: Différés
523
806
  queue: File d'attente
524
807
  total_ever: Total jamais
525
808
  visible: Visible
526
809
  pause: Pause
527
810
  pause_confirm: Mettre en pause le traitement pour %{name} ?
528
- paused: En pause
529
811
  purge: Purger
530
812
  purge_confirm: Purger tous les messages de %{name} ?
531
813
  resume: Reprendre
532
814
  show:
533
- arguments: Arguments
534
815
  back: Retour aux files d'attente
535
816
  delete_confirm: Supprimer définitivement cette file d'attente ? Cette action est irréversible.
536
817
  delete_queue: Supprimer la file d'attente
537
- depth: 'Profondeur :'
538
- discard: Rejeter
539
- discard_confirm: Rejeter ce message ?
540
- empty: La file d'attente est vide
541
- full_json_payload: Charge utile JSON complète
542
- headers:
543
- enqueued: Enregistré
544
- id: ID
545
- job_class: Classe de travail
546
- reads: Lectures
547
- vt: VT
548
- headers_section: En-têtes
549
- job_id: 'ID du travail :'
818
+ dlq_link: Les relancer ou les supprimer sur la page Dead Letter
819
+ dlq_pointer:
820
+ one: File de lettres mortes de %{logical} — %{count} message.
821
+ other: File de lettres mortes de %{logical} — %{count} messages.
550
822
  message_discard_failed: Impossible de rejeter le message.
551
823
  message_discarded: Message rejeté.
552
824
  message_retried: Visibilité du message réinitialisée.
553
825
  message_retry_failed: Impossible de réessayer le message.
554
- metadata: Métadonnées
555
- metadata_labels:
556
- last_read: 'Dernière lecture :'
557
- locale: 'Langue :'
558
- priority: 'Priorité :'
559
- queue: 'File d''attente :'
560
- scheduled: 'Planifié :'
561
- timezone: 'Fuseau horaire :'
562
- visible_at: 'Visible à :'
563
- oldest: 'Plus ancien :'
564
- oldest_claimable: 'Plus ancien disponible :'
565
- parked: 'Différés :'
826
+ metrics:
827
+ claimable: Récupérables
828
+ depth: Profondeur
829
+ oldest: Plus ancien
830
+ oldest_claimable: Plus ancien récupérable
831
+ parked: En attente
832
+ total: Total cumulé
833
+ other_levels: 'Autres niveaux de priorité :'
566
834
  pause: Pause
567
835
  pause_confirm: Mettre en pause le traitement ?
568
836
  purge_confirm: Purger tous les messages ?
569
837
  purge_queue: Purger la file d'attente
570
838
  resume: Reprendre
571
- retry: Réessayer
572
- retry_confirm: Réinitialiser le délai de visibilité et réessayer ?
839
+ summary:
840
+ backlog_html: "%{visible} récupérables maintenant, le plus ancien attend depuis %{age} · %{parked} en attente (planifiés ou en nouvelle tentative)"
841
+ backlog_parked_only_html: Rien de récupérable maintenant · %{parked} en attente (planifiés ou en nouvelle tentative)
842
+ dlq_html: 'File de lettres mortes de %{logical} : les jobs arrivent ici après %{max} tentatives échouées'
843
+ drained_by_html:
844
+ one: Vidée par %{capsules} (%{count} worker sain)
845
+ other: Vidée par %{capsules} (%{count} workers sains)
846
+ drained_live_html:
847
+ one: Vidée par %{count} worker sain qui écoute cette file
848
+ other: Vidée par %{count} workers sains qui écoutent cette file
849
+ drained_wildcard_html:
850
+ one: Vidée par une capsule de workers joker (%{count} worker sain)
851
+ other: Vidée par une capsule de workers joker (%{count} workers sains)
852
+ empty_html: Rien en attente
853
+ handler_html: File de gestionnaire d'événements — vidée par les consommateurs (%{count} sains)
854
+ no_consumers_html:
855
+ one: File de gestionnaire d'événements sans consommateur sain — %{count} événement attend
856
+ other: File de gestionnaire d'événements sans consommateur sain — %{count} événements attendent
857
+ no_workers_html:
858
+ one: Aucun worker sain en cours — %{count} job est récupérable mais personne ne le prend
859
+ other: Aucun worker sain en cours — %{count} jobs sont récupérables mais personne ne les prend
860
+ not_drained_html: Aucune capsule de workers ne vide cette file — les jobs attendent qu'une soit configurée
861
+ paused_circuit_breaker_html: Mise en pause automatiquement %{ago} après %{failures} échecs consécutifs — reprend %{time} (déclenchement n°%{trip})
862
+ paused_operator_html: En pause %{ago} — %{reason}
863
+ paused_operator_no_reason_html: Mise en pause %{ago} par un opérateur
864
+ priority_level_html: Niveau de priorité %{level} de %{logical}
865
+ stream_html: File de stream — distribuée par peek, non vidée par les workers
866
+ summary_label: Résumé de la file
573
867
  table_health:
574
868
  headers:
575
869
  bloat: Bloat
@@ -579,8 +873,6 @@ fr:
579
873
  table: Table
580
874
  oldest_txn: 'Plus ancienne transaction ouverte :'
581
875
  title: Santé des tables
582
- total: 'Total :'
583
- visible: 'Visible :'
584
876
  recurring_tasks:
585
877
  index:
586
878
  task_count: