Subida de código

This commit is contained in:
Root
2025-05-30 19:09:28 +02:00
parent 31208a52ba
commit faa7458439
32 changed files with 1375 additions and 70 deletions

134
README.md
View File

@@ -1,93 +1,87 @@
# docker-whisper # Sistema Distribuido de Transcripción con Whisper
Este proyecto implementa un sistema distribuido para la transcripción de archivos de audio utilizando el modelo Whisper de OpenAI. El sistema divide los archivos de audio en segmentos más pequeños (de 5 minutos), procesa estos segmentos en paralelo utilizando múltiples contenedores, y luego unifica las transcripciones para generar un archivo de subtítulos.
## Arquitectura del Sistema
## Getting started El sistema está compuesto por cuatro tipos de componentes principales:
To make it easy for you to get started with GitLab, here's a list of recommended next steps. 1. **Receptor (Receiver)**: Monitorea el directorio de entrada para nuevos archivos de audio y los envía a RabbitMQ para su procesamiento.
2. **Particionador (Splitter)**: Divide los archivos de audio en segmentos de 5 minutos.
3. **Procesadores (Processors)**: Transcriben los segmentos de audio utilizando Whisper (7 contenedores en paralelo).
4. **Unificador (Unifier)**: Recopila todas las transcripciones, las ordena y genera un archivo final de subtítulos (.srt).
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! ## Requisitos previos
## Add your files - Docker
- Docker Compose
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files ## Estructura del proyecto
- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command:
``` ```
cd existing_repo whisper-distributed/
git remote add origin http://gitlab.local/root/docker-whisper.git ├── docker-compose.yml # Definición de los servicios
git branch -M main ├── input/ # Directorio para colocar los archivos de audio a transcribir
git push -uf origin main ├── output/ # Directorio donde se guardarán los subtítulos generados
├── shared/ # Directorio compartido para almacenamiento temporal
├── processor/ # Código del procesador Whisper
│ ├── app.py
│ └── Dockerfile
├── receiver/ # Código del receptor
│ ├── app.py
│ └── Dockerfile
├── splitter/ # Código del particionador
│ ├── app.py
│ └── Dockerfile
└── unifier/ # Código del unificador
├── app.py
└── Dockerfile
``` ```
## Integrate with your tools ## Uso del sistema
- [ ] [Set up project integrations](http://gitlab.local/root/docker-whisper/-/settings/integrations) 1. **Preparación**:
```bash
docker-compose build
```
## Collaborate with your team 2. **Iniciar el sistema**:
```bash
docker-compose up -d
```
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) 3. **Uso**:
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) - Coloca los archivos de audio que deseas transcribir en el directorio `input/`.
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) - El sistema detectará automáticamente los archivos y comenzará a procesarlos.
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) - Los subtítulos resultantes se guardarán en el directorio `output/` con el formato `nombre_original_transcription.srt`.
- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/)
## Test and Deploy 4. **Monitoreo de logs**:
```bash
docker-compose logs -f
```
Use the built-in continuous integration in GitLab. 5. **Detener el sistema**:
```bash
docker-compose down
```
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/) ## Flujo de trabajo
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
*** 1. El **receptor** detecta un nuevo archivo de audio en el directorio `input/` y lo envía a la cola `audio_split_queue`.
2. El **particionador** recibe el archivo, lo divide en segmentos de 5 minutos y envía cada segmento a la cola `audio_process_queue`.
3. Los **procesadores** (7 contenedores) reciben los segmentos, los transcriben utilizando Whisper y envían las transcripciones a la cola `text_unify_queue`.
4. El **unificador** recopila todas las transcripciones de un mismo archivo, las ordena según su posición original y genera un archivo de subtítulos en formato SRT.
# Editing this README ## Configuración
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. El sistema viene configurado con valores predeterminados, pero se pueden ajustar varios parámetros:
## Suggestions for a good README - **Tamaño de los segmentos**: Por defecto, 5 minutos. Se puede modificar en `splitter/app.py` (variable `SEGMENT_DURATION_MS`).
- **Modelo de Whisper**: Por defecto, "base". Se puede cambiar a "tiny", "small", "medium" o "large" en `processor/app.py` (variable `WHISPER_MODEL`).
- **Número de procesadores**: Se pueden agregar o quitar procesadores modificando el archivo `docker-compose.yml`.
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. ## Notas
## Name - El modelo "base" de Whisper ofrece un buen equilibrio entre precisión y velocidad. Los modelos más grandes (como "medium" o "large") son más precisos pero requieren más recursos.
Choose a self-explaining name for your project. - Para archivos muy largos, el sistema puede tardar bastante tiempo en procesarlos, especialmente con modelos grandes.
- Asegúrate de tener suficiente espacio en disco para los archivos temporales.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

0
logs/log_processor1.log Normal file
View File

308
logs/log_rabbitMQ.log Normal file
View File

