Làm cách nào để chuyển hướng nhật ký vùng chứa docker đến một tệp duy nhất?


110

Tôi muốn chuyển hướng tất cả nhật ký của vùng chứa docker của mình thành một tệp nhật ký duy nhất để phân tích chúng. Tôi đã thử

docker logs container > /tmp/stdout.log 2>/tmp/stderr.log

nhưng điều này cho đăng nhập vào hai tệp khác nhau. Tôi đã thử

docker logs container > /tmp/stdout.log

nhưng nó đã không hoạt động.

Câu trả lời:


137

Không cần chuyển hướng nhật ký.

Docker lưu trữ theo mặc định ghi nhật ký vào một tệp nhật ký. Để kiểm tra lệnh chạy đường dẫn tệp nhật ký:

docker inspect --format='{{.LogPath}}' containername

/var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.log

Mở tệp nhật ký đó và phân tích.

nếu bạn chuyển hướng nhật ký thì bạn sẽ chỉ nhận được nhật ký trước khi chuyển hướng. bạn sẽ không thể xem nhật ký trực tiếp.

BIÊN TẬP:

Để xem nhật ký trực tiếp, bạn có thể chạy lệnh dưới đây

tail -f `docker inspect --format='{{.LogPath}}' containername`

Ghi chú:

Tệp nhật ký /var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.lognày sẽ được tạo chỉ khi trình docker tạo nhật ký nếu không có nhật ký thì tệp này sẽ không ở đó. nó tương tự như đôi khi nếu chúng ta chạy lệnh docker logs containernamevà nó không trả về gì. Trong trường hợp đó, tệp này sẽ không có sẵn.


tail -f `docker inspect --format='{{.LogPath}}' myapp`- nó thực sự là JSON
Adam

nó sẽ không thành công nếu tệp đó không có ở đó. có nghĩa là nếu docker không tạo bất kỳ nhật ký nào thì tệp này sẽ không được tạo. nhưng nếu docker tạo nhật ký thì lệnh này rất tốt để xem nhật ký trực tiếp. cảm ơn Adam. thêm nó vào câu trả lời của tôi để giúp những người khác.
pl_rock

"Docker lưu trữ theo mặc định ghi nhật ký vào một tệp nhật ký." - trong bối cảnh nào? Tất cả các vùng chứa đang chạy trên máy chủ docker đều nhận được đầu ra cho một tệp duy nhất? Một thùng chứa duy nhất?
Chris Stryczynski

@ChrisStryczynski Docker tạo một tệp nhật ký cho mỗi vùng chứa
Eddy Hernandez

126

Làm thế nào về tùy chọn này:

docker logs containername >& logs/myFile.log

Nó sẽ không chuyển hướng các bản ghi được yêu cầu trong câu hỏi, nhưng sao chép chúng một lần vào một tệp cụ thể.


Nếu tôi không nhầm, lệnh này về cơ bản sẽ sao chép tất cả các bản ghi từ khi vùng chứa được bắt đầu trình bày sang myFile.logs. Đúng.?
S Andrew

@SAndrew về cơ bản là có! nhưng các phiên bản mới của Docker có thể thay đổi. tốt hơn để xem docker logs --helpđể chắc chắn
Eddy Hernandez

38

docker logs -f <yourContainer> &> your.log &

Giải trình:

  • -f(tức là --follow): ghi tất cả nhật ký hiện có và tiếp tục (tiếp theo ) ghi lại mọi thứ tiếp theo.
  • &> chuyển hướng cả đầu ra tiêu chuẩn và lỗi tiêu chuẩn.
  • Có thể bạn muốn chạy phương thức đó trong nền, do đó &.
  • Bạn có thể tách đầu ra và stderr bằng: > output.log 2> error.log(thay vì sử dụng &>).

9

Để nắm bắt cả stdout & stderr từ vùng chứa docker của bạn vào một tệp nhật ký duy nhất, hãy chạy như sau:

docker logs container > container.log 2>&1

8

