Есть приложение, которое включает в себя 5 Docker-контейнеров.
Для наблюдения за логами используется Loggly, но мне он жутко неудобен — в консоли логи удобнее смотреть и грепать.
Запущенное приложение выглядит так:
ubuntu@ip-10-5-3-54:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 63937e07a5cf tag-docker.jfrog.io/api-gateway:staging-test-eureka-cloud-versioning-124 "java -Djava.security" 30 minutes ago Up 30 minutes 0.0.0.0:8080->8080/tcp peaceful_blackwell cbf2394197bc tag-docker.jfrog.io/producers:staging-test-eureka-cloud-versioning-124 "java -Djava.security" 30 minutes ago Up 30 minutes 0.0.0.0:8090->8090/tcp cocky_nobel 1884543d61b1 tag-docker.jfrog.io/configuration:staging-test-eureka-cloud-versioning-124 "java -Djava.security" 30 minutes ago Restarting (1) 2 minutes ago 0.0.0.0:8084->8084/tcp kickass_kirch 65be0b7bb07e tag-docker.jfrog.io/profile:staging-test-eureka-cloud-versioning-124 "java -Djava.security" 30 minutes ago Up 30 minutes 0.0.0.0:8083->8083/tcp nauseous_kowalevski 947a92a1a629 tag-docker.jfrog.io/oauth2-authserver:staging-test-eureka-cloud-versioning-124 "java -Djava.security" 30 minutes ago Up 30 minutes 0.0.0.0:9999->9999/tcp nauseous_wescoff
Задача скрипта — создать файл лога для каждого сервиса и начать в него писать STDERR
и STDOUT
из контейнера.
Сам скрипт:
#!/usr/bin/env bash # To catch STDERR and STDOUT from each Docker container with $API_SERVICES # to a propriate log file from $API_LOGS # run: tail -f *.log to watch them # объявляем два именованных массива declare -A API_SERVICES declare -A API_LOGS # наполняем их API_SERVICES=( [GATEWAY]=api-gateway \ [PRODUCERS]=producers \ [CONFIGURATION]=configuration \ [PROFILE]=profile \ [AUTHSERVER]=oauth2-authserver ) API_LOGS=( [GATEWAY]=gateway.log \ [PRODUCERS]=producers.log \ [CONFIGURATION]=configuration.log \ [PROFILE]=profile.log \ [AUTHSERVER]=authserver.log ) # получаем имя ключа из массива (GATEWAY и т.д.) for service in ${!API_SERVICES[@]}; do # используя имя ключа в виде имени сервиса - получаем значение этой пары ключ-значение # например, для GATEWAY - это будет api-gateway # по значению находим контейнер (grep), и получаем его ID (awk - print первое поле) container_id=$(docker ps | grep ${API_SERVICES[$service]} | awk '{print $1}') # используя имя ключа в виде имени сервиса - находим в массиве API_LOGS значение # например, для GATEWAY - это будет gateway.log log_name=${API_LOGS[$service]} echo Service: $service Container ID: $container_id Log file: $log_name # и используя $container_id (666555444) и $log_name (gateway.log) # выполняем docker logs -f перенаправляя STDERR и STDOUT в соответствующий файл docker logs -f $container_id >> $log_name 2>&1 & done
Запускаем:
ubuntu@ip-10-5-3-54:~$ ./logs.sh Service: CONFIGURATION Container ID: 1884543d61b1 Log file: configuration.log Service: PROFILE Container ID: 65be0b7bb07e Log file: profile.log Service: PRODUCERS Container ID: cbf2394197bc Log file: producers.log Service: GATEWAY Container ID: 63937e07a5cf Log file: gateway.log Service: AUTHSERVER Container ID: 947a92a1a629 Log file: authserver.log
Проверяем:
ubuntu@ip-10-5-3-54:~$ tail -f *.log ==> authserver.log <== profile: 15:46:40.248 o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read ==> configuration.log <== at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138) at ==> gateway.log <== profile: 16:05:11.247 o.s.b.a.e.mvc.EndpointHandlerMapping - Returning handler method [public java.lang.Object ...
Готово.