2010-08-05 33 views
9

tôi làm việc với một số hệ thống đăng nhập mà tạo ra một tập tin đăng nhập mỗi giờ, như sau:Làm thế nào để tail -f file log mới nhất với một mô hình cho

SoftwareLog.2010-08-01-08 
SoftwareLog.2010-08-01-09 
SoftwareLog.2010-08-01-10 

Tôi đang cố gắng để đuôi đi theo mới nhất tệp nhật ký đưa ra một mẫu (ví dụ: SoftwareLog *) và tôi nhận ra có:

tail -F (tail --follow=name --retry) 

nhưng chỉ theo một tên cụ thể - và chúng có tên khác theo ngày và giờ. Tôi đã thử một cái gì đó như:

tail --follow=name --retry SoftwareLog*(.om[1]) 

nhưng tuyên bố ký tự đại diện được đặt lại trước khi nó được chuyển đến đuôi và không thực hiện lại mọi lần thử lại đuôi.

Mọi đề xuất?

Trả lời

6

[Chỉnh sửa: sau một googling nhanh chóng cho một công cụ]

Bạn có thể muốn thử ra multitail - http://www.vanheusden.com/multitail/

Nếu bạn muốn gắn bó với câu trả lời Dennis Williamson (và tôi đã +1 anh ta cho phù hợp) ở đây là những khoảng trống điền vào cho bạn.

Trong shell của bạn, hãy chạy đoạn mã sau (hoặc nó zsh tương đương, tôi quất này lên trong bash trước khi tôi thấy thẻ zsh):

#!/bin/bash 

TARGET_DIR="some/logfiles/" 
SYMLINK_FILE="SoftwareLog.latest" 
SYMLINK_PATH="$TARGET_DIR/$SYMLINK_FILE" 

function getLastModifiedFile { 
    echo $(ls -t "$TARGET_DIR" | grep -v "$SYMLINK_FILE" | head -1) 
} 

function getCurrentlySymlinkedFile { 
    if [[ -h $SYMLINK_PATH ]] 
    then 
     echo $(ls -l $SYMLINK_PATH | awk '{print $NF}') 
    else 
     echo "" 
    fi 
} 

symlinkedFile=$(getCurrentlySymlinkedFile) 
while true 
do 
    sleep 10 
    lastModified=$(getLastModifiedFile) 
    if [[ $symlinkedFile != $lastModified ]] 
    then 
     ln -nsf $lastModified $SYMLINK_PATH 
     symlinkedFile=$lastModified 
    fi 
done 

Bối cảnh đó quá trình sử dụng các phương pháp thông thường (một lần nữa, tôi không biết zsh, vì vậy nó có thể khác nhau) ...

./updateSymlink.sh 2>&1 > /dev/null

Sau đó tail -F $SYMLINK_PATH để đuôi trao sự thay đổi của liên kết tượng trưng hay một vòng quay của tập tin.

Điều này hơi phức tạp, nhưng tôi không biết cách khác để làm điều này với đuôi. Nếu bất cứ ai biết về một tiện ích xử lý vấn đề này, thì hãy để họ tiến lên vì tôi cũng muốn tự mình xem - các ứng dụng như Jetty theo mặc định sẽ ghi nhật ký theo cách này và tôi luôn viết kịch bản lệnh symlinking chạy trên cron để bù cho nó.

[Chỉnh sửa: Đã xóa sai 'j' từ cuối một trong các dòng.Bạn cũng có một biến tên xấu "lastModifiedFile" không tồn tại, tên riêng mà bạn thiết lập là "lastModified"]

+0

cảm ơn, tôi có thể phải làm điều đó. Tôi nhìn vào multitail, nhưng tiếc là nó tương tác chỉ có nghĩa là tôi không thể ống nó đầu ra ở nơi khác. Tôi sẽ thử nó và xem nơi tôi nhận được. Điều này là tôi muốn điều này chỉ chạy khi đuôi đang chạy và thoát ra khi thoát ra, và tôi không chắc chắn làm thế nào để làm điều đó. – Axiverse

+0

Cảm ơn! Về cơ bản, đây là giải pháp duy nhất tôi thích (và tôi đã tìm kiếm rất nhiều về điều này). –

+0

Neato. Đã chỉnh sửa để sửa lỗi mà nó không hoạt động lần đầu tiên đối với tôi. (Bởi vì getCurrentlySymlinkedFile đã trả về một chuỗi rỗng, và typo'd không tồn tại lastModifiedDate cũng được đánh giá thành một chuỗi trống.) – funroll

2

Tôi chưa thử nghiệm điều này, nhưng cách tiếp cận có thể hoạt động là chạy một quá trình nền tạo và cập nhật liên kết tượng trưng đến tệp nhật ký mới nhất và sau đó bạn sẽ tail -f (hoặc tail -F) liên kết tượng trưng.

11

tôi tin rằng các giải pháp đơn giản nhất là như sau:

tail -f `ls -tr | tail -n 1` 

Bây giờ, nếu bạn thư mục chứa tệp nhật ký khác như "SystemLog" và bạn chỉ muốn "SoftwareLog" tập tin mới nhất, sau đó bạn sẽ chỉ đơn giản bao gồm một grep như sau:

tail -f `ls -tr | grep SoftwareLog | tail -n 1` 
+6

hoặc sử dụng đầu thay vì đuôi, để làm cho mọi thứ đơn giản hơn =) ls -t | đầu -1 | xargs tail -F –

+0

Hoặc có thể sử dụng: '' 'tail -f SoftwareLog.'date + '% Y-% m-% d-% H''' '' –

0
#!/bin/bash 

PATTERN="$1" 

# Try to make sure sub-shells exit when we do. 
trap "kill -9 -- -$BASHPID" SIGINT SIGTERM EXIT 

PID=0 
OLD_FILES="" 
while true; do 
    FILES="$(echo $PATTERN)" 
    if test "$FILES" != "$OLD_FILES"; then 
    if test "$PID" != "0"; then 
     kill $PID 
     PID=0 
    fi 
    if test "$FILES" != "$PATTERN" || test -f "$PATTERN"; then 
     tail --pid=$$ -n 0 -F $PATTERN & 
     PID=$! 
    fi 
    fi 
    OLD_FILES="$FILES" 
    sleep 1 
done 

sau đó chạy nó như: tail.sh 'SoftwareLog*'

Tập lệnh sẽ mất một số dòng nhật ký nếu nhật ký được ghi giữa các lần kiểm tra. Nhưng ít nhất đó là một kịch bản duy nhất, không yêu cầu liên kết tượng trưng.

Các vấn đề liên quan