github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/stats/config.go (about) 1 // Copyright (c) 2015-2021, NVIDIA CORPORATION. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package stats 5 6 import ( 7 "fmt" 8 "net" 9 "strconv" 10 "time" 11 12 "github.com/swiftstack/ProxyFS/conf" 13 "github.com/swiftstack/ProxyFS/trackedlock" 14 "github.com/swiftstack/ProxyFS/transitions" 15 ) 16 17 const ( 18 expectedNumberOfDistinctStatNames = 100 19 ) 20 21 type statStruct struct { 22 name *string 23 increment uint64 24 } 25 26 type statNameLinkStruct struct { 27 name string 28 next *statNameLinkStruct 29 } 30 31 type globalsStruct struct { 32 trackedlock.Mutex // Used only for snapshotting statFullMap 33 ipAddr string 34 udpPort uint16 35 tcpPort uint16 36 useUDP bool // Logically useTCP == !useUDP 37 connectionType string // Either "udp" or "tcp" 38 udpLAddr *net.UDPAddr 39 udpRAddr *net.UDPAddr 40 tcpLAddr *net.TCPAddr 41 tcpRAddr *net.TCPAddr 42 bufferLength uint16 43 maxLatency time.Duration // Timer should pop in maxLatency/statTree.Len() 44 statChan chan *statStruct 45 tickChan <-chan time.Time 46 stopChan chan bool 47 doneChan chan bool 48 statDeltaMap map[string]uint64 // Key is stat.name, Value is the sum of all un-sent/accumulated stat.increment's 49 statFullMap map[string]uint64 // Key is stat.name, Value is the sum of all accumulated stat.increment's 50 headStatNameLink *statNameLinkStruct 51 tailStatNameLink *statNameLinkStruct 52 } 53 54 var globals globalsStruct 55 56 func init() { 57 transitions.Register("stats", &globals) 58 } 59 60 func (dummy *globalsStruct) Up(confMap conf.ConfMap) (err error) { 61 var ( 62 errFetchingTCPPort error 63 errFetchingUDPPort error 64 ) 65 66 globals.ipAddr = "localhost" // Hard-coded since we only want to talk to the local StatsD 67 68 globals.udpPort, errFetchingUDPPort = confMap.FetchOptionValueUint16("Stats", "UDPPort") 69 globals.tcpPort, errFetchingTCPPort = confMap.FetchOptionValueUint16("Stats", "TCPPort") 70 71 if (nil != errFetchingUDPPort) && (nil != errFetchingTCPPort) { 72 err = fmt.Errorf("confMap.FetchOptionValueUint16(\"Stats\", \"UDPPort\") failed: %v AND confMap.FetchOptionValueUint16(\"Stats\", \"TCPPort\") failed: %v", errFetchingTCPPort, errFetchingUDPPort) 73 return 74 } 75 76 if (nil == errFetchingUDPPort) && (nil == errFetchingTCPPort) { 77 err = fmt.Errorf("Only one of [Stats]UDPPort and [Stats]TCPPort may be specified") 78 return 79 } 80 81 globals.useUDP = (nil == errFetchingUDPPort) 82 83 if globals.useUDP { 84 globals.udpLAddr, err = net.ResolveUDPAddr("udp", globals.ipAddr+":0") 85 if nil != err { 86 return 87 } 88 globals.udpRAddr, err = net.ResolveUDPAddr("udp", globals.ipAddr+":"+strconv.FormatUint(uint64(globals.udpPort), 10)) 89 if nil != err { 90 return 91 } 92 } else { // globals.useTCP 93 globals.tcpLAddr, err = net.ResolveTCPAddr("tcp", globals.ipAddr+":0") 94 if nil != err { 95 return 96 } 97 globals.tcpRAddr, err = net.ResolveTCPAddr("tcp", globals.ipAddr+":"+strconv.FormatUint(uint64(globals.tcpPort), 10)) 98 if nil != err { 99 return 100 } 101 } 102 103 globals.bufferLength, err = confMap.FetchOptionValueUint16("Stats", "BufferLength") 104 if nil != err { 105 err = fmt.Errorf("confMap.FetchOptionValueUint16(\"Stats\", \"BufferLength\") failed: %v", err) 106 return 107 } 108 109 globals.maxLatency, err = confMap.FetchOptionValueDuration("Stats", "MaxLatency") 110 if nil != err { 111 err = fmt.Errorf("confMap.FetchOptionValueUint16(\"Stats\", \"MaxLatency\") failed: %v", err) 112 return 113 } 114 115 globals.statChan = make(chan *statStruct, globals.bufferLength) 116 globals.stopChan = make(chan bool, 1) 117 globals.doneChan = make(chan bool, 1) 118 119 globals.statDeltaMap = make(map[string]uint64, expectedNumberOfDistinctStatNames) 120 globals.headStatNameLink = nil 121 globals.tailStatNameLink = nil 122 123 globals.statFullMap = make(map[string]uint64, expectedNumberOfDistinctStatNames) 124 125 // Start the ticker 126 var timeoutDuration time.Duration 127 if expectedNumberOfDistinctStatNames > 0 { 128 timeoutDuration = globals.maxLatency 129 } 130 // else our ticker is disabled 131 globals.tickChan = time.Tick(timeoutDuration) 132 133 go sender() 134 135 err = nil 136 return 137 } 138 139 func (dummy *globalsStruct) VolumeGroupCreated(confMap conf.ConfMap, volumeGroupName string, activePeer string, virtualIPAddr string) (err error) { 140 return nil 141 } 142 func (dummy *globalsStruct) VolumeGroupMoved(confMap conf.ConfMap, volumeGroupName string, activePeer string, virtualIPAddr string) (err error) { 143 return nil 144 } 145 func (dummy *globalsStruct) VolumeGroupDestroyed(confMap conf.ConfMap, volumeGroupName string) (err error) { 146 return nil 147 } 148 func (dummy *globalsStruct) VolumeCreated(confMap conf.ConfMap, volumeName string, volumeGroupName string) (err error) { 149 return nil 150 } 151 func (dummy *globalsStruct) VolumeMoved(confMap conf.ConfMap, volumeName string, volumeGroupName string) (err error) { 152 return nil 153 } 154 func (dummy *globalsStruct) VolumeDestroyed(confMap conf.ConfMap, volumeName string) (err error) { 155 return nil 156 } 157 func (dummy *globalsStruct) ServeVolume(confMap conf.ConfMap, volumeName string) (err error) { 158 return nil 159 } 160 func (dummy *globalsStruct) UnserveVolume(confMap conf.ConfMap, volumeName string) (err error) { 161 return nil 162 } 163 func (dummy *globalsStruct) VolumeToBeUnserved(confMap conf.ConfMap, volumeName string) (err error) { 164 return nil 165 } 166 func (dummy *globalsStruct) SignaledStart(confMap conf.ConfMap) (err error) { 167 return nil 168 } 169 func (dummy *globalsStruct) SignaledFinish(confMap conf.ConfMap) (err error) { 170 return nil 171 } 172 173 func (dummy *globalsStruct) Down(confMap conf.ConfMap) (err error) { 174 globals.stopChan <- true 175 176 _ = <-globals.doneChan 177 178 globals.statChan = nil 179 180 err = nil 181 182 return 183 }