วิธีเปลี่ยนเส้นทางล็อกคอนเทนเนอร์ของนักเทียบท่าไปยังไฟล์เดียว


113

ฉันต้องการเปลี่ยนเส้นทางบันทึกทั้งหมดของคอนเทนเนอร์นักเทียบท่าของฉันไปยังไฟล์บันทึกเดียวเพื่อวิเคราะห์ ฉันเหนื่อย

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

แต่จะให้ล็อกในสองไฟล์ที่แตกต่างกัน ฉันพยายามแล้ว

docker logs container > /tmp/stdout.log

แต่มันไม่ได้ผล

คำตอบ:


142

ไม่จำเป็นต้องเปลี่ยนเส้นทางบันทึก

Docker โดยค่าเริ่มต้นจะจัดเก็บบันทึกไปยังไฟล์บันทึกเดียว ในการตรวจสอบคำสั่งเรียกใช้เส้นทางไฟล์บันทึก:

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

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

เปิดไฟล์บันทึกนั้นและวิเคราะห์

หากคุณเปลี่ยนเส้นทางบันทึกคุณจะได้รับบันทึกก่อนที่จะเปลี่ยนเส้นทางเท่านั้น คุณจะไม่สามารถดูบันทึกสดได้

แก้ไข:

หากต้องการดูบันทึกสดคุณสามารถเรียกใช้คำสั่งด้านล่าง

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

บันทึก:

ไฟล์บันทึกนี้/var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.logจะถูกสร้างขึ้นก็ต่อเมื่อนักเทียบท่าสร้างบันทึกหากไม่มีบันทึกไฟล์นี้จะไม่อยู่ที่นั่น มันคล้าย ๆ กับบางครั้งถ้าเรารันคำสั่งdocker logs containernameแล้วมันไม่ส่งคืน ในสถานการณ์นั้นไฟล์นี้จะไม่พร้อมใช้งาน


tail -f `docker inspect --format='{{.LogPath}}' myapp`- มันคือ JSON จริงๆ
อดัม

มันจะล้มเหลวหากไม่มีไฟล์นั้น หมายความว่าถ้านักเทียบท่าไม่สร้างบันทึกใด ๆ ไฟล์นี้จะไม่ถูกสร้างขึ้น แต่ถ้านักเทียบท่าสร้างบันทึกคำสั่งนี้จะดีในการดูบันทึกสด ขอบคุณอดัม เพิ่มในคำตอบของฉันเพื่อช่วยเหลือผู้อื่น
pl_rock

"Docker โดยค่าเริ่มต้นจะจัดเก็บบันทึกไว้ในไฟล์บันทึกเดียว" - ในบริบทใด? คอนเทนเนอร์ทั้งหมดที่ทำงานบนโฮสต์ Docker ได้รับเอาต์พุตเป็นไฟล์เดียวหรือไม่ ตู้คอนเทนเนอร์เดียว?
Chris Stryczynski

@ChrisStryczynski Docker สร้างไฟล์บันทึกต่อคอนเทนเนอร์
Eddy Hernandez

128

วิธีการเกี่ยวกับตัวเลือกนี้:

docker logs containername >& logs/myFile.log

จะไม่เปลี่ยนเส้นทางบันทึกที่ถูกถามในคำถาม แต่จะคัดลอกหนึ่งครั้งไปยังไฟล์เฉพาะ


ถ้าฉันไม่ผิดคำสั่งนี้โดยทั่วไปจะคัดลอกบันทึกทั้งหมดจากตอนที่เริ่มคอนเทนเนอร์เพื่อนำเสนอไปยัง myFile.logs ขวา.?
S Andrew

@SAndrew โดยทั่วไปใช่! แต่ Docker เวอร์ชันใหม่อาจมีการเปลี่ยนแปลง ดีกว่าที่จะเห็นdocker logs --helpให้แน่ใจ
Eddy Hernandez

40

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

คำอธิบาย:

  • -f(เช่น--follow): เขียนบันทึกที่มีอยู่ทั้งหมดและดำเนินการต่อ ( ติดตาม ) บันทึกทุกอย่างที่จะเกิดขึ้นถัดไป
  • &> เปลี่ยนเส้นทางทั้งเอาต์พุตมาตรฐานและข้อผิดพลาดมาตรฐาน
  • คุณอาจต้องการเรียกใช้วิธีการนั้นในพื้นหลังดังนั้นไฟล์&.
  • คุณสามารถแยกเอาต์พุตและ stderr โดย: > output.log 2> error.log(แทนที่จะใช้&>)

