github.com/uber-go/tally/v4@v4.1.17/m3/example/m3_main.go (about)

     1  // Copyright (c) 2024 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package main
    22  
    23  import (
    24  	"flag"
    25  	"fmt"
    26  	"io/ioutil"
    27  	"log"
    28  	"math/rand"
    29  	"os"
    30  	"time"
    31  
    32  	tally "github.com/uber-go/tally/v4"
    33  	"github.com/uber-go/tally/v4/m3"
    34  	m3thrift "github.com/uber-go/tally/v4/m3/thrift/v1"
    35  
    36  	validator "gopkg.in/validator.v2"
    37  	yaml "gopkg.in/yaml.v2"
    38  )
    39  
    40  var configFileArg = flag.String("config", "config.yaml", "YAML config file path")
    41  
    42  type config struct {
    43  	M3 m3.Configuration `yaml:"m3"`
    44  }
    45  
    46  func configFromFile(file string) (*config, error) {
    47  	fd, err := os.Open(file)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	defer fd.Close()
    53  
    54  	data, err := ioutil.ReadAll(fd)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	cfg := &config{}
    60  
    61  	if err := yaml.Unmarshal(data, cfg); err != nil {
    62  		return nil, err
    63  	}
    64  	if err := validator.Validate(cfg); err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	return cfg, nil
    69  }
    70  
    71  func main() {
    72  	flag.Parse()
    73  	configFile := *configFileArg
    74  	if configFile == "" {
    75  		flag.Usage()
    76  		return
    77  	}
    78  
    79  	cfg, err := configFromFile(configFile)
    80  	if err != nil {
    81  		log.Fatalf("failed to read config file %s: %v", configFile, err)
    82  	}
    83  
    84  	r, err := cfg.M3.NewReporter()
    85  	if err != nil {
    86  		log.Fatalf("failed to create reporter: %v", err)
    87  	}
    88  
    89  	scope, closer := tally.NewRootScope(tally.ScopeOptions{
    90  		CachedReporter:         r,
    91  		CardinalityMetricsTags: cfg.M3.InternalTags,
    92  	}, 1*time.Second)
    93  
    94  	defer closer.Close()
    95  
    96  	counter := scope.Tagged(map[string]string{
    97  		"foo": "bar",
    98  	}).Counter("test_counter")
    99  
   100  	gauge := scope.Tagged(map[string]string{
   101  		"foo": "baz",
   102  	}).Gauge("test_gauge")
   103  
   104  	timer := scope.Tagged(map[string]string{
   105  		"foo": "qux",
   106  	}).Timer("test_timer_summary")
   107  
   108  	histogram := scope.Tagged(map[string]string{
   109  		"foo": "quk",
   110  	}).Histogram("test_histogram", tally.DefaultBuckets)
   111  
   112  	go func() {
   113  		for {
   114  			counter.Inc(1)
   115  			time.Sleep(time.Second)
   116  		}
   117  	}()
   118  
   119  	go func() {
   120  		for {
   121  			gauge.Update(rand.Float64() * 1000)
   122  			time.Sleep(time.Second)
   123  		}
   124  	}()
   125  
   126  	go func() {
   127  		for {
   128  			tsw := timer.Start()
   129  			hsw := histogram.Start()
   130  			time.Sleep(time.Duration(rand.Float64() * float64(time.Second)))
   131  			tsw.Stop()
   132  			hsw.Stop()
   133  		}
   134  	}()
   135  
   136  	srv, err := newLocalM3Server("127.0.0.1:6396", m3.Compact, func(b *m3thrift.MetricBatch) {
   137  		for _, m := range b.Metrics {
   138  			tags := make(map[string]string)
   139  			for tag := range b.CommonTags {
   140  				tags[tag.GetTagName()] = tag.GetTagValue()
   141  			}
   142  			for tag := range m.Tags {
   143  				tags[tag.GetTagName()] = tag.GetTagValue()
   144  			}
   145  			metVal := m.GetMetricValue()
   146  			switch {
   147  			case metVal != nil && metVal.Count != nil:
   148  				fmt.Printf("counter value: %d, tags: %v\n", metVal.Count.GetI64Value(), tags)
   149  			case metVal != nil && metVal.Gauge != nil && metVal.Gauge.I64Value != nil:
   150  				fmt.Printf("gauge value: %d, tags: %v\n", metVal.Gauge.GetI64Value(), tags)
   151  			case metVal != nil && metVal.Gauge != nil && metVal.Gauge.DValue != nil:
   152  				fmt.Printf("gauge value: %f, tags: %v\n", metVal.Gauge.GetDValue(), tags)
   153  			case metVal != nil && metVal.Timer != nil:
   154  				fmt.Printf("timer value: %v, tags: %v\n", time.Duration(metVal.Timer.GetI64Value()), tags)
   155  			}
   156  		}
   157  	})
   158  	if err != nil {
   159  		log.Fatalf("failed to create test listen server: %v", err)
   160  	}
   161  	if err := srv.Serve(); err != nil {
   162  		log.Fatalf("failed to serve test listen server: %v", err)
   163  	}
   164  }