Làm thế nào để xóa nhật ký đúng cách cho một Docker container?


210

Tôi sử dụng docker logs [container-name]để xem nhật ký của một container cụ thể.

Có một cách thanh lịch để xóa các bản ghi này?


14
Trên một sidenote, bạn có thể nhận được kích thước của các bản ghi thông quasudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log"
Daniel F

Câu trả lời:


251

Từ câu hỏi này, có một lớp lót mà bạn có thể chạy:

echo "" > $(docker inspect --format='{{.LogPath}}' <container_name_or_id>)

hoặc có lệnh cắt ngắn tương tự:

truncate -s 0 $(docker inspect --format='{{.LogPath}}' <container_name_or_id>)

Tôi không phải là một fan hâm mộ lớn của một trong hai người vì họ sửa đổi trực tiếp các tệp của Docker. Việc xóa nhật ký bên ngoài có thể xảy ra trong khi docker đang ghi dữ liệu được định dạng json vào tệp, dẫn đến một dòng và phá vỡ khả năng đọc bất kỳ nhật ký nào từ docker logscli.

Thay vào đó, bạn có thể để Docker tự động xoay vòng các bản ghi cho bạn. Điều này được thực hiện với các cờ bổ sung cho dockerd nếu bạn đang sử dụng trình điều khiển ghi nhật ký JSON mặc định :

dockerd ... --log-opt max-size=10m --log-opt max-file=3

Bạn cũng có thể đặt đây là một phần của tệp daemon.json thay vì sửa đổi tập lệnh khởi động:

{
  "log-driver": "json-file",
  "log-opts": {"max-size": "10m", "max-file": "3"}
}

Các tùy chọn này cần được cấu hình với quyền truy cập root. Đảm bảo chạy systemctl reload dockersau khi thay đổi tệp này để áp dụng các cài đặt. Cài đặt này sau đó sẽ là mặc định cho bất kỳ vùng chứa mới được tạo. Lưu ý, các container hiện có cần phải được xóa và tạo lại để nhận các giới hạn nhật ký mới.


Các tùy chọn nhật ký tương tự có thể được chuyển đến các vùng chứa riêng lẻ để ghi đè các giá trị mặc định này, cho phép bạn lưu nhiều hơn hoặc ít hơn các bản ghi trên các thùng chứa riêng lẻ. Từ docker runđây trông như:

docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 ...

hoặc trong tệp soạn thảo:

version: '3.7'
services:
  app:
    image: ...
    logging:
      options:
        max-size: "10m"
        max-file: "3"

Để tiết kiệm không gian bổ sung, bạn có thể chuyển từ trình điều khiển nhật ký json sang trình điều khiển nhật ký "cục bộ". Nó có cùng tùy chọn kích thước tối đa và tệp tối đa, nhưng thay vì lưu trữ trong json, nó sử dụng cú pháp nhị phân nhanh hơn và nhỏ hơn. Điều này cho phép bạn lưu trữ nhiều nhật ký hơn trong cùng một tệp có kích thước. Mục daemon.json cho đó trông giống như:

{
  "log-driver": "local",
  "log-opts": {"max-size": "10m", "max-file": "3"}
}

Nhược điểm của trình điều khiển cục bộ là trình phân tích / chuyển tiếp nhật ký bên ngoài phụ thuộc vào quyền truy cập trực tiếp vào nhật ký json sẽ không còn hoạt động. Vì vậy, nếu bạn sử dụng một công cụ như filebeat để gửi tới công cụ chuyển tiếp phổ biến của Splunk hoặc Splunk, tôi sẽ tránh trình điều khiển "cục bộ".

Tôi đã có thêm một chút về điều này trong bài thuyết trình Mẹo và Thủ thuật của tôi .


6
Tôi đã làm một service docker restart cái mà bản thân nó không hoạt động. Cũng phải tạo thương hiệu cho các container mới trước khi nó có hiệu lực. tức là chỉ đưa lên các container cũ không áp dụng ghi nhật ký mới
Robbo_UK

Tôi đang sử dụng Docker 1.13.1 và 'docker tests --format =' {{. LogPath}} '<container id>' trả về một chuỗi null ("") .... nhưng tôi vẫn nhận được đầu ra từ ' Nhật ký docker <id id> '?!? Nó đến từ đâu và làm thế nào để tôi xóa nó ??
JD Allen

@JDAllen 1.13.1 không còn hỗ trợ. Tôi không có một hệ thống cũ để xem đầu ra kiểm tra của họ.
BMitch

Tốt hơn nữa sẽ là echo -n > .... Dù sao, tôi muốn có thể kiểm soát nhiều hơn các bản ghi của tôi. Ví dụ, sau khi khởi động lại docker-compose , tôi rất thích có cơ chế để làm một cái gì đó với các bản ghi được bảo quản.
NarnasK

