fix(be):使用next-terminal 自定义的日志

This commit is contained in:
neverteaser
2021-03-19 22:58:47 +08:00
committed by dushixiang
parent 518e665d17
commit 9d38e5fef7
19 changed files with 322 additions and 184 deletions

292
pkg/guacd/guacd.go Normal file
View File

@ -0,0 +1,292 @@
package guacd
import (
"bufio"
"errors"
"fmt"
"net"
"strings"
)
const (
Host = "host"
Port = "port"
EnableRecording = "enable-recording"
RecordingPath = "recording-path"
CreateRecordingPath = "create-recording-path"
FontName = "font-name"
FontSize = "font-size"
ColorScheme = "color-scheme"
Backspace = "backspace"
TerminalType = "terminal-type"
EnableDrive = "enable-drive"
DriveName = "drive-name"
DrivePath = "drive-path"
EnableWallpaper = "enable-wallpaper"
EnableTheming = "enable-theming"
EnableFontSmoothing = "enable-font-smoothing"
EnableFullWindowDrag = "enable-full-window-drag"
EnableDesktopComposition = "enable-desktop-composition"
EnableMenuAnimations = "enable-menu-animations"
DisableBitmapCaching = "disable-bitmap-caching"
DisableOffscreenCaching = "disable-offscreen-caching"
DisableGlyphCaching = "disable-glyph-caching"
Domain = "domain"
RemoteApp = "remote-app"
RemoteAppDir = "remote-app-dir"
RemoteAppArgs = "remote-app-args"
ColorDepth = "color-depth"
Cursor = "cursor"
SwapRedBlue = "swap-red-blue"
DestHost = "dest-host"
DestPort = "dest-port"
UsernameRegex = "username-regex"
PasswordRegex = "password-regex"
LoginSuccessRegex = "login-success-regex"
LoginFailureRegex = "login-failure-regex"
Namespace = "namespace"
Pod = "pod"
Container = "container"
UesSSL = "use-ssl"
ClientCert = "client-cert"
ClientKey = "client-key"
CaCert = "ca-cert"
IgnoreCert = "ignore-cert"
)
const Delimiter = ';'
const Version = "VERSION_1_3_0"
type Configuration struct {
ConnectionID string
Protocol string
Parameters map[string]string
}
func NewConfiguration() (ret Configuration) {
ret.Parameters = make(map[string]string)
return ret
}
func (opt *Configuration) SetParameter(name, value string) {
opt.Parameters[name] = value
}
func (opt *Configuration) UnSetParameter(name string) {
delete(opt.Parameters, name)
}
func (opt *Configuration) GetParameter(name string) string {
return opt.Parameters[name]
}
type Instruction struct {
Opcode string
Args []string
ProtocolForm string
}
func NewInstruction(opcode string, args ...string) (ret Instruction) {
ret.Opcode = opcode
ret.Args = args
return ret
}
func (opt *Instruction) String() string {
if len(opt.ProtocolForm) > 0 {
return opt.ProtocolForm
}
opt.ProtocolForm = fmt.Sprintf("%d.%s", len(opt.Opcode), opt.Opcode)
for _, value := range opt.Args {
opt.ProtocolForm += fmt.Sprintf(",%d.%s", len(value), value)
}
opt.ProtocolForm += string(Delimiter)
return opt.ProtocolForm
}
func (opt *Instruction) Parse(content string) Instruction {
if strings.LastIndex(content, ";") > 0 {
content = strings.TrimRight(content, ";")
}
messages := strings.Split(content, ",")
var args = make([]string, len(messages))
for i := range messages {
lm := strings.Split(messages[i], ".")
args[i] = lm[1]
}
return NewInstruction(args[0], args[1:]...)
}
type Tunnel struct {
rw *bufio.ReadWriter
conn net.Conn
UUID string
Config Configuration
IsOpen bool
}
func NewTunnel(address string, config Configuration) (ret *Tunnel, err error) {
conn, err := net.Dial("tcp", address)
if err != nil {
return
}
ret = &Tunnel{}
ret.conn = conn
ret.rw = bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
ret.Config = config
selectArg := config.ConnectionID
if selectArg == "" {
selectArg = config.Protocol
}
if err := ret.WriteInstructionAndFlush(NewInstruction("select", selectArg)); err != nil {
return nil, err
}
args, err := ret.expect("args")
if err != nil {
return
}
width := config.GetParameter("width")
height := config.GetParameter("height")
dpi := config.GetParameter("dpi")
// send size
if err := ret.WriteInstructionAndFlush(NewInstruction("size", width, height, dpi)); err != nil {
return nil, err
}
if err := ret.WriteInstructionAndFlush(NewInstruction("audio", "audio/L8", "audio/L16")); err != nil {
return nil, err
}
if err := ret.WriteInstructionAndFlush(NewInstruction("video")); err != nil {
return nil, err
}
if err := ret.WriteInstructionAndFlush(NewInstruction("image", "image/jpeg", "image/png", "image/webp")); err != nil {
return nil, err
}
if err := ret.WriteInstructionAndFlush(NewInstruction("timezone", "Asia/Shanghai")); err != nil {
return nil, err
}
parameters := make([]string, len(args.Args))
for i := range args.Args {
argName := args.Args[i]
if strings.Contains(argName, "VERSION") {
parameters[i] = Version
continue
}
parameters[i] = config.GetParameter(argName)
}
// send connect
if err := ret.WriteInstructionAndFlush(NewInstruction("connect", parameters...)); err != nil {
return nil, err
}
ready, err := ret.expect("ready")
if err != nil {
return
}
if len(ready.Args) == 0 {
return nil, errors.New("no connection id received")
}
ret.UUID = ready.Args[0]
ret.IsOpen = true
return ret, nil
}
func (opt *Tunnel) WriteInstructionAndFlush(instruction Instruction) error {
if _, err := opt.WriteAndFlush([]byte(instruction.String())); err != nil {
return err
}
return nil
}
func (opt *Tunnel) WriteInstruction(instruction Instruction) error {
if _, err := opt.Write([]byte(instruction.String())); err != nil {
return err
}
return nil
}
func (opt *Tunnel) WriteAndFlush(p []byte) (int, error) {
//fmt.Printf("-> %v\n", string(p))
nn, err := opt.rw.Write(p)
if err != nil {
return nn, err
}
err = opt.rw.Flush()
if err != nil {
return nn, err
}
return nn, nil
}
func (opt *Tunnel) Write(p []byte) (int, error) {
//fmt.Printf("-> %v \n", string(p))
nn, err := opt.rw.Write(p)
if err != nil {
return nn, err
}
return nn, nil
}
func (opt *Tunnel) Flush() error {
return opt.rw.Flush()
}
func (opt *Tunnel) ReadInstruction() (instruction Instruction, err error) {
msg, err := opt.rw.ReadString(Delimiter)
//fmt.Printf("<- %v \n", msg)
if err != nil {
return instruction, err
}
return instruction.Parse(msg), err
}
func (opt *Tunnel) Read() (p []byte, err error) {
p, err = opt.rw.ReadBytes(Delimiter)
//fmt.Printf("<- %v \n", string(p))
s := string(p)
if s == "rate=44100,channels=2;" {
return make([]byte, 0), nil
}
if s == "rate=22050,channels=2;" {
return make([]byte, 0), nil
}
if s == "5.audio,1.1,31.audio/L16;" {
s += "rate=44100,channels=2;"
}
return []byte(s), err
}
func (opt *Tunnel) expect(opcode string) (instruction Instruction, err error) {
instruction, err = opt.ReadInstruction()
if err != nil {
return instruction, err
}
if opcode != instruction.Opcode {
msg := fmt.Sprintf(`expected "%s" instruction but instead received "%s"`, opcode, instruction.Opcode)
return instruction, errors.New(msg)
}
return instruction, nil
}
func (opt *Tunnel) Close() error {
opt.IsOpen = false
return opt.conn.Close()
}

