วิธีล้างบันทึกอย่างถูกต้องสำหรับคอนเทนเนอร์ Docker


210

ฉันใช้docker logs [container-name]เพื่อดูบันทึกของภาชนะที่เฉพาะเจาะจง

มีวิธีหรูหราในการล้างบันทึกเหล่านี้หรือไม่


14
บน sidenote คุณสามารถรับขนาดของบันทึกผ่านทางsudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log"
Daniel F

คำตอบ:


251

จากคำถามนี้มีหนึ่งซับไลน์ที่คุณสามารถรัน:

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

หรือมีคำสั่ง truncate ที่คล้ายกัน:

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

ฉันไม่ได้เป็นแฟนตัวยงของทั้งคู่เพราะพวกเขาแก้ไขไฟล์ของ Docker โดยตรง การลบบันทึกภายนอกอาจเกิดขึ้นในขณะที่นักเทียบท่ากำลังเขียนข้อมูลที่จัดรูปแบบ json ไปยังไฟล์ส่งผลให้เกิดบรรทัดบางส่วนและทำลายความสามารถในการอ่านบันทึกใด ๆ จากdocker logsCLI

แต่คุณสามารถให้ Docker หมุนบันทึกให้คุณโดยอัตโนมัติ สิ่งนี้ทำกับแฟล็กเพิ่มเติมไปยัง dockerd หากคุณใช้ไดรเวอร์การบันทึก JSONดีฟอลต์:

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

คุณสามารถตั้งค่านี้เป็นส่วนหนึ่งของไฟล์daemon.jsonของคุณแทนการแก้ไขสคริปต์เริ่มต้นของคุณ:

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

ตัวเลือกเหล่านี้ต้องได้รับการกำหนดค่าด้วยการเข้าถึงรูท ตรวจสอบให้แน่ใจว่าได้รันsystemctl reload dockerหลังจากเปลี่ยนไฟล์นี้เพื่อให้การตั้งค่าถูกนำไปใช้ การตั้งค่านี้จะเป็นค่าเริ่มต้นสำหรับคอนเทนเนอร์ที่สร้างขึ้นใหม่ หมายเหตุคอนเทนเนอร์ที่มีอยู่ต้องถูกลบและสร้างใหม่เพื่อรับขีด จำกัด การบันทึกใหม่


ตัวเลือกบันทึกที่คล้ายกันสามารถส่งผ่านไปยังแต่ละคอนเทนเนอร์เพื่อลบล้างค่าเริ่มต้นเหล่านี้ช่วยให้คุณสามารถบันทึกล็อกได้มากขึ้นหรือน้อยลงในแต่ละคอนเทนเนอร์ จากdocker runนี้ดูเหมือนว่า:

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

หรือในไฟล์เขียน:

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

สำหรับการประหยัดพื้นที่เพิ่มเติมคุณสามารถสลับจากไดร์เวอร์บันทึก json เป็นไดร์เวอร์บันทึก "ท้องถิ่น" ใช้ขนาดสูงสุดและตัวเลือกไฟล์สูงสุดเดียวกัน แต่แทนที่จะเก็บไว้ใน json จะใช้ไวยากรณ์ไบนารีที่เร็วขึ้นและเล็กลง สิ่งนี้อนุญาตให้คุณเก็บบันทึกเพิ่มเติมในไฟล์ขนาดเดียวกัน รายการ daemon.json สำหรับที่ดูเหมือนว่า:

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

ข้อเสียของไดรเวอร์ท้องถิ่นคือ parsers / forwarders ภายนอกที่ขึ้นอยู่กับการเข้าถึงโดยตรงไปยังบันทึก json จะไม่ทำงานอีกต่อไป ดังนั้นหากคุณใช้เครื่องมือเช่น filebeat เพื่อส่งไปยัง Elastic หรือตัวส่งต่อสากลของ Splunk ฉันจะหลีกเลี่ยงไดรเวอร์ "local"

ฉันมีอีกเล็กน้อยเกี่ยวกับเรื่องนี้ในของฉันเคล็ดลับและเทคนิคการนำเสนอ


