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.
Introduction to Envoy
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 found its performance satisfying and appreciated the functionality it provided when integrated into our control plane at Greymatter.io. However, the more I familiarized myself with the code, the more I wanted to improve it and give back to the community. After all, a change made upstream benefits everyone, so why patch logic in a closed source implementation and keep the improvements 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{})
}
Digging Deeper into the Control Plane
As you can imagine, you’re quite limited with 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 suppress that, we moved their Info level to our Debug level to reduce Info level log pollution. We pass this logger 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…)
}
Beyond Control
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!