Skip to content

Commit d5ad797

Browse files
authored
Add sampling handler and sampling strategy store (#674)
1 parent b61b7ec commit d5ad797

File tree

18 files changed

+890
-2
lines changed

18 files changed

+890
-2
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) 2018 The Jaeger Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package sampling
16+
17+
import (
18+
"github.com/uber/tchannel-go/thrift"
19+
20+
"github.com/jaegertracing/jaeger/cmd/collector/app/sampling/strategystore"
21+
"github.com/jaegertracing/jaeger/thrift-gen/sampling"
22+
)
23+
24+
// Handler returns sampling strategies for specified services
25+
type Handler interface {
26+
// GetSamplingStrategy returns recommended sampling strategy for a given service name.
27+
GetSamplingStrategy(ctx thrift.Context, serviceName string) (*sampling.SamplingStrategyResponse, error)
28+
}
29+
30+
type handler struct {
31+
store strategystore.StrategyStore
32+
}
33+
34+
// NewHandler creates a handler that controls sampling strategies for services.
35+
func NewHandler(store strategystore.StrategyStore) Handler {
36+
return &handler{
37+
store: store,
38+
}
39+
}
40+
41+
// GetSamplingStrategy returns allowed sampling strategy for a given service name.
42+
func (h *handler) GetSamplingStrategy(ctx thrift.Context, serviceName string) (*sampling.SamplingStrategyResponse, error) {
43+
return h.store.GetSamplingStrategy(serviceName)
44+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2018 The Jaeger Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package sampling
16+
17+
import (
18+
"testing"
19+
20+
"github.com/stretchr/testify/assert"
21+
22+
"github.com/jaegertracing/jaeger/thrift-gen/sampling"
23+
)
24+
25+
func TestHandler(t *testing.T) {
26+
handler := NewHandler(mockStore{})
27+
_, err := handler.GetSamplingStrategy(nil, "")
28+
assert.NoError(t, err)
29+
}
30+
31+
type mockStore struct{}
32+
33+
func (s mockStore) GetSamplingStrategy(serviceName string) (*sampling.SamplingStrategyResponse, error) {
34+
return nil, nil
35+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) 2018 The Jaeger Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package strategystore
16+
17+
import (
18+
"github.com/uber/jaeger-lib/metrics"
19+
"go.uber.org/zap"
20+
)
21+
22+
// Factory defines an interface for a factory that can create implementations of different strategy storage components.
23+
// Implementations are also encouraged to implement plugin.Configurable interface.
24+
//
25+
// See also
26+
//
27+
// plugin.Configurable
28+
type Factory interface {
29+
// Initialize performs internal initialization of the factory.
30+
Initialize(metricsFactory metrics.Factory, logger *zap.Logger) error
31+
32+
// CreateStrategyStore initializes the StrategyStore and returns it.
33+
CreateStrategyStore() (StrategyStore, error)
34+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) 2018 The Jaeger Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package strategystore
16+
17+
import (
18+
"github.com/jaegertracing/jaeger/thrift-gen/sampling"
19+
)
20+
21+
// StrategyStore keeps track of service specific sampling strategies.
22+
type StrategyStore interface {
23+
// GetSamplingStrategy retrieves the sampling strategy for the specified service.
24+
GetSamplingStrategy(serviceName string) (*sampling.SamplingStrategyResponse, error)
25+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright (c) 2018 The Jaeger Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package strategystore
16+
17+
import (
18+
"flag"
19+
"fmt"
20+
21+
"github.com/spf13/viper"
22+
"github.com/uber/jaeger-lib/metrics"
23+
"go.uber.org/zap"
24+
25+
"github.com/jaegertracing/jaeger/cmd/collector/app/sampling/strategystore"
26+
"github.com/jaegertracing/jaeger/plugin"
27+
"github.com/jaegertracing/jaeger/plugin/sampling/strategystore/static"
28+
)
29+
30+
const (
31+
staticStrategyStoreType = "static"
32+
adaptiveStrategyStoreType = "adaptive"
33+
)
34+
35+
var allSamplingTypes = []string{staticStrategyStoreType} // TODO support adaptive
36+
37+
// Factory implements strategystore.Factory interface as a meta-factory for strategy storage components.
38+
type Factory struct {
39+
FactoryConfig
40+
41+
factories map[string]strategystore.Factory
42+
}
43+
44+
// NewFactory creates the meta-factory.
45+
func NewFactory(config FactoryConfig) (*Factory, error) {
46+
f := &Factory{FactoryConfig: config}
47+
uniqueTypes := map[string]struct{}{
48+
f.StrategyStoreType: {},
49+
}
50+
f.factories = make(map[string]strategystore.Factory)
51+
for t := range uniqueTypes {
52+
ff, err := f.getFactoryOfType(t)
53+
if err != nil {
54+
return nil, err
55+
}
56+
f.factories[t] = ff
57+
}
58+
return f, nil
59+
}
60+
61+
func (f *Factory) getFactoryOfType(factoryType string) (strategystore.Factory, error) {
62+
switch factoryType {
63+
case staticStrategyStoreType:
64+
return static.NewFactory(), nil
65+
default:
66+
return nil, fmt.Errorf("Unknown sampling strategy store type %s. Valid types are %v", factoryType, allSamplingTypes)
67+
}
68+
}
69+
70+
// AddFlags implements plugin.Configurable
71+
func (f *Factory) AddFlags(flagSet *flag.FlagSet) {
72+
for _, factory := range f.factories {
73+
if conf, ok := factory.(plugin.Configurable); ok {
74+
conf.AddFlags(flagSet)
75+
}
76+
}
77+
}
78+
79+
// InitFromViper implements plugin.Configurable
80+
func (f *Factory) InitFromViper(v *viper.Viper) {
81+
for _, factory := range f.factories {
82+
if conf, ok := factory.(plugin.Configurable); ok {
83+
conf.InitFromViper(v)
84+
}
85+
}
86+
}
87+
88+
// Initialize implements strategystore.Factory
89+
func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) error {
90+
for _, factory := range f.factories {
91+
if err := factory.Initialize(metricsFactory, logger); err != nil {
92+
return err
93+
}
94+
}
95+
return nil
96+
}
97+
98+
// CreateStrategyStore implements strategystore.Factory
99+
func (f *Factory) CreateStrategyStore() (strategystore.StrategyStore, error) {
100+
factory, ok := f.factories[f.StrategyStoreType]
101+
if !ok {
102+
return nil, fmt.Errorf("No %s strategy store registered", f.StrategyStoreType)
103+
}
104+
return factory.CreateStrategyStore()
105+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) 2018 The Jaeger Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package strategystore
16+
17+
import (
18+
"os"
19+
)
20+
21+
const (
22+
// SamplingTypeEnvVar is the name of the env var that defines the type of sampling strategy store used.
23+
SamplingTypeEnvVar = "SAMPLING_TYPE"
24+
)
25+
26+
// FactoryConfig tells the Factory what sampling type it needs to create.
27+
type FactoryConfig struct {
28+
StrategyStoreType string
29+
}
30+
31+
// FactoryConfigFromEnv reads the desired sampling type from the SAMPLING_TYPE environment variable. Allowed values:
32+
// * `static` - built-in
33+
// * `adaptive` - built-in // TODO
34+
func FactoryConfigFromEnv() FactoryConfig {
35+
strategyStoreType := os.Getenv(SamplingTypeEnvVar)
36+
if strategyStoreType == "" {
37+
strategyStoreType = staticStrategyStoreType
38+
}
39+
return FactoryConfig{
40+
StrategyStoreType: strategyStoreType,
41+
}
42+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) 2018 Uber Technologies, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package strategystore
16+
17+
import (
18+
"os"
19+
"testing"
20+
21+
"github.com/stretchr/testify/assert"
22+
)
23+
24+
func clearEnv() {
25+
os.Setenv(SamplingTypeEnvVar, "")
26+
}
27+
28+
func TestFactoryConfigFromEnv(t *testing.T) {
29+
clearEnv()
30+
defer clearEnv()
31+
32+
f := FactoryConfigFromEnv()
33+
assert.Equal(t, staticStrategyStoreType, f.StrategyStoreType)
34+
}

0 commit comments

Comments
 (0)