6
ผมservice docker restart ซึ่งในตัวเองไม่ได้ทำงาน ต้องสร้างแบรนด์ภาชนะใหม่ก่อนจึงจะมีผลบังคับใช้ เช่นการนำขึ้นภาชนะเก่าไม่ได้ใช้การบันทึกใหม่
Robbo_UK

ฉันกำลังใช้ Docker 1.13.1 และ 'นักเทียบท่าตรวจสอบ --format =' {{. LogPath}} '<container id>' ส่งคืนสตริง null ("") .... แต่ฉันยังคงได้รับผลลัพธ์จาก ' นักเทียบท่าบันทึก <container id> '?!? ที่มาจากไหนและฉันจะล้างมันได้อย่างไร?
JD Allen

@JDAllen 1.13.1 ไม่สนับสนุนนาน ฉันไม่มีระบบที่เก่าแก่เพื่อดูผลลัพธ์การตรวจสอบของพวกเขา
BMitch

echo -n > ...ยังดีกว่าจะเป็น อย่างไรก็ตามฉันต้องการควบคุมบันทึกของฉันได้มากขึ้น ตัวอย่างเช่นหลังจากการเริ่มต้นใหม่นักเทียบท่าเขียนฉันชอบที่จะมีกลไกในการทำบางสิ่งบางอย่างกับบันทึกที่เก็บรักษาไว้
NarūnasK

2
@AlexisWilke ถ้าคุณสามารถหยุดนักเทียบท่าคุณก็น่าจะหยุดคอนเทนเนอร์ได้ หากคุณสามารถทำหลังแล้วสร้างภาชนะที่มีตัวเลือกการบันทึกจะเป็นคำแนะนำของฉัน คอนเทนเนอร์ใหม่ไม่มีบันทึกเก่าและบันทึกใหม่จะถูกรีดโดยอัตโนมัติแก้ไขทั้งปัญหาระยะสั้นและระยะยาวในเวลาเดียวกัน
BMitch

227

ใช้:

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

คุณอาจต้อง sudo

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

อ้าง Jeff S. วิธีล้างบันทึกอย่างถูกต้องสำหรับคอนเทนเนอร์ Docker อย่างไร

การอ้างอิง: การตัดทอนไฟล์ในขณะที่กำลังใช้งานอยู่ (Linux)


4
truncate: ไม่สามารถเปิด '/var/lib/docker/containers/*/*-json.log' สำหรับการเขียน: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว
BTR Naidu

2
@BTRNaidu คุณต้องเรียกใช้เป็น root / sudo เนื้อหาของcontainersไม่สามารถใช้งานได้
spydon

25
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"- ทำงานให้ฉัน
เจฟฟ์เอส

7
ไม่ต้องสนใจผู้เชี่ยวชาญสองคนด้านบน หากคุณไม่แน่ใจคุณสามารถตรวจสอบกับ "ls /var/lib/docker/containers/*/*-json.log" สิ่งที่จะถูกตัดทอน
duketwo

1
หลังจากล้างไฟล์บันทึกการทำงานฉันได้รับข้อผิดพลาดนี้:error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
arcol

42

บน Docker สำหรับ Windows และ Mac และอื่น ๆ ด้วยเช่นกันคุณสามารถใช้ตัวเลือกหางได้ ตัวอย่างเช่น:

docker logs -f --tail 100

ด้วยวิธีนี้จะแสดงเฉพาะ 100 บรรทัดสุดท้ายเท่านั้นและคุณไม่มีครั้งแรกที่เลื่อนดู 1M บรรทัด ...

(และการลบบันทึกอาจไม่จำเป็น)


12
แนวคิดคือทำความสะอาดไฟล์บันทึกและไม่พิมพ์บรรทัดสุดท้ายของไฟล์บันทึก
Youssouf Maiga

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

4
ในการรับขนาดของบันทึกsudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log"เพื่อให้ได้ขนาดโดยรวมเท่านั้นsudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log | grep total"
Daniel F

มีปัญหาใด ๆ กับ dockerd / aufs ที่ไม่รู้และไม่สามารถลบไฟล์บันทึกที่หมุนได้หรือไม่?
ThorSummoner

