1
+ // Copyright (c) 2019 FOSS contributors of https://github.com/nxadm/tail
1
2
// Copyright (c) 2015 HPE Software Inc. All rights reserved.
2
3
// Copyright (c) 2013 ActiveState Software Inc. All rights reserved.
3
4
5
+ //nxadm/tail provides a Go library that emulates the features of the BSD `tail`
6
+ //program. The library comes with full support for truncation/move detection as
7
+ //it is designed to work with log rotation tools. The library works on all
8
+ //operating systems supported by Go, including POSIX systems like Linux and
9
+ //*BSD, and MS Windows. Go 1.9 is the oldest compiler release supported.
4
10
package tail
5
11
6
12
import (
@@ -22,26 +28,31 @@ import (
22
28
)
23
29
24
30
var (
31
+ // ErrStop is returned when the tail of a file has been marked to be stopped.
25
32
ErrStop = errors .New ("tail should now stop" )
26
33
)
27
34
28
35
type Line struct {
29
- Text string
30
- Num int
31
- SeekInfo SeekInfo
32
- Time time.Time
33
- Err error // Error from tail
36
+ Text string // The contents of the file
37
+ Num int // The line number
38
+ SeekInfo SeekInfo // SeekInfo
39
+ Time time.Time // Present time
40
+ Err error // Error from tail
34
41
}
35
42
36
- // NewLine returns a Line with present time.
43
+ // Deprecated: this function is no longer used internally and it has little of no
44
+ // use in the API. As such, it will be removed from the API in a future major
45
+ // release.
46
+ //
47
+ // NewLine returns a * pointer to a Line struct.
37
48
func NewLine (text string , lineNum int ) * Line {
38
49
return & Line {text , lineNum , SeekInfo {}, time .Now (), nil }
39
50
}
40
51
41
- // SeekInfo represents arguments to ` io.Seek`
52
+ // SeekInfo represents arguments to io.Seek. See: https://golang.org/pkg/io/#SectionReader.Seek
42
53
type SeekInfo struct {
43
54
Offset int64
44
- Whence int // io.Seek*
55
+ Whence int
45
56
}
46
57
47
58
type logger interface {
@@ -59,26 +70,28 @@ type logger interface {
59
70
// Config is used to specify how a file must be tailed.
60
71
type Config struct {
61
72
// File-specifc
62
- Location * SeekInfo // Seek to this location before tailing
63
- ReOpen bool // Reopen recreated files (tail -F)
64
- MustExist bool // Fail early if the file does not exist
65
- Poll bool // Poll for file changes instead of using inotify
66
- Pipe bool // Is a named pipe (mkfifo)
67
- RateLimiter * ratelimiter.LeakyBucket
73
+ Location * SeekInfo // Tail from this location. If nil, start at the beginning of the file
74
+ ReOpen bool // Reopen recreated files (tail -F)
75
+ MustExist bool // Fail early if the file does not exist
76
+ Poll bool // Poll for file changes instead of using the default inotify
77
+ Pipe bool // The file is a named pipe (mkfifo)
68
78
69
79
// Generic IO
70
80
Follow bool // Continue looking for new lines (tail -f)
71
81
MaxLineSize int // If non-zero, split longer lines into multiple lines
72
82
73
- // Logger, when nil, is set to tail.DefaultLogger
74
- // To disable logging: set field to tail.DiscardingLogger
83
+ // Optionally, use a ratelimiter (e.g. created by the ratelimiter/NewLeakyBucket function)
84
+ RateLimiter * ratelimiter.LeakyBucket
85
+
86
+ // Optionally use a Logger. When nil, the Logger is set to tail.DefaultLogger.
87
+ // To disable logging, set it to tail.DiscardingLogger
75
88
Logger logger
76
89
}
77
90
78
91
type Tail struct {
79
- Filename string
80
- Lines chan * Line
81
- Config
92
+ Filename string // The filename
93
+ Lines chan * Line // A consumable channel of *Line
94
+ Config // Tail.Configuration
82
95
83
96
file * os.File
84
97
reader * bufio.Reader
@@ -93,16 +106,17 @@ type Tail struct {
93
106
}
94
107
95
108
var (
96
- // DefaultLogger is used when Config.Logger == nil
109
+ // DefaultLogger logs to os.Stderr and it is used when Config.Logger == nil
97
110
DefaultLogger = log .New (os .Stderr , "" , log .LstdFlags )
98
111
// DiscardingLogger can be used to disable logging output
99
112
DiscardingLogger = log .New (ioutil .Discard , "" , 0 )
100
113
)
101
114
102
- // TailFile begins tailing the file. Output stream is made available
103
- // via the `Tail.Lines` channel. To handle errors during tailing,
104
- // invoke the `Wait` or `Err` method after finishing reading from the
105
- // `Lines` channel.
115
+ // TailFile begins tailing the file. And returns a pointer to a Tail struct
116
+ // and an error. An output stream is made available via the Tail.Lines
117
+ // channel (e.g. to be looped and printed). To handle errors during tailing,
118
+ // after finishing reading from the Lines channel, invoke the `Wait` or `Err`
119
+ // method on the returned *Tail.
106
120
func TailFile (filename string , config Config ) (* Tail , error ) {
107
121
if config .ReOpen && ! config .Follow {
108
122
util .Fatal ("cannot set ReOpen without Follow." )
@@ -138,10 +152,9 @@ func TailFile(filename string, config Config) (*Tail, error) {
138
152
return t , nil
139
153
}
140
154
141
- // Tell returns the file's current position, like stdio's ftell().
142
- // But this value is not very accurate.
143
- // One line from the chan(tail.Lines) may have been read,
144
- // so it may have lost one line.
155
+ // Tell returns the file's current position, like stdio's ftell() and an error.
156
+ // Beware that this value may not be completely accurate because one line from
157
+ // the chan(tail.Lines) may have been read already.
145
158
func (tail * Tail ) Tell () (offset int64 , err error ) {
146
159
if tail .file == nil {
147
160
return
@@ -167,7 +180,8 @@ func (tail *Tail) Stop() error {
167
180
return tail .Wait ()
168
181
}
169
182
170
- // StopAtEOF stops tailing as soon as the end of the file is reached.
183
+ // StopAtEOF stops tailing as soon as the end of the file is reached. The function
184
+ // returns an error,
171
185
func (tail * Tail ) StopAtEOF () error {
172
186
tail .Kill (errStopAtEOF )
173
187
return tail .Wait ()
0 commit comments