github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/log/log_gc.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package log 12 13 import ( 14 "context" 15 "fmt" 16 "math" 17 "os" 18 "path/filepath" 19 "sync/atomic" 20 ) 21 22 func init() { 23 mainLog.gcNotify = make(chan struct{}, 1) 24 } 25 26 // StartGCDaemon starts the log file GC -- this must be called after 27 // command-line parsing has completed so that no data is lost when the 28 // user configures larger max sizes than the defaults. 29 // 30 // The logger's GC daemon stops when the provided context is canceled. 31 // 32 // Note that secondary logger get their GC daemon started when 33 // they are allocated (NewSecondaryLogger). This assumes that 34 // secondary loggers are only allocated after command line parsing 35 // has completed too. 36 func StartGCDaemon(ctx context.Context) { 37 go mainLog.gcDaemon(ctx) 38 } 39 40 // gcDaemon runs the GC loop for the given logger. 41 func (l *loggerT) gcDaemon(ctx context.Context) { 42 l.gcOldFiles() 43 for { 44 select { 45 case <-ctx.Done(): 46 return 47 case <-l.gcNotify: 48 } 49 50 logging.mu.Lock() 51 doGC := !logging.mu.disableDaemons 52 logging.mu.Unlock() 53 54 if doGC { 55 l.gcOldFiles() 56 } 57 } 58 } 59 60 // gcOldFiles removes the "old" files that do not match 61 // the configured size and number threshold. 62 func (l *loggerT) gcOldFiles() { 63 dir, isSet := l.logDir.get() 64 if !isSet { 65 // No log directory configured. Nothing to do. 66 return 67 } 68 69 // This only lists the log files for the current logger (sharing the 70 // prefix). 71 allFiles, err := l.listLogFiles() 72 if err != nil { 73 fmt.Fprintf(OrigStderr, "unable to GC log files: %s\n", err) 74 return 75 } 76 77 logFilesCombinedMaxSize := atomic.LoadInt64(&LogFilesCombinedMaxSize) 78 files := selectFiles(allFiles, math.MaxInt64) 79 if len(files) == 0 { 80 return 81 } 82 // files is sorted with the newest log files first (which we want 83 // to keep). Note that we always keep the most recent log file. 84 sum := files[0].SizeBytes 85 for _, f := range files[1:] { 86 sum += f.SizeBytes 87 if sum < logFilesCombinedMaxSize { 88 continue 89 } 90 path := filepath.Join(dir, f.Name) 91 if err := os.Remove(path); err != nil { 92 fmt.Fprintln(OrigStderr, err) 93 } 94 } 95 }