คำสั่งนี้ใช้งานได้สำหรับฉันในขณะที่คำสั่งอื่นใน SO นี้ไม่มี หากเป็นเรื่องสำคัญฉันกำลังใช้งาน Docker เวอร์ชัน 18 บน CentOS 7
Tundra Fizz

27

คุณสามารถตั้งค่า logrotate เพื่อล้างบันทึกเป็นระยะ

ไฟล์ตัวอย่างใน /etc/logrotate.d/docker-logs

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

และฉันจะใช้สิ่งนี้ได้อย่างไร มันถูกใช้เป็นค่าเริ่มต้นด้วยdocker runหรือไม่ ไฟล์/etc/logrotate.d/docker-logsไม่มีอยู่ฉันต้องสร้างมันขึ้นมาเหรอ?
Carlos.V

คุณต้องเรียกใช้ยูทิลิตี logrotate (logrotate <config-file>) และมันจะอ่านการกำหนดค่าของคุณและทำการล้างข้อมูล คุณยังสามารถตั้งค่าเป็นงาน cron ได้อีกด้วย
AlexPnt

ปัญหาเกี่ยวกับสิ่งนี้คือมันอาจจะไม่ตรงกับสิ่งที่นักเทียบท่ากำลังทำ การใช้สิ่งอำนวยความสะดวกนักเทียบท่าน่าจะฉลาดกว่ามาก ( "log-opts"ดังที่แสดงโดย BMitch)
Alexis Wilke

12

Docker4Mac โซลูชั่น 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

บรรทัดแรกรับเส้นทางไฟล์บันทึกซึ่งคล้ายกับคำตอบที่ยอมรับ

บรรทัดที่สองใช้nsenterเพื่อให้คุณสามารถรันคำสั่งในxhyveVM ที่เซิร์ฟเวอร์เป็นโฮสต์สำหรับคอนเทนเนอร์นักเทียบท่าทั้งหมดภายใต้ Docker4Mac คำสั่งที่เราเรียกใช้นั้นเป็นtruncate -s0 $LOGPATHคำตอบที่ไม่คุ้นเคยกับ Mac

หากคุณกำลังใช้docker-composeบรรทัดแรกจะกลายเป็น:

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

และ<service>เป็นชื่อบริการจากdocker-compose.ymlไฟล์ของคุณ

ขอบคุณhttps://github.com/justincormack/nsenter1สำหรับnsenterเคล็ดลับ


4
และตัดทอนบันทึกของภาชนะบรรจุทั้งหมดที่คุณสามารถใช้สัญลักษณ์แทนเปลือกตามที่ปรากฏในคำตอบอื่น ๆ ดังนั้นจึงเป็นเพียงหนึ่งคำสั่ง: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

คุณไม่สามารถทำได้โดยตรงผ่านคำสั่ง Docker

คุณสามารถ จำกัด ขนาดของบันทึกหรือใช้สคริปต์เพื่อลบบันทึกที่เกี่ยวข้องกับคอนเทนเนอร์ คุณสามารถค้นหาตัวอย่างสคริปต์ได้ที่นี่ (อ่านจากด้านล่าง): คุณสมบัติ: ความสามารถในการล้างประวัติบันทึก # 1083

ตรวจสอบส่วนการบันทึกของการอ้างอิงไฟล์นักเทียบท่าซึ่งคุณสามารถระบุตัวเลือก (เช่นการหมุนบันทึกและขีด จำกัด ขนาดบันทึก) สำหรับไดรเวอร์การบันทึกบางตัว


7

ในฐานะผู้ใช้รูทพยายามรันสิ่งต่อไปนี้:

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

หรือ

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

หรือ

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

6

บนเซิร์ฟเวอร์ Ubuntu ของฉันแม้เป็น sudo ฉันจะได้รับ Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory

แต่การรวมนักเทียบท่าจะตรวจสอบและตัดคำตอบที่ทำงาน:

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

2

ฉันชอบสิ่งนี้ (จากโซลูชันด้านบน):

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

อย่างไรก็ตามฉันใช้หลาย ๆ ระบบ (เช่น Ubuntu 18.x Bionic) ซึ่งเส้นทางนี้ใช้งานไม่ได้ตามที่คาดไว้ นักเทียบท่าถูกติดตั้งผ่าน Snap ดังนั้นเส้นทางไปยังภาชนะบรรจุจึงมีลักษณะดังนี้

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

