github.com/minio/console@v1.4.1/pkg/logger/targets.go (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2022 MinIO, Inc. 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 package logger 18 19 import ( 20 "sync" 21 "sync/atomic" 22 23 "github.com/minio/console/pkg/logger/target/http" 24 "github.com/minio/console/pkg/logger/target/types" 25 ) 26 27 // Target is the entity that we will receive 28 // a single log entry and Send it to the log target 29 // e.g. Send the log to a http server 30 type Target interface { 31 String() string 32 Endpoint() string 33 Init() error 34 Cancel() 35 Send(entry interface{}, errKind string) error 36 Type() types.TargetType 37 } 38 39 var ( 40 // swapMu must be held while reading slice info or swapping targets or auditTargets. 41 swapMu sync.Mutex 42 43 // systemTargets is the set of enabled loggers. 44 // Must be immutable at all times. 45 // Can be swapped to another while holding swapMu 46 systemTargets = []Target{} 47 48 // This is always set represent /dev/console target 49 consoleTgt Target 50 51 nTargets int32 // atomic count of len(targets) 52 ) 53 54 // SystemTargets returns active targets. 55 // Returned slice may not be modified in any way. 56 func SystemTargets() []Target { 57 if atomic.LoadInt32(&nTargets) == 0 { 58 // Lock free if none... 59 return nil 60 } 61 swapMu.Lock() 62 res := systemTargets 63 swapMu.Unlock() 64 return res 65 } 66 67 // AuditTargets returns active audit targets. 68 // Returned slice may not be modified in any way. 69 func AuditTargets() []Target { 70 if atomic.LoadInt32(&nAuditTargets) == 0 { 71 // Lock free if none... 72 return nil 73 } 74 swapMu.Lock() 75 res := auditTargets 76 swapMu.Unlock() 77 return res 78 } 79 80 // auditTargets is the list of enabled audit loggers 81 // Must be immutable at all times. 82 // Can be swapped to another while holding swapMu 83 var ( 84 auditTargets = []Target{} 85 nAuditTargets int32 // atomic count of len(auditTargets) 86 ) 87 88 func cancelAllSystemTargets() { 89 for _, tgt := range systemTargets { 90 tgt.Cancel() 91 } 92 } 93 94 func initSystemTargets(cfgMap map[string]http.Config) (tgts []Target, err error) { 95 for _, l := range cfgMap { 96 if l.Enabled { 97 t := http.New(l) 98 if err = t.Init(); err != nil { 99 return tgts, err 100 } 101 tgts = append(tgts, t) 102 } 103 } 104 return tgts, err 105 } 106 107 // UpdateSystemTargets swaps targets with newly loaded ones from the cfg 108 func UpdateSystemTargets(cfg Config) error { 109 updated, err := initSystemTargets(cfg.HTTP) 110 if err != nil { 111 return err 112 } 113 114 swapMu.Lock() 115 for _, tgt := range systemTargets { 116 // Preserve console target when dynamically updating 117 // other HTTP targets, console target is always present. 118 if tgt.Type() == types.TargetConsole { 119 updated = append(updated, tgt) 120 break 121 } 122 } 123 atomic.StoreInt32(&nTargets, int32(len(updated))) 124 cancelAllSystemTargets() // cancel running targets 125 systemTargets = updated 126 swapMu.Unlock() 127 return nil 128 } 129 130 func cancelAuditTargetType(t types.TargetType) { 131 for _, tgt := range auditTargets { 132 if tgt.Type() == t { 133 tgt.Cancel() 134 } 135 } 136 } 137 138 // UpdateAuditWebhookTargets swaps audit webhook targets with newly loaded ones from the cfg 139 func UpdateAuditWebhookTargets(cfg Config) error { 140 updated, err := initSystemTargets(cfg.AuditWebhook) 141 if err != nil { 142 return err 143 } 144 145 swapMu.Lock() 146 atomic.StoreInt32(&nAuditTargets, int32(len(updated))) 147 cancelAuditTargetType(types.TargetHTTP) // cancel running targets 148 auditTargets = updated 149 swapMu.Unlock() 150 return nil 151 }