252
pkg/log/logger.go Normal file
View File

@ -0,0 +1,252 @@
package log
import (
"fmt"
"io"
"os"
"path"
"strconv"
"time"
"github.com/labstack/echo/v4"
"github.com/sirupsen/logrus"
)
var stdOut = NewLogger()
// Trace logs a message at level Trace on the standard logger.
func Trace(args ...interface{}) {
stdOut.Trace(args...)
}
// Debug logs a message at level Debug on the standard logger.
func Debug(args ...interface{}) {
stdOut.Debug(args...)
}
// Print logs a message at level Info on the standard logger.
func Print(args ...interface{}) {
stdOut.Print(args...)
}
// Info logs a message at level Info on the standard logger.
func Info(args ...interface{}) {
stdOut.Info(args...)
}
// Warn logs a message at level Warn on the standard logger.
func Warn(args ...interface{}) {
stdOut.Warn(args...)
}
// Warning logs a message at level Warn on the standard logger.
func Warning(args ...interface{}) {
stdOut.Warning(args...)
}
// Error logs a message at level Error on the standard logger.
func Error(args ...interface{}) {
stdOut.Error(args...)
}
// Panic logs a message at level Panic on the standard logger.
func Panic(args ...interface{}) {
stdOut.Panic(args...)
}
// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
func Fatal(args ...interface{}) {
stdOut.Fatal(args...)
}
// Tracef logs a message at level Trace on the standard logger.
func Tracef(format string, args ...interface{}) {
stdOut.Tracef(format, args...)
}
// Debugf logs a message at level Debug on the standard logger.
func Debugf(format string, args ...interface{}) {
stdOut.Debugf(format, args...)
}
// Printf logs a message at level Info on the standard logger.
func Printf(format string, args ...interface{}) {
stdOut.Printf(format, args...)
}
// Infof logs a message at level Info on the standard logger.
func Infof(format string, args ...interface{}) {
stdOut.Infof(format, args...)
}
// Warnf logs a message at level Warn on the standard logger.
func Warnf(format string, args ...interface{}) {
stdOut.Warnf(format, args...)
}
// Warningf logs a message at level Warn on the standard logger.
func Warningf(format string, args ...interface{}) {
stdOut.Warningf(format, args...)
}
// Errorf logs a message at level Error on the standard logger.
func Errorf(format string, args ...interface{}) {
stdOut.Errorf(format, args...)
}
// Panicf logs a message at level Panic on the standard logger.
func Panicf(format string, args ...interface{}) {
stdOut.Panicf(format, args...)
}
// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
func Fatalf(format string, args ...interface{}) {
stdOut.Fatalf(format, args...)
}
// Traceln logs a message at level Trace on the standard logger.
func Traceln(args ...interface{}) {
stdOut.Traceln(args...)
}
// Debugln logs a message at level Debug on the standard logger.
func Debugln(args ...interface{}) {
stdOut.Debugln(args...)
}
// Println logs a message at level Info on the standard logger.
func Println(args ...interface{}) {
stdOut.Println(args...)
}
// Infoln logs a message at level Info on the standard logger.
func Infoln(args ...interface{}) {
stdOut.Infoln(args...)
}
// Warnln logs a message at level Warn on the standard logger.
func Warnln(args ...interface{}) {
stdOut.Warnln(args...)
}
// Warningln logs a message at level Warn on the standard logger.
func Warningln(args ...interface{}) {
stdOut.Warningln(args...)
}
// Errorln logs a message at level Error on the standard logger.
func Errorln(args ...interface{}) {
stdOut.Errorln(args...)
}
// Panicln logs a message at level Panic on the standard logger.
func Panicln(args ...interface{}) {
stdOut.Panicln(args...)
}
// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
func Fatalln(args ...interface{}) {
stdOut.Fatalln(args...)
}
// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
func WithError(err error) *logrus.Entry {
return stdOut.WithField(logrus.ErrorKey, err)
}
// WithField creates an entry from the standard logger and adds a field to
// it. If you want multiple fields, use `WithFields`.
//
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
// or Panic on the Entry it returns.
func WithField(key string, value interface{}) *logrus.Entry {
return stdOut.WithField(key, value)
}
// Logrus : implement log
type Logrus struct {
*logrus.Logger
}
// GetEchoLogger for e.l
func NewLogger() Logrus {
logFilePath := ""
if dir, err := os.Getwd(); err == nil {
logFilePath = dir + "/log/"
}
if err := os.MkdirAll(logFilePath, 0755); err != nil {
fmt.Println(err.Error())
}
// TODO 滚动日志
logFileName := "next-terminal.log"
//日志文件
fileName := path.Join(logFilePath, logFileName)
if _, err := os.Stat(fileName); err != nil {
if _, err := os.Create(fileName); err != nil {
fmt.Println(err.Error())
}
}
//写入文件
src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Println("err", err)
}
//实例化
logger := logrus.New()
//设置输出
logger.SetOutput(io.MultiWriter(os.Stdout, src))
//设置日志级别
logger.SetLevel(logrus.DebugLevel)
//设置日志格式
logger.SetFormatter(&logrus.TextFormatter{
TimestampFormat: "2006-01-02 15:04:05",
})
return Logrus{Logger: logger}
}
func logrusMiddlewareHandler(c echo.Context, next echo.HandlerFunc) error {
l := NewLogger()
req := c.Request()
res := c.Response()
start := time.Now()
if err := next(c); err != nil {
c.Error(err)
}
stop := time.Now()
p := req.URL.Path
bytesIn := req.Header.Get(echo.HeaderContentLength)
l.WithFields(map[string]interface{}{
"time_rfc3339": time.Now().Format(time.RFC3339),
"remote_ip": c.RealIP(),
"host": req.Host,
"uri": req.RequestURI,
"method": req.Method,
"path": p,
"referer": req.Referer(),
"user_agent": req.UserAgent(),
"status": res.Status,
"latency": strconv.FormatInt(stop.Sub(start).Nanoseconds()/1000, 10),
"latency_human": stop.Sub(start).String(),
"bytes_in": bytesIn,
"bytes_out": strconv.FormatInt(res.Size, 10),
}).Info("Handled request")
return nil
}
func logger(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
return logrusMiddlewareHandler(c, next)
}
}
// Hook is a function to process log.
func Hook() echo.MiddlewareFunc {
return logger
}