1

คุณสามารถจัดหาพารามิเตอร์ log-opts ในdocker runบรรทัดคำสั่งเช่นนี้:

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

หรือใน docker-compose.yml เช่นนี้

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

เครดิต: https://medium.com/@Quigley_Ja/rotating-docker-logs-keeping-your-overlay-folder-small-40cfa2155412 (James Quigley)


ค่าพารามิเตอร์ควรเสนอราคา (เช่น"5"และ"10m"ตามลำดับ) ดังที่แสดงไว้ที่นี่สำหรับไฟล์ daemon.json ทั่วโลก แต่จะเหมือนกันสำหรับ docker-compose.yml ในทั้งสองกรณีจะมีผลกับคอนเทนเนอร์ที่สร้างขึ้นใหม่เท่านั้น
Adrian W

@AdrianW: docker-compose.yml ไม่จำเป็นต้องมีเครื่องหมายคำพูด รูปแบบไฟล์เหล่านี้แตกต่างกันอย่างสิ้นเชิง และใช่คุณพูดถูก: คำสั่ง "นักเทียบท่าเรียกใช้" และพารามิเตอร์การเรียงนักเทียบท่าจะมีผลกับคอนเทนเนอร์ที่สร้างขึ้นใหม่เท่านั้นซึ่งต่างจากคำตอบที่นี่ด้วยคะแนนเสียงส่วนใหญ่ที่มีผลต่อรีสตาร์ท dockerd daemons เท่านั้น คำตอบของฉันควรจะแสดงเส้นทางที่ง่ายและอัปเดตมากกว่าการแก้ไขมากกว่าการรีสตาร์ทกระบวนการ dockerd ทั้งหมด
Dag Baardsen

หากไม่มีเครื่องหมายอัญประกาศฉันจะได้รับ: ข้อผิดพลาด: สำหรับแอปไม่สามารถสร้างคอนเทนเนอร์สำหรับแอปบริการ: json: ไม่สามารถ unmarshal หมายเลขลงในฟิลด์ Go struct LogConfig.Config ของสตริงประเภท ถ้าฉันพูดแบบนี้"5"มันทำงานได้ การ10mทำงานโดยไม่ต้องพูดถึงอย่างแน่นอน
Adrian W

ดูเหมือนว่าจะมีความแตกต่างระหว่าง Docker สำหรับ Windows และ Docker สำหรับ Linux ในตอนหลังฉันต้องใส่ค่าในเครื่องหมายคำพูด ไม่ได้อยู่ที่อดีต อัปเดตคำอธิบายให้พอดีกับทั้งสอง ขอบคุณ @AdrianW
Dag Baardsen

0

ผู้ใช้ Docker for Mac นี่คือวิธีแก้ไข:

    1. ค้นหาเส้นทางของไฟล์บันทึกโดย:

      $ docker inspect | grep log

    1. SSH ลงในเครื่องนักเทียบท่า (หากชื่อdefaultไม่ได้ให้เรียกใช้docker-machine lsเพื่อค้นหา):

      $ docker-machine ssh default

    1. เปลี่ยนเป็นผู้ใช้รูท ( ข้อมูลอ้างอิง ):

      $ sudo -i

    1. ลบเนื้อหาไฟล์บันทึก:

      $ echo "" > log_file_path_from_step1


2
นักเทียบท่าเครื่องไม่ทำงานกับ Docker สำหรับ Mac คุณสามารถเรียกใช้แทน "นักเทียบท่าวิ่ง -ti -v / var / lib / นักเทียบท่า / ถังบรรจุ: / var / การลงทะเบียนเรียน CentOS ทุบตี" แล้ว "ตัด --size 0 /var/inception/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de-json.log"
แจม

คุณอาจใช้docker exec -it default shเพื่อใส่เปลือก sh ในภาชนะ อย่างไรก็ตามคอนเทนเนอร์จำนวนมากไม่ได้ทำให้sudoคำสั่งพร้อมใช้งานโดยปริยาย
Dag Baardsen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.