[DOC] improve godoc

This commit is contained in:
Martin Geno 2017-06-13 00:21:19 +02:00
parent b8ff3e5842
commit 0620dcaa88
No known key found for this signature in database
GPG Key ID: F0D39A37E925E941
12 changed files with 113 additions and 21 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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) {

View File

@ -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

2
lib/doc.go Normal file
View File

@ -0,0 +1,2 @@
// some little goodies for logmania
package lib

View File

@ -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()

View File

@ -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()

View File

@ -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() {
}

View File

@ -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(),

View File

@ -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...)
}

View File

@ -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)
}

View File

@ -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 {