2
@AlexisWilke nếu bạn có thể dừng docker, thì có khả năng bạn có thể dừng container của bạn. Nếu bạn có thể làm sau, thì việc tạo lại container với các tùy chọn ghi nhật ký sẽ là lời khuyên của tôi. Container mới không có nhật ký cũ và nhật ký mới sẽ được cuộn tự động, giải quyết cả vấn đề ngắn hạn và dài hạn cùng một lúc.
BMitch

227

Sử dụng:

truncate -s 0 /var/lib/docker/containers/*/*-json.log

Bạn có thể cần sudo

sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

tham chiếu Jeff S. Làm thế nào để xóa nhật ký đúng cách cho container Docker?

Tham khảo: Cắt bớt một tập tin trong khi nó đang được sử dụng (Linux)


4
cắt ngắn: không thể mở '/var/lib/docker/containers/*/*-json.log' để viết: Không có tệp hoặc thư mục như vậy
BTR

2
@BTRN Nikol bạn phải chạy nó dưới dạng root / sudo, nội dung của containerskhông có sẵn nếu không.
spydon

25
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"- làm việc cho tôi
Jeff S.

7
Bỏ qua hai chuyên gia ở trên. Nếu bạn không chắc chắn, bạn chỉ có thể kiểm tra với "ls /var/lib/docker/containers/*/*-json.log" những gì đang bị cắt ngắn.
duketwo

1
sau khi làm trống logfile, tôi gặp lỗi này:error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
arcol

42

Trên Docker cho Windows và Mac, và có lẽ những người khác cũng vậy, có thể sử dụng tùy chọn đuôi. Ví dụ:

docker logs -f --tail 100

Theo cách này, chỉ có 100 dòng cuối cùng được hiển thị và trước tiên bạn không phải cuộn qua 1M dòng ...

(Và do đó, xóa nhật ký có lẽ không cần thiết)


12
Ý tưởng là làm sạch các tệp nhật ký và không in n dòng cuối cùng của tệp nhật ký
Youssouf Maiga

41
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

4
Để có được kích thước của các bản ghi sudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log", chỉ lấy tổng số kích thước của các bản ghisudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log | grep total"
Daniel F

Có bất kỳ vấn đề nào với dockerd / aufs không biết và không có khả năng loại bỏ các tệp nhật ký được xoay không?
ThorSummoner

Lệnh này hoạt động với tôi trong khi các lệnh khác trong SO này thì không. Nếu có vấn đề, tôi đang chạy Docker phiên bản 18 trên CentOS 7
Tundra Fizz

27

Bạn có thể thiết lập logrotate để xóa nhật ký định kỳ.

Tệp ví dụ trong /etc/logrotate.d/docker-logs

/var/lib/docker/containers/*/*.log {
 rotate 7
 daily
 compress
 size=50M
 missingok
 delaycompress
 copytruncate
}

và làm thế nào để tôi sử dụng này? Nó được sử dụng như mặc định với docker run? tập tin /etc/logrotate.d/docker-logskhông tồn tại, tôi phải tạo ra nó?
Carlos.V

Bạn phải gọi tiện ích logrotate (logrotate <config-file>) và nó sẽ đọc cấu hình của bạn và chạy dọn dẹp. Bạn cũng có thể đặt nó làm công việc định kỳ chẳng hạn.
AlexPnt

Vấn đề với cái này là nó có thể không được đồng bộ hóa đúng với những gì docker đang làm. Sử dụng các cơ sở docker có lẽ là khôn ngoan hơn nhiều. ( "log-opts"như được hiển thị bởi BMitch)
Alexis Wilke

12

Docker4Mac, một giải pháp năm 2018:

LOGPATH=$(docker inspect --format='{{.LogPath}}' <container_name_or_id>)
docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- truncate -s0 $LOGPATH

Dòng đầu tiên có đường dẫn tệp nhật ký, tương tự như câu trả lời được chấp nhận.

Dòng thứ hai sử dụng nsentercho phép bạn chạy các lệnh trong xhyveVM mà máy chủ là máy chủ lưu trữ cho tất cả các bộ chứa docker trong Docker4Mac. Lệnh chúng tôi chạy là quen thuộc truncate -s0 $LOGPATHtừ các câu trả lời không phải của Mac.

Nếu bạn đang sử dụng docker-compose, dòng đầu tiên sẽ trở thành:

local LOGPATH=$(docker inspect --format='{{.LogPath}}' $(docker-compose ps -q <service>))

<service>là tên dịch vụ từ docker-compose.ymltập tin của bạn .

Cảm ơn https://github.com/justincormack/nsenter1 cho nsentermánh khóe.


4
Và để cắt bớt nhật ký của tất cả các thùng chứa, bạn có thể sử dụng ký tự đại diện vỏ như trong các câu trả lời khác, vì vậy đó chỉ là một lệnh:docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- sh -c 'truncate -s0 /var/lib/docker/containers/*/*-json.log'
bradenm

11

Bạn không thể làm điều này trực tiếp thông qua lệnh Docker.

