Skip to content

Commit 9778b16

Browse files
joe-elliotttigrannajaryan
authored andcommitted
Refactor Jaeger Receiver config (#490)
Fixes #445, #158 This PR addresses some Jaeger receiver config cleanup as well as makes some breaking changes to the way the config is handled. See below for details. **Fixes/Updates** - Disabled flag is respected per protocol - Unspecified protocols will no longer be started - Empty protocol configs can now be specified to start the protocol with defaults. e.g. ``` jaeger: protocols: grpc: ``` - Updated readmes - Naming and behavior of per protocol Addr/Enabled functions in `trace_reciever.go` has been standardized. - Added thrift tchannel test to meet code coverage **Breaking Change** Changed the way an empty `jaeger:` config is handled. An empty/default config does not start any jaeger protocols. Previously it started all three collector protocols. This is a consequence of not starting unspecified protocols.
1 parent ec4ad0c commit 9778b16

File tree

16 files changed

+524
-177
lines changed

16 files changed

+524
-177
lines changed

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,10 @@ receivers:
162162
jaeger:
163163
protocols:
164164
grpc:
165-
endpoint: "localhost:9876"
166165
thrift-http:
167-
endpoint: "localhost:14268"
168166
thrift-tchannel:
169-
endpoint: "localhost:14267"
170167
thrift-compact:
171-
endpoint: "localhost:6831"
172168
thrift-binary:
173-
endpoint: "localhost:6832"
174169

175170
prometheus:
176171
config:

config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ func loadReceivers(v *viper.Viper, factories map[string]receiver.Factory) (confi
366366
customUnmarshaler := factory.CustomUnmarshaler()
367367
if customUnmarshaler != nil {
368368
// This configuration requires a custom unmarshaler, use it.
369-
err = customUnmarshaler(subViper, key, receiverCfg)
369+
err = customUnmarshaler(subViper, key, sv, receiverCfg)
370370
} else {
371371
err = sv.UnmarshalExact(receiverCfg)
372372
}

receiver/README.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,32 +107,27 @@ This receiver receives traces in the [Jaeger](https://www.jaegertracing.io)
107107
format. It translates them into the internal format and sends
108108
it to processors and exporters.
109109

110-
It supports the Jaeger Collector protocols:
110+
It supports the Jaeger Collector and Agent protocols:
111+
- gRPC
111112
- Thrift HTTP
112113
- Thrift TChannel
113-
- gRPC
114+
- Thrift Compact
115+
- Thrift Binary
114116

115-
By default, the Jaeger receiver supports all three protocols on the default ports
116-
specified in [factory.go](jaegerreceiver/factory.go). The following demonstrates
117-
how to specify the default Jaeger receiver.
117+
By default, the Jaeger receiver will not serve any protocol. A protocol must be named
118+
for the jaeger receiver to start. The following demonstrates how to start the Jaeger
119+
receiver with only gRPC enabled on the default port.
118120
```yaml
119121
receivers:
120122
jaeger:
123+
protocols:
124+
grpc:
121125
```
122126

123-
It also supports the Jaeger Agent protocols:
124-
- Thrift Compact
125-
- Thrift Binary
126-
127-
By default, these services are not started unless an endpoint is explicitly defined.
128-
129127
It is possible to configure the protocols on different ports, refer to
130128
[config.yaml](jaegerreceiver/testdata/config.yaml) for detailed config
131129
examples.
132130

133-
// TODO Issue https://github.com/open-telemetry/opentelemetry-collector/issues/158
134-
// The Jaeger receiver enables all protocols even when one is specified or a
135-
// subset is enabled. The documentation should be updated when that fix occurs.
136131
### Communicating over TLS
137132
This receiver supports communication using Transport Layer Security (TLS), but only using the gRPC protocol. It can be configured by specifying a `tls-crendentials` object in the gRPC receiver configuration.
138133
```yaml

receiver/factory.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,17 @@ type Factory interface {
5959

6060
// CustomUnmarshaler is a function that un-marshals a viper data into a config struct
6161
// in a custom way.
62-
type CustomUnmarshaler func(v *viper.Viper, viperKey string, intoCfg interface{}) error
62+
// v *viper.Viper
63+
// A viper instance at the "receivers" node in the config yaml. v.Sub(viperKey) is
64+
// the raw config this function should load.
65+
// viperKey string
66+
// The name of this config. i.e. "jaeger/custom". v.Sub(viperKey) is the raw config
67+
// this function should load.
68+
// sourceViperSection *viper.Viper
69+
// The value of v.Sub(viperKey) with all environment substitution complete.
70+
// intoCfg interface{}
71+
// An empty interface wrapping a pointer to the config struct to unmarshal into.
72+
type CustomUnmarshaler func(v *viper.Viper, viperKey string, sourceViperSection *viper.Viper, intoCfg interface{}) error
6373

6474
// Build takes a list of receiver factories and returns a map of type map[string]Factory
6575
// with factory type as keys. It returns a non-nil error when more than one factories

receiver/jaegerreceiver/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import (
1818
"github.com/open-telemetry/opentelemetry-collector/receiver"
1919
)
2020

21+
// The config field name to load the protocol map from
22+
const protocolsFieldName = "protocols"
23+
2124
// RemoteSamplingConfig defines config key for remote sampling fetch endpoint
2225
type RemoteSamplingConfig struct {
2326
FetchEndpoint string `mapstructure:"fetch_endpoint"`

receiver/jaegerreceiver/config_test.go

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,9 @@ func TestLoadConfig(t *testing.T) {
3737
require.NoError(t, err)
3838
require.NotNil(t, cfg)
3939

40-
// The receiver `jaeger/disabled` doesn't count because disabled receivers
40+
// The receiver `jaeger/disabled` and `jaeger` don't count because disabled receivers
4141
// are excluded from the final list.
42-
assert.Equal(t, len(cfg.Receivers), 3)
43-
44-
r0 := cfg.Receivers["jaeger"]
45-
assert.Equal(t, r0, factory.CreateDefaultConfig())
42+
assert.Equal(t, len(cfg.Receivers), 4)
4643

4744
r1 := cfg.Receivers["jaeger/customname"].(*Config)
4845
assert.Equal(t, r1,
@@ -81,6 +78,59 @@ func TestLoadConfig(t *testing.T) {
8178
},
8279
})
8380

81+
rDefaults := cfg.Receivers["jaeger/defaults"].(*Config)
82+
assert.Equal(t, rDefaults,
83+
&Config{
84+
TypeVal: typeStr,
85+
NameVal: "jaeger/defaults",
86+
Protocols: map[string]*receiver.SecureReceiverSettings{
87+
"grpc": {
88+
ReceiverSettings: configmodels.ReceiverSettings{
89+
Endpoint: defaultGRPCBindEndpoint,
90+
},
91+
},
92+
"thrift-http": {
93+
ReceiverSettings: configmodels.ReceiverSettings{
94+
Endpoint: defaultHTTPBindEndpoint,
95+
},
96+
},
97+
"thrift-tchannel": {
98+
ReceiverSettings: configmodels.ReceiverSettings{
99+
Endpoint: defaultTChannelBindEndpoint,
100+
},
101+
},
102+
"thrift-compact": {
103+
ReceiverSettings: configmodels.ReceiverSettings{
104+
Endpoint: defaultThriftCompactBindEndpoint,
105+
},
106+
},
107+
"thrift-binary": {
108+
ReceiverSettings: configmodels.ReceiverSettings{
109+
Endpoint: defaultThriftBinaryBindEndpoint,
110+
},
111+
},
112+
},
113+
})
114+
115+
rMixed := cfg.Receivers["jaeger/mixed"].(*Config)
116+
assert.Equal(t, rMixed,
117+
&Config{
118+
TypeVal: typeStr,
119+
NameVal: "jaeger/mixed",
120+
Protocols: map[string]*receiver.SecureReceiverSettings{
121+
"grpc": {
122+
ReceiverSettings: configmodels.ReceiverSettings{
123+
Endpoint: "localhost:9876",
124+
},
125+
},
126+
"thrift-compact": {
127+
ReceiverSettings: configmodels.ReceiverSettings{
128+
Endpoint: defaultThriftCompactBindEndpoint,
129+
},
130+
},
131+
},
132+
})
133+
84134
tlsConfig := cfg.Receivers["jaeger/tls"].(*Config)
85135

86136
assert.Equal(t, tlsConfig,
@@ -110,3 +160,19 @@ func TestLoadConfig(t *testing.T) {
110160
},
111161
})
112162
}
163+
164+
func TestFailedLoadConfig(t *testing.T) {
165+
factories, err := config.ExampleComponents()
166+
assert.Nil(t, err)
167+
168+
factory := &Factory{}
169+
factories.Receivers[typeStr] = factory
170+
_, err = config.LoadConfigFile(t, path.Join(".", "testdata", "bad_proto_config.yaml"), factories)
171+
assert.EqualError(t, err, `error reading settings for receiver type "jaeger": unknown Jaeger protocol badproto`)
172+
173+
_, err = config.LoadConfigFile(t, path.Join(".", "testdata", "bad_no_proto_config.yaml"), factories)
174+
assert.EqualError(t, err, `error reading settings for receiver type "jaeger": must specify at least one protocol when using the Jaeger receiver`)
175+
176+
_, err = config.LoadConfigFile(t, path.Join(".", "testdata", "bad_empty_config.yaml"), factories)
177+
assert.EqualError(t, err, `error reading settings for receiver type "jaeger": Jaeger receiver config is empty`)
178+
}

receiver/jaegerreceiver/factory.go

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"net"
2323
"strconv"
2424

25+
"github.com/spf13/viper"
2526
"go.uber.org/zap"
2627
"google.golang.org/grpc"
2728

@@ -48,6 +49,9 @@ const (
4849
defaultGRPCBindEndpoint = "localhost:14250"
4950
defaultHTTPBindEndpoint = "localhost:14268"
5051
defaultTChannelBindEndpoint = "localhost:14267"
52+
53+
defaultThriftCompactBindEndpoint = "localhost:6831"
54+
defaultThriftBinaryBindEndpoint = "localhost:6832"
5155
)
5256

5357
// Factory is the factory for Jaeger receiver.
@@ -59,33 +63,48 @@ func (f *Factory) Type() string {
5963
return typeStr
6064
}
6165

62-
// CustomUnmarshaler returns nil because we don't need custom unmarshaling for this config.
66+
// CustomUnmarshaler is used to add defaults for named but empty protocols
6367
func (f *Factory) CustomUnmarshaler() receiver.CustomUnmarshaler {
64-
return nil
68+
return func(v *viper.Viper, viperKey string, sourceViperSection *viper.Viper, intoCfg interface{}) error {
69+
// first load the config normally
70+
err := sourceViperSection.UnmarshalExact(intoCfg)
71+
if err != nil {
72+
return err
73+
}
74+
75+
receiverCfg, ok := intoCfg.(*Config)
76+
if !ok {
77+
return fmt.Errorf("config type not *jaegerreceiver.Config")
78+
}
79+
80+
// next manually search for protocols in viper that do not appear in the normally loaded config
81+
// these protocols were excluded during normal loading and we need to add defaults for them
82+
vSub := v.Sub(viperKey)
83+
if vSub == nil {
84+
return fmt.Errorf("Jaeger receiver config is empty")
85+
}
86+
protocols := vSub.GetStringMap(protocolsFieldName)
87+
if len(protocols) == 0 {
88+
return fmt.Errorf("must specify at least one protocol when using the Jaeger receiver")
89+
}
90+
for k := range protocols {
91+
if _, ok := receiverCfg.Protocols[k]; !ok {
92+
if receiverCfg.Protocols[k], err = defaultsForProtocol(k); err != nil {
93+
return err
94+
}
95+
}
96+
}
97+
98+
return nil
99+
}
65100
}
66101

67102
// CreateDefaultConfig creates the default configuration for Jaeger receiver.
68103
func (f *Factory) CreateDefaultConfig() configmodels.Receiver {
69104
return &Config{
70-
TypeVal: typeStr,
71-
NameVal: typeStr,
72-
Protocols: map[string]*receiver.SecureReceiverSettings{
73-
protoGRPC: {
74-
ReceiverSettings: configmodels.ReceiverSettings{
75-
Endpoint: defaultGRPCBindEndpoint,
76-
},
77-
},
78-
protoThriftTChannel: {
79-
ReceiverSettings: configmodels.ReceiverSettings{
80-
Endpoint: defaultTChannelBindEndpoint,
81-
},
82-
},
83-
protoThriftHTTP: {
84-
ReceiverSettings: configmodels.ReceiverSettings{
85-
Endpoint: defaultHTTPBindEndpoint,
86-
},
87-
},
88-
},
105+
TypeVal: typeStr,
106+
NameVal: typeStr,
107+
Protocols: map[string]*receiver.SecureReceiverSettings{},
89108
}
90109
}
91110

@@ -208,3 +227,29 @@ func extractPortFromEndpoint(endpoint string) (int, error) {
208227
}
209228
return int(port), nil
210229
}
230+
231+
// returns a default value for a protocol name. this really just boils down to the endpoint
232+
func defaultsForProtocol(proto string) (*receiver.SecureReceiverSettings, error) {
233+
var defaultEndpoint string
234+
235+
switch proto {
236+
case protoGRPC:
237+
defaultEndpoint = defaultGRPCBindEndpoint
238+
case protoThriftHTTP:
239+
defaultEndpoint = defaultHTTPBindEndpoint
240+
case protoThriftTChannel:
241+
defaultEndpoint = defaultTChannelBindEndpoint
242+
case protoThriftBinary:
243+
defaultEndpoint = defaultThriftBinaryBindEndpoint
244+
case protoThriftCompact:
245+
defaultEndpoint = defaultThriftCompactBindEndpoint
246+
default:
247+
return nil, fmt.Errorf("unknown Jaeger protocol %s", proto)
248+
}
249+
250+
return &receiver.SecureReceiverSettings{
251+
ReceiverSettings: configmodels.ReceiverSettings{
252+
Endpoint: defaultEndpoint,
253+
},
254+
}, nil
255+
}

0 commit comments

Comments
 (0)