Skip to content

Calling Tail.Cleanup can prevent future tailing #153

@danielnelson

Description

@danielnelson

Calling Cleanup() on a Tail can decrement the watch counter below zero, which can prevent future attempts to tail the file.

Here is some code that can be used to show the issue:

func main() {

	// Setup and tail, being careful to avoid issue #93
	t, err := tail.TailFile(os.Args[1], tail.Config{Follow: true})
	if err != nil {
		fmt.Println(err)
	}
	go func() {
		for line := range t.Lines {
		}
	}()
	t.Stop()
	t.Cleanup()

	// At this point, the watch count for this is negative, the next time we
	// try to tail a watch will not be set.

	t, err = tail.TailFile(os.Args[1], tail.Config{Follow: true})
	if err != nil {
		fmt.Println(err)
	}
	go func() {
		for line := range t.Lines {
			fmt.Printf("%q\n", line.Text)
		}
	}()
	t.Wait()
}

To duplicate:

go run ./main.go test.log

# from another shell
echo 1 >> test.log
echo 2 >> test.log

Expected: the lines appended to test.log should be printed to screen.
Actual: no output


Looking into the history of this function, it appears it was originally added to close all inotify watches before the program exists and it did not originally require access to the Tail objects.

Since now you need the Tail to call, it seems preferrable to call Stop() instead. The Cleanup function also does not ensure that the watch count goes to zero, it just does a single decrement, which won't be enough if there are multiple tails on a file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions