-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add receiver for sapm protocol (#48)
- Loading branch information
1 parent
056258e
commit e9cdcd5
Showing
13 changed files
with
1,991 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright 2019, OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package sapmreceiver | ||
|
||
import ( | ||
"github.com/open-telemetry/opentelemetry-collector/config/configmodels" | ||
) | ||
|
||
// Config defines configuration for SAPM receiver. | ||
type Config struct { | ||
configmodels.ReceiverSettings `mapstructure:",squash"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Copyright 2019, OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package sapmreceiver | ||
|
||
import ( | ||
"path" | ||
"testing" | ||
|
||
"github.com/open-telemetry/opentelemetry-collector/config" | ||
"github.com/open-telemetry/opentelemetry-collector/config/configmodels" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestLoadConfig(t *testing.T) { | ||
factories, err := config.ExampleComponents() | ||
assert.Nil(t, err) | ||
|
||
factory := &Factory{} | ||
factories.Receivers[typeStr] = factory | ||
cfg, err := config.LoadConfigFile(t, path.Join(".", "testdata", "config.yaml"), factories) | ||
|
||
require.NoError(t, err) | ||
require.NotNil(t, cfg) | ||
|
||
// The receiver `sapm/disabled` doesn't count because disabled receivers | ||
// are excluded from the final list. | ||
assert.Equal(t, len(cfg.Receivers), 2) | ||
|
||
r0 := cfg.Receivers["sapm"] | ||
assert.Equal(t, r0, factory.CreateDefaultConfig()) | ||
|
||
r1 := cfg.Receivers["sapm/customname"].(*Config) | ||
assert.Equal(t, r1, | ||
&Config{ | ||
ReceiverSettings: configmodels.ReceiverSettings{ | ||
TypeVal: typeStr, | ||
NameVal: "sapm/customname", | ||
Endpoint: "0.0.0.0:7276", | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright 2019, OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Package sapmreceiver implements a receiver that can be used by the | ||
// Opentelemetry collector to receive traces in the Splunk SAPM format. | ||
package sapmreceiver |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Copyright 2019, OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package sapmreceiver | ||
|
||
// This file implements factory for SAPM receiver. | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net" | ||
"strconv" | ||
|
||
"github.com/open-telemetry/opentelemetry-collector/config/configerror" | ||
"github.com/open-telemetry/opentelemetry-collector/config/configmodels" | ||
"github.com/open-telemetry/opentelemetry-collector/consumer" | ||
"github.com/open-telemetry/opentelemetry-collector/receiver" | ||
"go.uber.org/zap" | ||
) | ||
|
||
const ( | ||
// The value of "type" key in configuration. | ||
typeStr = "sapm" | ||
|
||
// Default endpoints to bind to. | ||
defaultEndpoint = ":7276" | ||
) | ||
|
||
// Factory is the factory for SAPM receiver. | ||
type Factory struct { | ||
} | ||
|
||
// Type gets the type of the Receiver config created by this factory. | ||
func (f *Factory) Type() string { | ||
return typeStr | ||
} | ||
|
||
// CustomUnmarshaler returns nil because we don't need custom unmarshaling for this config. | ||
func (f *Factory) CustomUnmarshaler() receiver.CustomUnmarshaler { | ||
return nil | ||
} | ||
|
||
// CreateDefaultConfig creates the default configuration for SAPM receiver. | ||
func (f *Factory) CreateDefaultConfig() configmodels.Receiver { | ||
return &Config{ | ||
ReceiverSettings: configmodels.ReceiverSettings{ | ||
TypeVal: typeStr, | ||
NameVal: typeStr, | ||
Endpoint: defaultEndpoint, | ||
}, | ||
} | ||
} | ||
|
||
// extract the port number from string in "address:port" format. If the | ||
// port number cannot be extracted returns an error. | ||
// TODO make this a utility function | ||
func extractPortFromEndpoint(endpoint string) (int, error) { | ||
_, portStr, err := net.SplitHostPort(endpoint) | ||
if err != nil { | ||
return 0, fmt.Errorf("endpoint is not formatted correctly: %s", err.Error()) | ||
} | ||
port, err := strconv.ParseInt(portStr, 10, 0) | ||
if err != nil { | ||
return 0, fmt.Errorf("endpoint port is not a number: %s", err.Error()) | ||
} | ||
if port < 1 || port > 65535 { | ||
return 0, fmt.Errorf("port number must be between 1 and 65535") | ||
} | ||
return int(port), nil | ||
} | ||
|
||
// CreateTraceReceiver creates a trace receiver based on provided config. | ||
func (f *Factory) CreateTraceReceiver( | ||
ctx context.Context, | ||
logger *zap.Logger, | ||
cfg configmodels.Receiver, | ||
nextConsumer consumer.TraceConsumer, | ||
) (receiver.TraceReceiver, error) { | ||
// assert config is SAPM config | ||
rCfg := cfg.(*Config) | ||
|
||
port, err := extractPortFromEndpoint(rCfg.Endpoint) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// verify that the configured port is not 0 | ||
if port == 0 { | ||
err = fmt.Errorf("endpoint with non-zero port must be enabled for %s receiver", | ||
rCfg.Name(), | ||
) | ||
return nil, err | ||
} | ||
|
||
// Create the receiver. | ||
return New(ctx, logger, rCfg, nextConsumer) | ||
} | ||
|
||
// CreateMetricsReceiver creates a metrics receiver based on provided config. | ||
func (f *Factory) CreateMetricsReceiver( | ||
logger *zap.Logger, | ||
cfg configmodels.Receiver, | ||
consumer consumer.MetricsConsumer, | ||
) (receiver.MetricsReceiver, error) { | ||
return nil, configerror.ErrDataTypeIsNotSupported | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright 2019, OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package sapmreceiver | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/open-telemetry/opentelemetry-collector/config/configcheck" | ||
"github.com/open-telemetry/opentelemetry-collector/config/configerror" | ||
"github.com/stretchr/testify/assert" | ||
"go.uber.org/zap" | ||
) | ||
|
||
func TestCreateDefaultConfig(t *testing.T) { | ||
factory := Factory{} | ||
cfg := factory.CreateDefaultConfig() | ||
assert.NotNil(t, cfg, "failed to create default config") | ||
assert.NoError(t, configcheck.ValidateConfig(cfg)) | ||
} | ||
|
||
func TestCreateReceiver(t *testing.T) { | ||
factory := Factory{} | ||
cfg := factory.CreateDefaultConfig() | ||
|
||
tReceiver, err := factory.CreateTraceReceiver(context.Background(), zap.NewNop(), cfg, nil) | ||
assert.NoError(t, err, "receiver creation failed") | ||
assert.NotNil(t, tReceiver, "receiver creation failed") | ||
|
||
mReceiver, err := factory.CreateMetricsReceiver(zap.NewNop(), cfg, nil) | ||
assert.Equal(t, err, configerror.ErrDataTypeIsNotSupported) | ||
assert.Nil(t, mReceiver) | ||
} | ||
|
||
func TestCreateInvalidHTTPEndpoint(t *testing.T) { | ||
factory := Factory{} | ||
cfg := factory.CreateDefaultConfig() | ||
rCfg := cfg.(*Config) | ||
|
||
rCfg.Endpoint = "" | ||
_, err := factory.CreateTraceReceiver(context.Background(), zap.NewNop(), cfg, nil) | ||
assert.Error(t, err, "receiver creation with no endpoints must fail") | ||
} | ||
|
||
func TestCreateNoPort(t *testing.T) { | ||
factory := Factory{} | ||
cfg := factory.CreateDefaultConfig() | ||
rCfg := cfg.(*Config) | ||
|
||
rCfg.Endpoint = "localhost:" | ||
_, err := factory.CreateTraceReceiver(context.Background(), zap.NewNop(), cfg, nil) | ||
assert.Error(t, err, "receiver creation with no port number must fail") | ||
} | ||
|
||
func TestCreateLargePort(t *testing.T) { | ||
factory := Factory{} | ||
cfg := factory.CreateDefaultConfig() | ||
rCfg := cfg.(*Config) | ||
|
||
rCfg.Endpoint = "localhost:65536" | ||
_, err := factory.CreateTraceReceiver(context.Background(), zap.NewNop(), cfg, nil) | ||
assert.Error(t, err, "receiver creation with too large port number must fail") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module github.com/optelemetry-collector-contrib/receiver/sapmreceiver | ||
|
||
go 1.12 | ||
|
||
require ( | ||
cloud.google.com/go v0.49.0 // indirect | ||
github.com/census-instrumentation/opencensus-proto v0.2.1 | ||
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect | ||
github.com/golang/protobuf v1.3.2 | ||
github.com/google/go-cmp v0.3.1 | ||
github.com/gorilla/mux v1.7.3 | ||
github.com/jaegertracing/jaeger v1.15.1 | ||
github.com/jstemmer/go-junit-report v0.9.1 // indirect | ||
github.com/open-telemetry/opentelemetry-collector v0.2.1-0.20191205151336-8e2473c5e754 | ||
github.com/prometheus/client_model v0.0.0-20191202183732-d1d2010b5bee // indirect | ||
github.com/signalfx/sapm-proto v0.0.2 | ||
github.com/stretchr/testify v1.4.0 | ||
go.opencensus.io v0.22.2 | ||
go.uber.org/zap v1.13.0 | ||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd // indirect | ||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect | ||
golang.org/x/net v0.0.0-20191206103017-1ddd1de85cb0 // indirect | ||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 // indirect | ||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect | ||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e // indirect | ||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect | ||
golang.org/x/tools v0.0.0-20191205225056-3393d29bb9fe // indirect | ||
google.golang.org/appengine v1.6.5 // indirect | ||
google.golang.org/genproto v0.0.0-20191205163323-51378566eb59 // indirect | ||
google.golang.org/grpc v1.25.1 // indirect | ||
gopkg.in/yaml.v2 v2.2.7 // indirect | ||
) |
Oops, something went wrong.