9

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

ดังนั้นใน Docker-compose คุณต้องกำหนดไดรเวอร์การบันทึก

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

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

ขั้นตอนที่สองคือการอัปเดต fluentd conf เพื่อรองรับบันทึกสำหรับทั้งบริการ 1 และบริการ 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> 

ในการกำหนดค่านี้เราขอให้เขียนบันทึกเป็นไฟล์เดียวไปยังเส้นทางนี้
/fluentd/log/service/service.*.log

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

นี่คือลิงค์สำหรับคำแนะนำทีละขั้นตอน

Bit Long แต่เป็นวิธีที่ถูกต้องเนื่องจากคุณสามารถควบคุมเส้นทางไฟล์บันทึกได้มากขึ้นและทำงานได้ดีใน Docker Swarm ด้วย


1
ฉันได้เรียนรู้บางอย่างจากคำตอบนี้ แม้ว่ามันอาจจะไม่เหมาะกับ OP โดยตรง แต่ก็อาจเป็นแรงบันดาลใจสำหรับคนส่วนใหญ่ที่สะดุดกับกระทู้นี้
ทรมาน

9

ในการจับทั้ง stdout & stderr จากคอนเทนเนอร์นักเทียบท่าของคุณไปยังไฟล์บันทึกเดียวให้รันดังต่อไปนี้:

docker logs container > container.log 2>&1

1

หากคุณทำงานบน Windows และใช้ PowerShell (เช่นฉัน) คุณสามารถใช้บรรทัดต่อไปนี้เพื่อจับภาพstdoutและstderr:

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

ฉันหวังว่ามันจะช่วยใครสักคน!


1
ในการบันทึกล็อกคอนเทนเนอร์ทั้งหมดลงในไฟล์โดยยึดตามชื่อคอนเทนเนอร์ ...foreach ($element in $(docker ps -a --format "{{.Names}}")) {docker logs $element | Out-File "C:/dockerlogs/$element.log"}
xisket

1

ขั้นแรกให้ตรวจสอบรหัสคอนเทนเนอร์ของคุณ

docker ps -a

คุณสามารถดูแถวแรกในคอลัมน์ CONTAINER ID น่าจะเป็นแบบนี้ "3fd0bfce2806" จากนั้นพิมพ์ในเชลล์

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

คุณจะเห็นอะไรแบบนี้

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

จากนั้นคุณจะเห็นเป็น

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

จะอยู่ในรูปแบบ JSON คุณสามารถใช้การประทับเวลาเพื่อติดตามข้อผิดพลาด


0

Bash script เพื่อคัดลอกบันทึกคอนเทนเนอร์ทั้งหมดไปยังไดเร็กทอรีที่ระบุ:

#!/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

0

เนื่องจากนักเทียบท่าผสาน stdout และ stderr สำหรับเราเราจึงสามารถปฏิบัติกับเอาต์พุตบันทึกเหมือนกับเชลล์สตรีมอื่น ๆ ในการเปลี่ยนเส้นทางบันทึกปัจจุบันไปยังไฟล์ให้ใช้ตัวดำเนินการเปลี่ยนเส้นทาง

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

แทนที่จะส่งเอาต์พุตไปยัง stderr และ stdout ให้เปลี่ยนทิศทางเอาต์พุตของแอปพลิเคชันของคุณไปยังไฟล์และแมปไฟล์ไปยังที่จัดเก็บถาวรภายนอกคอนเทนเนอร์

$ docker logs test_container> /tmp/output.log

นักเทียบท่าจะไม่ยอมรับพา ธ สัมพัทธ์ในบรรทัดคำสั่งดังนั้นหากคุณต้องการใช้ไดเร็กทอรีอื่นคุณจะต้องใช้พา ธ ที่สมบูรณ์


สิ่งนี้ไม่ได้จับบันทึกทั้งหมดคุณต้องเปลี่ยนเส้นทาง std out และ std err ด้วย&>ดูคำตอบอื่น
Harry Moreno

0

วิธีที่ง่ายที่สุดที่ฉันใช้คือคำสั่งนี้บนเทอร์มินัล:

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

โครงสร้างคือ:

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

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