Skip to content

Commit

Permalink
Added chrome logger middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
gravityblast committed Oct 1, 2013
1 parent 2461e85 commit 3e72fd1
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 0 deletions.
45 changes: 45 additions & 0 deletions data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package chromelogger

const VERSION = "0.1.0"

type LogData []interface{}

func (data *LogData) Add(item interface{}) {
*data = append(*data, item)
}

type LogRow []interface{}

func NewLogRow(logData *LogData, backtrace, logType string) *LogRow {
row := LogRow{
logData,
backtrace,
logType,
}

return &row
}

type Data struct {
Version string `json:"version"`
Columns []string `json:"columns"`
Rows []*LogRow `json:"rows"`
}

func (data *Data) AddRow(item interface{}, backtrace, logType string) {
logData := make(LogData, 0)
logData.Add(item)
row := NewLogRow(&logData, backtrace, logType)
data.Rows = append(data.Rows, row)
}

func NewData() *Data {
data := &Data{
Version: VERSION,
Columns: []string{"log", "backtrace", "type"},
}
data.Rows = make([]*LogRow, 0)

return data
}

32 changes: 32 additions & 0 deletions data_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package chromelogger

import(
"testing"
assert "github.com/pilu/miniassert"
)

func TestLogData_Add(t *testing.T) {
logData := make(LogData, 0)

assert.Equal(t, 0, len(logData))

logData.Add(1)
assert.Equal(t, 1, len(logData))
}

func TestNewLogRow(t *testing.T) {
logData := make(LogData, 0)
row := NewLogRow(&logData, "foo.go:100", "log")

assert.Equal(t, &logData, (*row)[0])
assert.Equal(t, "foo.go:100", (*row)[1])
assert.Equal(t, "log", (*row)[2])
}

func TestNewData(t *testing.T) {
data := NewData()

assert.Equal(t, VERSION, data.Version)
assert.Equal(t, []string{"log", "backtrace", "type"}, data.Columns)
assert.Equal(t, 0, len(data.Rows))
}
32 changes: 32 additions & 0 deletions example/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"log"
"fmt"
"net/http"
"github.com/pilu/traffic"
"github.com/pilu/chromelogger"
)

func rootHandler(w http.ResponseWriter, r *http.Request) {
chromelogger.Logger.Log("Hello")

chromelogger.Logger.Log(map[string]string{
"foo": "bar",
})

fmt.Fprint(w, "Hello World\n")
}

func main() {
router := traffic.New()
router.AddMiddleware(chromelogger.New())
router.Get("/", rootHandler)

http.Handle("/", router)
err := http.ListenAndServe(":7000", nil)

if err != nil {
log.Fatal(err)
}
}
64 changes: 64 additions & 0 deletions logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package chromelogger

import (
"fmt"
"strings"
"runtime"
"encoding/base64"
"encoding/json"
)

const LOG_TYPE_LOG = "log"
const LOG_TYPE_WARN = "warn"
const LOG_TYPE_ERROR = "error"
const LOG_TYPE_INFO = "info"

type chromeLogger struct {
data *Data
}

func (logger *chromeLogger) add(item interface{}, logType string) {
_, file, line, ok := runtime.Caller(2)
var backtrace string
if ok {
backtrace = fmt.Sprintf("%s:%d", file, line)
}

logger.data.AddRow(item, backtrace, logType)
}

func (logger *chromeLogger) Log(item interface{}) {
logger.add(item, LOG_TYPE_LOG)
}

func (logger *chromeLogger) Warn(item interface{}) {
logger.add(item, LOG_TYPE_WARN)
}

func (logger *chromeLogger) Error(item interface{}) {
logger.add(item, LOG_TYPE_ERROR)
}

func (logger *chromeLogger) Info(item interface{}) {
logger.add(item, LOG_TYPE_INFO)
}

func (logger chromeLogger) Export() string {
jsonBytes, err := json.Marshal(logger.data)
if err != nil {
return ""
}

encodedData := base64.StdEncoding.EncodeToString(jsonBytes)
finalData := strings.Replace(encodedData, "\n", "", -1)

return finalData
}

func newLogger() *chromeLogger {
logger := &chromeLogger{
data: NewData(),
}

return logger
}
58 changes: 58 additions & 0 deletions logger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package chromelogger

import (
"testing"
"path/filepath"
"strings"
assert "github.com/pilu/miniassert"
)

func TestLogger_Add(t *testing.T) {
logger := newLogger()

assert.Equal(t, 0, len(logger.data.Rows))

logger.add("foo", "log")
assert.Equal(t, 1, len(logger.data.Rows))
}

func TestLogger_Log(t *testing.T) {
logger := newLogger()

assert.Equal(t, 0, len(logger.data.Rows))

logger.Log("foo")
assert.Equal(t, 1, len(logger.data.Rows))

row := logger.data.Rows[0]
backtracePath := (*row)[1].(string)
backtraceFilenameAndLine := filepath.Base(backtracePath)
backtraceChunks := strings.Split(backtraceFilenameAndLine, ":")

assert.Equal(t, "logger_test.go", backtraceChunks[0])
assert.Equal(t, "log", (*row)[2])
}

func TestLogger_Warn(t *testing.T) {
logger := newLogger()

logger.Warn("foo")
row := logger.data.Rows[0]
assert.Equal(t, "warn", (*row)[2])
}

func TestLogger_Error(t *testing.T) {
logger := newLogger()

logger.Error("foo")
row := logger.data.Rows[0]
assert.Equal(t, "error", (*row)[2])
}

func TestLogger_Info(t *testing.T) {
logger := newLogger()

logger.Info("foo")
row := logger.data.Rows[0]
assert.Equal(t, "info", (*row)[2])
}
40 changes: 40 additions & 0 deletions middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package chromelogger

import (
"net/http"
"github.com/pilu/traffic"
)

type ChromeLoggerMiddleware struct {}

var Logger *chromeLogger

func (middleware ChromeLoggerMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next traffic.NextMiddlewareFunc) (http.ResponseWriter, *http.Request) {
Logger = newLogger()

flushed := false

flush := func() {
w.Header().Set("X-ChromeLogger-Data", Logger.Export())
flushed = true
}

arw := w.(*traffic.AppResponseWriter)
arw.AddBeforeWriteHandler(flush)

if nextMiddleware := next(); nextMiddleware != nil {
w, r = nextMiddleware.ServeHTTP(w, r, next)
}

if !flushed {
flush()
}

return w, r
}

func New() *ChromeLoggerMiddleware {
middleware := &ChromeLoggerMiddleware{}

return middleware
}

0 comments on commit 3e72fd1

Please sign in to comment.