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  }