opentelemetry-collector icon indicating copy to clipboard operation
opentelemetry-collector copied to clipboard

Config file builder for OpenTelemetry-Collector

Open mat-rumian opened this issue 4 years ago • 5 comments

I would like to suggest adding a builder for opentelemetry-collector configuration file for testing purposes. In current implementation https://github.com/open-telemetry/opentelemetry-collector/blob/master/testbed/tests/scenarios.go#L34 config file is generated based on the provided string. This can cause a lot of problems during tests development (one whitespace more can cause the otelcol crash). I could take care of it.

mat-rumian avatar Apr 07 '20 15:04 mat-rumian

I like the general idea. Can you elaborate a bit more to understand what you aim for?

tigrannajaryan avatar Apr 07 '20 16:04 tigrannajaryan

So I was thinking about creation of specific builder for YAML configs. Current implementation is very sensitive for any kind of human mistakes like whitespaces or invalid/not supported keywords. I was thinking about something like this:

package main

import (
	"fmt"

	"gopkg.in/yaml.v2"
)

type Jaeger struct {
	Protocols struct {
		Grpc struct {
			Endpoint string `yaml:"endpoint"`
		} `yaml:"grpc,omitempty"`
		ThriftHttp struct {
			Endpoint string `yaml:"endpoint"`
		} `yaml:"thrift_http,omitempty"`
	} `yaml:"protocols"`
}

type Opencensus struct {
	Endpoint string `yaml:"endpoint"`
}

type Receivers struct {
	Opencensus Opencensus 	`yaml:"opencensus,omitempty"`
	Jaeger Jaeger 			`yaml:"jaeger,omitempty"`
}
type Exporters struct {
}

type Config struct {
	Receivers Receivers `yaml:"receivers"`
	Exporters Exporters `yaml:"exporters"`
}

func (c *Config) addReceiver(receiverName string, receiverProtocol string, value string) {

	switch receiverName {
		case "opencensus":
			c.Receivers.Opencensus.Endpoint = value
		case "jaeger":
			switch receiverProtocol {
				case "grpc":
					c.Receivers.Jaeger.Protocols.Grpc.Endpoint = value
				case "thrift_http":
					c.Receivers.Jaeger.Protocols.ThriftHttp.Endpoint = value
			}
	}
}


func printYaml(config Config) {
	bytes, err := yaml.Marshal(config)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(bytes))
}
func main() {
	
	cfg := Config{}
	cfg.addReceiver("opencensus", "protocol", "localhost:1234")
	printYaml(cfg)

	cfg.addReceiver("jaeger", "grpc", "localhost:5555")
	printYaml(cfg)
}

It's just a general idea, but I think it should be simple and intuitive to use for end users. You can execute code by this link: https://play.golang.org/p/P1Xzz4eAND8

mat-rumian avatar Apr 08 '20 17:04 mat-rumian

@mat-rumian instead of declaring a new set of structs, one for each receiver or exporter type, can we reuse the Config structs that are alredy declared by each receiver and exporter?

tigrannajaryan avatar Apr 22 '20 19:04 tigrannajaryan

@tigrannajaryan I think each receiver and exporter config should be little bit tuned - e.g. zipkin-receiver - some kind of struct should be used there instead of raw text. I could take care of it.

mat-rumian avatar Apr 27 '20 11:04 mat-rumian

@mat-rumian I was referring to declarations in your proposal. For example you have

type Jaeger struct {

which declares configuration for Jaeger receiver. Instead of declaring this type can we use already existing Jaeger Config type?

tigrannajaryan avatar Apr 27 '20 22:04 tigrannajaryan

Config marshaling was added in https://github.com/open-telemetry/opentelemetry-collector/issues/5566. @mat-rumian please let us know if that solves your problem

dmitryax avatar Nov 12 '22 00:11 dmitryax