@@ -0,0 +1,308 @@
2025-05-08 00:39:50 2025-05-07 22:39:50.662362+00:00 [notice] <0.44.0> Application syslog exited with reason: stopped
2025-05-08 00:39:50 2025-05-07 22:39:50.668550+00:00 [notice] <0.254.0> Logging: switching to configured handler(s); following messages may not be visible in this log output
2025-05-08 00:39:50 2025-05-07 22:39:50.669346+00:00 [notice] <0.254.0> Logging: configured log handlers are now ACTIVE
2025-05-08 00:39:50 2025-05-07 22:39:50.681515+00:00 [info] <0.254.0> ra: starting system quorum_queues
2025-05-08 00:39:50 2025-05-07 22:39:50.681675+00:00 [info] <0.254.0> starting Ra system: quorum_queues in directory: /var/lib/rabbitmq/mnesia/rabbit@62947c89d30c/quorum/rabbit@62947c89d30c
2025-05-08 00:39:50 2025-05-07 22:39:50.750228+00:00 [info] <0.268.0> ra system 'quorum_queues' running pre init for 0 registered servers
2025-05-08 00:39:50 2025-05-07 22:39:50.760336+00:00 [info] <0.269.0> ra: meta data store initialised for system quorum_queues. 0 record(s) recovered
2025-05-08 00:39:50 2025-05-07 22:39:50.776980+00:00 [notice] <0.274.0> WAL: ra_log_wal init, open tbls: ra_log_open_mem_tables, closed tbls: ra_log_closed_mem_tables
2025-05-08 00:39:50 2025-05-07 22:39:50.815739+00:00 [info] <0.254.0> ra: starting system coordination
2025-05-08 00:39:50 2025-05-07 22:39:50.815953+00:00 [info] <0.254.0> starting Ra system: coordination in directory: /var/lib/rabbitmq/mnesia/rabbit@62947c89d30c/coordination/rabbit@62947c89d30c
2025-05-08 00:39:50 2025-05-07 22:39:50.824238+00:00 [info] <0.282.0> ra system 'coordination' running pre init for 0 registered servers
2025-05-08 00:39:50 2025-05-07 22:39:50.827046+00:00 [info] <0.283.0> ra: meta data store initialised for system coordination. 0 record(s) recovered
2025-05-08 00:39:50 2025-05-07 22:39:50.827537+00:00 [notice] <0.288.0> WAL: ra_coordination_log_wal init, open tbls: ra_coordination_log_open_mem_tables, closed tbls: ra_coordination_log_closed_mem_tables
2025-05-08 00:39:50 2025-05-07 22:39:50.838825+00:00 [info] <0.254.0> ra: starting system coordination
2025-05-08 00:39:50 2025-05-07 22:39:50.838959+00:00 [info] <0.254.0> starting Ra system: coordination in directory: /var/lib/rabbitmq/mnesia/rabbit@62947c89d30c/coordination/rabbit@62947c89d30c
2025-05-08 00:39:51 2025-05-07 22:39:51.018518+00:00 [info] <0.254.0> Waiting for Khepri leader for 30000 ms, 9 retries left
2025-05-08 00:39:51 2025-05-07 22:39:51.048630+00:00 [notice] <0.292.0> RabbitMQ metadata store: candidate -> leader in term: 1 machine version: 1
2025-05-08 00:39:51 2025-05-07 22:39:51.059311+00:00 [info] <0.254.0> Khepri leader elected
2025-05-08 00:39:51 2025-05-07 22:39:51.059415+00:00 [info] <0.254.0> Waiting for Khepri projections for 30000 ms, 9 retries left
2025-05-08 00:39:51 2025-05-07 22:39:51.554340+00:00 [info] <0.254.0>
2025-05-08 00:39:51 2025-05-07 22:39:51.554340+00:00 [info] <0.254.0> Starting RabbitMQ 3.13.7 on Erlang 26.2.5.11 [jit]
2025-05-08 00:39:51 2025-05-07 22:39:51.554340+00:00 [info] <0.254.0> Copyright (c) 2007-2024 Broadcom Inc and/or its subsidiaries
2025-05-08 00:39:51 2025-05-07 22:39:51.554340+00:00 [info] <0.254.0> Licensed under the MPL 2.0. Website: https://rabbitmq.com
2025-05-08 00:39:51
2025-05-08 00:39:51 ## ## RabbitMQ 3.13.7
2025-05-08 00:39:51 ## ##
2025-05-08 00:39:51 ########## Copyright (c) 2007-2024 Broadcom Inc and/or its subsidiaries
2025-05-08 00:39:51 ###### ##
2025-05-08 00:39:51 ########## Licensed under the MPL 2.0. Website: https://rabbitmq.com
2025-05-08 00:39:51
2025-05-08 00:39:51 Erlang: 26.2.5.11 [jit]
2025-05-08 00:39:51 TLS Library: OpenSSL - OpenSSL 3.1.8 11 Feb 2025
2025-05-08 00:39:51 Release series support status: see https://www.rabbitmq.com/release-information
2025-05-08 00:39:51
2025-05-08 00:39:51 Doc guides: https://www.rabbitmq.com/docs
2025-05-08 00:39:51 Support: https://www.rabbitmq.com/docs/contact
2025-05-08 00:39:51 Tutorials: https://www.rabbitmq.com/tutorials
2025-05-08 00:39:51 Monitoring: https://www.rabbitmq.com/docs/monitoring
2025-05-08 00:39:51 Upgrading: https://www.rabbitmq.com/docs/upgrade
2025-05-08 00:39:51
2025-05-08 00:39:51 Logs: <stdout>
2025-05-08 00:39:51
2025-05-08 00:39:51 Config file(s): /etc/rabbitmq/conf.d/10-defaults.conf
2025-05-08 00:39:51
2025-05-08 00:39:51 Starting broker...2025-05-07 22:39:51.555311+00:00 [info] <0.254.0>
2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> node : rabbit@62947c89d30c
2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> home dir : /var/lib/rabbitmq
2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> config file(s) : /etc/rabbitmq/conf.d/10-defaults.conf
2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> cookie hash : I86zuTAeUmEN7sUO2/OmLw==
2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> log(s) : <stdout>
2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> data dir : /var/lib/rabbitmq/mnesia/rabbit@62947c89d30c
2025-05-08 00:39:52 2025-05-07 22:39:52.138572+00:00 [info] <0.254.0> Running boot step pre_boot defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.138716+00:00 [info] <0.254.0> Running boot step rabbit_global_counters defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.138936+00:00 [info] <0.254.0> Running boot step rabbit_osiris_metrics defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.139028+00:00 [info] <0.254.0> Running boot step rabbit_core_metrics defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.140039+00:00 [info] <0.254.0> Running boot step rabbit_alarm defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.148091+00:00 [info] <0.329.0> Memory high watermark set to 1899 MiB (1991522713 bytes) of 4748 MiB (4978806784 bytes) total
2025-05-08 00:39:52 2025-05-07 22:39:52.150701+00:00 [info] <0.331.0> Enabling free disk space monitoring (disk free space: 994872799232, total memory: 4978806784)
2025-05-08 00:39:52 2025-05-07 22:39:52.150797+00:00 [info] <0.331.0> Disk free limit set to 50MB
2025-05-08 00:39:52 2025-05-07 22:39:52.152232+00:00 [info] <0.254.0> Running boot step code_server_cache defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.152342+00:00 [info] <0.254.0> Running boot step file_handle_cache defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.156605+00:00 [info] <0.334.0> Limiting to approx 1048479 file handles (943629 sockets)
2025-05-08 00:39:52 2025-05-07 22:39:52.156820+00:00 [info] <0.335.0> FHC read buffering: OFF
2025-05-08 00:39:52 2025-05-07 22:39:52.156868+00:00 [info] <0.335.0> FHC write buffering: ON
2025-05-08 00:39:52 2025-05-07 22:39:52.157230+00:00 [info] <0.254.0> Running boot step worker_pool defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.157360+00:00 [info] <0.315.0> Will use 8 processes for default worker pool
2025-05-08 00:39:52 2025-05-07 22:39:52.157393+00:00 [info] <0.315.0> Starting worker pool 'worker_pool' with 8 processes in it
2025-05-08 00:39:52 2025-05-07 22:39:52.157880+00:00 [info] <0.254.0> Running boot step database defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.158346+00:00 [info] <0.254.0> Peer discovery: configured backend: rabbit_peer_discovery_classic_config
2025-05-08 00:39:52 2025-05-07 22:39:52.159944+00:00 [notice] <0.316.0> Feature flags: attempt to enable `detailed_queues_endpoint`...
2025-05-08 00:39:52 2025-05-07 22:39:52.241270+00:00 [notice] <0.316.0> Feature flags: `detailed_queues_endpoint` enabled
2025-05-08 00:39:52 2025-05-07 22:39:52.241471+00:00 [notice] <0.316.0> Feature flags: attempt to enable `quorum_queue_non_voters`...
2025-05-08 00:39:52 2025-05-07 22:39:52.318612+00:00 [notice] <0.316.0> Feature flags: `quorum_queue_non_voters` enabled
2025-05-08 00:39:52 2025-05-07 22:39:52.318879+00:00 [notice] <0.316.0> Feature flags: attempt to enable `stream_update_config_command`...
2025-05-08 00:39:52 2025-05-07 22:39:52.395204+00:00 [notice] <0.316.0> Feature flags: `stream_update_config_command` enabled
2025-05-08 00:39:52 2025-05-07 22:39:52.395479+00:00 [notice] <0.316.0> Feature flags: attempt to enable `stream_filtering`...
2025-05-08 00:39:52 2025-05-07 22:39:52.485430+00:00 [notice] <0.316.0> Feature flags: `stream_filtering` enabled
2025-05-08 00:39:52 2025-05-07 22:39:52.485608+00:00 [notice] <0.316.0> Feature flags: attempt to enable `stream_sac_coordinator_unblock_group`...
2025-05-08 00:39:52 2025-05-07 22:39:52.569301+00:00 [notice] <0.316.0> Feature flags: `stream_sac_coordinator_unblock_group` enabled
2025-05-08 00:39:52 2025-05-07 22:39:52.569692+00:00 [notice] <0.316.0> Feature flags: attempt to enable `restart_streams`...
2025-05-08 00:39:52 2025-05-07 22:39:52.653870+00:00 [notice] <0.316.0> Feature flags: `restart_streams` enabled
2025-05-08 00:39:52 2025-05-07 22:39:52.654465+00:00 [notice] <0.316.0> Feature flags: attempt to enable `message_containers`...
2025-05-08 00:39:52 2025-05-07 22:39:52.742245+00:00 [notice] <0.316.0> Feature flags: `message_containers` enabled
2025-05-08 00:39:52 2025-05-07 22:39:52.742447+00:00 [notice] <0.316.0> Feature flags: attempt to enable `message_containers_deaths_v2`...
2025-05-08 00:39:52 2025-05-07 22:39:52.826180+00:00 [notice] <0.316.0> Feature flags: `message_containers_deaths_v2` enabled
2025-05-08 00:39:52 2025-05-07 22:39:52.826431+00:00 [info] <0.254.0> DB: virgin node -> run peer discovery
2025-05-08 00:39:52 2025-05-07 22:39:52.826525+00:00 [warning] <0.254.0> Classic peer discovery backend: list of nodes does not contain the local node []
2025-05-08 00:39:52 2025-05-07 22:39:52.836796+00:00 [notice] <0.44.0> Application mnesia exited with reason: stopped
2025-05-08 00:39:52 2025-05-07 22:39:52.979237+00:00 [info] <0.254.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:39:52 2025-05-07 22:39:52.979423+00:00 [info] <0.254.0> Successfully synced tables from a peer
2025-05-08 00:39:52 2025-05-07 22:39:52.979552+00:00 [info] <0.254.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:39:52 2025-05-07 22:39:52.979670+00:00 [info] <0.254.0> Successfully synced tables from a peer
2025-05-08 00:39:52 2025-05-07 22:39:52.987684+00:00 [info] <0.254.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:39:52 2025-05-07 22:39:52.988064+00:00 [info] <0.254.0> Successfully synced tables from a peer
2025-05-08 00:39:52 2025-05-07 22:39:52.988311+00:00 [info] <0.254.0> Running boot step tracking_metadata_store defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.988509+00:00 [info] <0.562.0> Setting up a table for connection tracking on this node: tracked_connection
2025-05-08 00:39:52 2025-05-07 22:39:52.988576+00:00 [info] <0.562.0> Setting up a table for per-vhost connection counting on this node: tracked_connection_per_vhost
2025-05-08 00:39:52 2025-05-07 22:39:52.988699+00:00 [info] <0.562.0> Setting up a table for per-user connection counting on this node: tracked_connection_per_user
2025-05-08 00:39:52 2025-05-07 22:39:52.988775+00:00 [info] <0.562.0> Setting up a table for channel tracking on this node: tracked_channel
2025-05-08 00:39:52 2025-05-07 22:39:52.988891+00:00 [info] <0.562.0> Setting up a table for channel tracking on this node: tracked_channel_per_user
2025-05-08 00:39:52 2025-05-07 22:39:52.989007+00:00 [info] <0.254.0> Running boot step networking_metadata_store defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.989172+00:00 [info] <0.254.0> Running boot step feature_flags defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.989469+00:00 [info] <0.254.0> Running boot step codec_correctness_check defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.989589+00:00 [info] <0.254.0> Running boot step external_infrastructure defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.989669+00:00 [info] <0.254.0> Running boot step rabbit_event defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.989895+00:00 [info] <0.254.0> Running boot step rabbit_registry defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.989984+00:00 [info] <0.254.0> Running boot step rabbit_auth_mechanism_amqplain defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990074+00:00 [info] <0.254.0> Running boot step rabbit_auth_mechanism_cr_demo defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990135+00:00 [info] <0.254.0> Running boot step rabbit_auth_mechanism_plain defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990189+00:00 [info] <0.254.0> Running boot step rabbit_exchange_type_direct defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990262+00:00 [info] <0.254.0> Running boot step rabbit_exchange_type_fanout defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990316+00:00 [info] <0.254.0> Running boot step rabbit_exchange_type_headers defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990381+00:00 [info] <0.254.0> Running boot step rabbit_exchange_type_topic defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990437+00:00 [info] <0.254.0> Running boot step rabbit_mirror_queue_mode_all defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990494+00:00 [info] <0.254.0> Running boot step rabbit_mirror_queue_mode_exactly defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990555+00:00 [info] <0.254.0> Running boot step rabbit_mirror_queue_mode_nodes defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990618+00:00 [info] <0.254.0> Running boot step rabbit_priority_queue defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990647+00:00 [info] <0.254.0> Priority queues enabled, real BQ is rabbit_variable_queue
2025-05-08 00:39:52 2025-05-07 22:39:52.990693+00:00 [info] <0.254.0> Running boot step rabbit_queue_location_client_local defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990744+00:00 [info] <0.254.0> Running boot step rabbit_queue_location_min_masters defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990814+00:00 [info] <0.254.0> Running boot step rabbit_queue_location_random defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990862+00:00 [info] <0.254.0> Running boot step kernel_ready defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.990888+00:00 [info] <0.254.0> Running boot step rabbit_sysmon_minder defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.991053+00:00 [info] <0.254.0> Running boot step rabbit_epmd_monitor defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.991707+00:00 [info] <0.570.0> epmd monitor knows us, inter-node communication (distribution) port: 25672
2025-05-08 00:39:52 2025-05-07 22:39:52.991820+00:00 [info] <0.254.0> Running boot step guid_generator defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.994121+00:00 [info] <0.254.0> Running boot step rabbit_node_monitor defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.994475+00:00 [info] <0.574.0> Starting rabbit_node_monitor (in ignore mode)
2025-05-08 00:39:52 2025-05-07 22:39:52.994618+00:00 [info] <0.254.0> Running boot step delegate_sup defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.995245+00:00 [info] <0.254.0> Running boot step rabbit_memory_monitor defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.995645+00:00 [info] <0.254.0> Running boot step rabbit_fifo_dlx_sup defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.995793+00:00 [info] <0.254.0> Running boot step core_initialized defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.995875+00:00 [info] <0.254.0> Running boot step rabbit_channel_tracking_handler defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.995941+00:00 [info] <0.254.0> Running boot step rabbit_connection_tracking_handler defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.996042+00:00 [info] <0.254.0> Running boot step rabbit_definitions_hashing defined by app rabbit
2025-05-08 00:39:52 2025-05-07 22:39:52.996109+00:00 [info] <0.254.0> Running boot step rabbit_exchange_parameters defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.037017+00:00 [info] <0.254.0> Running boot step rabbit_mirror_queue_misc defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.037701+00:00 [info] <0.254.0> Running boot step rabbit_policies defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.038025+00:00 [info] <0.254.0> Running boot step rabbit_policy defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.038137+00:00 [info] <0.254.0> Running boot step rabbit_queue_location_validator defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.038446+00:00 [info] <0.254.0> Running boot step rabbit_quorum_memory_manager defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.038497+00:00 [info] <0.254.0> Running boot step rabbit_quorum_queue defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.038560+00:00 [info] <0.254.0> Running boot step rabbit_stream_coordinator defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.038722+00:00 [info] <0.254.0> Running boot step rabbit_vhost_limit defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.038916+00:00 [info] <0.254.0> Running boot step rabbit_federation_parameters defined by app rabbitmq_federation
2025-05-08 00:39:53 2025-05-07 22:39:53.039082+00:00 [info] <0.254.0> Running boot step rabbit_federation_supervisor defined by app rabbitmq_federation
2025-05-08 00:39:53 2025-05-07 22:39:53.048561+00:00 [info] <0.254.0> Running boot step rabbit_federation_queue defined by app rabbitmq_federation
2025-05-08 00:39:53 2025-05-07 22:39:53.048929+00:00 [info] <0.254.0> Running boot step rabbit_federation_upstream_exchange defined by app rabbitmq_federation
2025-05-08 00:39:53 2025-05-07 22:39:53.049101+00:00 [info] <0.254.0> Running boot step rabbit_mgmt_reset_handler defined by app rabbitmq_management
2025-05-08 00:39:53 2025-05-07 22:39:53.049203+00:00 [info] <0.254.0> Running boot step rabbit_mgmt_db_handler defined by app rabbitmq_management_agent
2025-05-08 00:39:53 2025-05-07 22:39:53.049249+00:00 [info] <0.254.0> Management plugin: using rates mode 'basic'
2025-05-08 00:39:53 2025-05-07 22:39:53.049570+00:00 [info] <0.254.0> Running boot step recovery defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.065051+00:00 [info] <0.254.0> Running boot step empty_db_check defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.065272+00:00 [info] <0.254.0> Will seed default virtual host and user...
2025-05-08 00:39:53 2025-05-07 22:39:53.065643+00:00 [info] <0.254.0> Adding vhost '/' (description: 'Default virtual host', tags: [])
2025-05-08 00:39:53 2025-05-07 22:39:53.086530+00:00 [info] <0.634.0> Making sure data directory '/var/lib/rabbitmq/mnesia/rabbit@62947c89d30c/msg_stores/vhosts/628WB79CIFDYO9LJI6DKMI09L' for vhost '/' exists
2025-05-08 00:39:53 2025-05-07 22:39:53.088241+00:00 [info] <0.634.0> Setting segment_entry_count for vhost '/' with 0 queues to '2048'
2025-05-08 00:39:53 2025-05-07 22:39:53.097360+00:00 [info] <0.634.0> Starting message stores for vhost '/'
2025-05-08 00:39:53 2025-05-07 22:39:53.097592+00:00 [info] <0.643.0> Message store "628WB79CIFDYO9LJI6DKMI09L/msg_store_transient": using rabbit_msg_store_ets_index to provide index
2025-05-08 00:39:53 2025-05-07 22:39:53.100863+00:00 [info] <0.634.0> Started message store of type transient for vhost '/'
2025-05-08 00:39:53 2025-05-07 22:39:53.101137+00:00 [info] <0.647.0> Message store "628WB79CIFDYO9LJI6DKMI09L/msg_store_persistent": using rabbit_msg_store_ets_index to provide index
2025-05-08 00:39:53 2025-05-07 22:39:53.101782+00:00 [warning] <0.647.0> Message store "628WB79CIFDYO9LJI6DKMI09L/msg_store_persistent": rebuilding indices from scratch
2025-05-08 00:39:53 2025-05-07 22:39:53.102437+00:00 [info] <0.634.0> Started message store of type persistent for vhost '/'
2025-05-08 00:39:53 2025-05-07 22:39:53.102574+00:00 [info] <0.634.0> Recovering 0 queues of type rabbit_classic_queue took 13ms
2025-05-08 00:39:53 2025-05-07 22:39:53.102629+00:00 [info] <0.634.0> Recovering 0 queues of type rabbit_quorum_queue took 0ms
2025-05-08 00:39:53 2025-05-07 22:39:53.102676+00:00 [info] <0.634.0> Recovering 0 queues of type rabbit_stream_queue took 0ms
2025-05-08 00:39:53 2025-05-07 22:39:53.107559+00:00 [info] <0.254.0> Created user 'user'
2025-05-08 00:39:53 2025-05-07 22:39:53.110154+00:00 [info] <0.254.0> Successfully set user tags for user 'user' to [administrator]
2025-05-08 00:39:53 2025-05-07 22:39:53.112408+00:00 [info] <0.254.0> Successfully set permissions for user 'user' in virtual host '/' to '.*', '.*', '.*'
2025-05-08 00:39:53 2025-05-07 22:39:53.112490+00:00 [info] <0.254.0> Running boot step rabbit_observer_cli defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.112766+00:00 [info] <0.254.0> Running boot step rabbit_looking_glass defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.112830+00:00 [info] <0.254.0> Running boot step rabbit_core_metrics_gc defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.113033+00:00 [info] <0.254.0> Running boot step background_gc defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.113192+00:00 [info] <0.254.0> Running boot step routing_ready defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.113230+00:00 [info] <0.254.0> Running boot step pre_flight defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.113268+00:00 [info] <0.254.0> Running boot step notify_cluster defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.113305+00:00 [info] <0.254.0> Running boot step networking defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.113352+00:00 [info] <0.254.0> Running boot step rabbit_quorum_queue_periodic_membership_reconciliation defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.113466+00:00 [info] <0.254.0> Running boot step definition_import_worker_pool defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.113521+00:00 [info] <0.315.0> Starting worker pool 'definition_import_pool' with 8 processes in it
2025-05-08 00:39:53 2025-05-07 22:39:53.114143+00:00 [info] <0.254.0> Running boot step cluster_name defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.114227+00:00 [info] <0.254.0> Initialising internal cluster ID to 'rabbitmq-cluster-id-npKafAOABkeMhPtpDbOVuw'
2025-05-08 00:39:53 2025-05-07 22:39:53.116441+00:00 [info] <0.254.0> Running boot step virtual_host_reconciliation defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.116731+00:00 [info] <0.254.0> Running boot step direct_client defined by app rabbit
2025-05-08 00:39:53 2025-05-07 22:39:53.116820+00:00 [info] <0.254.0> Running boot step rabbit_federation_exchange defined by app rabbitmq_federation
2025-05-08 00:39:53 2025-05-07 22:39:53.116952+00:00 [info] <0.254.0> Running boot step rabbit_management_load_definitions defined by app rabbitmq_management
2025-05-08 00:39:53 2025-05-07 22:39:53.117033+00:00 [info] <0.688.0> Resetting node maintenance status
2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> Deprecated features: `management_metrics_collection`: Feature `management_metrics_collection` is deprecated.
2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> By default, this feature can still be used for now.
2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> Its use will not be permitted by default in a future minor RabbitMQ version and the feature will be removed from a future major RabbitMQ version; actual versions to be determined.
2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> To continue using this feature when it is not permitted by default, set the following parameter in your configuration:
2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> "deprecated_features.permit.management_metrics_collection = true"
2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> To test RabbitMQ as if the feature was removed, set this in your configuration:
2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> "deprecated_features.permit.management_metrics_collection = false"
2025-05-08 00:39:56 2025-05-07 22:39:56.676986+00:00 [info] <0.754.0> Management plugin: HTTP (non-TLS) listener started on port 15672
2025-05-08 00:39:56 2025-05-07 22:39:56.677233+00:00 [info] <0.784.0> Statistics database started.
2025-05-08 00:39:56 2025-05-07 22:39:56.677362+00:00 [info] <0.783.0> Starting worker pool 'management_worker_pool' with 3 processes in it
2025-05-08 00:39:56 2025-05-07 22:39:56.688467+00:00 [info] <0.802.0> Prometheus metrics: HTTP (non-TLS) listener started on port 15692
2025-05-08 00:39:56 2025-05-07 22:39:56.688698+00:00 [info] <0.688.0> Ready to start client connection listeners
2025-05-08 00:39:56 2025-05-07 22:39:56.690341+00:00 [info] <0.846.0> started TCP listener on [::]:5672
2025-05-08 00:39:56 completed with 5 plugins.
2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> Server startup complete; 5 plugins started.
2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_prometheus
2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_federation
2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_management
2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_management_agent
2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_web_dispatch
2025-05-08 00:39:56 2025-05-07 22:39:56.763812+00:00 [info] <0.9.0> Time to start RabbitMQ: 21128 ms
2025-05-08 00:39:57 2025-05-07 22:39:57.325312+00:00 [info] <0.850.0> accepting AMQP connection <0.850.0> (172.18.0.10:54858 -> 172.18.0.2:5672)
2025-05-08 00:39:57 2025-05-07 22:39:57.329386+00:00 [info] <0.850.0> connection <0.850.0> (172.18.0.10:54858 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:40:01 2025-05-07 22:40:01.156082+00:00 [info] <0.875.0> accepting AMQP connection <0.875.0> (172.18.0.5:44442 -> 172.18.0.2:5672)
2025-05-08 00:40:01 2025-05-07 22:40:01.158843+00:00 [info] <0.875.0> connection <0.875.0> (172.18.0.5:44442 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:40:15 2025-05-07 22:40:15.943110+00:00 [info] <0.893.0> accepting AMQP connection <0.893.0> (172.18.0.6:41738 -> 172.18.0.2:5672)
2025-05-08 00:40:15 2025-05-07 22:40:15.960296+00:00 [info] <0.893.0> connection <0.893.0> (172.18.0.6:41738 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:40:17 2025-05-07 22:40:17.098095+00:00 [info] <0.906.0> accepting AMQP connection <0.906.0> (172.18.0.8:35750 -> 172.18.0.2:5672)
2025-05-08 00:40:17 2025-05-07 22:40:17.232657+00:00 [info] <0.906.0> connection <0.906.0> (172.18.0.8:35750 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:40:18 2025-05-07 22:40:18.059680+00:00 [info] <0.919.0> accepting AMQP connection <0.919.0> (172.18.0.4:33952 -> 172.18.0.2:5672)
2025-05-08 00:40:18 2025-05-07 22:40:18.076198+00:00 [info] <0.919.0> connection <0.919.0> (172.18.0.4:33952 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:40:19 2025-05-07 22:40:19.149330+00:00 [info] <0.932.0> accepting AMQP connection <0.932.0> (172.18.0.11:58748 -> 172.18.0.2:5672)
2025-05-08 00:40:19 2025-05-07 22:40:19.155624+00:00 [info] <0.932.0> connection <0.932.0> (172.18.0.11:58748 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:40:20 2025-05-07 22:40:20.125333+00:00 [info] <0.945.0> accepting AMQP connection <0.945.0> (172.18.0.9:35214 -> 172.18.0.2:5672)
2025-05-08 00:40:20 2025-05-07 22:40:20.137163+00:00 [info] <0.945.0> connection <0.945.0> (172.18.0.9:35214 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:40:24 2025-05-07 22:40:24.253787+00:00 [info] <0.959.0> accepting AMQP connection <0.959.0> (172.18.0.7:44718 -> 172.18.0.2:5672)
2025-05-08 00:40:24 2025-05-07 22:40:24.261729+00:00 [info] <0.959.0> connection <0.959.0> (172.18.0.7:44718 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:40:28 2025-05-07 22:40:28.129182+00:00 [info] <0.972.0> accepting AMQP connection <0.972.0> (172.18.0.12:54626 -> 172.18.0.2:5672)
2025-05-08 00:40:28 2025-05-07 22:40:28.136032+00:00 [info] <0.972.0> connection <0.972.0> (172.18.0.12:54626 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:40:36 2025-05-07 22:40:36.606102+00:00 [notice] <0.86.0> alarm_handler: {set,{system_memory_high_watermark,[]}}
2025-05-08 00:42:28 2025-05-07 22:42:28.420562+00:00 [info] <0.1062.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:42:28 2025-05-07 22:42:28.421247+00:00 [info] <0.1062.0> Successfully synced tables from a peer
2025-05-08 00:42:32 2025-05-07 22:42:32.812303+00:00 [info] <0.1076.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:42:32 2025-05-07 22:42:32.812482+00:00 [info] <0.1076.0> Successfully synced tables from a peer
2025-05-08 00:42:42 2025-05-07 22:42:42.667226+00:00 [info] <0.1088.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:42:42 2025-05-07 22:42:42.667489+00:00 [info] <0.1088.0> Successfully synced tables from a peer
2025-05-08 00:45:46 2025-05-07 22:45:46.674479+00:00 [info] <0.1176.0> accepting AMQP connection <0.1176.0> (172.18.0.3:56882 -> 172.18.0.2:5672)
2025-05-08 00:45:46 2025-05-07 22:45:46.685208+00:00 [info] <0.1176.0> connection <0.1176.0> (172.18.0.3:56882 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:45:46 2025-05-07 22:45:46.707040+00:00 [info] <0.1176.0> closing AMQP connection <0.1176.0> (172.18.0.3:56882 -> 172.18.0.2:5672, vhost: '/', user: 'user')
2025-05-08 00:45:51 2025-05-07 22:45:51.693391+00:00 [info] <0.1195.0> accepting AMQP connection <0.1195.0> (172.18.0.10:42554 -> 172.18.0.2:5672)
2025-05-08 00:45:51 2025-05-07 22:45:51.708567+00:00 [info] <0.1195.0> connection <0.1195.0> (172.18.0.10:42554 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 00:45:51 2025-05-07 22:45:51.810772+00:00 [info] <0.1195.0> closing AMQP connection <0.1195.0> (172.18.0.10:42554 -> 172.18.0.2:5672, vhost: '/', user: 'user')
2025-05-08 00:46:08 2025-05-07 22:46:08.987067+00:00 [info] <0.1225.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:46:08 2025-05-07 22:46:08.987347+00:00 [info] <0.1225.0> Successfully synced tables from a peer
2025-05-08 00:46:11 2025-05-07 22:46:11.806552+00:00 [info] <0.1237.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:46:11 2025-05-07 22:46:11.806923+00:00 [info] <0.1237.0> Successfully synced tables from a peer
2025-05-08 00:46:24 2025-05-07 22:46:24.475575+00:00 [info] <0.1257.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:46:24 2025-05-07 22:46:24.475750+00:00 [info] <0.1257.0> Successfully synced tables from a peer
2025-05-08 00:46:30 2025-05-07 22:46:30.968293+00:00 [info] <0.1266.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:46:30 2025-05-07 22:46:30.968504+00:00 [info] <0.1266.0> Successfully synced tables from a peer
2025-05-08 00:46:34 2025-05-07 22:46:34.967466+00:00 [info] <0.1276.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:46:34 2025-05-07 22:46:34.967651+00:00 [info] <0.1276.0> Successfully synced tables from a peer
2025-05-08 00:46:35 2025-05-07 22:46:35.535311+00:00 [info] <0.1288.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:46:35 2025-05-07 22:46:35.535482+00:00 [info] <0.1288.0> Successfully synced tables from a peer
2025-05-08 00:48:15 2025-05-07 22:48:15.939642+00:00 [error] <0.893.0> closing AMQP connection <0.893.0> (172.18.0.6:41738 -> 172.18.0.2:5672):
2025-05-08 00:48:15 2025-05-07 22:48:15.939642+00:00 [error] <0.893.0> missed heartbeats from client, timeout: 60s
2025-05-08 00:48:17 2025-05-07 22:48:17.212677+00:00 [error] <0.906.0> closing AMQP connection <0.906.0> (172.18.0.8:35750 -> 172.18.0.2:5672):
2025-05-08 00:48:17 2025-05-07 22:48:17.212677+00:00 [error] <0.906.0> missed heartbeats from client, timeout: 60s
2025-05-08 00:48:18 2025-05-07 22:48:18.058676+00:00 [error] <0.919.0> closing AMQP connection <0.919.0> (172.18.0.4:33952 -> 172.18.0.2:5672):
2025-05-08 00:48:18 2025-05-07 22:48:18.058676+00:00 [error] <0.919.0> missed heartbeats from client, timeout: 60s
2025-05-08 00:48:19 2025-05-07 22:48:19.138623+00:00 [error] <0.932.0> closing AMQP connection <0.932.0> (172.18.0.11:58748 -> 172.18.0.2:5672):
2025-05-08 00:48:19 2025-05-07 22:48:19.138623+00:00 [error] <0.932.0> missed heartbeats from client, timeout: 60s
2025-05-08 00:49:47 2025-05-07 22:49:47.411874+00:00 [info] <0.1503.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:49:47 2025-05-07 22:49:47.423869+00:00 [info] <0.1503.0> Successfully synced tables from a peer
2025-05-08 00:49:49 2025-05-07 22:49:49.041300+00:00 [info] <0.1510.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:49:49 2025-05-07 22:49:49.065891+00:00 [info] <0.1510.0> Successfully synced tables from a peer
2025-05-08 00:50:10 2025-05-07 22:50:10.530545+00:00 [info] <0.1528.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:50:10 2025-05-07 22:50:10.545653+00:00 [info] <0.1528.0> Successfully synced tables from a peer
2025-05-08 00:50:20 2025-05-07 22:50:20.045026+00:00 [info] <0.1542.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:50:20 2025-05-07 22:50:20.081418+00:00 [info] <0.1542.0> Successfully synced tables from a peer
2025-05-08 00:50:20 2025-05-07 22:50:20.116816+00:00 [error] <0.945.0> closing AMQP connection <0.945.0> (172.18.0.9:35214 -> 172.18.0.2:5672):
2025-05-08 00:50:20 2025-05-07 22:50:20.116816+00:00 [error] <0.945.0> missed heartbeats from client, timeout: 60s
2025-05-08 00:50:24 2025-05-07 22:50:24.253931+00:00 [error] <0.959.0> closing AMQP connection <0.959.0> (172.18.0.7:44718 -> 172.18.0.2:5672):
2025-05-08 00:50:24 2025-05-07 22:50:24.253931+00:00 [error] <0.959.0> missed heartbeats from client, timeout: 60s
2025-05-08 00:50:28 2025-05-07 22:50:28.133809+00:00 [error] <0.972.0> closing AMQP connection <0.972.0> (172.18.0.12:54626 -> 172.18.0.2:5672):
2025-05-08 00:50:28 2025-05-07 22:50:28.133809+00:00 [error] <0.972.0> missed heartbeats from client, timeout: 60s
2025-05-08 00:52:17 2025-05-07 22:52:17.044407+00:00 [info] <0.1708.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:52:17 2025-05-07 22:52:17.092956+00:00 [info] <0.1708.0> Successfully synced tables from a peer
2025-05-08 00:52:25 2025-05-07 22:52:25.275627+00:00 [info] <0.1717.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:52:25 2025-05-07 22:52:25.277749+00:00 [info] <0.1717.0> Successfully synced tables from a peer
2025-05-08 00:52:26 2025-05-07 22:52:26.569660+00:00 [info] <0.1726.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:52:26 2025-05-07 22:52:26.597496+00:00 [info] <0.1726.0> Successfully synced tables from a peer
2025-05-08 00:52:27 2025-05-07 22:52:27.695674+00:00 [info] <0.1736.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:52:27 2025-05-07 22:52:27.698046+00:00 [info] <0.1736.0> Successfully synced tables from a peer
2025-05-08 00:52:28 2025-05-07 22:52:28.216426+00:00 [info] <0.1745.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:52:28 2025-05-07 22:52:28.301230+00:00 [info] <0.1745.0> Successfully synced tables from a peer
2025-05-08 00:52:35 2025-05-07 22:52:35.577230+00:00 [info] <0.1759.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:52:35 2025-05-07 22:52:35.581596+00:00 [info] <0.1759.0> Successfully synced tables from a peer
2025-05-08 00:52:40 2025-05-07 22:52:40.549543+00:00 [info] <0.1772.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:52:40 2025-05-07 22:52:40.621826+00:00 [info] <0.1772.0> Successfully synced tables from a peer
2025-05-08 00:52:49 2025-05-07 22:52:49.753059+00:00 [warning] <0.1777.0> AMQP 0-9-1 client call timeout was 70000 ms, is updated to a safe effective value of 130000 ms
2025-05-08 00:57:02 2025-05-07 22:57:02.200826+00:00 [info] <0.1954.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:57:02 2025-05-07 22:57:02.224175+00:00 [info] <0.1954.0> Successfully synced tables from a peer
2025-05-08 00:57:09 2025-05-07 22:57:09.305246+00:00 [info] <0.1968.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:57:09 2025-05-07 22:57:09.323530+00:00 [info] <0.1968.0> Successfully synced tables from a peer
2025-05-08 00:57:18 2025-05-07 22:57:18.337609+00:00 [info] <0.1982.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:57:18 2025-05-07 22:57:18.392710+00:00 [info] <0.1982.0> Successfully synced tables from a peer
2025-05-08 00:57:21 2025-05-07 22:57:21.654491+00:00 [info] <0.1990.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 00:57:21 2025-05-07 22:57:21.660117+00:00 [info] <0.1990.0> Successfully synced tables from a peer
2025-05-08 01:02:00 2025-05-07 23:02:00.731071+00:00 [info] <0.2166.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 01:02:00 2025-05-07 23:02:00.755919+00:00 [info] <0.2166.0> Successfully synced tables from a peer
2025-05-08 01:04:00 2025-05-07 23:04:00.787526+00:00 [info] <0.2286.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 01:04:00 2025-05-07 23:04:00.803380+00:00 [info] <0.2286.0> Successfully synced tables from a peer
2025-05-08 01:07:34 2025-05-07 23:07:34.311979+00:00 [info] <0.2406.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 01:07:34 2025-05-07 23:07:34.360990+00:00 [info] <0.2406.0> Successfully synced tables from a peer
2025-05-08 01:12:09 2025-05-07 23:12:09.342192+00:00 [info] <0.2664.0> Waiting for Mnesia tables for 30000 ms, 9 retries left
2025-05-08 01:12:09 2025-05-07 23:12:09.352579+00:00 [info] <0.2664.0> Successfully synced tables from a peer
2025-05-08 01:21:27 2025-05-07 23:21:27.224944+00:00 [info] <0.2998.0> accepting AMQP connection <0.2998.0> (172.18.0.11:50692 -> 172.18.0.2:5672)
2025-05-08 01:21:27 2025-05-07 23:21:27.235852+00:00 [info] <0.2998.0> connection <0.2998.0> (172.18.0.11:50692 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/'
2025-05-08 01:21:27 2025-05-07 23:21:27.277399+00:00 [info] <0.2998.0> closing AMQP connection <0.2998.0> (172.18.0.11:50692 -> 172.18.0.2:5672, vhost: '/', user: 'user')

74
logs/log_unifier.log Normal file
View File

@@ -0,0 +1,74 @@
2025-05-08 00:39:36 2025-05-07 22:39:36,064 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672)
2025-05-08 00:39:36 2025-05-07 22:39:36,073 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('172.18.0.5', 57130)>; error=111 (Connection refused)
2025-05-08 00:39:36 2025-05-07 22:39:36,074 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('172.18.0.2', 5672))
2025-05-08 00:39:36 2025-05-07 22:39:36,074 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused')
2025-05-08 00:39:36 2025-05-07 22:39:36,074 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None.
2025-05-08 00:39:36 2025-05-07 22:39:36,074 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:36 2025-05-07 22:39:36,075 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:36 2025-05-07 22:39:36,075 - pika.adapters.blocking_connection - ERROR - Error in _create_connection().
2025-05-08 00:39:36 Traceback (most recent call last):
2025-05-08 00:39:36 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection
2025-05-08 00:39:36 raise self._reap_last_connection_workflow_error(error)
2025-05-08 00:39:36 pika.exceptions.AMQPConnectionError
2025-05-08 00:39:36 2025-05-07 22:39:36,085 - unifier - WARNING - Intento 1: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...
2025-05-08 00:39:41 2025-05-07 22:39:41,115 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672)
2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('172.18.0.5', 57142)>; error=111 (Connection refused)
2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('172.18.0.2', 5672))
2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused')
2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None.
2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:41 2025-05-07 22:39:41,118 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:41 2025-05-07 22:39:41,118 - pika.adapters.blocking_connection - ERROR - Error in _create_connection().
2025-05-08 00:39:41 Traceback (most recent call last):
2025-05-08 00:39:41 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection
2025-05-08 00:39:41 raise self._reap_last_connection_workflow_error(error)
2025-05-08 00:39:41 pika.exceptions.AMQPConnectionError
2025-05-08 00:39:41 2025-05-07 22:39:41,118 - unifier - WARNING - Intento 2: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...
2025-05-08 00:39:46 2025-05-07 22:39:46,134 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672)
2025-05-08 00:39:46 2025-05-07 22:39:46,135 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('172.18.0.5', 46992)>; error=111 (Connection refused)
2025-05-08 00:39:46 2025-05-07 22:39:46,135 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('172.18.0.2', 5672))
2025-05-08 00:39:46 2025-05-07 22:39:46,135 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused')
2025-05-08 00:39:46 2025-05-07 22:39:46,136 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None.
2025-05-08 00:39:46 2025-05-07 22:39:46,136 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:46 2025-05-07 22:39:46,136 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:46 2025-05-07 22:39:46,136 - pika.adapters.blocking_connection - ERROR - Error in _create_connection().
2025-05-08 00:39:46 Traceback (most recent call last):
2025-05-08 00:39:46 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection
2025-05-08 00:39:46 raise self._reap_last_connection_workflow_error(error)
2025-05-08 00:39:46 pika.exceptions.AMQPConnectionError
2025-05-08 00:39:46 2025-05-07 22:39:46,138 - unifier - WARNING - Intento 3: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...
2025-05-08 00:39:51 2025-05-07 22:39:51,140 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672)
2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('172.18.0.5', 46998)>; error=111 (Connection refused)
2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('172.18.0.2', 5672))
2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused')
2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None.
2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.blocking_connection - ERROR - Error in _create_connection().
2025-05-08 00:39:51 Traceback (most recent call last):
2025-05-08 00:39:51 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection
2025-05-08 00:39:51 raise self._reap_last_connection_workflow_error(error)
2025-05-08 00:39:51 pika.exceptions.AMQPConnectionError
2025-05-08 00:39:51 2025-05-07 22:39:51,141 - unifier - WARNING - Intento 4: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...
2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672)
2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('172.18.0.5', 44438)>; error=111 (Connection refused)
2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('172.18.0.2', 5672))
2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused')
2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None.
2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None
2025-05-08 00:39:56 2025-05-07 22:39:56,151 - pika.adapters.blocking_connection - ERROR - Error in _create_connection().
2025-05-08 00:39:56 Traceback (most recent call last):
2025-05-08 00:39:56 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection
2025-05-08 00:39:56 raise self._reap_last_connection_workflow_error(error)
2025-05-08 00:39:56 pika.exceptions.AMQPConnectionError
2025-05-08 00:39:56 2025-05-07 22:39:56,151 - unifier - WARNING - Intento 5: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...
2025-05-08 00:40:01 2025-05-07 22:40:01,154 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672)
2025-05-08 00:40:01 2025-05-07 22:40:01,155 - pika.adapters.utils.io_services_utils - INFO - Socket connected: <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('172.18.0.5', 44442), raddr=('172.18.0.2', 5672)>
2025-05-08 00:40:01 2025-05-07 22:40:01,155 - pika.adapters.utils.connection_workflow - INFO - Streaming transport linked up: (<pika.adapters.utils.io_services_utils._AsyncPlaintextTransport object at 0x7f7f280782e0>, _StreamingProtocolShim: <SelectConnection PROTOCOL transport=<pika.adapters.utils.io_services_utils._AsyncPlaintextTransport object at 0x7f7f280782e0> params=<ConnectionParameters host=rabbitmq port=5672 virtual_host=/ ssl=False>>).
2025-05-08 00:40:01 2025-05-07 22:40:01,158 - pika.adapters.utils.connection_workflow - INFO - AMQPConnector - reporting success: <SelectConnection OPEN transport=<pika.adapters.utils.io_services_utils._AsyncPlaintextTransport object at 0x7f7f280782e0> params=<ConnectionParameters host=rabbitmq port=5672 virtual_host=/ ssl=False>>
2025-05-08 00:40:01 2025-05-07 22:40:01,158 - pika.adapters.utils.connection_workflow - INFO - AMQPConnectionWorkflow - reporting success: <SelectConnection OPEN transport=<pika.adapters.utils.io_services_utils._AsyncPlaintextTransport object at 0x7f7f280782e0> params=<ConnectionParameters host=rabbitmq port=5672 virtual_host=/ ssl=False>>
2025-05-08 00:40:01 2025-05-07 22:40:01,159 - pika.adapters.blocking_connection - INFO - Connection workflow succeeded: <SelectConnection OPEN transport=<pika.adapters.utils.io_services_utils._AsyncPlaintextTransport object at 0x7f7f280782e0> params=<ConnectionParameters host=rabbitmq port=5672 virtual_host=/ ssl=False>>
2025-05-08 00:40:01 2025-05-07 22:40:01,159 - pika.adapters.blocking_connection - INFO - Created channel=1
2025-05-08 00:40:01 2025-05-07 22:40:01,213 - unifier - INFO - Servicio unificador iniciado. Esperando transcripciones...
2025-05-08 01:21:27 2025-05-07 23:21:27,297 - unifier - INFO - Recibida transcripción 4/4 para 1746657946_Episodios.mp3

View File

@@ -0,0 +1,169 @@
services:
rabbitmq:
image: rabbitmq:3-management
ports:
- "5672:5672" # AMQP port
- "15672:15672" # Management UI
environment:
- RABBITMQ_DEFAULT_USER=user
- RABBITMQ_DEFAULT_PASS=password
volumes:
- rabbitmq_data:/var/lib/rabbitmq
networks:
- whisper_network
receiver:
build:
context: ./receiver
volumes:
- ./input:/app/input
- ./shared:/app/shared
depends_on:
- rabbitmq
networks:
- whisper_network
splitter:
build:
context: ./splitter
volumes:
- ./shared:/app/shared
depends_on:
- rabbitmq
networks:
- whisper_network
processor1:
build:
context: ./processor
volumes:
- ./shared:/app/shared
depends_on:
- rabbitmq
environment:
- PROCESSOR_ID=1
networks:
- whisper_network
processor2:
build:
context: ./processor
volumes:
- ./shared:/app/shared
depends_on:
- rabbitmq
environment:
- PROCESSOR_ID=2
networks:
- whisper_network
# processor3:
# build:
# context: ./processor
# volumes:
# - ./shared:/app/shared
# depends_on:
# - rabbitmq
# environment:
# - PROCESSOR_ID=3
# networks:
# - whisper_network
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
# processor4:
# build:
# context: ./processor
# volumes:
# - ./shared:/app/shared
# depends_on:
# - rabbitmq
# environment:
# - PROCESSOR_ID=4
# networks:
# - whisper_network
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
# processor5:
# build:
# context: ./processor
# volumes:
# - ./shared:/app/shared
# depends_on:
# - rabbitmq
# environment:
# - PROCESSOR_ID=5
# networks:
# - whisper_network
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
# processor6:
# build:
# context: ./processor
# volumes:
# - ./shared:/app/shared
# depends_on:
# - rabbitmq
# environment:
# - PROCESSOR_ID=6
# networks:
# - whisper_network
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
# processor7:
# build:
# context: ./processor
# volumes:
# - ./shared:/app/shared
# depends_on:
# - rabbitmq
# environment:
# - PROCESSOR_ID=7
# networks:
# - whisper_network
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
unifier:
build:
context: ./unifier
volumes:
- ./shared:/app/shared
- ./output:/app/output
depends_on:
- rabbitmq
networks:
- whisper_network
networks:
whisper_network:
volumes:
rabbitmq_data:

View File

Binary file not shown.

View File

@@ -0,0 +1,32 @@
1
00:00:00,000 --> 00:02:00,000
Ser Podcast La socho de hoy por hoy en Ser Podcast Hola muy buenos días, lo que pasó ayer en Alemania no solo explica la situación allí en la primera potencia europea, sino que explica de alguna manera cómo están los tiempos y cómo se extiende la inestabilidad y la incertidumbres, si uno de los países con la política más previsible de las últimas décadas vive con sorpresa y hasta contraiciones la elección de su canciller tras el acuerdo entre conservadores y social democratas. Por si faltaran cosas, esta madrugada hemos asistido a la escala de militar entre India y Pakistan, que son dos potencias nucleares y que añaden incertidumbre a un mundo removido por un donaltram que ahora busca acercar posturas con China. Esta es otra de las novedades con las que amanecemos hoy, una delegación de Washington y otra de Pequín, prevén reunirse a finales de esta misma semana para hablar de los araceles será la primera vez que se vean desde que Trump empezó la guerra comercial y se va a ver en Suiza. Sastre, buenos días. Buenos días, Barceló. Bueno, con este contexto internacional de fondo y con el rear me envoca de todos los gobiernos, esta mañana comparece a quien España, Pedro Sanchez, para hablar de un insólito a Pagón cuyas causas aún desconocemos. También para explicar cómo puede subir el gastón de fence al 2% aunque no tenga presupuestos generales. De hecho, en este momento el gobierno no tiene una mayoría que garantice para empezar, lo último que aprobó ayer mismo el Consejo de Ministros, la reducción de la jornada laboral contra la que Xi'unz ha presentado una enmienda a la totalidad. Pues ya decíamos que la incertidumbre explica buena parte de lo que ocurre y esa es la palabra que define precisamente lo que desde hoy va a pasar en Roma. Hoy por hoy noticias. Ser podcast. El conclave. Que empieza esta tarde a las 4 y media, con tantos nombres en las quinielas que sea hay algo en lo que coincide en los pronósticos es que toda punta a que vamos a un conclave que no se va a resolver el primer día, seguramente tampoco el segundo, aunque en verdad nadie sabe si todo está rodeado no solo de una gran...
2
00:02:00,000 --> 00:04:00,000
en la liturgia, sino de un silencio que se alarga. Vamos a Roma con responsabil John Soles. Al término de la última congregación en la que intervenieron otros 26 cardenales sobre las prioridades de la iglesia católica en el mundo, no se había definido el perfil del próximo pontífice que deberá ser elegido a partir de esta tarde y según se desprende de comentarios de algunos purporados. Francisco era Francisco, no habrá otro Francisco, ha invertido el cardenal francés Vesco. Él abrió las puertas y yo deseo añadido que estas puertas sigan abiertas con el nuevo papa y que siga la línea trazada. La 17a mañana empezará la misa proeligiendo romano pontífice tras el almuerzo los electores podrán descansar, pero a primera hora de la tarde se han trasladado en microbuses de la residencia de Santa Marta al otro extremo del ápcide de la basilica de San Pedro. Se dirigirán a la capilla paulina y en procesión a la 16a juraran mantener el secreto de las deliberaciones y a continuación el maestro de ceremonias papales pronunciará al tradicional extra-omnes, es decir, todos fuera salvo los electores. La primera fuma tallegara, previsiblemente, entre las 6 y las 7 de la tarde. Los focos de la actualidad internacional empezan a apuntar a Roma esta tarde para cuando veamos entrar a los cardenales uno en uno en la capilla 16. De momento, los grandes asuntos en la crónica del mundo son dos, como les decía al empezar, por un lado, la reunión que tendrá en China y Estados Unidos a finales de semana con la esperanza de que puedan aliviar la guerra que ha agitado el mundo, la guerra de los aranceles. Y el otro gran asunto es ese ataque de India contra varias tonas de Pakistan en una serie de bombardeos que nueva Delhi ha justificado como represalias después de los atentados de abril en la cachemira India. Estados Unidos ha dicho ya que está pendiente de lo que pase entre estos dos países, las dos, los dos son potencias nucleares y cuyo enfrentamiento vayan bienete de lejos. Hace más de siete décadas que India y Pakistan se disputan ese territorio fronterizo de cachemira, uno de los puntos calientes de...
3
00:04:00,000 --> 00:06:00,000
y donde ambas potencias han librado ya cuatro guerras desde 1947. Así sonaba noche, el intercambio de disparos en la denominada línea de control, escaramuzas fronterizas que siguieron al ataque con misiles por parte de India, contra varios objetivos en territorio paquistánín. El gobierno de Islamabad habla de un ataque injustificado por parte de India que deja al menos 26 civiles muertos en ese país. En paquistán, otras 10 personas han fallecido esta noche en el lado indio de la frontera, mientras se suceden los llamamientos a la contención para evitar una escalada bélica. En esta habilidad, y escalada militar en Asia, en esta habilidad política en el país, cuya política se prefiaba de su estabilidad desde el final de la Segunda Guerra Mundial, que es Alemania, corresponde a Lemberlín Carmen Vinyas, buenos días. Hola, buenos días, señor. Todo el mundo Carmen se hace allí esta mañana la misma pregunta, quién trató de boicotear la elección de Merst como Canciller, en una votación secreta que sumió al país en la incertidumbre durante unas horas, hasta que se precipitó una nueva votación y pudo salir elegido, pero salió elegido y a Carmen exhibiendo su debilidad. Pues sí, sigue siendo un incógnita porque todo era secreto, aunque motivos para la disidencia no faltaban. El caos que conservadores y social democratas han provocado en el Bundestak, ha supuesto un duro golpe. Es un revés sobre todo para los líderes de ambos grupos que no han podido convencer a los suyos de la necesidad de un gobierno conjunto. Muchos conservadores están molestos por la relajación del Freno a la deuda y muchos social democratas se sienten frustrados por el endurecimiento de la política migratoria. También hay malestar por elección del gabinete a las derechas de la acusa de buscar perfiles muy empresariales y los social democratas de arriesgar con juventud y inexperiencia. A sus señorías, Ángeles hizo falta recordarles que Alemania necesita esta habilidad en tiempos de guerra con Ucrania, de frágil relación con Estados Unidos y de fortaleza de la estrema derecha. Quizá una mirada a la bismo sirvió para elegir finalmente a Merch. Seguimos en el abierto. Hasta luego. Hay una imagen internacional más, todavía señal también de los tiempos de los que estamos. El encuentro en el despacho Val de la...
4
00:06:00,000 --> 00:08:00,000
Casa Blanca entre Donald Trump y luego primer ministro de Canadá, Marcarnei, que dijo a Trump, Canadá no está en venta. Y esta es la respuesta que le dio ayer la Casa Blanca Donald Trump. Pero nunca he dicho, nunca he dicho, nunca. Nunca digas nunca. Aquí en España también va a ser noticia hoy el Parlamento, porque hoy es el pleno del Congreso, en el que va a comparecer Pedro Sánchez para hablar del aumento del gasto en defensa, aunque en realidad va a hablar también de la pagón Guillermo Lermabu nos días. ¿Qué tal, Buenos días, Angelo? Y el pleno servirá de nuevo cómo termómetro de la legislatura. Sí, una legislatura que el gobierno da por hecho, que va a estar marcada por ese debate sobre la defensa y la seguridad, algo que en el ejecutivo dicen conecta precisamente con la necesidad de reforzar las capacidades de España para prever esos imprevistos como el apagón. En el gobierno, dan por hecho, que la pregunta que más se va a repetir o bien el pleno es esa que ocurrió, lo que está en el origen de eso apagón, que dejó a España sin electricidad del pasado lunes. No hay ninguna certeza sobre el origen de ese cero eléctrico, Sánchez acude al pleno, sin poder aportar respuestas claras. Así que el jefe del ejecutivo va a defender que todas las posibilidades están abiertas. No hay ninguna certeza sobre el origen, así que en el ejecutivo, creo que sería una responsabilidad a apuntar a cualquier posibilidad, sin haber analizado todos los datos técnicos. Sánchez va a insistir en no descartar ninguna opción. Ayer el pleno del Senado vivió una peritivo de lo que va a ser la sesión de hoy, desde esa comparecencia Sara Gensen, pedía rigor y responsable. Lo peor que podríamos hacer por la ciudadanía, por la seguridad del suministro de este país, es empezar a hacer hipótesis de lo más variopinto sin ninguna certeza. Por favor, rigor para la ciudadanía, rigor en la aportación de soluciones. El presidente intentará sobre todo desmontar la imagen de colapso y caos que intenta fijar...
5
00:08:00,000 --> 00:10:00,000
la derecha, una realidad paralela dicen en la mongla. Y, gracias. Hasta luego. Fejo por su parte su maral apagó en el robo del domingo en los cables de alta velocidad para denunciar eso una situación de caos en el país de habito en que era buenos días. Hola, Angel Sanctismo, en fase de paranoia. Es el resumen que hacen en Genova de los que ellos califican como los dos lunes negros. En la herida de la paón, en la herida del caos ferroviario quiere urgar hoy fejó que hacear al presidente que siempre culpa a terceros sin pruebas. Mucho ciber ataque, muchos a botaje, pero pocas explicaciones y pocas disculpas. Tampoco vea el tema de gasto en defensa, remarcando que poco podemos aportar como país para solucionar la inestabilidad que se acude a Europa cuando nuestro gobierno no es capaz de garantizar el suministro eléctrico las comunicaciones o las redes de transporte en España. Es lo que quiere dejar patente el líder de un PP desde el que ironizan. Para hacer tan valer, se abruselas, Putin tiene que empeñarse a fondo, pero para poner a España en hacke, basta con una socialista como Beatriz Corredor al frente de Recelectrica. Hoy por hoy, noticias. Ser podcast. El juez peinado ha imputado al actual delegado del gobierno en Madrid por el caso begóña Gómez. El juez admite en parte la crey de box, por tanto imputa el delito de malversación, al delegado guberramental en Madrid, Francisco Martín, por la contratación de Cristina Álvarez. El juez, que se mantuvo con Martín, continuó en el cargo ahora con Judí González en la Secretaría General General. El juez sortía a González en el caso de la Secretaría General General General, y se mantuvo con Martín, al que atribuye el juez esta supuesta en malversación. ¿Qué tal, Álvarez? ¿Cuáles son? La razón es de peinado. Pues dice el juez que Francisco Martín era el responsable y superior gerar quico de Cristina Álvarez, la sesora de Begoña Gómez, que se nombró con Feliz Bolaños como Secretario General de Presidencia, que se mantuvo con Martín, y que continúan el cargo ahora con Judí González y al Ministro Bolaños, que está aforado ante el Supremo y se queda con el delegado del Gobierno, al que atribuye la malversación, porque sostiene que se pagó a…
6
00:10:00,000 --> 00:12:00,000
Cristina Álvarez con fondos públicos para ayudar en las actividades privadas de Begoña Gómez. Juan Carlos Peinado vuelve a dar un nuevo giro de timón esta vez en la última línea de investigación que abrió para mantener viva la causa, pone el foco en Francisco Martín y ahora decide exculpar a la asesora porque dice que se limitó a hacer su trabajo y a cobrar por ello, por lo tanto no cometió delito y también a la mujer de Pedro Sánchez, porque dice que se limitó a contar con esos servicios profesionales aunque fuera para fines personales. Gracias, Pedro. Hasta luego. Así es como se refiere a esta instrucción judicial de Peinado, el ministro de Justicia Félix volaños. Esta instrucción ya no es motivo de preocupación para la gente honesta y con la conciencia tranquila que se está viendo afectada. Es motivo de preocupación máxima para todos los que defendemos el buen nombre y la impartialidad de los jueces imaginados de nuestro país. Y en Valencia mientras sigue la investigación de la bana que está llevando a cabo la jueza de Catarrotjante, la que ayer declaró uno de los técnicos que envió la alerta a los teléfonos móviles el día de la catástrofe. A la alerta que llegó, como saben, cuando la mayoría de las víctimas ya habían muerto, este técnico explicó que las concelleras salomepradas les ordenó que no envías en el mensaje hasta que ella lo hubiera visto a Natalense Von Diem. Bon día, el técnico declaró un calidad de testigo con la obligación de decir la verdad y contestar a todas las partes. A firmó que la ex-consellera Pradas le dijo que no envía a nada hasta que ella diera el visto bueno. Indicó que hubo un primer borrador de mensajes sobre la situación del barranco de Forata que se descartó y que se decidió redactar otro para toda la provincia. El técnico añade que pasó una hora desde que se decidió enviar el mensaje hasta que efectivamente se remitió a las ocho y once minutos de la tarde. Aunque considera que no debía haberse tardado más de 20 minutos. Por su parte fuentes pero próximas a la ex-consellera Pradas han negado a la ser cualquier retraso en el visto bueno el envío el mensaje y se remiten a la literalidad de su declaración no a la transcripción que se filtró a los medios. Dicen que en esa declaración quedó claro que el visto bueno en mensaje que introdujen los técnicos en el sistema informático fue inmediato y tenía que ver con la situación de Forata.
7
00:12:00,000 --> 00:14:00,000
Esas fuentes aseguran también que efectivamente se tardó una hora entre la propuesta del subdirector para el borrador del mensaje hasta que se envió, pero añada en que el técnico no dijo en ningún momento que ese tiempo fuera, porque Pradas le dijera que esperase a que ella lidera el visto bueno. Y además, el poder judicial va a seguir investigando los jueces el hoy Velasco y Carros del Valle, persa que quien lleva su expediente había propuesto que se archivara. Se trata del juez que interrogó a un humorista actor de Miguel y también del juez que cuestionó la legitimidad del gobierno y que llegó a decir que no iba a ser Irene Montero desde la caja del Mercadona, dijo, la que les iba a explicar a ellos a los magistrados que es el consentimiento. Más de cuatro millones de personas ya han cobrado la devolución de la renta, acaba de cumplirse un mes del inicio de la campaña y haciendo informa de que ha recibido menos declaraciones. O bastante menos, en concreto se han presentado en total siete millones, lo que supone casi un cinco por ciento menos que es el mismo periodo de 2024. La agencia tributaria recuerda que el plazo para presentar la declaración termina el 30 de junio, Jordi Fabregam. Después del furor inicial este año y menos prisa por presentar la declaración de la renta. En el primer mes de campaña, la agencia tributaria ha recibido siete millones y cientos mil declaraciones. Es un 4,7 por ciento menos que el año pasado. Es verdad que esta vez, dentro del periodo en el que se ha podido presentar la declaración entra la semana santa y eso ha condicionado las cifras. En el 16 de diciembre, la agencia tributaria ha puesto en marcha el plan de ayuda telefónica para elaborar la declaración. Un equipo del Centro Nacional de Investigaciones Oncológicas ha identificado el interruptor clave en el desarrollo del cáncer de colon. El estudio lo publica la revista net huri muestra que cuando falta una proteína, se puede poner en marcha el desarrollo del tumor. Es decir, que con la dieta con lo que comemos, se puede evitar que se actenmarina farmández. En bruto este descubrim...
8
00:14:00,000 --> 00:15:59,269
que publican eiturpodes sonarnos poco asequible. Hemos demostrado que degradar la proteína P53 es un evento necesario para la iniciación del proceso tumoral. Pero la investigadora Irene Erranzo, una de las autoras lo traduce para que entendamos su potencial. Efectivamente evitar la degradación de P53 evitaría el desarrollo de tumores en pacientes humanos. Lo han comprobado en modelos animales y también en muestras humanas y su hallazgo va más allá. Describimos que otra proteína, llamada URI, favorece la degradación de P53. Sabemos que la dieta puede influir en los niveles de URI y con ello influir en los niveles de P53. Y de esta manera, promover o prevenir el desarrollo de los tumores. El cáncer color dectales es más frecuente en España, en la población general, con más de 40.000 nuevos diagnósticos al año. Y los mirlos nuevos médicos quieren ser dermatólogos y no médicos de familia y eso andan la carencia que ya sufren los centros de salud en buena parte del país, Mario Lleuridón. 15.000 mil a por una de las 9.000 plazas estos días se eligen su futuro. ¿Y oftándolo, Xi'a? Yo, cardiología. Gené, golgón. Ecogi de neurociología. Hay una especialidad estrella, las plazas se agotaron en tiempo record. Yo he elegido dermatología. Es una especialidad que tiene muy buenas salidas, laborales actualmente. También están ajudicadas ya en cirugía plástica, ambasón el top. Yo creo que hermar montas tu consulta privada con muy poca inversión y ves muchos pacientes. Curros de Córdoba le toca elegir hoy. Yo, por más y lo facial, tiene muy buena calidad de vida y tiene muy buena privada, la verdad. La Cenecienta es medicina familiar de las 2.500 plazas ofertadas, solo 22 han elegido de momento la atención primaria. No, no está tan bien reconocida, igual. También tiene mucho trabajo burocrático, que igual a la gente después de medicina no es lo que más la petece. Hay una pena que hayan bien que las cosas mejoraron para los médicos de familia. Desde hace tres años hay vacantes, si no se cubren todas las plazas en un servicio muy debilitado y con falta de personal. Y en diez minutos se la abiertó. Cone de guarda Madina, a victor la puente y elisa de la 9. ¿Para no perder ningún episodio? Sigue no ser la aplicación o la web de la ser, podí un podcast o tu plataforma de audio favorita.

View File

@@ -0,0 +1,29 @@
FROM python:3.9
WORKDIR /app
# Instalar dependencias básicas
RUN apt-get update && apt-get install -y ffmpeg
# Instalar torch con soporte CUDA y otras dependencias
RUN pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
RUN pip install pika openai-whisper
# Crear un script para descargar el modelo
RUN echo '\
import whisper\n\
import torch\n\
print("Verificando disponibilidad de CUDA:", torch.cuda.is_available())\n\
if torch.cuda.is_available():\n\
print("Dispositivo CUDA:", torch.cuda.get_device_name(0))\n\
print("Descargando modelo Whisper base...")\n\
whisper.load_model("base")\n\
print("Modelo descargado correctamente")\
' > download_model.py
# Ejecutar el script para descargar el modelo durante la construcción
RUN python download_model.py
COPY app.py .
CMD ["python", "app.py"]

View File

@@ -0,0 +1,189 @@
#!/usr/bin/env python
import os
import time
import json
import pika
import logging
import whisper
import torch
from datetime import datetime
# Configuración de logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('processor')
# Configuración de RabbitMQ
RABBITMQ_HOST = 'rabbitmq'
RABBITMQ_USER = 'user'
RABBITMQ_PASS = 'password'
PROCESS_QUEUE = 'audio_process_queue'
UNIFY_QUEUE = 'text_unify_queue'
# Configuración de Whisper
WHISPER_MODEL = "base" # Opciones: "tiny", "base", "small", "medium", "large"
# Directorios
SHARED_DIR = '/app/shared'
# ID del procesador para logs
PROCESSOR_ID = os.environ.get('PROCESSOR_ID', 'unknown')
def connect_to_rabbitmq():
"""Establece conexión con RabbitMQ"""
tries = 0
while True:
try:
credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS)
connection = pika.BlockingConnection(
pika.ConnectionParameters(
host=RABBITMQ_HOST,
credentials=credentials,
heartbeat=600 # 10 minutos
)
)
return connection
except pika.exceptions.AMQPConnectionError:
tries += 1
logger.warning(f"Intento {tries}: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...")
time.sleep(5)
def load_whisper_model():
"""Carga el modelo de Whisper"""
# Verificar si hay GPU disponible
device = "cuda" if torch.cuda.is_available() else "cpu"
if device == "cuda":
gpu_name = torch.cuda.get_device_name(0)
logger.info(f"Procesador {PROCESSOR_ID}: GPU detectada: {gpu_name}")
else:
logger.info(f"Procesador {PROCESSOR_ID}: No se detectó GPU, usando CPU")
logger.info(f"Procesador {PROCESSOR_ID}: Cargando modelo Whisper '{WHISPER_MODEL}' en {device}...")
model = whisper.load_model(WHISPER_MODEL, device=device)
logger.info(f"Procesador {PROCESSOR_ID}: Modelo Whisper cargado correctamente")
return model
def transcribe_audio(model, audio_path):
"""Transcribe un archivo de audio usando Whisper"""
logger.info(f"Procesador {PROCESSOR_ID}: Transcribiendo {audio_path}")
# Realizar transcripción
result = model.transcribe(audio_path)
logger.info(f"Procesador {PROCESSOR_ID}: Transcripción completada para {audio_path}")
return result
def save_transcription(result, segment_info):
"""Guarda la transcripción en un archivo de texto"""
segment_id = segment_info['segment_id']
original_file_id = segment_info['original_file_id']
segments_dir = segment_info['segments_dir']
# Crear directorio para transcripciones
transcriptions_dir = os.path.join(segments_dir, "transcriptions")
os.makedirs(transcriptions_dir, exist_ok=True)
# Generar nombre para archivo de transcripción
transcription_filename = f"transcription_{segment_id:03d}_{original_file_id}.txt"
transcription_path = os.path.join(transcriptions_dir, transcription_filename)
# Guardar texto en archivo
with open(transcription_path, 'w', encoding='utf-8') as f:
f.write(result['text'])
logger.info(f"Procesador {PROCESSOR_ID}: Transcripción guardada en {transcription_path}")
return transcription_path
def send_to_unify_queue(channel, transcription_path, segment_info):
"""Envía la transcripción a la cola de unificación"""
# Preparar mensaje
message = {
**segment_info,
'transcription_path': transcription_path,
'processor_id': PROCESSOR_ID,
'processed_timestamp': datetime.now().isoformat()
}
# Publicar mensaje
channel.basic_publish(
exchange='',
routing_key=UNIFY_QUEUE,
body=json.dumps(message),
properties=pika.BasicProperties(
delivery_mode=2 # mensaje persistente
)
)
logger.info(f"Procesador {PROCESSOR_ID}: Transcripción enviada a la cola de unificación")
def callback(ch, method, properties, body):
"""Callback para procesar mensajes de la cola de procesamiento"""
try:
# Decodificar mensaje
segment_info = json.loads(body)
segment_id = segment_info['segment_id']
segment_path = segment_info['segment_path']
original_file_id = segment_info['original_file_id']
total_segments = segment_info['total_segments']
logger.info(f"Procesador {PROCESSOR_ID}: Recibido segmento {segment_id+1}/{total_segments} para {original_file_id}")
# Transcribir audio
result = transcribe_audio(model, segment_path)
# Guardar transcripción
transcription_path = save_transcription(result, segment_info)
# Enviar a cola de unificación
send_to_unify_queue(ch, transcription_path, segment_info)
# Confirmar procesamiento
ch.basic_ack(delivery_tag=method.delivery_tag)
logger.info(f"Procesador {PROCESSOR_ID}: Transcripción completada para segmento {segment_id+1}/{total_segments}")
except Exception as e:
logger.error(f"Procesador {PROCESSOR_ID}: Error procesando mensaje: {str(e)}")
# Rechazar mensaje en caso de error para reintentarlo
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
def main():
"""Función principal"""
global model
# Cargar modelo Whisper
model = load_whisper_model()
# Conexión a RabbitMQ
connection = connect_to_rabbitmq()
channel = connection.channel()
# Declarar colas
channel.queue_declare(queue=PROCESS_QUEUE, durable=True)
channel.queue_declare(queue=UNIFY_QUEUE, durable=True)
# Configurar prefetch count -> 1 mensaje a la vez
channel.basic_qos(prefetch_count=1)
# Configurar callback
channel.basic_consume(queue=PROCESS_QUEUE, on_message_callback=callback)
logger.info(f"Procesador {PROCESSOR_ID}: Servicio iniciado. Esperando segmentos...")
# Iniciar consumo
try:
channel.start_consuming()
except KeyboardInterrupt:
logger.info(f"Procesador {PROCESSOR_ID}: Servicio detenido")
channel.stop_consuming()
connection.close()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,10 @@
FROM python:3.9-slim
WORKDIR /app
# Instalar dependencias
RUN pip install pika
COPY app.py .
CMD ["python", "app.py"]

