This is a creation in Article, where the information may have evolved or changed.
This post was a spin-off from various conversations around improving (I ' m trying not to say standardising, otherwise I ' ll h Ave to link to XKCD) the "logging is performed" in Go projects.
Consider this familiar pattern for establishing a package level log variable.
Package Fooimport "MyLogger" var log = MyLogger. GetLogger ("Github.com/project/foo")
What's wrong with this pattern?
The first problem with declaring a package level log variable are the tight coupling between package and package foo . Package now depends directly in package at foo mylogger compile time .
The second problem is the tight coupling between package and it is foo mylogger transitive. Any of the consumes package is foo itself dependant on at mylogger compile time.
This leads to a third problem, Go projects composed of packages using multiple logging
libraries, or fiefdoms of projects who can is only consume packages this use their particular logging library.
Avoid Source Level coupling
The solution to this anti pattern was to delay the binding between the type that does the logging, and the type that needs To log, until it is needed. That's, until the variable is declared.
Package Fooimport "Github.com/pkg/log" type T struct { logger log. Logger //other fields}
Now, the consumer of type T supplies a value of type when log.Logger constructing new T ' s, and the methods on T US E The logger they were provided when they want to log.
Interfaces to the rescue
The Eagle eyed Reader would note that the previous selection removed the "level log variable" but the coupling bet Ween Package and package foo log remains.
However, this can is remedied by the consumer of the logger type declaring its own interface for the behaviour it expects.
Package Footype Logger Interface { Printf (string, ... interface{})}type T struct { logger //other fields}
As long as the type assigned to foo.T.logger implements the foo.logger decision for which specific type to use can is deferred until Ru n time in the same-the-escapes any knowledge of the and implementations in use io.Copy io.Reader io.Writer until it is invoked.
It ' s not just logging
Logging is a cross cutting concern, but the anti patterns associated with it also apply to other common areas like metrics , telemetry, and auditing.
Get involved
The Go 1.9 Development window is opening next month. If This topic are important to you, get involved.
Related Posts:
- Term:low level serial with a high level interface
- Stack traces and the errors package
- how To include C code in your Go package
- Profiling package moved, updated