Add support for tracing via OpenCencus

This adds a few flags for configuring the tracer.
Includes support for jaeger tracing (built into OC).
This commit is contained in:
Brian Goff
2018-09-19 18:01:39 -07:00
parent 43d32d2301
commit 682b2bccf8
139 changed files with 19834 additions and 42 deletions

View File

@@ -33,6 +33,7 @@ import (
"github.com/virtual-kubelet/virtual-kubelet/providers"
"github.com/virtual-kubelet/virtual-kubelet/providers/register"
vkubelet "github.com/virtual-kubelet/virtual-kubelet/vkubelet"
"go.opencensus.io/trace"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
)
@@ -58,6 +59,10 @@ var p providers.Provider
var rm *manager.ResourceManager
var apiConfig vkubelet.APIConfig
var userTraceExporters []string
var userTraceConfig = TracingExporterOptions{Tags: make(map[string]string)}
var traceSampler string
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: "virtual-kubelet",
@@ -94,6 +99,38 @@ func Execute() {
}
}
type mapVar map[string]string
func (mv mapVar) String() string {
var s string
for k, v := range mv {
if s == "" {
s = fmt.Sprintf("%s=%v", k, v)
} else {
s += fmt.Sprintf(", %s=%v", k, v)
}
}
return s
}
func (mv mapVar) Set(s string) error {
split := strings.SplitN(s, "=", 2)
if len(split) != 2 {
return errors.Errorf("invalid format, must be `key=value`: %s", s)
}
_, ok := mv[split[0]]
if ok {
return errors.Errorf("duplicate key: %s", split[0])
}
mv[split[0]] = split[1]
return nil
}
func (mv mapVar) Type() string {
return "map"
}
func init() {
cobra.OnInitialize(initConfig)
@@ -120,6 +157,11 @@ func init() {
RootCmd.PersistentFlags().MarkDeprecated("taint", "Taint key should now be configured using the VK_TAINT_KEY environment variable")
RootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", `set the log level, e.g. "trace", debug", "info", "warn", "error"`)
RootCmd.PersistentFlags().StringSliceVar(&userTraceExporters, "trace-exporter", nil, fmt.Sprintf("sets the tracing exporter to use, available exporters: %s", AvailableTraceExporters()))
RootCmd.PersistentFlags().StringVar(&userTraceConfig.ServiceName, "trace-service-name", "virtual-kubelet", "sets the name of the service used to register with the trace exporter")
RootCmd.PersistentFlags().Var(mapVar(userTraceConfig.Tags), "trace-tag", "add tags to include with traces in key=value form")
RootCmd.PersistentFlags().StringVar(&traceSampler, "trace-sample-rate", "", "set probability of tracing samples")
// Cobra also supports local flags, which will only run
// when this action is called directly.
// RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
@@ -223,6 +265,49 @@ func initConfig() {
if err != nil {
logger.WithError(err).Fatal("Error reading API config")
}
for k := range userTraceConfig.Tags {
if reservedTagNames[k] {
logger.WithField("tag", k).Fatal("must not use a reserved tag key")
}
}
userTraceConfig.Tags["operatingSystem"] = operatingSystem
userTraceConfig.Tags["provider"] = provider
userTraceConfig.Tags["nodeName"] = nodeName
for _, e := range userTraceExporters {
exporter, err := GetTracingExporter(e, userTraceConfig)
if err != nil {
log.L.WithError(err).WithField("exporter", e).Fatal("Cannot initialize exporter")
}
trace.RegisterExporter(exporter)
}
if len(userTraceExporters) > 0 {
var s trace.Sampler
switch strings.ToLower(traceSampler) {
case "":
case "always":
s = trace.AlwaysSample()
case "never":
s = trace.NeverSample()
default:
rate, err := strconv.Atoi(traceSampler)
if err != nil {
logger.WithError(err).WithField("rate", traceSampler).Fatal("unsupported trace sample rate, supported values: always, never, or number 0-100")
}
if rate < 0 || rate > 100 {
logger.WithField("rate", traceSampler).Fatal("trace sample rate must not be less than zero or greater than 100")
}
s = trace.ProbabilitySampler(float64(rate) / 100)
}
if s != nil {
trace.ApplyConfig(
trace.Config{
DefaultSampler: s,
},
)
}
}
}
func getAPIConfig() (vkubelet.APIConfig, error) {