Skip to content

Commit

Permalink
[dbnode] Add example for using the Go DB node client to query/write m…
Browse files Browse the repository at this point in the history
…etrics (#2658)
  • Loading branch information
robskillington authored Sep 25, 2020
1 parent 41b4bc4 commit 21cceab
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 0 deletions.
12 changes: 12 additions & 0 deletions examples/dbnode/metrics_client/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
client:
config:
service:
env: default_env
zone: embedded
service: m3db
etcdClusters:
- zone: embedded
endpoints:
- 127.0.0.1:2379
writeConsistencyLevel: majority
readConsistencyLevel: unstrict_majority
153 changes: 153 additions & 0 deletions examples/dbnode/metrics_client/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Copyright (c) 2020 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package main

import (
"flag"
"io/ioutil"
"log"
"time"

"github.com/m3db/m3/src/dbnode/client"
"github.com/m3db/m3/src/dbnode/storage/index"
"github.com/m3db/m3/src/m3ninx/idx"
"github.com/m3db/m3/src/x/ident"
xtime "github.com/m3db/m3/src/x/time"
yaml "gopkg.in/yaml.v2"
)

const (
namespace = "default"
)

var (
namespaceID = ident.StringID(namespace)
)

type config struct {
Client client.Configuration `yaml:"client"`
}

var configFile = flag.String("f", "", "configuration file")

func main() {
flag.Parse()
if *configFile == "" {
flag.Usage()
return
}

cfgBytes, err := ioutil.ReadFile(*configFile)
if err != nil {
log.Fatalf("unable to read config file: %s, err: %v", *configFile, err)
}

cfg := &config{}
if err := yaml.UnmarshalStrict(cfgBytes, cfg); err != nil {
log.Fatalf("unable to parse YAML: %v", err)
}

client, err := cfg.Client.NewClient(client.ConfigurationParameters{})
if err != nil {
log.Fatalf("unable to create new M3DB client: %v", err)
}

session, err := client.DefaultSession()
if err != nil {
log.Fatalf("unable to create new M3DB session: %v", err)
}
defer session.Close()

runTaggedExample(session)
}

// runTaggedExample demonstrates how to write "tagged" (indexed) metrics data
// and then read it back out again by either:
//
// 1. Querying for a set of time series using an inverted index query
// 2. Querying for a specific time series by its ID directly
func runTaggedExample(session client.Session) {
log.Printf("------ run tagged example ------")
var (
seriesID = ident.StringID("{__name__=\"network_in\",host=\"host-01\",region=\"us-east-1\"}")
tags = []ident.Tag{
{Name: ident.StringID("host"), Value: ident.StringID("host01")},
{Name: ident.StringID("region"), Value: ident.StringID("us-east-1")},
}
tagsIter = ident.NewTagsIterator(ident.NewTags(tags...))
)
// Write a tagged series ID using millisecond precision.
timestamp := time.Now()
value := 42.0
err := session.WriteTagged(namespaceID, seriesID, tagsIter,
timestamp, value, xtime.Millisecond, nil)
if err != nil {
log.Fatalf("error writing series %s, err: %v", seriesID.String(), err)
}

// 1. Fetch data for the tagged seriesID using a query (only data written
// within the last minute).
start, end := time.Now().Add(-time.Minute), time.Now()

// Use regexp to filter on a single tag, use idx.NewConjunctionQuery to
// to search on multiple tags, etc.
reQuery, err := idx.NewRegexpQuery([]byte("host"), []byte("host[0-9]+"))
if err != nil {
log.Fatalf("error in creating query: %v", err)
}

resultsIter, _, err := session.FetchTagged(namespaceID, index.Query{Query: reQuery},
index.QueryOptions{StartInclusive: start, EndExclusive: end})
if err != nil {
log.Fatalf("error fetching data for tagged series: %v", err)
}
for _, seriesIter := range resultsIter.Iters() {
log.Printf("series: %s", seriesIter.ID().String())
tags := seriesIter.Tags()
for tags.Next() {
tag := tags.Current()
log.Printf("%s=%s", tag.Name.String(), tag.Value.String())
}
if err := tags.Err(); err != nil {
log.Fatalf("error in tag iterator: %v", err)
}
for seriesIter.Next() {
dp, _, _ := seriesIter.Current()
log.Printf("%s: %v", dp.Timestamp.String(), dp.Value)
}
if err := seriesIter.Err(); err != nil {
log.Fatalf("error in series iterator: %v", err)
}
}

// 2. Fetch data for the series ID directly, skips the inverted index.
seriesIter, err := session.Fetch(namespaceID, seriesID, start, end)
if err != nil {
log.Fatalf("error fetching data for untagged series: %v", err)
}
for seriesIter.Next() {
dp, _, _ := seriesIter.Current()
log.Printf("%s: %v", dp.Timestamp.String(), dp.Value)
}
if err := seriesIter.Err(); err != nil {
log.Fatalf("error in series iterator: %v", err)
}
}
20 changes: 20 additions & 0 deletions examples/dbnode/proto_client/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
// Copyright (c) 2020 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package main

import (
Expand Down
2 changes: 2 additions & 0 deletions scripts/development/m3_stack/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ services:
environment:
- M3DB_HOST_ID=m3db_seed
expose:
- "2379"
- "9002"
- "9003"
- "9004"
ports:
- "0.0.0.0:2379:2379"
- "0.0.0.0:9002:9002"
- "0.0.0.0:9003:9003"
- "0.0.0.0:9004:9004"
Expand Down

0 comments on commit 21cceab

Please sign in to comment.