mirror of
https://github.com/raz-varren/sacrificial-socket.git
synced 2024-08-05 10:58:36 +08:00
moved log into it's own repository
This commit is contained in:
parent
d1e27b73ef
commit
d12965af3a
4
LICENSE
4
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) [2017] [raz-varren]
|
||||
Copyright (c) [2018] [raz-varren]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
|
@ -1,4 +1,4 @@
|
||||
Sacrificial-Socket
|
||||
Sacrificial-Socket [![GoDoc](https://godoc.org/github.com/raz-varren/sacrificial-socket?status.svg)](https://godoc.org/github.com/raz-varren/sacrificial-socket)
|
||||
==================
|
||||
|
||||
A Go server library and pure JS client library for managing communication between websockets, that has an API similar to Socket.IO, but feels less... well, *Javascripty*. Socket.IO is great, but nowadays all modern browsers support websockets natively, so in most cases there is no need to have websocket simulation fallbacks like XHR long polling or Flash. Removing these allows Sacrificial-Socket to be lightweight and very performant.
|
||||
@ -7,7 +7,7 @@ Sacrificial-Socket supports rooms, roomcasts, broadcasts, and event emitting jus
|
||||
|
||||
Sacrificial-Socket also has a MultihomeBackend interface for syncronizing broadcasts and roomcasts across multiple instances of Sacrificial-Socket running on multiple machines. Out of the box Sacrificial-Socket provides a MultihomeBackend interface for the popular noSQL database MongoDB, one for the moderately popular key/value storage engine Redis, and one for the not so popular GRPC protocol, for syncronizing instances on multiple machines.
|
||||
|
||||
In depth examples can be found in the [__examples__ ](https://github.com/raz-varren/sacrificial-socket/tree/master/examples "Examples") directory and full documentation can be found here: [![GoDoc](https://godoc.org/github.com/raz-varren/sacrificial-socket?status.svg)](https://godoc.org/github.com/raz-varren/sacrificial-socket)
|
||||
In depth examples can be found in the [__examples__ ](https://github.com/raz-varren/sacrificial-socket/tree/master/examples "Examples") directory.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
@ -3,7 +3,7 @@ package ssdummy
|
||||
|
||||
import (
|
||||
ss "github.com/raz-varren/sacrificial-socket"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -2,7 +2,7 @@ package ssgrpc
|
||||
|
||||
import (
|
||||
"github.com/raz-varren/sacrificial-socket/backend/ssgrpc/token"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"golang.org/x/net/context"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
ss "github.com/raz-varren/sacrificial-socket"
|
||||
"github.com/raz-varren/sacrificial-socket/backend/ssgrpc/token"
|
||||
"github.com/raz-varren/sacrificial-socket/backend/ssgrpc/transport"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"strings"
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"encoding/json"
|
||||
ss "github.com/raz-varren/sacrificial-socket"
|
||||
"github.com/raz-varren/sacrificial-socket/backend/ssgrpc/transport"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
@ -6,7 +6,7 @@ package ssmongo
|
||||
import (
|
||||
"encoding/json"
|
||||
ss "github.com/raz-varren/sacrificial-socket"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"gopkg.in/mgo.v2"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"io"
|
||||
|
@ -6,7 +6,7 @@ package ssredis
|
||||
import (
|
||||
"github.com/go-redis/redis"
|
||||
ss "github.com/raz-varren/sacrificial-socket"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"github.com/raz-varren/sacrificial-socket/tools"
|
||||
)
|
||||
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"flag"
|
||||
"github.com/raz-varren/sacrificial-socket"
|
||||
"github.com/raz-varren/sacrificial-socket/backend/ssgrpc"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/go-redis/redis"
|
||||
"github.com/raz-varren/sacrificial-socket"
|
||||
"github.com/raz-varren/sacrificial-socket/backend/ssredis"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
ss "github.com/raz-varren/sacrificial-socket"
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
154
log/json.go
154
log/json.go
@ -1,154 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
//JLog is the json structure used to output logs created by NewJSONLogger
|
||||
type JLog struct {
|
||||
Timestamp time.Time `json:"ts"`
|
||||
File string `json:"file"`
|
||||
Line int `json:"line"`
|
||||
Level string `json:"level"`
|
||||
Fatal bool `json:"fatal"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
func (jl *JLog) Marshal() []byte {
|
||||
data, err := json.Marshal(jl)
|
||||
if err != nil {
|
||||
return []byte(fmt.Sprintf(`{"Error":"%s", "Line": %d, "File":"%s"}`, err, jl.Line, jl.File))
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
type jsonLogFmt struct {
|
||||
out io.Writer
|
||||
logLevel int
|
||||
logLevelAllowed int
|
||||
}
|
||||
|
||||
func (j *jsonLogFmt) canLog() bool {
|
||||
return (j.logLevel & j.logLevelAllowed) == j.logLevelAllowed
|
||||
}
|
||||
|
||||
func (j *jsonLogFmt) writeJLog(msg string, fatal bool) {
|
||||
jl := newJLog(msg, LogLevelMap[j.logLevelAllowed], fatal, 3)
|
||||
data := jl.Marshal()
|
||||
j.out.Write(append(data, '\n'))
|
||||
}
|
||||
|
||||
func newJLog(msg, level string, fatal bool, callDepth int) *JLog {
|
||||
jl := &JLog{
|
||||
Timestamp: time.Now(),
|
||||
Level: level,
|
||||
Fatal: fatal,
|
||||
Msg: msg,
|
||||
}
|
||||
_, file, line, ok := runtime.Caller(callDepth)
|
||||
|
||||
jl.File = file
|
||||
jl.Line = line
|
||||
|
||||
if !ok {
|
||||
jl.File = "???"
|
||||
jl.Line = -1
|
||||
}
|
||||
|
||||
return jl
|
||||
}
|
||||
|
||||
func (j *jsonLogFmt) Print(v ...interface{}) {
|
||||
if !j.canLog() {
|
||||
return
|
||||
}
|
||||
msg, fatal := fmt.Sprint(v...), false
|
||||
msg = strings.TrimRight(msg, "\n")
|
||||
j.writeJLog(msg, fatal)
|
||||
}
|
||||
|
||||
func (j *jsonLogFmt) Printf(format string, v ...interface{}) {
|
||||
if !j.canLog() {
|
||||
return
|
||||
}
|
||||
|
||||
msg, fatal := fmt.Sprintf(format, v...), false
|
||||
msg = strings.TrimRight(msg, "\n")
|
||||
|
||||
j.writeJLog(msg, fatal)
|
||||
}
|
||||
|
||||
func (j *jsonLogFmt) Println(v ...interface{}) {
|
||||
if !j.canLog() {
|
||||
return
|
||||
}
|
||||
|
||||
msg, fatal := fmt.Sprintln(v...), false
|
||||
msg = strings.TrimRight(msg, "\n")
|
||||
|
||||
j.writeJLog(msg, fatal)
|
||||
}
|
||||
|
||||
func (j *jsonLogFmt) Fatal(v ...interface{}) {
|
||||
msg, fatal := fmt.Sprint(v...), true
|
||||
msg = strings.TrimRight(msg, "\n")
|
||||
|
||||
j.writeJLog(msg, fatal)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (j *jsonLogFmt) Fatalf(format string, v ...interface{}) {
|
||||
msg, fatal := fmt.Sprintf(format, v...), true
|
||||
msg = strings.TrimRight(msg, "\n")
|
||||
|
||||
j.writeJLog(msg, fatal)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (j *jsonLogFmt) Fatalln(v ...interface{}) {
|
||||
msg, fatal := fmt.Sprintln(v...), true
|
||||
msg = strings.TrimRight(msg, "\n")
|
||||
|
||||
j.writeJLog(msg, fatal)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
//NewJSONLogger creates a *Logger that outputs a single json object for each log in the marshaled format of JLog.
|
||||
func NewJSONLogger(out io.Writer, logLevel int) *Logger {
|
||||
info := &jsonLogFmt{
|
||||
out: out,
|
||||
logLevel: logLevel,
|
||||
logLevelAllowed: LogLevelINFO,
|
||||
}
|
||||
|
||||
warn := &jsonLogFmt{
|
||||
out: out,
|
||||
logLevel: logLevel,
|
||||
logLevelAllowed: LogLevelWARN,
|
||||
}
|
||||
|
||||
err := &jsonLogFmt{
|
||||
out: out,
|
||||
logLevel: logLevel,
|
||||
logLevelAllowed: LogLevelERR,
|
||||
}
|
||||
|
||||
debug := &jsonLogFmt{
|
||||
out: out,
|
||||
logLevel: logLevel,
|
||||
logLevelAllowed: LogLevelDEBUG,
|
||||
}
|
||||
|
||||
return &Logger{
|
||||
Info: info,
|
||||
Warn: warn,
|
||||
Err: err,
|
||||
Debug: debug,
|
||||
}
|
||||
}
|
76
log/log.go
76
log/log.go
@ -1,76 +0,0 @@
|
||||
//Package log is a robust logging system that provides a standard logger, an ANSI color logger, and a json logger that all make use of log levels
|
||||
package log
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
//Base log levels
|
||||
LogLevelINFO = 1 << iota
|
||||
LogLevelWARN
|
||||
LogLevelERR
|
||||
LogLevelDEBUG
|
||||
|
||||
//Common log level combinations
|
||||
LogLevelNone = 0
|
||||
LogLevelStd = LogLevelINFO | LogLevelWARN | LogLevelERR
|
||||
LogLevelWarn = LogLevelWARN | LogLevelERR
|
||||
LogLevelErr = LogLevelERR
|
||||
LogLevelDbg = LogLevelStd | LogLevelDEBUG
|
||||
)
|
||||
|
||||
var (
|
||||
defaultLogger = NewColorLogger(os.Stdout, LogLevelDbg)
|
||||
|
||||
Info = defaultLogger.Info
|
||||
Warn = defaultLogger.Warn
|
||||
Err = defaultLogger.Err
|
||||
Debug = defaultLogger.Debug
|
||||
|
||||
LogLevelMap = map[int]string{
|
||||
LogLevelINFO: "INFO",
|
||||
LogLevelWARN: "WARN",
|
||||
LogLevelERR: "ERROR",
|
||||
LogLevelDEBUG: "DEBUG",
|
||||
}
|
||||
|
||||
LogLevelNames = map[string]int{
|
||||
"none": LogLevelNone,
|
||||
"standard": LogLevelStd,
|
||||
"warn": LogLevelWarn,
|
||||
"error": LogLevelErr,
|
||||
"debug": LogLevelDbg,
|
||||
}
|
||||
)
|
||||
|
||||
//SetDefaultLogger sets the default logger... Yeah really.
|
||||
//This is pretty much the only thing that isn't safe to run
|
||||
//in multiple go routines. You should call SetDefaultLogger
|
||||
//in your init or at the beginning of your main function.
|
||||
func SetDefaultLogger(l *Logger) {
|
||||
defaultLogger = l
|
||||
Info = defaultLogger.Info
|
||||
Warn = defaultLogger.Warn
|
||||
Err = defaultLogger.Err
|
||||
Debug = defaultLogger.Debug
|
||||
}
|
||||
|
||||
//LogFormatter is the interface containing all the print methods needed for a typical Logger.
|
||||
type LogFormatter interface {
|
||||
Fatal(v ...interface{})
|
||||
Fatalf(format string, v ...interface{})
|
||||
Fatalln(v ...interface{})
|
||||
|
||||
Print(v ...interface{})
|
||||
Printf(format string, v ...interface{})
|
||||
Println(v ...interface{})
|
||||
}
|
||||
|
||||
//Logger is a struct containing a LogFormatter for each of the four basic log levels.
|
||||
type Logger struct {
|
||||
Info LogFormatter
|
||||
Warn LogFormatter
|
||||
Err LogFormatter
|
||||
Debug LogFormatter
|
||||
}
|
182
log/std-out.go
182
log/std-out.go
@ -1,182 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
goLog "log"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
colorLogDepth = 4
|
||||
)
|
||||
|
||||
var (
|
||||
ansiColorPallet = map[string][]byte{
|
||||
"none": []byte("\x1b[0m"),
|
||||
"black": []byte("\x1b[0;30m"),
|
||||
"red": []byte("\x1b[0;31m"),
|
||||
"green": []byte("\x1b[0;32m"),
|
||||
"orange": []byte("\x1b[0;33m"),
|
||||
"blue": []byte("\x1b[0;34m"),
|
||||
"purple": []byte("\x1b[0;35m"),
|
||||
"cyan": []byte("\x1b[0;36m"),
|
||||
"light-gray": []byte("\x1b[0;37m"),
|
||||
"dark-gray": []byte("\x1b[1;30m"),
|
||||
"light-red": []byte("\x1b[1;31m"),
|
||||
"light-green": []byte("\x1b[1;32m"),
|
||||
"yellow": []byte("\x1b[1;33m"),
|
||||
"light-blue": []byte("\x1b[1;34m"),
|
||||
"light-purple": []byte("\x1b[1;35m"),
|
||||
"light-cyan": []byte("\x1b[1;36m"),
|
||||
"white": []byte("\x1b[1;37m"),
|
||||
}
|
||||
|
||||
logColors = map[int][]byte{
|
||||
LogLevelINFO: ansiColorPallet["white"],
|
||||
LogLevelWARN: ansiColorPallet["orange"],
|
||||
LogLevelERR: ansiColorPallet["red"],
|
||||
LogLevelDEBUG: ansiColorPallet["light-blue"],
|
||||
}
|
||||
)
|
||||
|
||||
//NewColorLogger creates a new *Logger that outputs different log levels as different ANSI colors
|
||||
func NewColorLogger(out io.Writer, logLevel int) *Logger {
|
||||
return newLogger(out, logLevel, true)
|
||||
}
|
||||
|
||||
//NewLogger creates a new *Logger without ANSI colors
|
||||
func NewLogger(out io.Writer, logLevel int) *Logger {
|
||||
return newLogger(out, logLevel, false)
|
||||
}
|
||||
|
||||
func newLogger(out io.Writer, logLevel int, color bool) *Logger {
|
||||
logger := &Logger{
|
||||
Info: newColorLogFmt(out, logLevel, LogLevelINFO, color),
|
||||
Warn: newColorLogFmt(out, logLevel, LogLevelWARN, color),
|
||||
Err: newColorLogFmt(out, logLevel, LogLevelERR, color),
|
||||
Debug: newColorLogFmt(out, logLevel, LogLevelDEBUG, color),
|
||||
}
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
type colorLogFmt struct {
|
||||
out io.Writer
|
||||
logger *goLog.Logger
|
||||
logLevel int
|
||||
fmtLevel int
|
||||
color bool
|
||||
}
|
||||
|
||||
func newColorLogFmt(out io.Writer, logLevel, fmtLevel int, color bool) *colorLogFmt {
|
||||
clf := &colorLogFmt{
|
||||
logLevel: logLevel,
|
||||
fmtLevel: fmtLevel,
|
||||
out: out,
|
||||
color: color,
|
||||
}
|
||||
lFlags := goLog.LstdFlags
|
||||
|
||||
if fmtLevel != LogLevelINFO {
|
||||
lFlags |= goLog.Lshortfile
|
||||
}
|
||||
clf.logger = goLog.New(out, padStr(LogLevelMap[fmtLevel], 6), lFlags)
|
||||
|
||||
return clf
|
||||
}
|
||||
|
||||
func (lf *colorLogFmt) canLog() bool {
|
||||
return (lf.logLevel & lf.fmtLevel) == lf.fmtLevel
|
||||
}
|
||||
|
||||
func (lf *colorLogFmt) doOutput(pType, format string, v ...interface{}) {
|
||||
switch pType {
|
||||
case "Print", "Fatal":
|
||||
lf.logger.Output(colorLogDepth, fmt.Sprint(v...))
|
||||
case "Printf", "Fatalf":
|
||||
lf.logger.Output(colorLogDepth, fmt.Sprintf(format, v...))
|
||||
case "Println", "Fatalln":
|
||||
lf.logger.Output(colorLogDepth, fmt.Sprintln(v...))
|
||||
default:
|
||||
lf.logger.Output(colorLogDepth, fmt.Sprint(v...))
|
||||
}
|
||||
}
|
||||
|
||||
func (lf *colorLogFmt) doPrint(pType, format string, v ...interface{}) {
|
||||
switch pType {
|
||||
case "Fatal", "Fatalf", "Fatalln":
|
||||
lf.setErrColor()
|
||||
lf.doOutput(pType, format, v...)
|
||||
lf.dropColor()
|
||||
os.Exit(1)
|
||||
case "Print", "Printf", "Println":
|
||||
if !lf.canLog() {
|
||||
return
|
||||
}
|
||||
lf.setFmtColor()
|
||||
lf.doOutput(pType, format, v...)
|
||||
lf.dropColor()
|
||||
}
|
||||
}
|
||||
|
||||
//Fatal logs don't care what the logLevel is. They print using the
|
||||
//LogLevelERR color (if using the color logger) and exit with a satus of 1
|
||||
func (lf *colorLogFmt) Fatal(v ...interface{}) {
|
||||
lf.doPrint("Fatal", "", v...)
|
||||
}
|
||||
|
||||
func (lf *colorLogFmt) Fatalf(format string, v ...interface{}) {
|
||||
lf.doPrint("Fatalf", format, v...)
|
||||
}
|
||||
|
||||
func (lf *colorLogFmt) Fatalln(v ...interface{}) {
|
||||
lf.doPrint("Fatalln", "", v...)
|
||||
}
|
||||
|
||||
//Print operates the same as fmt.Print but with a log prefix
|
||||
func (lf *colorLogFmt) Print(v ...interface{}) {
|
||||
lf.doPrint("Print", "", v...)
|
||||
}
|
||||
|
||||
//Printf operates the same as fmt.Printf but with a log prefix
|
||||
func (lf *colorLogFmt) Printf(format string, v ...interface{}) {
|
||||
lf.doPrint("Printf", format, v...)
|
||||
}
|
||||
|
||||
//Println operates the same as fmt.Println but with a log prefix
|
||||
func (lf *colorLogFmt) Println(v ...interface{}) {
|
||||
lf.doPrint("Println", "", v...)
|
||||
}
|
||||
|
||||
func (lf *colorLogFmt) setColor(color []byte) {
|
||||
if !lf.color {
|
||||
return
|
||||
}
|
||||
|
||||
lf.out.Write(color)
|
||||
}
|
||||
|
||||
func (lf *colorLogFmt) setErrColor() {
|
||||
lf.setColor(logColors[LogLevelERR])
|
||||
}
|
||||
|
||||
func (lf *colorLogFmt) setFmtColor() {
|
||||
lf.setColor(logColors[lf.fmtLevel])
|
||||
}
|
||||
|
||||
func (lf *colorLogFmt) dropColor() {
|
||||
lf.setColor(ansiColorPallet["none"])
|
||||
}
|
||||
|
||||
func padStr(s string, length int) string {
|
||||
b := bytes.NewBuffer(nil)
|
||||
b.WriteString(s)
|
||||
for {
|
||||
if b.Len() >= length {
|
||||
return b.String()
|
||||
}
|
||||
b.WriteString(" ")
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ Sacrificial-Socket also has a MultihomeBackend interface for syncronizing broadc
|
||||
package ss
|
||||
|
||||
import (
|
||||
"github.com/raz-varren/sacrificial-socket/log"
|
||||
"github.com/raz-varren/log"
|
||||
"golang.org/x/net/websocket"
|
||||
"io"
|
||||
"net/http"
|
||||
|
Loading…
Reference in New Issue
Block a user