View File

@@ -0,0 +1,108 @@
#!/usr/bin/env python
import os
import time
import pika
import json
import logging
from pathlib import Path
from datetime import datetime
# Configuración de logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('receiver')
# Configuración de RabbitMQ
RABBITMQ_HOST = 'rabbitmq'
RABBITMQ_USER = 'user'
RABBITMQ_PASS = 'password'
SPLIT_QUEUE = 'audio_split_queue'
# Directorios
INPUT_DIR = '/app/input'
SHARED_DIR = '/app/shared'
def connect_to_rabbitmq():
"""Establece conexión con RabbitMQ"""
tries = 0
while True:
try:
credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS)
connection = pika.BlockingConnection(
pika.ConnectionParameters(
host=RABBITMQ_HOST,
credentials=credentials
)
)
return connection
except pika.exceptions.AMQPConnectionError:
tries += 1
logger.warning(f"Intento {tries}: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...")
time.sleep(5)
def process_audio_file(filepath):
"""Procesa un archivo de audio y lo envía a la cola de RabbitMQ"""
filename = os.path.basename(filepath)
file_id = f"{int(datetime.now().timestamp())}_{filename}"
# Guardar una copia en el directorio compartido
shared_path = os.path.join(SHARED_DIR, file_id)
os.system(f"cp {filepath} {shared_path}")
# Enviar mensaje a RabbitMQ para procesamiento
connection = connect_to_rabbitmq()
channel = connection.channel()
# Declarar la cola
channel.queue_declare(queue=SPLIT_QUEUE, durable=True)
# Preparar mensaje
message = {
'file_id': file_id,
'filename': filename,
'filepath': shared_path,
'timestamp': datetime.now().isoformat()
}
# Publicar mensaje
channel.basic_publish(
exchange='',
routing_key=SPLIT_QUEUE,
body=json.dumps(message),
properties=pika.BasicProperties(
delivery_mode=2 # mensaje persistente
)
)
logger.info(f"Archivo {filename} enviado a la cola {SPLIT_QUEUE} con ID {file_id}")
connection.close()
def monitor_input_directory():
"""Monitorea el directorio de entrada para nuevos archivos de audio"""
# Asegurar que el directorio compartido existe
os.makedirs(SHARED_DIR, exist_ok=True)
# Crear conjunto de archivos ya procesados
processed_files = set()
logger.info(f"Iniciando monitoreo del directorio {INPUT_DIR}")
while True:
# Buscar archivos de audio en el directorio de entrada
audio_extensions = ['.mp3', '.wav', '.flac', '.m4a', '.ogg']
for ext in audio_extensions:
for audio_file in Path(INPUT_DIR).glob(f'*{ext}'):
filepath = str(audio_file)
if filepath not in processed_files:
logger.info(f"Nuevo archivo detectado: {filepath}")
process_audio_file(filepath)
processed_files.add(filepath)
# Esperar antes de volver a comprobar
time.sleep(10)
if __name__ == "__main__":
logger.info("Servicio receptor iniciado")
monitor_input_directory()

