blog

Giving Back to Envoy’s Control Plane

Contributing back to the Envoy go-control-plane.



Editor’s note: The following blog post is part of a series of reflections and observations made by individual Greymatter.io team members while conducting research and development in support of the Envoy Proxy open source community.

I’ve been using Envoy for quite a while now, since v1 of the xDS APIs. Recently I was able to contribute back to their go-control-plane repository which, if you’re not familiar, is their open-source implementation of a control plane that adheres to their predefined xDS discovery spec.

As an active user of this repository, I was quite satisfied with how it performed, as well as the functionality it gave to me as an end-user when bringing it into our own control plane at Greymatter.io. But the more I became familiar with the code the more I wanted to improve it and give back to the community. After all, a change made upstream is a change inherited by everyone, so why patch logic in your closed source implementation and hold the goods to yourself!

One thing my co-worker and I noted when we first brought the project in was an overload of logging in the console from go-control-plane. There weren’t any levels so we couldn’t apply our own logging mechanism without having to overload go-control-planes exposed interface. Originally, something like this existed:

// Logger interface for reporting informational and warning messages.
type Logger interface {
// Infof logs a formatted informational message.
Infof(format string, args ...interface{})
// Errorf logs a formatted error message.
Errorf(format string, args ...interface{})
}

As you could imagine, you’re pretty limited by just Info and Error levels. We had to overload our Info level to hold our debug messages which got messy rather quickly:

type consoleLogger struct{}

func (consoleLogger) Infof(format string, args ...interface{}) {
// the go-control-plane repo over-utilizes the Info log level causing our xDS logs to become polluted with RPC log statements. To supress that we moved their info level to our debug level to reduce the Info level log pollution .This logger is passed into the snapshot cache package as it implements their logger interface
console.Debug().Printf(format, args...)
}

func (consoleLogger) Debugf(format string, args ...interface{}) {
console.Debug().Printf(format, args...)
}

func (consoleLogger) Errorf(format string, args ...interface{}) {
console.Error().Printf(format, args...)
}

So instead of dealing with this patch locally, I took it upstream and implemented a change that will benefit everyone with better logs and easier debugging:

// Logger interface for reporting informational and warning messages.
type Logger interface {
// Debugf logs a formatted debugging message.
Debugf(format string, args ...interface{})
// Infof logs a formatted informational message.
Infof(format string, args ...interface{})
// Warnf logs a formatted warning message.
Warnf(format string, args ...interface{})
// Errorf logs a formatted error message.
Errorf(format string, args ...interface{})
}

Though it was a simple contribution back to the open-source, I was excited to finally get involved in the community and provide some logic that everyone across the go-control-plane and envoy user base can benefit from. Happy debugging!

Read Next Post