github.com/blend/go-sdk@v1.20220411.3/statsutil/new_multi_collector.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package statsutil
     9  
    10  import (
    11  	"github.com/blend/go-sdk/configmeta"
    12  	"github.com/blend/go-sdk/datadog"
    13  	"github.com/blend/go-sdk/env"
    14  	"github.com/blend/go-sdk/logger"
    15  	"github.com/blend/go-sdk/stats"
    16  	"github.com/blend/go-sdk/statsd"
    17  )
    18  
    19  // MultiCollectorOptions are the options for the multi-collector.
    20  type MultiCollectorOptions struct {
    21  	configmeta.Meta
    22  
    23  	DefaultTags []string
    24  	Datadog     datadog.Config
    25  	Prometheus  statsd.Config
    26  	Printer     bool
    27  }
    28  
    29  // MultiCollectorOption mutates MultiCollectorOptions.
    30  type MultiCollectorOption func(*MultiCollectorOptions)
    31  
    32  // OptServiceName sets the default service name.
    33  func OptServiceName(serviceName string) MultiCollectorOption {
    34  	return func(mco *MultiCollectorOptions) {
    35  		mco.ServiceName = serviceName
    36  	}
    37  }
    38  
    39  // OptServiceEnv sets the default service env.
    40  func OptServiceEnv(serviceEnv string) MultiCollectorOption {
    41  	return func(mco *MultiCollectorOptions) {
    42  		mco.ServiceEnv = serviceEnv
    43  	}
    44  }
    45  
    46  // OptVersion sets the default version tag.
    47  func OptVersion(version string) MultiCollectorOption {
    48  	return func(mco *MultiCollectorOptions) {
    49  		mco.Version = version
    50  	}
    51  }
    52  
    53  // OptHostname sets the default hostname.
    54  func OptHostname(hostname string) MultiCollectorOption {
    55  	return func(mco *MultiCollectorOptions) {
    56  		mco.Hostname = hostname
    57  	}
    58  }
    59  
    60  // OptDefaultTags adds default tags.
    61  func OptDefaultTags(tags ...string) MultiCollectorOption {
    62  	return func(mco *MultiCollectorOptions) {
    63  		mco.DefaultTags = append(mco.DefaultTags, tags...)
    64  	}
    65  }
    66  
    67  // OptMetaConfig sets the datadog config.
    68  func OptMetaConfig(meta configmeta.Meta) MultiCollectorOption {
    69  	return func(mco *MultiCollectorOptions) {
    70  		mco.Meta = meta
    71  	}
    72  }
    73  
    74  // OptDatadogConfig sets the datadog config.
    75  func OptDatadogConfig(cfg datadog.Config) MultiCollectorOption {
    76  	return func(mco *MultiCollectorOptions) {
    77  		mco.Datadog = cfg
    78  	}
    79  }
    80  
    81  // OptPrometheusConfig sets the prometheus config.
    82  func OptPrometheusConfig(cfg statsd.Config) MultiCollectorOption {
    83  	return func(mco *MultiCollectorOptions) {
    84  		mco.Prometheus = cfg
    85  	}
    86  }
    87  
    88  // OptPrinter sets if we should enable the printer.
    89  func OptPrinter(printer bool) MultiCollectorOption {
    90  	return func(mco *MultiCollectorOptions) {
    91  		mco.Printer = printer
    92  	}
    93  }
    94  
    95  // NewMultiCollector initializes the stats collector(s).
    96  func NewMultiCollector(log logger.Log, opts ...MultiCollectorOption) (stats.Collector, error) {
    97  	var options MultiCollectorOptions
    98  	for _, opt := range opts {
    99  		opt(&options)
   100  	}
   101  
   102  	var collector stats.MultiCollector
   103  	if options.Printer {
   104  		logger.MaybeInfof(log, "using debug statsd printer")
   105  		collector = append(collector, stats.NewPrinter(log))
   106  	}
   107  
   108  	if !options.Datadog.IsZero() {
   109  		logger.MaybeInfof(log, "using datadog statsd collector: %s", options.Datadog.GetAddress())
   110  		dd, err := datadog.New(options.Datadog)
   111  		if err != nil {
   112  			return nil, err
   113  		}
   114  		collector = append(collector, dd)
   115  	} else {
   116  		logger.MaybeDebugf(log, "datadog config unset, skipping")
   117  	}
   118  
   119  	if !options.Prometheus.IsZero() {
   120  		logger.MaybeInfof(log, "using prometheus stats collector: %s", options.Prometheus.Addr)
   121  		statsd, err := statsd.New(statsd.OptConfig(options.Prometheus))
   122  		if err != nil {
   123  			return nil, err
   124  		}
   125  		collector = append(collector, statsd)
   126  	} else {
   127  		logger.MaybeDebugf(log, "prometheus config unset, skipping")
   128  	}
   129  
   130  	// add default tags if there are collectors provisioned
   131  	if len(collector) > 0 {
   132  		if options.Meta.ServiceName != "" {
   133  			collector.AddDefaultTags(stats.Tag(stats.TagService, options.Meta.ServiceName))
   134  		} else if env.Env().ServiceName() != "" {
   135  			collector.AddDefaultTags(stats.Tag(stats.TagService, env.Env().ServiceName()))
   136  		}
   137  		if options.Meta.ServiceEnv != "" {
   138  			collector.AddDefaultTags(stats.Tag(stats.TagEnv, options.Meta.ServiceEnv))
   139  		} else if env.Env().ServiceEnv() != "" {
   140  			collector.AddDefaultTags(stats.Tag(stats.TagEnv, env.Env().ServiceEnv()))
   141  		}
   142  		if options.Meta.Hostname != "" {
   143  			collector.AddDefaultTags(stats.Tag(stats.TagHostname, options.Meta.Hostname))
   144  		} else if env.Env().Hostname() != "" {
   145  			collector.AddDefaultTags(stats.Tag(stats.TagHostname, env.Env().Hostname()))
   146  		}
   147  		if options.Meta.Version != "" {
   148  			collector.AddDefaultTags(stats.Tag(stats.TagVersion, options.Meta.Version))
   149  		} else if env.Env().Version() != "" {
   150  			collector.AddDefaultTags(stats.Tag(stats.TagVersion, env.Env().Version()))
   151  		}
   152  		collector.AddDefaultTags(options.DefaultTags...)
   153  	}
   154  	return collector, nil
   155  }