Вопрос по – Чтение файлов журналов по мере их обновления в Go

36

Я пытаюсь проанализировать некоторые файлы журналов, когда они пишутся на Go, но я не уверен, как мне это сделать, не перечитывая файл снова и снова, проверяя изменения.

Мне бы хотелось иметь возможность читать в EOF, ждать, пока будет написана следующая строка, и снова читать в EOF и т. Д. Это похоже на то, какtail -f выглядит.

Ваш Ответ

4   ответа
4

но еще не успел заняться этим. Один из подходов, который мне пришёл в голову, это позволить «хвосту» сделать тяжелую работу. Это, вероятно, сделает ваш инструмент специфичным для платформы, но это может быть хорошо. Основная идея заключается в использованииCmd из "os / exec" пакет, чтобы следовать за файлом. Вы могли бы разветвить процесс, который был эквивалентен «tail --retry --follow = name prog.log», и затем прослушать его Stdout, используя программу чтения Stdout объекта Cmd.

Извините, я знаю, что это всего лишь эскиз, но, возможно, это полезно.

Error: User Rate Limit Exceeded
45

github.com/ActiveState/tail - чтобы сделать именно это.

t, err := tail.TailFile("/var/log/nginx.log", tail.Config{Follow: true})
for line := range t.Lines {
    fmt.Println(line.Text)
}

...

Цитирую ответ kostix:

in real life files might be truncated, replaced or renamed (because that's what tools like logrotate are supposed to do).

Если файл обрезается, он автоматически открывается заново. Для поддержки повторного открытия переименованных файлов (из-за logrotate и т. Д.) Вы можете установитьConfig.ReOpenа именно:

t, err := tail.TailFile("/var/log/nginx.log", tail.Config{
    Follow: true,
    ReOpen: true})
for line := range t.Lines {
    fmt.Println(line.Text)
}

Config.ReOpen аналогичноtail -F (заглавная F):

 -F      The -F option implies the -f option, but tail will also check to see if the file being followed has been
         renamed or rotated.  The file is closed and reopened when tail detects that the filename being read from
         has a new inode number.  The -F option is ignored if reading from standard input rather than a file.
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Nick
1

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "time"
)

func tail(filename string, out io.Writer) {
    f, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    defer f.Close()
    r := bufio.NewReader(f)
    info, err := f.Stat()
    if err != nil {
        panic(err)
    }
    oldSize := info.Size()
    for {
        for line, prefix, err := r.ReadLine(); err != io.EOF; line, prefix, err = r.ReadLine() {
            if prefix {
                fmt.Fprint(out, string(line))
            } else {
                fmt.Fprintln(out, string(line))
            }
        }
        pos, err := f.Seek(0, io.SeekCurrent)
        if err != nil {
            panic(err)
        }
        for {
            time.Sleep(time.Second)
            newinfo, err := f.Stat()
            if err != nil {
                panic(err)
            }
            newSize := newinfo.Size()
            if newSize != oldSize {
                if newSize < oldSize {
                    f.Seek(0, 0)
                } else {
                    f.Seek(pos, io.SeekStart)
                }
                r = bufio.NewReader(f)
                oldSize = newSize
                break
            }
        }
    }
}

func main() {
    tail("x.txt", os.Stdout)
}
6

го конкретную ОС-подсистему), либо периодически опрашивать егоувидеть, изменилось ли время его модификации (и размер), В любом случае, прочитав другой кусок данных, вы запомните смещение файла ивосстановить его перед чтением другой кусок после обнаружения изменения.

Но обратите внимание, что это кажется простым только на бумаге: в реальной жизни файлы могут быть обрезаны, заменены или переименованы (потому что это то, что инструментыlogrotate должны делать).

Увидетьэтот вопрос для дальнейшего обсуждения этой проблемы.

Error: User Rate Limit ExceededexpError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Nick

Похожие вопросы