github.com/m3db/m3@v1.5.0/src/metrics/matcher/config.go (about)

     1  // Copyright (c) 2017 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 matcher
    22  
    23  import (
    24  	"fmt"
    25  	"time"
    26  
    27  	"github.com/m3db/m3/src/cluster/client"
    28  	"github.com/m3db/m3/src/cluster/kv"
    29  	"github.com/m3db/m3/src/metrics/filters"
    30  	"github.com/m3db/m3/src/metrics/matcher/cache"
    31  	"github.com/m3db/m3/src/metrics/matcher/namespace"
    32  	"github.com/m3db/m3/src/metrics/metric/id"
    33  	"github.com/m3db/m3/src/metrics/metric/id/m3"
    34  	"github.com/m3db/m3/src/metrics/rules"
    35  	"github.com/m3db/m3/src/x/clock"
    36  	"github.com/m3db/m3/src/x/instrument"
    37  	"github.com/m3db/m3/src/x/pool"
    38  )
    39  
    40  // Configuration is config used to create a Matcher.
    41  type Configuration struct {
    42  	InitWatchTimeout      time.Duration                `yaml:"initWatchTimeout"`
    43  	RulesKVConfig         kv.OverrideConfiguration     `yaml:"rulesKVConfig"`
    44  	NamespacesKey         string                       `yaml:"namespacesKey" validate:"nonzero"`
    45  	RuleSetKeyFmt         string                       `yaml:"ruleSetKeyFmt" validate:"nonzero"`
    46  	NamespaceTag          string                       `yaml:"namespaceTag" validate:"nonzero"`
    47  	DefaultNamespace      string                       `yaml:"defaultNamespace" validate:"nonzero"`
    48  	NameTagKey            string                       `yaml:"nameTagKey" validate:"nonzero"`
    49  	MatchRangePast        *time.Duration               `yaml:"matchRangePast"`
    50  	SortedTagIteratorPool pool.ObjectPoolConfiguration `yaml:"sortedTagIteratorPool"`
    51  }
    52  
    53  // NewNamespaces creates a matcher.Namespaces.
    54  func (cfg *Configuration) NewNamespaces(
    55  	kvCluster client.Client,
    56  	clockOpts clock.Options,
    57  	instrumentOpts instrument.Options,
    58  ) (Namespaces, error) {
    59  	opts, err := cfg.NewOptions(kvCluster, clockOpts, instrumentOpts)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	namespaces := NewNamespaces(opts.NamespacesKey(), opts)
    65  	return namespaces, nil
    66  }
    67  
    68  // NewMatcher creates a Matcher.
    69  func (cfg *Configuration) NewMatcher(
    70  	cache cache.Cache,
    71  	kvCluster client.Client,
    72  	clockOpts clock.Options,
    73  	instrumentOpts instrument.Options,
    74  ) (Matcher, error) {
    75  	opts, err := cfg.NewOptions(kvCluster, clockOpts, instrumentOpts)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	return NewMatcher(cache, opts)
    81  }
    82  
    83  // NewOptions creates a Options.
    84  func (cfg *Configuration) NewOptions(
    85  	kvCluster client.Client,
    86  	clockOpts clock.Options,
    87  	instrumentOpts instrument.Options,
    88  ) (Options, error) {
    89  	// Configure rules kv store.
    90  	kvOpts, err := cfg.RulesKVConfig.NewOverrideOptions()
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	rulesStore, err := kvCluster.Store(kvOpts)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	// Configure rules options.
   101  	scope := instrumentOpts.MetricsScope().SubScope("sorted-tag-iterator-pool")
   102  	poolOpts := cfg.SortedTagIteratorPool.NewObjectPoolOptions(instrumentOpts.SetMetricsScope(scope))
   103  	sortedTagIteratorPool := id.NewSortedTagIteratorPool(poolOpts)
   104  	sortedTagIteratorPool.Init(func() id.SortedTagIterator {
   105  		return m3.NewPooledSortedTagIterator(nil, sortedTagIteratorPool)
   106  	})
   107  	sortedTagIteratorFn := func(tagPairs []byte) id.SortedTagIterator {
   108  		it := sortedTagIteratorPool.Get()
   109  		it.Reset(tagPairs)
   110  		return it
   111  	}
   112  	tagsFilterOptions := filters.TagsFilterOptions{
   113  		NameTagKey:          []byte(cfg.NameTagKey),
   114  		NameAndTagsFn:       m3.NameAndTags,
   115  		SortedTagIteratorFn: sortedTagIteratorFn,
   116  	}
   117  
   118  	isRollupIDFn := func(name []byte, tags []byte) bool {
   119  		return m3.IsRollupID(name, tags, sortedTagIteratorPool)
   120  	}
   121  
   122  	ruleSetOpts := rules.NewOptions().
   123  		SetTagsFilterOptions(tagsFilterOptions).
   124  		SetNewRollupIDFn(m3.NewRollupID).
   125  		SetIsRollupIDFn(isRollupIDFn)
   126  
   127  	// Configure ruleset key function.
   128  	ruleSetKeyFn := func(namespace []byte) string {
   129  		return fmt.Sprintf(cfg.RuleSetKeyFmt, namespace)
   130  	}
   131  
   132  	opts := NewOptions().
   133  		SetClockOptions(clockOpts).
   134  		SetInstrumentOptions(instrumentOpts).
   135  		SetRuleSetOptions(ruleSetOpts).
   136  		SetKVStore(rulesStore).
   137  		SetNamespacesKey(cfg.NamespacesKey).
   138  		SetRuleSetKeyFn(ruleSetKeyFn).
   139  		SetNamespaceResolver(namespace.NewResolver([]byte(cfg.NamespaceTag), []byte(cfg.DefaultNamespace)))
   140  
   141  	if cfg.InitWatchTimeout != 0 {
   142  		opts = opts.SetInitWatchTimeout(cfg.InitWatchTimeout)
   143  	}
   144  	if cfg.MatchRangePast != nil {
   145  		opts = opts.SetMatchRangePast(*cfg.MatchRangePast)
   146  	}
   147  
   148  	return opts, nil
   149  }