View File

@ -1,90 +0,0 @@
package middleware
import (
"fmt"
"os"
"path"
"strconv"
"time"
"github.com/labstack/echo/v4"
log "github.com/sirupsen/logrus"
)
type NTLog struct {
*log.Logger
}
func (l *NTLog) Level() {
}
func Logger() *log.Logger {
now := time.Now()
logFilePath := ""
if dir, err := os.Getwd(); err == nil {
logFilePath = dir + "/log/"
}
if err := os.MkdirAll(logFilePath, 0755); err != nil {
fmt.Println(err.Error())
}
// TODO 滚动日志
logFileName := now.Format("2006-01-02") + ".log"
//日志文件
fileName := path.Join(logFilePath, logFileName)
if _, err := os.Stat(fileName); err != nil {
if _, err := os.Create(fileName); err != nil {
fmt.Println(err.Error())
}
}
//写入文件
src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Println("err", err)
}
//实例化
logger := log.New()
//设置输出
logger.Out = src
logger.SetOutput(os.Stdout)
//设置日志级别
logger.SetLevel(log.DebugLevel)
//设置日志格式
logger.SetFormatter(&log.TextFormatter{
TimestampFormat: "2006-01-02 15:04:05",
})
return logger
}
func LoggerToFile() echo.MiddlewareFunc {
logger := Logger()
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) (err error) {
req := c.Request()
res := c.Response()
start := time.Now()
if err = next(c); err != nil {
c.Error(err)
}
stop := time.Now()
logger.Infof("%s [%v] %s %-7s %s %3d %s %13v %s %s",
c.RealIP(),
stop.Format(time.RFC3339),
req.Host,
req.Method,
req.RequestURI,
res.Status,
strconv.FormatInt(res.Size, 10),
stop.Sub(start).String(),
req.Referer(),
req.UserAgent(),
)
return err
}
}
}