[DOC] improve godoc
This commit is contained in:
parent
b8ff3e5842
commit
0620dcaa88
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
// some little goodies for logmania
|
||||
package lib
|
31
lib/http.go
31
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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
43
log/level.go
43
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...)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
10
log/main.go
10
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 {
|
||||
|
|
Loading…
Reference in New Issue