github.com/m3db/m3@v1.5.0/examples/dbnode/metrics_client/main.go (about)

     1  // Copyright (c) 2020 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  	"context"
    25  	"flag"
    26  	"io/ioutil"
    27  	"log"
    28  	"time"
    29  
    30  	"github.com/m3db/m3/src/dbnode/client"
    31  	"github.com/m3db/m3/src/dbnode/storage/index"
    32  	"github.com/m3db/m3/src/m3ninx/idx"
    33  	"github.com/m3db/m3/src/x/ident"
    34  	xtime "github.com/m3db/m3/src/x/time"
    35  
    36  	yaml "gopkg.in/yaml.v2"
    37  )
    38  
    39  const (
    40  	namespace = "default"
    41  )
    42  
    43  var (
    44  	namespaceID = ident.StringID(namespace)
    45  )
    46  
    47  type config struct {
    48  	Client client.Configuration `yaml:"client"`
    49  }
    50  
    51  var configFile = flag.String("f", "", "configuration file")
    52  
    53  func main() {
    54  	flag.Parse()
    55  	if *configFile == "" {
    56  		flag.Usage()
    57  		return
    58  	}
    59  
    60  	cfgBytes, err := ioutil.ReadFile(*configFile)
    61  	if err != nil {
    62  		log.Fatalf("unable to read config file: %s, err: %v", *configFile, err)
    63  	}
    64  
    65  	cfg := &config{}
    66  	if err := yaml.UnmarshalStrict(cfgBytes, cfg); err != nil {
    67  		log.Fatalf("unable to parse YAML: %v", err)
    68  	}
    69  
    70  	client, err := cfg.Client.NewClient(client.ConfigurationParameters{})
    71  	if err != nil {
    72  		log.Fatalf("unable to create new M3DB client: %v", err)
    73  	}
    74  
    75  	session, err := client.DefaultSession()
    76  	if err != nil {
    77  		log.Fatalf("unable to create new M3DB session: %v", err)
    78  	}
    79  	defer session.Close()
    80  
    81  	runTaggedExample(session)
    82  }
    83  
    84  // runTaggedExample demonstrates how to write "tagged" (indexed) metrics data
    85  // and then read it back out again by either:
    86  //
    87  //   1. Querying for a set of time series using an inverted index query
    88  //   2. Querying for a specific time series by its ID directly
    89  func runTaggedExample(session client.Session) {
    90  	log.Printf("------ run tagged example ------")
    91  	var (
    92  		seriesID = ident.StringID("{__name__=\"network_in\",host=\"host-01\",region=\"us-east-1\"}")
    93  		tags     = []ident.Tag{
    94  			{Name: ident.StringID("host"), Value: ident.StringID("host01")},
    95  			{Name: ident.StringID("region"), Value: ident.StringID("us-east-1")},
    96  		}
    97  		tagsIter = ident.NewTagsIterator(ident.NewTags(tags...))
    98  	)
    99  	// Write a tagged series ID using millisecond precision.
   100  	timestamp := xtime.Now()
   101  	value := 42.0
   102  	err := session.WriteTagged(namespaceID, seriesID, tagsIter,
   103  		timestamp, value, xtime.Millisecond, nil)
   104  	if err != nil {
   105  		log.Fatalf("error writing series %s, err: %v", seriesID.String(), err)
   106  	}
   107  
   108  	// 1. Fetch data for the tagged seriesID using a query (only data written
   109  	// within the last minute).
   110  	end := xtime.Now()
   111  	start := end.Add(-time.Minute)
   112  
   113  	// Use regexp to filter on a single tag, use idx.NewConjunctionQuery to
   114  	// to search on multiple tags, etc.
   115  	reQuery, err := idx.NewRegexpQuery([]byte("host"), []byte("host[0-9]+"))
   116  	if err != nil {
   117  		log.Fatalf("error in creating query: %v", err)
   118  	}
   119  
   120  	resultsIter, _, err := session.FetchTagged(context.Background(), namespaceID, index.Query{Query: reQuery},
   121  		index.QueryOptions{StartInclusive: start, EndExclusive: end})
   122  	if err != nil {
   123  		log.Fatalf("error fetching data for tagged series: %v", err)
   124  	}
   125  	for _, seriesIter := range resultsIter.Iters() {
   126  		log.Printf("series: %s", seriesIter.ID().String())
   127  		tags := seriesIter.Tags()
   128  		for tags.Next() {
   129  			tag := tags.Current()
   130  			log.Printf("%s=%s", tag.Name.String(), tag.Value.String())
   131  		}
   132  		if err := tags.Err(); err != nil {
   133  			log.Fatalf("error in tag iterator: %v", err)
   134  		}
   135  		for seriesIter.Next() {
   136  			dp, _, _ := seriesIter.Current()
   137  			log.Printf("%s: %v", dp.TimestampNanos.String(), dp.Value)
   138  		}
   139  		if err := seriesIter.Err(); err != nil {
   140  			log.Fatalf("error in series iterator: %v", err)
   141  		}
   142  	}
   143  
   144  	// 2. Fetch data for the series ID directly, skips the inverted index.
   145  	seriesIter, err := session.Fetch(namespaceID, seriesID, start, end)
   146  	if err != nil {
   147  		log.Fatalf("error fetching data for untagged series: %v", err)
   148  	}
   149  	for seriesIter.Next() {
   150  		dp, _, _ := seriesIter.Current()
   151  		log.Printf("%s: %v", dp.TimestampNanos.String(), dp.Value)
   152  	}
   153  	if err := seriesIter.Err(); err != nil {
   154  		log.Fatalf("error in series iterator: %v", err)
   155  	}
   156  }