View File

Binary file not shown.

View File

@@ -0,0 +1 @@
Ser Podcast La socho de hoy por hoy en Ser Podcast Hola muy buenos días, lo que pasó ayer en Alemania no solo explica la situación allí en la primera potencia europea, sino que explica de alguna manera cómo están los tiempos y cómo se extiende la inestabilidad y la incertidumbres, si uno de los países con la política más previsible de las últimas décadas vive con sorpresa y hasta contraiciones la elección de su canciller tras el acuerdo entre conservadores y social democratas. Por si faltaran cosas, esta madrugada hemos asistido a la escala de militar entre India y Pakistan, que son dos potencias nucleares y que añaden incertidumbre a un mundo removido por un donaltram que ahora busca acercar posturas con China. Esta es otra de las novedades con las que amanecemos hoy, una delegación de Washington y otra de Pequín, prevén reunirse a finales de esta misma semana para hablar de los araceles será la primera vez que se vean desde que Trump empezó la guerra comercial y se va a ver en Suiza. Sastre, buenos días. Buenos días, Barceló. Bueno, con este contexto internacional de fondo y con el rear me envoca de todos los gobiernos, esta mañana comparece a quien España, Pedro Sanchez, para hablar de un insólito a Pagón cuyas causas aún desconocemos. También para explicar cómo puede subir el gastón de fence al 2% aunque no tenga presupuestos generales. De hecho, en este momento el gobierno no tiene una mayoría que garantice para empezar, lo último que aprobó ayer mismo el Consejo de Ministros, la reducción de la jornada laboral contra la que Xi'unz ha presentado una enmienda a la totalidad. Pues ya decíamos que la incertidumbre explica buena parte de lo que ocurre y esa es la palabra que define precisamente lo que desde hoy va a pasar en Roma. Hoy por hoy noticias. Ser podcast. El conclave. Que empieza esta tarde a las 4 y media, con tantos nombres en las quinielas que sea hay algo en lo que coincide en los pronósticos es que toda punta a que vamos a un conclave que no se va a resolver el primer día, seguramente tampoco el segundo, aunque en verdad nadie sabe si todo está rodeado no solo de una gran...

