Пример #1
0
// errorChecks checks how the given error should be handled based on the config options
func (r *LogFile) errorChecks(err error) error {

	if err != io.EOF {
		logp.Err("Unexpected state reading from %s; error: %s", r.fs.Name(), err)
		return err
	}

	// Stdin is not continuable
	if !r.fs.Continuable() {
		logp.Debug("harvester", "Source is not continuable: %s", r.fs.Name())
		return err
	}

	if err == io.EOF && r.config.CloseEOF {
		return err
	}

	// Refetch fileinfo to check if the file was truncated or disappeared.
	// Errors if the file was removed/rotated after reading and before
	// calling the stat function
	info, statErr := r.fs.Stat()
	if statErr != nil {
		logp.Err("Unexpected error reading from %s; error: %s", r.fs.Name(), statErr)
		return statErr
	}

	// check if file was truncated
	if info.Size() < r.offset {
		logp.Debug("harvester",
			"File was truncated as offset (%d) > size (%d): %s", r.offset, info.Size(), r.fs.Name())
		return ErrFileTruncate
	}

	// Check file wasn't read for longer then CloseInactive
	age := time.Since(r.lastTimeRead)
	if age > r.config.CloseInactive {
		return ErrInactive
	}

	if r.config.CloseRenamed {
		// Check if the file can still be found under the same path
		if !file.IsSameFile(r.fs.Name(), info) {
			return 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 statErr != nil {
			return ErrRemoved
		}
	}

	return nil
}
Пример #2
0
func (r *logFileReader) Read(buf []byte) (int, error) {

	for {
		select {
		case <-r.done:
			return 0, nil
		default:
		}

		n, err := r.fs.Read(buf)
		if n > 0 {
			r.offset += int64(n)
			r.lastTimeRead = time.Now()
		}

		// reset backoff
		if err == nil {
			r.backoff = r.config.BackoffDuration
			return n, nil
		}

		if err == io.EOF && r.config.CloseEOF {
			return n, err
		}

		// Stdin is not continuable
		if err != io.EOF || !r.fs.Continuable() {
			logp.Err("Unexpected state reading from %s; error: %s", r.fs.Name(), err)
			return n, err
		}

		// Refetch fileinfo to check if the file was truncated or disappeared.
		// Errors if the file was removed/rotated after reading and before
		// calling the stat function
		info, statErr := r.fs.Stat()
		if statErr != nil {
			logp.Err("Unexpected error reading from %s; error: %s", r.fs.Name(), statErr)
			return n, statErr
		}

		// handle fails if file was truncated
		if info.Size() < r.offset {
			logp.Debug("harvester",
				"File was truncated as offset (%s) > size (%s): %s",
				r.offset, info.Size(), r.fs.Name())
			return n, ErrFileTruncate
		}

		age := time.Since(r.lastTimeRead)
		if age > r.config.CloseOlder {
			// If the file hasn't change for longer then maxInactive, harvester stops
			// and file handle will be closed.
			return n, ErrInactive
		}

		if r.config.CloseRenamed {
			// Check if the file can still be found under the same path
			if !file.IsSameFile(r.fs.Name(), info) {
				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 statErr != nil {
				return n, ErrRemoved
			}
		}

		if err != io.EOF {
			logp.Err("Unexpected state reading from %s; error: %s", r.fs.Name(), err)
		}

		logp.Debug("harvester", "End of file reached: %s; Backoff now.", r.fs.Name())
		buf = buf[n:]
		if len(buf) == 0 {
			return n, nil
		}
		r.wait()
	}
}
Пример #3
0
func (r *logFileReader) Read(buf []byte) (int, error) {

	for {
		select {
		case <-r.done:
			return 0, nil
		default:
		}

		n, err := r.fs.Read(buf)
		if n > 0 {
			r.offset += int64(n)
			r.lastTimeRead = time.Now()
		}
		if err == nil {
			// reset backoff
			r.backoff = r.config.BackoffDuration
			return n, nil
		}

		continuable := r.fs.Continuable()
		if err == io.EOF && !continuable {
			logp.Info("Reached end of file: %s", r.fs.Name())
			return n, err
		}

		if err != io.EOF || !continuable {
			logp.Err("Unexpected state reading from %s; error: %s", r.fs.Name(), err)
			return n, err
		}

		// Refetch fileinfo to check if the file was truncated or disappeared.
		// Errors if the file was removed/rotated after reading and before
		// calling the stat function
		info, statErr := r.fs.Stat()
		if statErr != nil {
			logp.Err("Unexpected error reading from %s; error: %s", r.fs.Name(), statErr)
			return n, statErr
		}

		// handle fails if file was truncated
		if info.Size() < r.offset {
			logp.Debug("harvester",
				"File was truncated as offset (%s) > size (%s): %s",
				r.offset, info.Size(), r.fs.Name())
			return n, ErrFileTruncate
		}

		age := time.Since(r.lastTimeRead)
		if age > r.config.CloseOlder {
			// If the file hasn't change for longer then maxInactive, harvester stops
			// and file handle will be closed.
			return n, ErrInactive
		}

		if r.config.ForceClose {
			// Check if the file name exists (see #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
			}
		}

		if err != io.EOF {
			logp.Err("Unexpected state reading from %s; error: %s", r.fs.Name(), err)
		}

		logp.Debug("harvester", "End of file reached: %s; Backoff now.", r.fs.Name())
		buf = buf[n:]
		if len(buf) == 0 {
			return n, nil
		}
		r.wait()
	}
}