From 0620dcaa8854a5e6c5e1de1dd1451ebc8a0bcf15 Mon Sep 17 00:00:00 2001 From: Martin Geno Date: Tue, 13 Jun 2017 00:21:19 +0200 Subject: [PATCH] [DOC] improve godoc --- README.md | 2 +- api/recieve/main.go | 5 +++++ cmd/logmania/main.go | 15 +++++++++----- lib/config.go | 3 +++ lib/doc.go | 2 ++ lib/http.go | 31 ++++++++++++++++++++++++----- log/hook/client/main.go | 10 ++++++++++ log/hook/output/main.go | 7 +++++++ log/init.go | 4 ++++ log/level.go | 43 +++++++++++++++++++++++++++++++---------- log/logger.go | 2 ++ log/main.go | 10 ++++++++++ 12 files changed, 113 insertions(+), 21 deletions(-) create mode 100644 lib/doc.go diff --git a/README.md b/README.md index 476db79..7a9a8b8 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# logmania [![CircleCI](https://circleci.com/gh/genofire/logmania/tree/master.svg?style=shield)](https://circleci.com/gh/genofire/logmania/tree/master) +# logmania [![CircleCI](https://circleci.com/gh/genofire/logmania/tree/master.svg?style=shield)](https://circleci.com/gh/genofire/logmania/tree/master) [![Coverage Status](https://coveralls.io/repos/github/genofire/logmania/badge.svg?branch=master)](https://coveralls.io/github/genofire/logmania?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/genofire/logmania)](https://goreportcard.com/report/github.com/genofire/logmania) [![GoDoc](https://godoc.org/github.com/genofire/logmania?status.svg)](https://godoc.org/github.com/genofire/logmania) diff --git a/api/recieve/main.go b/api/recieve/main.go index 72940ab..0c31182 100644 --- a/api/recieve/main.go +++ b/api/recieve/main.go @@ -1,3 +1,4 @@ +// reciever of log entry over network (websocket) package recieve import ( @@ -9,16 +10,20 @@ import ( "github.com/gorilla/websocket" ) +// http.Handler for init network type Handler struct { + http.Handler upgrader websocket.Upgrader } +// init new Handler func NewHandler() *Handler { return &Handler{ upgrader: websocket.Upgrader{}, } } +// server response of handler func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { logEntry := log.HTTP(r) c, err := h.upgrader.Upgrade(w, r, nil) diff --git a/cmd/logmania/main.go b/cmd/logmania/main.go index 31ce7f1..1b28796 100644 --- a/cmd/logmania/main.go +++ b/cmd/logmania/main.go @@ -1,3 +1,12 @@ +// logmania Server +// +// reload config with SIGUSR1 +// +// Usage of logmania: +// -config string +// config file (default "logmania.conf") +// -debug +// enable debuging package main import ( @@ -78,11 +87,7 @@ func reload() { log.Errorf("reload: could not load '%s' for new configuration. Skip reload.", configPath) return } - if config.API.Bind != api.Addr { - api.ErrorNoPanic = true - api.Close() - api.Addr = config.API.Bind - api.Start() + if api.Rebind(config.API.Bind) { log.Info("reload: new api bind") } if database.ReplaceConnect(config.Database.Type, config.Database.Connect) { diff --git a/lib/config.go b/lib/config.go index 626d84c..c7e8961 100644 --- a/lib/config.go +++ b/lib/config.go @@ -7,6 +7,8 @@ import ( "github.com/genofire/logmania/log" ) +// Struct of the configuration +// e.g. under github.com/genofire/logmania/logmania_example.conf type Config struct { API struct { Bind string `toml:"bind"` @@ -35,6 +37,7 @@ type Config struct { } `toml:"webserver"` } +// read configuration from a file (use toml as file-format) func ReadConfig(path string) (*Config, error) { log.Debugf("load of configfile: %s", path) var config Config diff --git a/lib/doc.go b/lib/doc.go new file mode 100644 index 0000000..6876973 --- /dev/null +++ b/lib/doc.go @@ -0,0 +1,2 @@ +// some little goodies for logmania +package lib diff --git a/lib/http.go b/lib/http.go index 19ccac3..e248cdc 100644 --- a/lib/http.go +++ b/lib/http.go @@ -2,17 +2,21 @@ package lib import ( "net/http" + "sync" "github.com/genofire/logmania/log" ) +// little httpserver to handle reconnect and http.Handlers type HTTPServer struct { - srv *http.Server - ErrorNoPanic bool - Addr string - Handler http.Handler + srv *http.Server + Addr string + Handler http.Handler + errorNoPanic bool + errorNoPanicAsync sync.Mutex } +// start httpserver func (hs *HTTPServer) Start() { hs.srv = &http.Server{ Addr: hs.Addr, @@ -21,7 +25,7 @@ func (hs *HTTPServer) Start() { go func() { log.Debug("startup of http listener") if err := hs.srv.ListenAndServe(); err != nil { - if hs.ErrorNoPanic { + if hs.errorNoPanic { log.Debug("httpserver shutdown without panic") return } @@ -29,6 +33,23 @@ func (hs *HTTPServer) Start() { } }() } + +// rebind httpserver to a new address (e.g. new configuration) +func (hs *HTTPServer) Rebind(addr string) bool { + if addr == hs.Addr { + return false + } + hs.errorNoPanicAsync.Lock() + hs.errorNoPanic = true + hs.Close() + hs.Addr = addr + hs.Start() + hs.errorNoPanic = false + hs.errorNoPanicAsync.Unlock() + return true +} + +// close/stop current httpserver func (hs *HTTPServer) Close() { log.Debug("startup of http listener") hs.srv.Close() diff --git a/log/hook/client/main.go b/log/hook/client/main.go index 8dfeabe..c4f3e20 100644 --- a/log/hook/client/main.go +++ b/log/hook/client/main.go @@ -1,3 +1,4 @@ +// logger to bind at github.com/genofire/logmania/log.AddLogger to send log entries to logmania server package client import ( @@ -8,6 +9,7 @@ import ( "github.com/genofire/logmania/log" ) +// client logger type Logger struct { log.Logger AboveLevel log.LogLevel @@ -15,8 +17,10 @@ type Logger struct { closed bool } +// CurrentLogger (for override settings e.g. AboveLevel) var CurrentLogger *Logger +// create a new logmania client logger func NewLogger(url, token string, AboveLevel log.LogLevel) *Logger { c, _, err := websocket.DefaultDialer.Dial(fmt.Sprint(url, "/logger"), nil) if err != nil { @@ -34,6 +38,7 @@ func NewLogger(url, token string, AboveLevel log.LogLevel) *Logger { } } +// handle a log entry (send to logmania server) func (l *Logger) Hook(e *log.Entry) { if l.closed { return @@ -47,6 +52,8 @@ func (l *Logger) Hook(e *log.Entry) { l.Close() } } + +// Listen if logmania server want to close the connection func (l *Logger) Listen() { for { msgType, _, err := l.conn.ReadMessage() @@ -60,11 +67,14 @@ func (l *Logger) Listen() { } } } + +// close connection to logger func (l *Logger) Close() { l.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) l.closed = true } +// init logmania's client logger and bind func Init(url, token string, AboveLevel log.LogLevel) *Logger { CurrentLogger = NewLogger(url, token, AboveLevel) go CurrentLogger.Listen() diff --git a/log/hook/output/main.go b/log/hook/output/main.go index d3e30cb..494416d 100644 --- a/log/hook/output/main.go +++ b/log/hook/output/main.go @@ -1,3 +1,5 @@ +// logger to print log entry (with color) +// this logger would be bind by importing package output import ( @@ -16,6 +18,7 @@ var ( AboveLevel = log.InfoLevel ) +// logger for output type Logger struct { log.Logger TimeFormat string @@ -23,8 +26,10 @@ type Logger struct { AboveLevel log.LogLevel } +// CurrentLogger (for override settings e.g. AboveLevel,ShowTime or TimeFormat) var CurrentLogger *Logger +// create a new output logger func NewLogger() *Logger { return &Logger{ TimeFormat: "2006-01-02 15:04:05", @@ -33,6 +38,7 @@ func NewLogger() *Logger { } } +// handle a log entry (print it on the terminal with color) func (l *Logger) Hook(e *log.Entry) { if e.Level < AboveLevel { return @@ -76,6 +82,7 @@ func (l *Logger) Hook(e *log.Entry) { } } +// do nothing - terminal did not need something to close func (l *Logger) Close() { } diff --git a/log/init.go b/log/init.go index 6065935..2358e40 100644 --- a/log/init.go +++ b/log/init.go @@ -15,6 +15,7 @@ func getIP(r *http.Request) string { return ip } +// init log entry with extra fields of interesting http request context func HTTP(r *http.Request) *Entry { return New().AddFields(map[string]interface{}{ "remote": getIP(r), @@ -23,6 +24,7 @@ func HTTP(r *http.Request) *Entry { }) } +// init log entry with extra fields of interesting websocket request context func WebsocketX(ws *websocket.Conn) *Entry { r := ws.Request() return New().AddFields(map[string]interface{}{ @@ -31,6 +33,8 @@ func WebsocketX(ws *websocket.Conn) *Entry { "url": r.URL.RequestURI(), }) } + +// init log entry with extra fields of interesting websocket request context func WebsocketGozilla(ws *wsGozilla.Conn) *Entry { return New().AddFields(map[string]interface{}{ "remote": ws.RemoteAddr().String(), diff --git a/log/level.go b/log/level.go index c067226..3a036ce 100644 --- a/log/level.go +++ b/log/level.go @@ -1,7 +1,9 @@ package log +// definition of loglevel type LogLevel int32 +// accepted LogLevels and his internal int values const ( DebugLevel = LogLevel(-1) InfoLevel = LogLevel(0) @@ -10,6 +12,7 @@ const ( PanicLevel = LogLevel(3) ) +// string of loglevel func (l LogLevel) String() string { switch l { case DebugLevel: @@ -31,42 +34,52 @@ func (l LogLevel) String() string { * log command */ -// debug +// close logentry with debug func (e *Entry) Debug(v ...interface{}) { e.Log(DebugLevel, v...) } + +// close logentry with formated debug func (e *Entry) Debugf(format string, v ...interface{}) { e.Logf(DebugLevel, format, v...) } -// info +// close logentry with info func (e *Entry) Info(v ...interface{}) { e.Log(InfoLevel, v...) } + +// close logentry with formated info func (e *Entry) Infof(format string, v ...interface{}) { e.Logf(InfoLevel, format, v...) } -// warn +// close logentry with warning func (e *Entry) Warn(v ...interface{}) { e.Log(WarnLevel, v...) } + +// close logentry with formated warning func (e *Entry) Warnf(format string, v ...interface{}) { e.Logf(WarnLevel, format, v...) } -// error +// close logentry with error func (e *Entry) Error(v ...interface{}) { e.Log(ErrorLevel, v...) } + +// close logentry with formated error func (e *Entry) Errorf(format string, v ...interface{}) { e.Logf(ErrorLevel, format, v...) } -// panic +// close logentry with panic func (e *Entry) Panic(v ...interface{}) { e.Log(PanicLevel, v...) } + +// close logentry with formated panic func (e *Entry) Panicf(format string, v ...interface{}) { e.Logf(PanicLevel, format, v...) } @@ -75,42 +88,52 @@ func (e *Entry) Panicf(format string, v ...interface{}) { * Direct log command */ -// debug +// direct log with debug func Debug(v ...interface{}) { New().Log(DebugLevel, v...) } + +// direct log with formated debug func Debugf(format string, v ...interface{}) { New().Logf(DebugLevel, format, v...) } -// info +// direct log with info func Info(v ...interface{}) { New().Log(InfoLevel, v...) } + +// direct log with formated info func Infof(format string, v ...interface{}) { New().Logf(InfoLevel, format, v...) } -// warn +// direct log with warning func Warn(v ...interface{}) { New().Log(WarnLevel, v...) } + +// direct log with formated warning func Warnf(format string, v ...interface{}) { New().Logf(WarnLevel, format, v...) } -// error +// direct log with error func Error(v ...interface{}) { New().Log(ErrorLevel, v...) } + +// direct log with formated error func Errorf(format string, v ...interface{}) { New().Logf(ErrorLevel, format, v...) } -// panic +// direct log with panic func Panic(v ...interface{}) { New().Log(PanicLevel, v...) } + +// direct log with formated panic func Panicf(format string, v ...interface{}) { New().Logf(PanicLevel, format, v...) } diff --git a/log/logger.go b/log/logger.go index b27939f..e5609bc 100644 --- a/log/logger.go +++ b/log/logger.go @@ -1,5 +1,6 @@ package log +// interface of a logger type Logger interface { Hook(*Entry) Close() @@ -7,6 +8,7 @@ type Logger interface { var loggers = make([]Logger, 0) +// bind logger to handle saving/output of a Log entry func AddLogger(logger Logger) { loggers = append(loggers, logger) } diff --git a/log/main.go b/log/main.go index 61756ab..ab6b14f 100644 --- a/log/main.go +++ b/log/main.go @@ -1,32 +1,41 @@ +// log package with entry as a lib in other go applications package log import "fmt" +// a struct with all information of a log entry type Entry struct { Level LogLevel `json:"level"` Fields map[string]interface{} `json:"fields"` Text string `json:"text"` } +// save/out current state of log entry func (e *Entry) Log(level LogLevel, v ...interface{}) { e.Text = fmt.Sprint(v...) e.Level = level save(e) } + +// save/out current state of log entry with formation func (e *Entry) Logf(level LogLevel, format string, v ...interface{}) { e.Text = fmt.Sprintf(format, v...) e.Level = level save(e) } +// init new log entry func New() *Entry { return &Entry{Fields: make(map[string]interface{})} } +// add extra value to entry (log entry with context) func (e *Entry) AddField(key string, value interface{}) *Entry { e.Fields[key] = value return e } + +// add multi extra values to entry (log entry with context) func (e *Entry) AddFields(fields map[string]interface{}) *Entry { for key, value := range fields { e.Fields[key] = value @@ -34,6 +43,7 @@ func (e *Entry) AddFields(fields map[string]interface{}) *Entry { return e } +// create a readable string of extra values (log entry with context) func (e *Entry) FieldString() string { text := "" for key, value := range e.Fields {