View File

@@ -0,0 +1 @@
en la liturgia, sino de un silencio que se alarga. Vamos a Roma con responsabil John Soles. Al término de la última congregación en la que intervenieron otros 26 cardenales sobre las prioridades de la iglesia católica en el mundo, no se había definido el perfil del próximo pontífice que deberá ser elegido a partir de esta tarde y según se desprende de comentarios de algunos purporados. Francisco era Francisco, no habrá otro Francisco, ha invertido el cardenal francés Vesco. Él abrió las puertas y yo deseo añadido que estas puertas sigan abiertas con el nuevo papa y que siga la línea trazada. La 17a mañana empezará la misa proeligiendo romano pontífice tras el almuerzo los electores podrán descansar, pero a primera hora de la tarde se han trasladado en microbuses de la residencia de Santa Marta al otro extremo del ápcide de la basilica de San Pedro. Se dirigirán a la capilla paulina y en procesión a la 16a juraran mantener el secreto de las deliberaciones y a continuación el maestro de ceremonias papales pronunciará al tradicional extra-omnes, es decir, todos fuera salvo los electores. La primera fuma tallegara, previsiblemente, entre las 6 y las 7 de la tarde. Los focos de la actualidad internacional empezan a apuntar a Roma esta tarde para cuando veamos entrar a los cardenales uno en uno en la capilla 16. De momento, los grandes asuntos en la crónica del mundo son dos, como les decía al empezar, por un lado, la reunión que tendrá en China y Estados Unidos a finales de semana con la esperanza de que puedan aliviar la guerra que ha agitado el mundo, la guerra de los aranceles. Y el otro gran asunto es ese ataque de India contra varias tonas de Pakistan en una serie de bombardeos que nueva Delhi ha justificado como represalias después de los atentados de abril en la cachemira India. Estados Unidos ha dicho ya que está pendiente de lo que pase entre estos dos países, las dos, los dos son potencias nucleares y cuyo enfrentamiento vayan bienete de lejos. Hace más de siete décadas que India y Pakistan se disputan ese territorio fronterizo de cachemira, uno de los puntos calientes de...

