[improvement/log-levels] Add support set log levels (#301)

This commit is contained in:
Edwar Baron 2020-06-06 10:54:27 -05:00 committed by GitHub
parent 1e25061e54
commit f4d553bd37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 10 deletions

View File

@ -219,7 +219,7 @@ Assuming that you want to provide a high availability to deal efficiently with,
|==============|
| Balancer |
|==============|
| |
| |
/ \
/ \
/ \
@ -305,7 +305,7 @@ Options:
-forward-headers Forwards custom headers to the image source server. -enable-url-source flag must be defined.
-enable-url-signature Enable URL signature (URL-safe Base64-encoded HMAC digest) [default: false]
-url-signature-key The URL signature key (32 characters minimum)
-allowed-origins <urls> Restrict remote image source processing to certain origins (separated by commas). Note: Origins are validated against host *AND* path.
-allowed-origins <urls> Restrict remote image source processing to certain origins (separated by commas). Note: Origins are validated against host *AND* path.
-max-allowed-size <bytes> Restrict maximum size of http image source (in bytes)
-certfile <path> TLS certificate file path
-keyfile <path> TLS private key file path
@ -316,6 +316,8 @@ Options:
-mrelease <num> OS memory release interval in seconds [default: 30]
-cpus <num> Number of used cpu cores.
(default for current machine is 8 cores)
-log-level Set log level for http-server. E.g: info,warning,error [default: info].
Or can use the environment variable GOLANG_LOG=info.
```
Start the server in a custom port:
@ -404,6 +406,11 @@ Or filter debug output by package:
DEBUG=imaginary imaginary -p 8080
```
Disable info logs:
```
GOLANG_LOG=error imaginary -p 8080
```
#### Examples
Reading a local image (you must pass the `-mount=<directory>` flag):

View File

@ -49,6 +49,7 @@ var (
aBurst = flag.Int("burst", 100, "Throttle burst max cache size")
aMRelease = flag.Int("mrelease", 30, "OS memory release interval in seconds")
aCpus = flag.Int("cpus", runtime.GOMAXPROCS(-1), "Number of cpu cores to use")
aLogLevel = flag.String("log-level", "info", "Define log level for http-server. E.g: info,warning,error")
)
const usage = `imaginary %s
@ -71,6 +72,7 @@ Usage:
imaginary -v | -version
Options:
-a <addr> Bind address [default: *]
-p <port> Bind port [default: 8088]
-h, -help Show help
@ -102,6 +104,8 @@ Options:
-mrelease <num> OS memory release interval in seconds [default: 30]
-cpus <num> Number of used cpu cores.
(default for current machine is %d cores)
-log-level Set log level for http-server. E.g: info,warning,error [default: info].
Or can use the environment variable GOLANG_LOG=info.
`
type URLSignature struct {
@ -152,6 +156,7 @@ func main() {
ForwardHeaders: parseForwardHeaders(*aForwardHeaders),
AllowedOrigins: parseOrigins(*aAllowedOrigins),
MaxAllowedSize: *aMaxAllowedSize,
LogLevel: getLogLevel(*aLogLevel),
}
// Show warning if gzip flag is passed
@ -238,6 +243,13 @@ func getURLSignature(key string) URLSignature {
return URLSignature{key}
}
func getLogLevel(logLevel string) string {
if logLevelEnv := os.Getenv("GOLANG_LOG"); logLevelEnv != "" {
logLevel = logLevelEnv
}
return logLevel
}
func showUsage() {
flag.Usage()
os.Exit(1)

22
log.go
View File

@ -44,13 +44,14 @@ func (r *LogRecord) WriteHeader(status int) {
// LogHandler maps the HTTP handler with a custom io.Writer compatible stream
type LogHandler struct {
handler http.Handler
io io.Writer
handler http.Handler
io io.Writer
logLevel string
}
// NewLog creates a new logger
func NewLog(handler http.Handler, io io.Writer) http.Handler {
return &LogHandler{handler, io}
func NewLog(handler http.Handler, io io.Writer, logLevel string) http.Handler {
return &LogHandler{handler, io, logLevel}
}
// Implements the required method as standard HTTP handler, serving the request.
@ -78,5 +79,16 @@ func (h *LogHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
record.time = finishTime.UTC()
record.elapsedTime = finishTime.Sub(startTime)
record.Log(h.io)
switch h.logLevel{
case "error":
if record.status >= http.StatusInternalServerError {
record.Log(h.io)
}
case "warning":
if record.status >= http.StatusBadRequest {
record.Log(h.io)
}
case "info":
record.Log(h.io)
}
}

View File

@ -13,7 +13,7 @@ func (fake fakeWriter) Write(buf []byte) (int, error) {
return fake(buf)
}
func TestLog(t *testing.T) {
func TestLogInfo(t *testing.T) {
var buf []byte
writer := fakeWriter(func(b []byte) (int, error) {
buf = b
@ -21,7 +21,7 @@ func TestLog(t *testing.T) {
})
noopHandler := func(w http.ResponseWriter, r *http.Request) {}
log := NewLog(http.HandlerFunc(noopHandler), writer)
log := NewLog(http.HandlerFunc(noopHandler), writer, "info")
ts := httptest.NewServer(log)
defer ts.Close()
@ -38,3 +38,27 @@ func TestLog(t *testing.T) {
t.Fatalf("Invalid log output: %s", data)
}
}
func TestLogError(t *testing.T) {
var buf []byte
writer := fakeWriter(func(b []byte) (int, error) {
buf = b
return 0, nil
})
noopHandler := func(w http.ResponseWriter, r *http.Request) {}
log := NewLog(http.HandlerFunc(noopHandler), writer, "error")
ts := httptest.NewServer(log)
defer ts.Close()
_, err := http.Get(ts.URL)
if err != nil {
t.Fatal(err)
}
data := string(buf)
if data != "" {
t.Fatalf("Invalid log output: %s", data)
}
}

View File

@ -38,6 +38,7 @@ type ServerOptions struct {
PlaceholderImage []byte
Endpoints Endpoints
AllowedOrigins []*url.URL
LogLevel string
}
// Endpoints represents a list of endpoint names to disable.
@ -57,7 +58,7 @@ func (e Endpoints) IsValid(r *http.Request) bool {
func Server(o ServerOptions) error {
addr := o.Address + ":" + strconv.Itoa(o.Port)
handler := NewLog(NewServerMux(o), os.Stdout)
handler := NewLog(NewServerMux(o), os.Stdout, o.LogLevel)
server := &http.Server{
Addr: addr,