In what format are you sending the configuration to the error reporting system? Maybe pass that to logging? Say, if it's json, then marshal the config before giving it to logging and then give logging the []byte
result only.
But in general, if two packages depend on each other directly what you can do is have one of them declare an interface that matches the other one's behaviour and then have a separate package pass the concrete instance as the interface.
For example:
/myapp/config
import "myapp/logging"
type Config struct {
// ...
}
func NewConfig() *Config {
// ...
if err != nil {
logging.LogError(err)
}
}
/myapp/logging
import "myapp/config"
func LogConfig(c *config.Config) {
// ...
}
func LogError(err error) {
// ...
}
So in this case you could declare an interface in the config package that matches the behaviour it needs from logging.
/myapp/config
type Logging interface {
LogError(error)
}
var logging Logging
func SetLogging(l Logging) {
logging = l
}
type Config struct {
// ...
}
func NewConfig() *Config {
// ...
if err != nil {
logging.LogError(err)
}
}
And then have a type in the logging package implement that interface by simply delegating to the original functions.
/myapp/logging
import "myapp/config"
func LogConfig(c *config.Config) {
// ...
}
func LogError(err error) {
// ...
}
type Logging struct{}
func (Logging) LogError(err error) {
LogError(err)
}
And lastly have a third package make it all work together.
/myapp
import "myapp/config"
import "myapp/logging"
func init() {
config.SetLogging(logging.Logging{})
}