View File

@@ -0,0 +1 @@
y donde ambas potencias han librado ya cuatro guerras desde 1947. Así sonaba noche, el intercambio de disparos en la denominada línea de control, escaramuzas fronterizas que siguieron al ataque con misiles por parte de India, contra varios objetivos en territorio paquistánín. El gobierno de Islamabad habla de un ataque injustificado por parte de India que deja al menos 26 civiles muertos en ese país. En paquistán, otras 10 personas han fallecido esta noche en el lado indio de la frontera, mientras se suceden los llamamientos a la contención para evitar una escalada bélica. En esta habilidad, y escalada militar en Asia, en esta habilidad política en el país, cuya política se prefiaba de su estabilidad desde el final de la Segunda Guerra Mundial, que es Alemania, corresponde a Lemberlín Carmen Vinyas, buenos días. Hola, buenos días, señor. Todo el mundo Carmen se hace allí esta mañana la misma pregunta, quién trató de boicotear la elección de Merst como Canciller, en una votación secreta que sumió al país en la incertidumbre durante unas horas, hasta que se precipitó una nueva votación y pudo salir elegido, pero salió elegido y a Carmen exhibiendo su debilidad. Pues sí, sigue siendo un incógnita porque todo era secreto, aunque motivos para la disidencia no faltaban. El caos que conservadores y social democratas han provocado en el Bundestak, ha supuesto un duro golpe. Es un revés sobre todo para los líderes de ambos grupos que no han podido convencer a los suyos de la necesidad de un gobierno conjunto. Muchos conservadores están molestos por la relajación del Freno a la deuda y muchos social democratas se sienten frustrados por el endurecimiento de la política migratoria. También hay malestar por elección del gabinete a las derechas de la acusa de buscar perfiles muy empresariales y los social democratas de arriesgar con juventud y inexperiencia. A sus señorías, Ángeles hizo falta recordarles que Alemania necesita esta habilidad en tiempos de guerra con Ucrania, de frágil relación con Estados Unidos y de fortaleza de la estrema derecha. Quizá una mirada a la bismo sirvió para elegir finalmente a Merch. Seguimos en el abierto. Hasta luego. Hay una imagen internacional más, todavía señal también de los tiempos de los que estamos. El encuentro en el despacho Val de la...

