A simple HTTP request/response logger for Go supporting multiple formatters.
We needed a way to log HTTP requests at Zendesk to different log backends (stdout, syslog etc.) with multiple ways to format them (including logstash). So we created this project to help us.
You'll need to create some sort of logger that conforms to the LogDestination
interface in this package. The go-logger package is recommended.
package main
import (
"fmt"
"github.com/op/go-logging"
"github.com/zendesk/go-httpclerk"
stdlog "log"
"net/http"
"os"
)
var log = logging.MustGetLogger("myApp")
func main() {
// Setup a go-logging logger
stdoutBackend := logging.NewLogBackend(os.Stderr, "", stdlog.LstdFlags|stdlog.Lshortfile)
logging.SetBackend(stdoutBackend) // See go-logging docs for multiple backends
logging.SetLevel(logging.DEBUG, "myApp")
// Boot web server and listen on 8080
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
formatter, _ := httpclerk.NewTextFormatter("myHandler")
clerk, err := httpclerk.NewHTTPLogger("myHandler", log, formatter)
if err != nil {
log.Fatal("HTTP logger could not be created", err)
}
defer clerk.Info(w, r)
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
This will produce logs like so:
2014/07/27 07:43:56 http_logger.go:39: myHandler 1974-carcher.local > Method: GET Path: /ciaran Status: Host: localhost:8080 Headers: map[User-Agent:[curl/7.30.0] Accept:[*/*]]
You'll notice that the Status
is blank. This is becuase there is no simple way to get the response status in a HTTP handler without wrapping the ResponseWriter
type. You can see an example of this here. If you do this, and use this type instead of the standard ResponseWriter
then the go-httpclerk
package can fetch the status code and include it in logging:
2014/07/27 07:43:56 http_logger.go:39: myHandler 1974-carcher.local > Method: GET Path: /ciaran Status: 200 Host: localhost:8080 Headers: map[User-Agent:[curl/7.30.0] Accept:[*/*]]
Included in the package is a TextFormatter
(examples above use this) and a LogStashFormatter
for JSON logging
formatter, _ := NewLogStashFormatter("fooApp", []string{"blimp", "foo"})
Other loggers can be used in place if they implement the the following interface:
type Formatter interface {
Format(interface{}) (string, error)
}
Create a Pull Request with your changes, ping someone and we'll look at getting it merged.
Copyright 2013 Zendesk
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.