github.com/cs3org/reva/v2@v2.27.7/pkg/storage/fs/posix/tree/gpfsfilauditloggingwatcher.go (about) 1 // Copyright 2018-2024 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package tree 20 21 import ( 22 "bufio" 23 "encoding/json" 24 "io" 25 "os" 26 "strconv" 27 "time" 28 29 "github.com/rs/zerolog" 30 ) 31 32 type GpfsFileAuditLoggingWatcher struct { 33 tree *Tree 34 log *zerolog.Logger 35 } 36 37 type lwe struct { 38 Event string 39 Path string 40 BytesWritten string 41 } 42 43 func NewGpfsFileAuditLoggingWatcher(tree *Tree, auditLogFile string, log *zerolog.Logger) (*GpfsFileAuditLoggingWatcher, error) { 44 w := &GpfsFileAuditLoggingWatcher{ 45 tree: tree, 46 log: log, 47 } 48 49 _, err := os.Stat(auditLogFile) 50 if err != nil { 51 return nil, err 52 } 53 54 return w, nil 55 } 56 57 func (w *GpfsFileAuditLoggingWatcher) Watch(path string) { 58 start: 59 file, err := os.Open(path) 60 if err != nil { 61 // try again later 62 time.Sleep(5 * time.Second) 63 goto start 64 } 65 defer file.Close() 66 67 // Seek to the end of the file 68 _, err = file.Seek(0, io.SeekEnd) 69 if err != nil { 70 time.Sleep(5 * time.Second) 71 goto start 72 } 73 74 reader := bufio.NewReader(file) 75 ev := &lwe{} 76 for { 77 line, err := reader.ReadString('\n') 78 switch err { 79 case nil: 80 err := json.Unmarshal([]byte(line), ev) 81 if err != nil { 82 w.log.Error().Err(err).Str("line", line).Msg("error unmarshalling line") 83 continue 84 } 85 if isLockFile(ev.Path) || isTrash(ev.Path) || w.tree.isUpload(ev.Path) { 86 continue 87 } 88 go func() { 89 switch ev.Event { 90 case "CREATE": 91 err = w.tree.Scan(ev.Path, ActionCreate, false) 92 case "CLOSE": 93 var bytesWritten int 94 bytesWritten, err = strconv.Atoi(ev.BytesWritten) 95 if err == nil && bytesWritten > 0 { 96 err = w.tree.Scan(ev.Path, ActionUpdate, false) 97 } 98 case "RENAME": 99 err = w.tree.Scan(ev.Path, ActionMove, false) 100 if warmupErr := w.tree.WarmupIDCache(ev.Path, false, false); warmupErr != nil { 101 w.log.Error().Err(warmupErr).Str("path", ev.Path).Msg("error warming up id cache") 102 } 103 } 104 if err != nil { 105 w.log.Error().Err(err).Str("line", line).Msg("error unmarshalling line") 106 } 107 }() 108 109 case io.EOF: 110 time.Sleep(1 * time.Second) 111 default: 112 time.Sleep(5 * time.Second) 113 goto start 114 } 115 } 116 }