View File

@@ -0,0 +1 @@
Casa Blanca entre Donald Trump y luego primer ministro de Canadá, Marcarnei, que dijo a Trump, Canadá no está en venta. Y esta es la respuesta que le dio ayer la Casa Blanca Donald Trump. Pero nunca he dicho, nunca he dicho, nunca. Nunca digas nunca. Aquí en España también va a ser noticia hoy el Parlamento, porque hoy es el pleno del Congreso, en el que va a comparecer Pedro Sánchez para hablar del aumento del gasto en defensa, aunque en realidad va a hablar también de la pagón Guillermo Lermabu nos días. ¿Qué tal, Buenos días, Angelo? Y el pleno servirá de nuevo cómo termómetro de la legislatura. Sí, una legislatura que el gobierno da por hecho, que va a estar marcada por ese debate sobre la defensa y la seguridad, algo que en el ejecutivo dicen conecta precisamente con la necesidad de reforzar las capacidades de España para prever esos imprevistos como el apagón. En el gobierno, dan por hecho, que la pregunta que más se va a repetir o bien el pleno es esa que ocurrió, lo que está en el origen de eso apagón, que dejó a España sin electricidad del pasado lunes. No hay ninguna certeza sobre el origen de ese cero eléctrico, Sánchez acude al pleno, sin poder aportar respuestas claras. Así que el jefe del ejecutivo va a defender que todas las posibilidades están abiertas. No hay ninguna certeza sobre el origen, así que en el ejecutivo, creo que sería una responsabilidad a apuntar a cualquier posibilidad, sin haber analizado todos los datos técnicos. Sánchez va a insistir en no descartar ninguna opción. Ayer el pleno del Senado vivió una peritivo de lo que va a ser la sesión de hoy, desde esa comparecencia Sara Gensen, pedía rigor y responsable. Lo peor que podríamos hacer por la ciudadanía, por la seguridad del suministro de este país, es empezar a hacer hipótesis de lo más variopinto sin ninguna certeza. Por favor, rigor para la ciudadanía, rigor en la aportación de soluciones. El presidente intentará sobre todo desmontar la imagen de colapso y caos que intenta fijar...

View File

@@ -0,0 +1 @@
la derecha, una realidad paralela dicen en la mongla. Y, gracias. Hasta luego. Fejo por su parte su maral apagó en el robo del domingo en los cables de alta velocidad para denunciar eso una situación de caos en el país de habito en que era buenos días. Hola, Angel Sanctismo, en fase de paranoia. Es el resumen que hacen en Genova de los que ellos califican como los dos lunes negros. En la herida de la paón, en la herida del caos ferroviario quiere urgar hoy fejó que hacear al presidente que siempre culpa a terceros sin pruebas. Mucho ciber ataque, muchos a botaje, pero pocas explicaciones y pocas disculpas. Tampoco vea el tema de gasto en defensa, remarcando que poco podemos aportar como país para solucionar la inestabilidad que se acude a Europa cuando nuestro gobierno no es capaz de garantizar el suministro eléctrico las comunicaciones o las redes de transporte en España. Es lo que quiere dejar patente el líder de un PP desde el que ironizan. Para hacer tan valer, se abruselas, Putin tiene que empeñarse a fondo, pero para poner a España en hacke, basta con una socialista como Beatriz Corredor al frente de Recelectrica. Hoy por hoy, noticias. Ser podcast. El juez peinado ha imputado al actual delegado del gobierno en Madrid por el caso begóña Gómez. El juez admite en parte la crey de box, por tanto imputa el delito de malversación, al delegado guberramental en Madrid, Francisco Martín, por la contratación de Cristina Álvarez. El juez, que se mantuvo con Martín, continuó en el cargo ahora con Judí González en la Secretaría General General. El juez sortía a González en el caso de la Secretaría General General General, y se mantuvo con Martín, al que atribuye el juez esta supuesta en malversación. ¿Qué tal, Álvarez? ¿Cuáles son? La razón es de peinado. Pues dice el juez que Francisco Martín era el responsable y superior gerar quico de Cristina Álvarez, la sesora de Begoña Gómez, que se nombró con Feliz Bolaños como Secretario General de Presidencia, que se mantuvo con Martín, y que continúan el cargo ahora con Judí González y al Ministro Bolaños, que está aforado ante el Supremo y se queda con el delegado del Gobierno, al que atribuye la malversación, porque sostiene que se pagó a…

View File

@@ -0,0 +1 @@
Cristina Álvarez con fondos públicos para ayudar en las actividades privadas de Begoña Gómez. Juan Carlos Peinado vuelve a dar un nuevo giro de timón esta vez en la última línea de investigación que abrió para mantener viva la causa, pone el foco en Francisco Martín y ahora decide exculpar a la asesora porque dice que se limitó a hacer su trabajo y a cobrar por ello, por lo tanto no cometió delito y también a la mujer de Pedro Sánchez, porque dice que se limitó a contar con esos servicios profesionales aunque fuera para fines personales. Gracias, Pedro. Hasta luego. Así es como se refiere a esta instrucción judicial de Peinado, el ministro de Justicia Félix volaños. Esta instrucción ya no es motivo de preocupación para la gente honesta y con la conciencia tranquila que se está viendo afectada. Es motivo de preocupación máxima para todos los que defendemos el buen nombre y la impartialidad de los jueces imaginados de nuestro país. Y en Valencia mientras sigue la investigación de la bana que está llevando a cabo la jueza de Catarrotjante, la que ayer declaró uno de los técnicos que envió la alerta a los teléfonos móviles el día de la catástrofe. A la alerta que llegó, como saben, cuando la mayoría de las víctimas ya habían muerto, este técnico explicó que las concelleras salomepradas les ordenó que no envías en el mensaje hasta que ella lo hubiera visto a Natalense Von Diem. Bon día, el técnico declaró un calidad de testigo con la obligación de decir la verdad y contestar a todas las partes. A firmó que la ex-consellera Pradas le dijo que no envía a nada hasta que ella diera el visto bueno. Indicó que hubo un primer borrador de mensajes sobre la situación del barranco de Forata que se descartó y que se decidió redactar otro para toda la provincia. El técnico añade que pasó una hora desde que se decidió enviar el mensaje hasta que efectivamente se remitió a las ocho y once minutos de la tarde. Aunque considera que no debía haberse tardado más de 20 minutos. Por su parte fuentes pero próximas a la ex-consellera Pradas han negado a la ser cualquier retraso en el visto bueno el envío el mensaje y se remiten a la literalidad de su declaración no a la transcripción que se filtró a los medios. Dicen que en esa declaración quedó claro que el visto bueno en mensaje que introdujen los técnicos en el sistema informático fue inmediato y tenía que ver con la situación de Forata.

View File

@@ -0,0 +1 @@
Esas fuentes aseguran también que efectivamente se tardó una hora entre la propuesta del subdirector para el borrador del mensaje hasta que se envió, pero añada en que el técnico no dijo en ningún momento que ese tiempo fuera, porque Pradas le dijera que esperase a que ella lidera el visto bueno. Y además, el poder judicial va a seguir investigando los jueces el hoy Velasco y Carros del Valle, persa que quien lleva su expediente había propuesto que se archivara. Se trata del juez que interrogó a un humorista actor de Miguel y también del juez que cuestionó la legitimidad del gobierno y que llegó a decir que no iba a ser Irene Montero desde la caja del Mercadona, dijo, la que les iba a explicar a ellos a los magistrados que es el consentimiento. Más de cuatro millones de personas ya han cobrado la devolución de la renta, acaba de cumplirse un mes del inicio de la campaña y haciendo informa de que ha recibido menos declaraciones. O bastante menos, en concreto se han presentado en total siete millones, lo que supone casi un cinco por ciento menos que es el mismo periodo de 2024. La agencia tributaria recuerda que el plazo para presentar la declaración termina el 30 de junio, Jordi Fabregam. Después del furor inicial este año y menos prisa por presentar la declaración de la renta. En el primer mes de campaña, la agencia tributaria ha recibido siete millones y cientos mil declaraciones. Es un 4,7 por ciento menos que el año pasado. Es verdad que esta vez, dentro del periodo en el que se ha podido presentar la declaración entra la semana santa y eso ha condicionado las cifras. En el 16 de diciembre, la agencia tributaria ha puesto en marcha el plan de ayuda telefónica para elaborar la declaración. Un equipo del Centro Nacional de Investigaciones Oncológicas ha identificado el interruptor clave en el desarrollo del cáncer de colon. El estudio lo publica la revista net huri muestra que cuando falta una proteína, se puede poner en marcha el desarrollo del tumor. Es decir, que con la dieta con lo que comemos, se puede evitar que se actenmarina farmández. En bruto este descubrim...

