github.com/AbhinandanKurakure/podman/v3@v3.4.10/libpod/events/logfile.go (about) 1 package events 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/containers/podman/v3/pkg/util" 10 "github.com/containers/storage/pkg/lockfile" 11 "github.com/pkg/errors" 12 ) 13 14 // EventLogFile is the structure for event writing to a logfile. It contains the eventer 15 // options and the event itself. Methods for reading and writing are also defined from it. 16 type EventLogFile struct { 17 options EventerOptions 18 } 19 20 // Writes to the log file 21 func (e EventLogFile) Write(ee Event) error { 22 // We need to lock events file 23 lock, err := lockfile.GetLockfile(e.options.LogFilePath + ".lock") 24 if err != nil { 25 return err 26 } 27 lock.Lock() 28 defer lock.Unlock() 29 f, err := os.OpenFile(e.options.LogFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0700) 30 if err != nil { 31 return err 32 } 33 defer f.Close() 34 eventJSONString, err := ee.ToJSONString() 35 if err != nil { 36 return err 37 } 38 if _, err := f.WriteString(fmt.Sprintf("%s\n", eventJSONString)); err != nil { 39 return err 40 } 41 return nil 42 } 43 44 // Reads from the log file 45 func (e EventLogFile) Read(ctx context.Context, options ReadOptions) error { 46 defer close(options.EventChannel) 47 filterMap, err := generateEventFilters(options.Filters, options.Since, options.Until) 48 if err != nil { 49 return errors.Wrapf(err, "failed to parse event filters") 50 } 51 t, err := e.getTail(options) 52 if err != nil { 53 return err 54 } 55 if len(options.Until) > 0 { 56 untilTime, err := util.ParseInputTime(options.Until, false) 57 if err != nil { 58 return err 59 } 60 go func() { 61 time.Sleep(time.Until(untilTime)) 62 t.Stop() 63 }() 64 } 65 funcDone := make(chan bool) 66 copy := true 67 go func() { 68 select { 69 case <-funcDone: 70 // Do nothing 71 case <-ctx.Done(): 72 copy = false 73 t.Kill(errors.New("hangup by client")) 74 } 75 }() 76 for line := range t.Lines { 77 select { 78 case <-ctx.Done(): 79 // the consumer has cancelled 80 return nil 81 default: 82 // fallthrough 83 } 84 85 event, err := newEventFromJSONString(line.Text) 86 if err != nil { 87 return err 88 } 89 switch event.Type { 90 case Image, Volume, Pod, System, Container, Network: 91 // no-op 92 default: 93 return errors.Errorf("event type %s is not valid in %s", event.Type.String(), e.options.LogFilePath) 94 } 95 if copy && applyFilters(event, filterMap) { 96 options.EventChannel <- event 97 } 98 } 99 funcDone <- true 100 return nil 101 } 102 103 // String returns a string representation of the logger 104 func (e EventLogFile) String() string { 105 return LogFile.String() 106 }