Bạn có thể giới hạn kích thước của nhật ký hoặc sử dụng tập lệnh để xóa các nhật ký liên quan đến vùng chứa. Bạn có thể tìm thấy các ví dụ về tập lệnh tại đây (đọc từ dưới lên): Tính năng: Khả năng xóa lịch sử nhật ký # 1083

Kiểm tra phần ghi nhật ký của tham chiếu tệp soạn thảo docker, nơi bạn có thể chỉ định các tùy chọn (chẳng hạn như xoay vòng nhật ký và giới hạn kích thước nhật ký) cho một số trình điều khiển ghi nhật ký.


7

Là người dùng root , hãy thử chạy như sau:

>  /var/lib/docker/containers/*/*-json.log

hoặc là

cat /dev/null > /var/lib/docker/containers/*/*-json.log

hoặc là

echo "" > /var/lib/docker/containers/*/*-json.log

6

Trên các máy chủ Ubuntu của tôi ngay cả khi sudo tôi sẽ nhận được Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory

Nhưng việc kết hợp các docker kiểm tra và cắt ngắn các câu trả lời đã có hiệu quả:

sudo truncate -s 0 `docker inspect --format='{{.LogPath}}' <container>`

2

Tôi thích cái này hơn (từ các giải pháp ở trên):

truncate -s 0 /var/lib/docker/containers/*/*-json.log

Tuy nhiên, tôi đang chạy một số hệ thống (ví dụ Ubuntu 18.x Bionic), nơi đường dẫn này không hoạt động như mong đợi. Docker được cài đặt thông qua Snap, vì vậy đường dẫn đến container giống như:

truncate -s 0 /var/snap/docker/common/var-lib-docker/containers/*/*-json.log

1

Bạn cũng có thể cung cấp các tham số log-opts trên docker rundòng lệnh, như sau:

docker run --log-opt max-size=10m --log-opt max-file=5 my-app:latest

hoặc trong một docker-compose.yml như thế này

my-app:
image: my-app:latest
logging:
    driver: "json-file"
    options:
        max-file: "5"
        max-size: 10m

Tín dụng: https://medium.com/@Quigley_Ja/rotating-docker-logs-keep-your-overlay-folder-small-40cfa2155412 (James Quigley)


Các giá trị tham số nên được trích dẫn (tức là "5""10m"tương ứng), như được hiển thị ở đây cho tệp daemon.json toàn cầu, nhưng nó cũng tương tự đối với một docker-compose.yml. Trong cả hai trường hợp, nó sẽ chỉ ảnh hưởng đến các container mới được tạo.
Adrian W

@AdrianW: docker-compose.yml không cần dấu ngoặc kép. Đây là các định dạng tập tin hoàn toàn khác nhau. Và đúng, bạn đã đúng: các lệnh "docker run" và các tham số soạn thảo docker chỉ ảnh hưởng đến các container mới được tạo - trái ngược với câu trả lời ở đây với hầu hết các phiếu bầu chỉ ảnh hưởng đến các trình nền dockerd được khởi động lại và chỉ có sẵn thông qua truy cập root. Câu trả lời của tôi được cho là hiển thị đường dẫn cập nhật và đơn giản hơn nhiều so với chỉnh sửa so với khởi động lại toàn bộ quá trình dockerd.
Dag Baardsen

Không có dấu ngoặc kép, tôi nhận được: LRI: cho ứng dụng Không thể tạo vùng chứa cho ứng dụng dịch vụ: json: không thể đánh số thứ tự vào trường cấu trúc Go LogConfig.Config của kiểu chuỗi Nếu tôi trích dẫn như thế này: "5"nó hoạt động. Các 10mcông việc mà không trích dẫn thực sự.
Adrian W

Có vẻ như có một sự khác biệt giữa Docker cho Windows và Docker cho Linux. Về sau, tôi phải kèm theo các giá trị trong dấu ngoặc kép. Không phải trên trước đây. Cập nhật mô tả để phù hợp với cả hai. Cảm ơn, @AdrianW
Dag Baardsen

0

Docker cho người dùng Mac, đây là giải pháp:

    1. Tìm đường dẫn tệp nhật ký bằng cách:

      $ docker inspect | grep log

    1. SSH vào máy docker (giả sử tên là default, nếu không, hãy chạy docker-machine lsđể tìm hiểu):

      $ docker-machine ssh default

    1. Thay đổi thành người dùng root ( tham khảo ):

      $ sudo -i

    1. Xóa nội dung tệp nhật ký:

      $ echo "" > log_file_path_from_step1


2
docker-machine không hoạt động với Docker cho Mac. Thay vào đó có thể chạy "Docker chạy -ti -v / var / lib / Docker / container: / var / thành lập centos bash" sau đó "truncate --size 0 /var/inception/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de-json.log"
Jamshid

Bạn có thể sử dụng docker exec -it default shđể nhập vỏ sh trong một container. Tuy nhiên, nhiều container không hoàn toàn làm cho sudolệnh có sẵn.
Dag Baardsen
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.