View File

@@ -0,0 +1 @@
que publican eiturpodes sonarnos poco asequible. Hemos demostrado que degradar la proteína P53 es un evento necesario para la iniciación del proceso tumoral. Pero la investigadora Irene Erranzo, una de las autoras lo traduce para que entendamos su potencial. Efectivamente evitar la degradación de P53 evitaría el desarrollo de tumores en pacientes humanos. Lo han comprobado en modelos animales y también en muestras humanas y su hallazgo va más allá. Describimos que otra proteína, llamada URI, favorece la degradación de P53. Sabemos que la dieta puede influir en los niveles de URI y con ello influir en los niveles de P53. Y de esta manera, promover o prevenir el desarrollo de los tumores. El cáncer color dectales es más frecuente en España, en la población general, con más de 40.000 nuevos diagnósticos al año. Y los mirlos nuevos médicos quieren ser dermatólogos y no médicos de familia y eso andan la carencia que ya sufren los centros de salud en buena parte del país, Mario Lleuridón. 15.000 mil a por una de las 9.000 plazas estos días se eligen su futuro. ¿Y oftándolo, Xi'a? Yo, cardiología. Gené, golgón. Ecogi de neurociología. Hay una especialidad estrella, las plazas se agotaron en tiempo record. Yo he elegido dermatología. Es una especialidad que tiene muy buenas salidas, laborales actualmente. También están ajudicadas ya en cirugía plástica, ambasón el top. Yo creo que hermar montas tu consulta privada con muy poca inversión y ves muchos pacientes. Curros de Córdoba le toca elegir hoy. Yo, por más y lo facial, tiene muy buena calidad de vida y tiene muy buena privada, la verdad. La Cenecienta es medicina familiar de las 2.500 plazas ofertadas, solo 22 han elegido de momento la atención primaria. No, no está tan bien reconocida, igual. También tiene mucho trabajo burocrático, que igual a la gente después de medicina no es lo que más la petece. Hay una pena que hayan bien que las cosas mejoraron para los médicos de familia. Desde hace tres años hay vacantes, si no se cubren todas las plazas en un servicio muy debilitado y con falta de personal. Y en diez minutos se la abiertó. Cone de guarda Madina, a victor la puente y elisa de la 9. ¿Para no perder ningún episodio? Sigue no ser la aplicación o la web de la ser, podí un podcast o tu plataforma de audio favorita.

View File

@@ -0,0 +1,11 @@
FROM python:3.9-slim
WORKDIR /app
# Instalar dependencias
RUN apt-get update && apt-get install -y ffmpeg
RUN pip install pika pydub
COPY app.py .
CMD ["python", "app.py"]

View File

@@ -0,0 +1,187 @@
#!/usr/bin/env python
import os
import time
import json
import pika
import logging
from pydub import AudioSegment
from datetime import datetime
# Configuración de logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('splitter')
# Configuración de RabbitMQ
RABBITMQ_HOST = 'rabbitmq'
RABBITMQ_USER = 'user'
RABBITMQ_PASS = 'password'
SPLIT_QUEUE = 'audio_split_queue'
PROCESS_QUEUE = 'audio_process_queue'
# Configuración de segmentos
SEGMENT_DURATION_MS = 2 * 60 * 1000 # 1 minuto en milisegundos
# Directorios
SHARED_DIR = '/app/shared'
def connect_to_rabbitmq():
"""Establece conexión con RabbitMQ"""
tries = 0
while True:
try:
credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS)
connection = pika.BlockingConnection(
pika.ConnectionParameters(
host=RABBITMQ_HOST,
credentials=credentials
)
)
return connection
except pika.exceptions.AMQPConnectionError:
tries += 1
logger.warning(f"Intento {tries}: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...")
time.sleep(5)
def split_audio(filepath, file_id, original_filename):
"""Divide un archivo de audio en segmentos de 5 minutos"""
logger.info(f"Dividiendo archivo: {filepath}")
# Cargar audio con pydub
audio = AudioSegment.from_file(filepath)
# Calcular número de segmentos
total_duration_ms = len(audio)
num_segments = (total_duration_ms + SEGMENT_DURATION_MS - 1) // SEGMENT_DURATION_MS
logger.info(f"Audio de duración {total_duration_ms}ms será dividido en {num_segments} segmentos")
# Crear directorio para segmentos
segments_dir = os.path.join(SHARED_DIR, f"segments_{file_id}")
os.makedirs(segments_dir, exist_ok=True)
# Dividir en segmentos
segments_info = []
for i in range(num_segments):
start_ms = i * SEGMENT_DURATION_MS
end_ms = min(start_ms + SEGMENT_DURATION_MS, total_duration_ms)
# Extraer segmento
segment = audio[start_ms:end_ms]
# Generar nombre de archivo para segmento
segment_filename = f"segment_{i:03d}_{file_id}.wav"
segment_path = os.path.join(segments_dir, segment_filename)
# Guardar segmento como WAV para Whisper
segment.export(segment_path, format="wav")
segments_info.append({
'segment_id': i,
'segment_path': segment_path,
'segment_filename': segment_filename,
'start_ms': start_ms,
'end_ms': end_ms,
'duration_ms': end_ms - start_ms
})
logger.info(f"Creado segmento {i+1}/{num_segments}: {segment_filename}")
return segments_info, segments_dir
def send_segments_to_process_queue(segments_info, original_file_id, original_filename, segments_dir):
"""Envía los segmentos a la cola para procesamiento con Whisper"""
connection = connect_to_rabbitmq()
channel = connection.channel()
# Declarar cola para procesamiento
channel.queue_declare(queue=PROCESS_QUEUE, durable=True)
# Información del trabajo completo
job_info = {
'original_file_id': original_file_id,
'original_filename': original_filename,
'total_segments': len(segments_info),
'segments_dir': segments_dir,
'timestamp': datetime.now().isoformat()
}
# Enviar cada segmento a la cola
for segment in segments_info:
# Mensaje con información del segmento y trabajo
message = {
**segment,
**job_info
}
channel.basic_publish(
exchange='',
routing_key=PROCESS_QUEUE,
body=json.dumps(message),
properties=pika.BasicProperties(
delivery_mode=2 # mensaje persistente
)
)
logger.info(f"Segmento {segment['segment_id']+1}/{job_info['total_segments']} enviado a la cola de procesamiento")
connection.close()
def callback(ch, method, properties, body):
"""Callback para procesar mensajes de la cola de división"""
try:
# Decodificar mensaje
message = json.loads(body)
file_id = message['file_id']
filepath = message['filepath']
filename = message['filename']
logger.info(f"Recibido archivo para división: {filename} ({file_id})")
# Dividir audio en segmentos
segments_info, segments_dir = split_audio(filepath, file_id, filename)
# Enviar segmentos a la cola de procesamiento
send_segments_to_process_queue(segments_info, file_id, filename, segments_dir)
# Confirmar procesamiento
ch.basic_ack(delivery_tag=method.delivery_tag)
logger.info(f"División completada para {filename} ({file_id})")
except Exception as e:
logger.error(f"Error procesando mensaje: {str(e)}")
# Rechazar mensaje en caso de error para reintentarlo
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
def main():
"""Función principal"""
connection = connect_to_rabbitmq()
channel = connection.channel()
# Declarar colas
channel.queue_declare(queue=SPLIT_QUEUE, durable=True)
channel.queue_declare(queue=PROCESS_QUEUE, durable=True)
# Configurar prefetch count
channel.basic_qos(prefetch_count=1)
# Configurar callback
channel.basic_consume(queue=SPLIT_QUEUE, on_message_callback=callback)
logger.info("Servicio de división iniciado. Esperando mensajes...")
# Iniciar consumo
try:
channel.start_consuming()
except KeyboardInterrupt:
logger.info("Servicio de división detenido")
channel.stop_consuming()
connection.close()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,10 @@
FROM python:3.9-slim
WORKDIR /app
# Instalar dependencias
RUN pip install pika
COPY app.py .
CMD ["python", "app.py"]

View File

@@ -0,0 +1,176 @@
#!/usr/bin/env python
import os
import time
import json
import pika
import logging
from collections import defaultdict
from datetime import datetime
# Configuración de logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('unifier')
# Configuración de RabbitMQ
RABBITMQ_HOST = 'rabbitmq'
RABBITMQ_USER = 'user'
RABBITMQ_PASS = 'password'
UNIFY_QUEUE = 'text_unify_queue'
# Directorios
SHARED_DIR = '/app/shared'
OUTPUT_DIR = '/app/output'
# Almacenamiento temporal de transcripciones por trabajo
pending_transcriptions = defaultdict(dict)
job_metadata = {}
def connect_to_rabbitmq():
"""Establece conexión con RabbitMQ"""
tries = 0
while True:
try:
credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS)
connection = pika.BlockingConnection(
pika.ConnectionParameters(
host=RABBITMQ_HOST,
credentials=credentials
)
)
return connection
except pika.exceptions.AMQPConnectionError:
tries += 1
logger.warning(f"Intento {tries}: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...")
time.sleep(5)
def process_transcription(segment_info):
"""Procesa una transcripción recibida"""
original_file_id = segment_info['original_file_id']
segment_id = segment_info['segment_id']
transcription_path = segment_info['transcription_path']
total_segments = segment_info['total_segments']
# Almacenar metadatos del trabajo si no existen
if original_file_id not in job_metadata:
job_metadata[original_file_id] = {
'original_filename': segment_info['original_filename'],
'total_segments': total_segments,
'start_time': datetime.now()
}
# Leer transcripción
with open(transcription_path, 'r', encoding='utf-8') as f:
text = f.read()
# Almacenar transcripción
pending_transcriptions[original_file_id][segment_id] = {
'text': text,
'start_ms': segment_info['start_ms'],
'end_ms': segment_info['end_ms']
}
logger.info(f"Recibida transcripción {segment_id+1}/{total_segments} para {original_file_id}")
# Verificar si se han recibido todas las transcripciones para este trabajo
if len(pending_transcriptions[original_file_id]) == total_segments:
unify_transcriptions(original_file_id)
def convert_milliseconds_to_srt_time(ms):
"""Convierte milisegundos a formato de tiempo SRT (HH:MM:SS,mmm)"""
seconds, milliseconds = divmod(ms, 1000)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
return f"{hours:02d}:{minutes:02d}:{seconds:02d},{milliseconds:03d}"
def unify_transcriptions(original_file_id):
"""Unifica las transcripciones de un trabajo y genera el archivo de subtítulos"""
logger.info(f"Unificando transcripciones para {original_file_id}")
# Obtener metadatos del trabajo
metadata = job_metadata[original_file_id]
original_filename = metadata['original_filename']
# Preparar nombre de archivo de salida
base_filename = os.path.splitext(original_filename)[0]
output_filename = f"{base_filename}_transcription.srt"
output_path = os.path.join(OUTPUT_DIR, output_filename)
# Ordenar transcripciones por segment_id
sorted_segments = sorted(pending_transcriptions[original_file_id].items(), key=lambda x: x[0])
# Crear directorio de salida si no existe
os.makedirs(OUTPUT_DIR, exist_ok=True)
# Generar archivo SRT (formato de subtítulos)
with open(output_path, 'w', encoding='utf-8') as f:
for i, (segment_id, segment_data) in enumerate(sorted_segments):
# Formatear tiempo de inicio y fin
start_time = convert_milliseconds_to_srt_time(segment_data['start_ms'])
end_time = convert_milliseconds_to_srt_time(segment_data['end_ms'])
# Escribir entrada de subtítulo
f.write(f"{i+1}\n")
f.write(f"{start_time} --> {end_time}\n")
f.write(f"{segment_data['text'].strip()}\n\n")
# Calcular tiempo total de procesamiento
total_time = datetime.now() - metadata['start_time']
logger.info(f"Archivo de subtítulos generado: {output_path}")
logger.info(f"Tiempo total de procesamiento: {total_time}")
# Limpiar datos del trabajo completado
del pending_transcriptions[original_file_id]
del job_metadata[original_file_id]
def callback(ch, method, properties, body):
"""Callback para procesar mensajes de la cola de unificación"""
try:
# Decodificar mensaje
segment_info = json.loads(body)
# Procesar transcripción
process_transcription(segment_info)
# Confirmar procesamiento
ch.basic_ack(delivery_tag=method.delivery_tag)
except Exception as e:
logger.error(f"Error procesando mensaje: {str(e)}")
# Rechazar mensaje en caso de error para reintentarlo
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
def main():
"""Función principal"""
# Asegurar que directorios existen
os.makedirs(OUTPUT_DIR, exist_ok=True)
# Conexión a RabbitMQ
connection = connect_to_rabbitmq()
channel = connection.channel()
# Declarar cola
channel.queue_declare(queue=UNIFY_QUEUE, durable=True)
# Configurar prefetch count
channel.basic_qos(prefetch_count=1)
# Configurar callback
channel.basic_consume(queue=UNIFY_QUEUE, on_message_callback=callback)
logger.info("Servicio unificador iniciado. Esperando transcripciones...")
# Iniciar consumo
try:
channel.start_consuming()
except KeyboardInterrupt:
logger.info("Servicio unificador detenido")
channel.stop_consuming()
connection.close()
if __name__ == "__main__":
main()