github.com/qubitproducts/logspray@v0.2.14/sources/filesystem/filesource.go (about) 1 // Copyright 2016 Qubit Digital Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 // Package logspray is a collection of tools for streaming and indexing 14 // large volumes of dynamic logs. 15 16 package filesystem 17 18 import ( 19 "context" 20 21 "github.com/QubitProducts/logspray/proto/logspray" 22 "github.com/QubitProducts/logspray/sources" 23 "github.com/hpcloud/tail" 24 ) 25 26 // MessageReader is used to tail a file path and create log data from 27 // the lines. 28 type MessageReader struct { 29 *tail.Tail 30 31 labels map[string]string 32 } 33 34 func (w *Watcher) ReadTarget(ctx context.Context, fn string, fromStart bool) (sources.MessageReader, error) { 35 ft, err := tail.TailFile(fn, tail.Config{ 36 Location: &tail.SeekInfo{Whence: 0, Offset: 0}, 37 MustExist: false, 38 Follow: true, 39 ReOpen: true, 40 Poll: w.Poll, 41 // Logger: logto, 42 }) 43 44 labels := map[string]string{"filename": fn} 45 46 return &MessageReader{Tail: ft, labels: labels}, err 47 } 48 49 // MessageRead implements the LogSourcer interface 50 func (fs *MessageReader) MessageRead(ctx context.Context) (*logspray.Message, error) { 51 m := logspray.Message{ 52 Labels: fs.labels, 53 } 54 err := fs.MessageWriteTo(ctx, &m) 55 return &m, err 56 } 57 58 // MessageWriteTo implements the LogSourcer interface 59 func (fs *MessageReader) MessageWriteTo(ctx context.Context, tm *logspray.Message) error { 60 select { 61 case l := <-fs.Lines: 62 if l.Err != nil { 63 return l.Err 64 } 65 tm.Text = l.Text 66 return nil 67 case <-ctx.Done(): 68 return ctx.Err() 69 } 70 }