Giả sử rằng bạn có nhiều vùng chứa và bạn muốn tổng hợp các nhật ký thành một tệp duy nhất, bạn cần sử dụng một số công cụ tổng hợp nhật ký như thông thạo. lưu loát được hỗ trợ như trình điều khiển ghi nhật ký cho các bộ chứa docker.

Vì vậy, trong docker-soạn, bạn cần xác định trình điều khiển ghi nhật ký

  service1:
    image: webapp:0.0.1
    logging:
      driver: "fluentd"
      options:
        tag: service1 

  service2:
        image: myapp:0.0.1
        logging:
          driver: "fluentd"
          options:
            tag: service2

Bước thứ hai là cập nhật thông tin lưu loát để cung cấp nhật ký cho cả dịch vụ 1 và dịch vụ 2

 <match service1>
   @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%z
  </store>
 </match> 
 <match service2>
    @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%
  </store>
 </match> 

Trong cấu hình này, chúng tôi yêu cầu các bản ghi được ghi vào một tệp duy nhất đến đường dẫn này
/fluentd/log/service/service.*.log

và bước thứ ba là chạy thông thạo tùy chỉnh sẽ bắt đầu ghi nhật ký vào tệp.

Đây là liên kết để hướng dẫn từng bước

Hơi dài, nhưng đúng cách vì bạn có nhiều quyền kiểm soát hơn đối với đường dẫn tệp nhật ký, v.v. và nó cũng hoạt động tốt trong Docker Swarm.


1

Vì Docker hợp nhất stdout và stderr cho chúng ta, chúng ta có thể coi đầu ra nhật ký giống như bất kỳ luồng shell nào khác. Để chuyển hướng các nhật ký hiện tại đến một tệp, hãy sử dụng toán tử chuyển hướng

$ docker logs test_container > output.log
docker logs -f test_container > output.log

Thay vì gửi đầu ra tới stderr và stdout, hãy chuyển hướng đầu ra của ứng dụng của bạn thành một tệp và ánh xạ tệp đó đến bộ nhớ vĩnh viễn bên ngoài vùng chứa.

$ docker logs test_container> /tmp/output.log

Docker sẽ không chấp nhận các đường dẫn tương đối trên dòng lệnh, vì vậy nếu bạn muốn sử dụng một thư mục khác, bạn sẽ cần sử dụng đường dẫn hoàn chỉnh.


1

Nếu bạn làm việc trên Windows và sử dụng PowerShell (như tôi), bạn có thể sử dụng dòng sau để nắm bắt stdoutstderr:

 docker logs <containerId> | Out-File 'C:/dev/mylog.txt'

Tôi hi vọng nó giúp ích cho ai đó!


1
Để lưu tất cả nhật ký vùng chứa vào tệp, dựa trên tên vùng chứa ...foreach ($element in $(docker ps -a --format "{{.Names}}")) {docker logs $element | Out-File "C:/dockerlogs/$element.log"}
xisket

1

Cách dễ nhất mà tôi sử dụng là lệnh này trên thiết bị đầu cuối:

docker logs elk > /home/Desktop/output.log

cấu trúc là:

docker logs <Container Name> > path/filename.log

1

Trước tiên hãy kiểm tra id vùng chứa của bạn

docker ps -a

Bạn có thể thấy hàng đầu tiên trong các cột ID CONTAINER. Có lẽ nó trông giống như thế này "3fd0bfce2806" sau đó nhập nó vào shell

docker inspect --format='{{.LogPath}}' 3fd0bfce2806

Bạn sẽ thấy một cái gì đó như thế này

/var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

thì bạn có thể thấy nó là

cat /var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

Nó sẽ ở định dạng JSON, bạn có thể sử dụng dấu thời gian để theo dõi lỗi


0

Tập lệnh Bash để sao chép tất cả nhật ký vùng chứa vào một thư mục được chỉ định:

#!/usr/bin/env bash

TARGET_DIR=~/logs/docker_logs
mkdir -p "$TARGET_DIR"
for name in `sudo docker ps --format '{{.Names}}'`;
do
    path=$(sudo docker inspect --format='{{.LogPath}}' $name)
    sudo cp -rf "$path" "$TARGET_DIR"/$name.log
done
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.