-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add close_removed and close_renamed, deprecate force_close_files #1909
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -166,22 +166,22 @@ filebeat.prospectors: | |
# The backoff value will be multiplied each time with the backoff_factor until max_backoff is reached | ||
#backoff_factor: 2 | ||
|
||
# This option closes a file, as soon as the file name changes. | ||
# This config option is recommended on windows only. Filebeat keeps the files it's reading open. This can cause | ||
# issues when the file is removed, as the file will not be fully removed until also Filebeat closes | ||
# the reading. Filebeat closes the file handler after ignore_older. During this time no new file with the | ||
# same name can be created. Turning this feature on the other hand can lead to loss of data | ||
# on rotate files. It can happen that after file rotation the beginning of the new | ||
# file is skipped, as the reading starts at the end. We recommend to leave this option on false | ||
# but lower the ignore_older value to release files faster. | ||
#force_close_files: false | ||
# Close renamed means a file handler is close when a file is renamed / rotated. In case the harvester was | ||
# not finished reading the roated file, the file will be picked up again after scan_frequency in case it | ||
# also matches the prospector patterns. | ||
#close_renamed: false | ||
|
||
# When enabling this option, a file handler is closed immidiately in case a file can't be found | ||
# any more. In case the file shows up again later, harvesting will continue at the last position | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/last position/last known position/
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @urso I plan to add a full page on all this configuration with more examples in the docs after implementation. |
||
# after scan_frequency | ||
#close_removed: false | ||
|
||
#----------------------------- Stdin prospector ------------------------------- | ||
# Configuration to use stdin input | ||
#- input_type: stdin | ||
|
||
#========================= Filebeat global options ============================ | ||
|
||
# Event count spool threshold - forces network flush if exceeded | ||
#filebeat.spool_size: 2048 | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ import ( | |
"github.com/elastic/beats/libbeat/common" | ||
|
||
"github.com/dustin/go-humanize" | ||
"github.com/elastic/beats/libbeat/logp" | ||
) | ||
|
||
var ( | ||
|
@@ -22,8 +23,10 @@ var ( | |
BackoffFactor: 2, | ||
MaxBackoff: 10 * time.Second, | ||
CloseOlder: 1 * time.Hour, | ||
ForceCloseFiles: false, | ||
MaxBytes: 10 * (1 << 20), // 10MB | ||
CloseRemoved: false, | ||
CloseRenamed: false, | ||
ForceCloseFiles: false, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. still in alpha, let's remove 'ForceCloseFiles' then. Don't treat config as deprecated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @urso I want to make the migration to 5.0 as seamless as possible. That is why I would prefer to keep this in. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe we want to add a 'deprecated' option to go-ucfg, which will print a warning when option is used. We can find deprecated options in code by grepping for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would be great TBH. Lets do this as soon as support for this is in ucfg (not a priority). |
||
} | ||
) | ||
|
||
|
@@ -38,6 +41,8 @@ type harvesterConfig struct { | |
BackoffFactor int `config:"backoff_factor" validate:"min=1"` | ||
MaxBackoff time.Duration `config:"max_backoff" validate:"min=0,nonzero"` | ||
CloseOlder time.Duration `config:"close_older"` | ||
CloseRemoved bool `config:"close_removed"` | ||
CloseRenamed bool `config:"close_renamed"` | ||
ForceCloseFiles bool `config:"force_close_files"` | ||
ExcludeLines []*regexp.Regexp `config:"exclude_lines"` | ||
IncludeLines []*regexp.Regexp `config:"include_lines"` | ||
|
@@ -48,6 +53,13 @@ type harvesterConfig struct { | |
|
||
func (config *harvesterConfig) Validate() error { | ||
|
||
// TODO: remove in 7.0 | ||
if config.ForceCloseFiles { | ||
config.CloseRemoved = true | ||
config.CloseRenamed = true | ||
logp.Warn("DEPRECATED: force_close_files was set to true. Use close_removed + close_rename") | ||
} | ||
|
||
// Check input type | ||
if _, ok := cfg.ValidInputType[config.InputType]; !ok { | ||
return fmt.Errorf("Invalid input type: %v", config.InputType) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package harvester | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestForceCloseFiles(t *testing.T) { | ||
|
||
config := defaultConfig | ||
assert.False(t, config.ForceCloseFiles) | ||
assert.False(t, config.CloseRemoved) | ||
assert.False(t, config.CloseRenamed) | ||
|
||
config.ForceCloseFiles = true | ||
config.Validate() | ||
|
||
assert.True(t, config.ForceCloseFiles) | ||
assert.True(t, config.CloseRemoved) | ||
assert.True(t, config.CloseRenamed) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,8 @@ import ( | |
|
||
var ( | ||
ErrFileTruncate = errors.New("detected file being truncated") | ||
ErrForceClose = errors.New("file must be closed") | ||
ErrRenamed = errors.New("file was renamed") | ||
ErrRemoved = errors.New("file was removed") | ||
ErrInactive = errors.New("file inactive") | ||
) | ||
|
||
|
@@ -27,11 +28,12 @@ type logFileReader struct { | |
} | ||
|
||
type LogFileReaderConfig struct { | ||
ForceClose bool | ||
CloseOlder time.Duration | ||
BackoffDuration time.Duration | ||
MaxBackoffDuration time.Duration | ||
BackoffFactor int | ||
CloseRenamed bool | ||
CloseRemoved bool | ||
} | ||
|
||
func NewLogFileReader( | ||
|
@@ -72,8 +74,9 @@ func (r *logFileReader) Read(buf []byte) (int, error) { | |
r.offset += int64(n) | ||
r.lastTimeRead = time.Now() | ||
} | ||
|
||
// reset backoff | ||
if err == nil { | ||
// reset backoff | ||
r.backoff = r.config.BackoffDuration | ||
return n, nil | ||
} | ||
|
@@ -113,16 +116,19 @@ func (r *logFileReader) Read(buf []byte) (int, error) { | |
return n, ErrInactive | ||
} | ||
|
||
if r.config.ForceClose { | ||
// Check if the file name exists (see #93) | ||
if r.config.CloseRenamed { | ||
if !file.IsSameFile(r.fs.Name(), info) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's keep the code comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't it be: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, changed it again to: |
||
return n, ErrRenamed | ||
} | ||
} | ||
|
||
if r.config.CloseRemoved { | ||
// Check if the file name exists. See https://github.com/elastic/filebeat/issues/93 | ||
_, statErr := os.Stat(r.fs.Name()) | ||
|
||
// Error means file does not exist. If no error, check if same file. If | ||
// not close as rotated. | ||
if statErr != nil || !file.IsSameFile(r.fs.Name(), info) { | ||
logp.Info("Force close file: %s; error: %s", r.fs.Name(), statErr) | ||
// Return directly on windows -> file is closing | ||
return n, ErrForceClose | ||
// Error means file does not exist. | ||
if statErr != nil { | ||
return n, ErrRemoved | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'Close ensures a file handler is closed when the file is renamed or rotated'.
'Note: Potential data loss if renamed file is not picked up by prospector'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added accordingly, and move the change to beat.yml :-)