youtubebeat/vendor/github.com/elastic/beats/filebeat/input/file/state.go

100 lines
2.9 KiB
Go

// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package file
import (
"os"
"strconv"
"strings"
"time"
"github.com/mitchellh/hashstructure"
"github.com/elastic/beats/libbeat/common/file"
)
// State is used to communicate the reading state of a file
type State struct {
Id string `json:"-"` // local unique id to make comparison more efficient
Finished bool `json:"-"` // harvester state
Fileinfo os.FileInfo `json:"-"` // the file info
Source string `json:"source"`
Offset int64 `json:"offset"`
Timestamp time.Time `json:"timestamp"`
TTL time.Duration `json:"ttl"`
Type string `json:"type"`
Meta map[string]string `json:"meta"`
FileStateOS file.StateOS
}
// NewState creates a new file state
func NewState(fileInfo os.FileInfo, path string, t string, meta map[string]string) State {
if len(meta) == 0 {
meta = nil
}
return State{
Fileinfo: fileInfo,
Source: path,
Finished: false,
FileStateOS: file.GetOSState(fileInfo),
Timestamp: time.Now(),
TTL: -1, // By default, state does have an infinite ttl
Type: t,
Meta: meta,
}
}
// ID returns a unique id for the state as a string
func (s *State) ID() string {
// Generate id on first request. This is needed as id is not set when converting back from json
if s.Id == "" {
if len(s.Meta) == 0 {
s.Id = s.FileStateOS.String()
} else {
hashValue, _ := hashstructure.Hash(s.Meta, nil)
var hashBuf [17]byte
hash := strconv.AppendUint(hashBuf[:0], hashValue, 16)
hash = append(hash, '-')
fileID := s.FileStateOS.String()
var b strings.Builder
b.Grow(len(hash) + len(fileID))
b.Write(hash)
b.WriteString(fileID)
s.Id = b.String()
}
}
return s.Id
}
// IsEqual compares the state to an other state supporting stringer based on the unique string
func (s *State) IsEqual(c *State) bool {
return s.ID() == c.ID()
}
// IsEmpty returns true if the state is empty
func (s *State) IsEmpty() bool {
return s.FileStateOS == file.StateOS{} &&
s.Source == "" &&
len(s.Meta) == 0 &&
s.Timestamp.IsZero()
}