upload anki proxy

This commit is contained in:
ouczb 2024-02-13 19:45:15 +08:00
commit baa77f4468
21 changed files with 983 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.log
.idea/*
*/.ipynb_checkpoints/*

7
go.mod Normal file
View File

@ -0,0 +1,7 @@
module zproxy
go 1.20
require go.uber.org/zap v1.25.0
require go.uber.org/multierr v1.10.0 // indirect

10
go.sum Normal file
View File

@ -0,0 +1,10 @@
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

21
http/miss.go Normal file
View File

@ -0,0 +1,21 @@
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("https://zh.xhamster.com/?ref=porndude")
if err != nil {
fmt.Println("http get error", err)
return
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read error", err)
return
}
fmt.Println(string(body))
}

51
proxy/client.go Normal file
View File

@ -0,0 +1,51 @@
package proxy
import (
"net"
"zproxy/zlog"
)
type UClientProxy struct {
ServerConn *UPacketConnection
}
func NewClientProxy() *UClientProxy {
return &UClientProxy{}
}
func (client *UClientProxy) ServeTCP(serverAddr string, clientAddr string) error {
conn, err := net.Dial("tcp", serverAddr)
if err != nil {
return err
}
zlog.Infof("connect server %s", serverAddr)
client.ServerConn = NewPacketConnection(conn)
_, err = client.ServerConn.Write([]byte("anki"))
if err != nil {
return err
}
for {
data := make([]byte, 4)
_, err := client.ServerConn.Read(data, 0, 4)
if err != nil {
return err
}
if string(data) != "anki" {
zlog.Error("rcv package error:", data)
client.ServerConn.Clear()
continue
}
conn, err := net.Dial("tcp", clientAddr)
if err != nil {
zlog.Error("connect local anki error: ", err.Error(), clientAddr)
client.ServerConn.ForwardError(err)
continue
}
pc := NewPacketConnection(conn)
client.ServerConn.Forward(pc)
pc.Forward(client.ServerConn)
err = pc.Close()
if err != nil {
zlog.Error("close local anki error: ", err.Error())
}
}
}

85
proxy/packetconnection.go Normal file
View File

@ -0,0 +1,85 @@
package proxy
import (
"net"
"zproxy/zlog"
)
type UPacketConnection struct {
*UHttpRequest
}
// 创建连接的方法
func NewPacketConnection(conn net.Conn) *UPacketConnection {
//初始化Conn属性
c := &UPacketConnection{
UHttpRequest: NewHttpRequest(conn),
}
return c
}
func (pc *UPacketConnection) Forward(target *UPacketConnection) {
pc.DataSize = 0
pc.IsLoadHeader = false
for !pc.IsLoadHeader {
data, err := pc.ReadLine()
if err != nil {
zlog.Error("read header line error: ", err.Error())
return
}
_, err = target.Write(data)
if err != nil {
zlog.Error("write header line error: ", err.Error())
return
}
}
if pc.DataSize == 0 {
return
}
data := make([]byte, 1024)
for pc.DataSize > 0 {
size := min(pc.DataSize, 1024)
n, err := pc.Read(data, 0, size)
if err != nil {
zlog.Error("read body error: ", err.Error())
return
}
pc.DataSize -= n
zlog.Infof("read body %d %s", n, data[:n])
_, err = target.Write(data[:n])
if err != nil {
zlog.Error("write body error: ", err.Error())
return
}
}
}
func (pc *UPacketConnection) Close() error {
err := pc.Conn.Close()
return err
}
func (pc *UPacketConnection) ForwardError(err error) {
pc.DataSize = 0
pc.IsLoadHeader = false
zlog.Infof("forward error: ", err.Error())
for !pc.IsLoadHeader {
_, err := pc.ReadLine()
if err != nil {
zlog.Error("read header line error: ", err.Error())
return
}
}
for pc.DataSize > 0 {
data := make([]byte, 1024)
size := min(pc.DataSize, 1024)
n, err := pc.Read(data, 0, size)
if err != nil {
zlog.Error("Read body error: ", err.Error())
return
}
pc.DataSize -= n
}
err = pc.WriteError(err)
if err != nil {
zlog.Error("write error http error: ", err.Error())
return
}
}

91
proxy/reader.go Normal file
View File

@ -0,0 +1,91 @@
package proxy
import (
"bytes"
"io"
)
func min(a int, b int) int {
if a < b {
return a
}
return b
}
type UReader struct {
io io.Reader
buf []byte
r, w int
err error
}
func NewReader(io io.Reader) *UReader {
return &UReader{
io: io,
buf: make([]byte, 4096),
r: 0,
w: 0,
}
}
func (b *UReader) Read(data []byte, s int, e int) (int, error) {
n := e - s
rn := 0
for rn < n {
d := min(b.w-b.r, n-rn)
if d > 0 {
copy(data[s+rn:s+rn+d], b.buf[b.r:b.r+d])
b.r += d
rn += d
if rn >= n {
break
}
}
err := b.fill()
if err != nil {
return rn, err
}
}
return rn, nil
}
func (b *UReader) ReadLine() ([]byte, error) {
line, err := b.ReadSlice('\n')
return line, err
}
func (b *UReader) ReadSlice(delim byte) ([]byte, error) {
s := 0 // search start index
for {
// Search buffer.
if i := bytes.IndexByte(b.buf[b.r+s:b.w], delim); i >= 0 {
i += s + 1
b.r += i
return b.buf[b.r-i : b.r], nil
}
err := b.fill()
if err != nil {
return b.buf[b.r:], err
}
}
}
func (b *UReader) fill() error {
d := b.w - b.r
if d >= len(b.buf) {
b.r = 0
b.w = 0
return ErrBufferFull
}
// Slide existing data to beginning.
if b.r > 0 {
copy(b.buf, b.buf[b.r:b.w])
b.w -= b.r
b.r = 0
}
// Read new data: try a limited number of times.
n, err := b.io.Read(b.buf[b.w:])
b.w += n
return err
}
func (b *UReader) Clear() {
b.r = 0
b.w = 0
}

80
proxy/request.go Normal file
View File

@ -0,0 +1,80 @@
package proxy
import (
"bytes"
"net"
"strconv"
"strings"
)
type UHttpRequest struct {
Conn net.Conn
io *UReader
IsLoadHeader bool
DataSize int
}
func NewHttpRequest(conn net.Conn) *UHttpRequest {
return &UHttpRequest{
Conn: conn,
io: NewReader(conn),
IsLoadHeader: false,
DataSize: 0,
}
}
func (req *UHttpRequest) ReadLine() ([]byte, error) {
line, err := req.io.ReadLine()
if err != nil {
return line, err
}
if !req.IsLoadHeader && bytes.Equal(line, []byte("\r\n")) {
req.IsLoadHeader = true
}
if !req.IsLoadHeader {
k, v, ok := bytes.Cut(line, []byte(":"))
if !ok {
return line, err
}
if bytes.Equal(k, []byte("Content-Length")) {
nv := strings.Trim(string(v), " \r\n")
n, err := strconv.ParseUint(nv, 10, 63)
if err != nil {
return line, err
}
req.DataSize = int(n)
}
}
return line, err
}
func (req *UHttpRequest) Read(data []byte, s int, e int) (int, error) {
return req.io.Read(data, s, e)
}
func (req *UHttpRequest) Write(data []byte) (int, error) {
return req.Conn.Write(data)
}
func (req *UHttpRequest) WriteError(err error) error {
return req.WriteHttp([]byte("HTTP/1.1 200 OK\r\n"), []byte(err.Error()))
}
func (req *UHttpRequest) WriteHttp(header []byte, data []byte) error {
_, err := req.Write(header)
if err != nil {
return err
}
var bufBody bytes.Buffer
bufBody.WriteString("{\n \"error\" : \"")
bufBody.WriteString(string(data))
bufBody.WriteString("\"\n}")
var bufWrap bytes.Buffer
bufWrap.WriteString("Content-Length:")
bufWrap.WriteString(strconv.Itoa(bufBody.Len()))
bufWrap.WriteString("\r\n\r\n")
_, err = req.Write(bufWrap.Bytes())
if err != nil {
return err
}
_, err = req.Write(bufBody.Bytes())
return err
}
func (req *UHttpRequest) Clear() {
req.io.Clear()
}

71
proxy/server.go Normal file
View File

@ -0,0 +1,71 @@
package proxy
import (
"net"
"zproxy/zlog"
)
type UServerProxy struct {
AnkiConn *UPacketConnection
}
func NewServerProxy() *UServerProxy {
return &UServerProxy{}
}
func (server *UServerProxy) NewTcpConnection(client *UPacketConnection) {
defer func() {
if client == server.AnkiConn {
return
}
err := client.Close()
if err != nil {
zlog.Error("close client error: ", err)
}
}()
data := []byte("anki0000")
_, err := client.Read(data, 4, 8)
if err != nil {
zlog.Error("read client error: ", client.Conn.RemoteAddr(), err.Error())
return
}
zlog.Infof("new client %s %s", client.Conn.RemoteAddr(), data[4:])
if string(data[4:]) == "anki" {
server.AnkiConn = client
return
}
if server.AnkiConn == nil {
client.ForwardError(ErrNoAnkiProxy)
return
}
_, err = server.AnkiConn.Write(data)
if err != nil {
return
}
client.Forward(server.AnkiConn)
server.AnkiConn.Forward(client)
}
func (server *UServerProxy) ServeTCP(listenAddr string) error {
// listenAddr 只能填端口号
ln, err := net.Listen("tcp", listenAddr)
if err != nil {
zlog.Error("listen server error: ", err.Error(), listenAddr)
return err
}
zlog.Infof("listen server %s", listenAddr)
defer func(ln net.Listener) {
err := ln.Close()
if err != nil {
zlog.Error("close listen server error: ", err.Error(), listenAddr)
}
}(ln)
for {
conn, err := ln.Accept()
if err != nil {
if IsTimeoutError(err) {
continue
}
return err
}
go server.NewTcpConnection(NewPacketConnection(conn))
}
}

37
proxy/type.go Normal file
View File

@ -0,0 +1,37 @@
package proxy
type timeoutError interface {
Timeout() bool // Is it a timeout error
}
// fundamental is an error that has a message and a stack, but no caller.
type errors struct {
msg string
}
func (e errors) Error() string {
return e.msg
}
func NewError(msg string) error {
return errors{msg: msg}
}
var (
ErrBufferFull = NewError("read: buffer full")
ErrNoAnkiProxy = NewError("anki: no client proxy connect")
)
var (
ServerAddr = ":8765"
RemoteServerAddr = "175.24.226.114" + ServerAddr
ClientAddr = "127.0.0.1:8765"
)
// IsTimeoutError checks if the error is a timeout error
func IsTimeoutError(err error) bool {
if err == nil {
return false
}
ne, ok := err.(timeoutError)
return ok && ne.Timeout()
}

Binary file not shown.

Binary file not shown.

155
python/anki.ipynb Normal file
View File

@ -0,0 +1,155 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 13,
"id": "1664172b",
"metadata": {},
"outputs": [],
"source": [
"from http2 import *\n",
"class AnkiClient(Http):\n",
" def __init__(self):\n",
" Http.__init__(self)\n",
" self.url = 'http://127.0.0.1:8764'\n",
" self.version = None\n",
" def api(self, data):\n",
" print(data)\n",
" data = json.dumps(data)\n",
" res = self._post(self.url, data)\n",
" return res\n",
" def make_version(self):\n",
" self.version = self.api({\"action\":\"version\"})\n",
" return self.version\n",
" def deckNames(self):\n",
" return self.api({\"action\":\"deckNames\"})\n",
" def modelNames(self):\n",
" return self.api({\"action\":\"modelNames\"})\n",
" def modelFieldNames(self, modelName):\n",
" return self.api({\"action\":\"modelFieldNames\", \"params\" :{\"modelName\" : modelName}})\n",
" def addNote(self, note):\n",
" return self.api({\"action\":\"addNote\", \"params\" : {\"note\": note}})"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "ee987c62",
"metadata": {},
"outputs": [],
"source": [
"anki = AnkiClient()"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "58e77a6b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'action': 'deckNames'}\n",
"_post http://127.0.0.1:8764\n"
]
},
{
"data": {
"text/plain": [
"b'[\"Git\", \"\\\\u53e5\\\\u7d20\", \"\\\\u793a\\\\u4f8b\\\\u724c\\\\u7ec4\", \"\\\\u7cfb\\\\u7edf\\\\u9ed8\\\\u8ba4\", \"\\\\u82f1\\\\u8bed\", \"\\\\u8d56\\\\u4e16\\\\u96c4\\\\u97f3\\\\u6807\", \"\\\\u97f3\\\\u6807\"]'"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t = anki.deckNames()\n",
"t"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "c3b5b237",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"b'{\\n error = \"anki: no client proxy connect\"\\n}'"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "53bd0e19",
"metadata": {},
"outputs": [],
"source": [
"b = b'{\\n error = \"anki: no client proxy connect\"\\n}'"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "9d89217c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" error = \"anki: no client proxy connect\"\n",
"}\n"
]
}
],
"source": [
"print(b.decode())"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "203e9f90",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

84
python/http2.py Normal file
View File

@ -0,0 +1,84 @@
import inspect
import json, requests , zlib
from functools import wraps
from http.cookiejar import LWPCookieJar
import http.cookiejar as cookielib
default_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\
/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
class Session(requests.Session):
def __init__(self, headers={}, cookie_file=None):
requests.Session.__init__(self)
if cookie_file:
self.cookies = LWPCookieJar(filename = cookie_file)
self.cookies.load(ignore_discard = True)
self.update(headers)
self.auth = ('user', 'pass')
def save(self, filename = None):
self.cookies.save()
def update(self, headers):
self.headers.update(headers)
def http_error(code):
def _with(func):
@wraps(func)
def _deco(self, url):
return func(self, url)
_deco.__error_code__ = code
return _deco
return _with
class Http():
def __init__(self, headers = default_headers, session = None):
session = session or Session()
session.update(headers)
self.session = session
self._type = 'str'
self._error_dict = self._get_error_dict()
def _gets(self, url, data = None):
res = self.session.get(url, params = data)
self._error(res, url)
return self._res_data(res, self._type)
def _posts(self, url, data = None):
res = self.session.get(url, params = data)
self._error(res, url)
return self._res_data(res, self._type)
def _get(self, url, data = None):
print("_get", url)
res = requests.get(url, params = data, headers = self.session.headers)
self._error(res, url)
return self._res_data(res, self._type)
def _post(self, url, data):
print("_post", url)
res = requests.get(url, data = data, headers = self.session.headers)
self._error(res, url)
return self._res_data(res, self._type)
def _get_error_dict(self):
error_dict = {}
methods = inspect.getmembers(self, predicate=inspect.ismethod)
for method in methods:
error_code = getattr(method[1], '__error_code__', None)
if error_code:
error_dict[error_code] = method[1]
return error_dict
def _error(self, res, url):
code = res.status_code
if code == 200:
return
print(res.content)
if code in self._error_dict:
self._error_dict[code](url)
return
raise RuntimeError(code + '- unknown error ' + url)
@http_error(403)
def _error_403(self, url):
raise RuntimeError('error:403 - Forbidden ' + url)
@http_error(404)
def _error_404(self, url):
raise RuntimeError('error:404 - Not Found ' + url)
def _res_data(self, res, _type):
# encoding = None
# if 'Content-Encoding' in res.headers:
# encoding = res.headers['Content-Encoding']
# if encoding == 'gzip':
# res.content = zlib.decompress(res.content, 16 + zlib.MAX_WBITS)
# if _type == 'json':
# return json.loads(res.content)
return res.content

64
python/test.ipynb Normal file
View File

@ -0,0 +1,64 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "3f40720a",
"metadata": {},
"outputs": [],
"source": [
"import requests"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "d2986616",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Response [200]>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"requests.get(\"http://localhost:8080/\",data = \"helloworld\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7f2dd59b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

14
run/client/client.go Normal file
View File

@ -0,0 +1,14 @@
package main
import (
"zproxy/proxy"
"zproxy/zlog"
)
func main() {
client := proxy.NewClientProxy()
err := client.ServeTCP(proxy.RemoteServerAddr, proxy.ClientAddr)
if err != nil {
zlog.Error("exist client remote proxy: ", err.Error())
}
}

15
run/server/server.go Normal file
View File

@ -0,0 +1,15 @@
package main
import (
"zproxy/proxy"
"zproxy/zlog"
)
func main() {
server := proxy.NewServerProxy()
err := server.ServeTCP(proxy.ServerAddr)
if err != nil {
zlog.Error("exist server proxy: ", err.Error())
return
}
}

11
run/test/test.go Normal file
View File

@ -0,0 +1,11 @@
package main
import "net/http"
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("ok"))
})
http.ListenAndServe(":8080", nil)
}

70
zlog/test Normal file
View File

@ -0,0 +1,70 @@
from .http import *
import json,functools
class util:
def api(func):
@functools.wraps(func)
def wrapper(self,**kwargs):
self._api({"params" : kwargs , "action":func.__name__ })
self.res = func(self, **kwargs) or self.res
return self.res
return wrapper
class AnkiClient(Http):
util = util
def __init__(self, url = None):
Http.__init__(self)
self.url = url or 'http://127.0.0.1:8765'
self._version = None
self.res = None
def _api(self, data):
if self._version and type(self._version) == int:
data["version"] = self._version
data = json.dumps(data)
res = self._post(self.url, data)
self.res = json.loads(res)
return self.res
@util.api
def version(self):
self._version = self.res
pass
@util.api
def deckNames(self):
pass
@util.api
def modelNames(self):
pass
@util.api
def modelFieldNames(self, modelName = "示例牌组"):
pass
@util.api
def modelFieldDescriptions(self, modelName = "示例牌组"):
pass
@util.api
def modelTemplates(self, modelName = "示例牌组"):
pass
@util.api
def addNote(self, note = {}):
pass
@util.api
def findNotes(self, query = "note:basic"):
pass
@util.api
def updateNote(self, note = {}):
pass
@util.api
def updateNoteTags(self, note = {}, tags = []):
pass
@util.api
def notesInfo(self, notes = []):
pass
@util.api
def findCards(self, query = "deck:示例牌组"):
pass
@util.api
def cardsInfo(self, cards = []):
pass
@util.api
def updateNoteFields(self, note = {}):
pass
@util.api
def createModel(self, modelName = "basic", inOrderFields = {}, cardTemplates = {}, css = None, isCloze = False):
pass

16
zlog/type.go Normal file
View File

@ -0,0 +1,16 @@
package zlog
import (
"go.uber.org/zap/zapcore"
)
// Level is type of log levels
type Level = zapcore.Level
type FLogf = func(template string, args ...interface{})
type FLog = func(args ...interface{})
var (
Debugf, Infof, Warnf, Errorf, Panicf, Fatalf FLogf
Debug, Error, Panic, Fatal FLog
)

98
zlog/zlog.go Normal file
View File

@ -0,0 +1,98 @@
package zlog
import (
"go.uber.org/zap"
"strings"
)
var (
cfg zap.Config
logger *zap.Logger
sugar *zap.SugaredLogger
source string
currentLevel Level
)
func init() {
currentLevel = zap.DebugLevel
cfg = zap.NewDevelopmentConfig()
cfg.Development = true
rebuildLoggerFromCfg()
}
// SetSource sets the component name (dispatcher/gate/game) of gwlog module
func SetSource(source_ string) {
source = source_
rebuildLoggerFromCfg()
}
func SetParseLevel(slv string) {
lv := ParseLevel(slv)
SetLevel(lv)
}
// SetLevel sets the zlog level
func SetLevel(lv Level) {
currentLevel = lv
cfg.Level.SetLevel(lv)
}
// GetLevel get the current zlog level
func GetLevel() Level {
return currentLevel
}
// SetOutput sets the output writer
func SetOutput(outputs []string) {
cfg.OutputPaths = outputs
rebuildLoggerFromCfg()
}
// ParseLevel converts string to Levels
func ParseLevel(s string) Level {
if strings.ToLower(s) == "debug" {
return zap.DebugLevel
} else if strings.ToLower(s) == "info" {
return zap.InfoLevel
} else if strings.ToLower(s) == "warn" || strings.ToLower(s) == "warning" {
return zap.WarnLevel
} else if strings.ToLower(s) == "error" {
return zap.ErrorLevel
} else if strings.ToLower(s) == "panic" {
return zap.PanicLevel
} else if strings.ToLower(s) == "fatal" {
return zap.FatalLevel
}
Errorf("ParseLevel: unknown level: %s", s)
return zap.DebugLevel
}
func rebuildLoggerFromCfg() {
newLogger, err := cfg.Build()
if err != nil {
panic(err)
return
}
if logger != nil {
logger.Sync()
}
logger = newLogger
if source != "" {
logger = logger.With(zap.String("source", source))
}
sugar = logger.Sugar()
initFLog()
}
func initFLog() {
Debugf = sugar.Debugf
Infof = sugar.Infof
Warnf = sugar.Warnf
Errorf = sugar.Errorf
Panicf = sugar.Panicf
Fatalf = sugar.Fatalf
Debug = sugar.Debug
Error = sugar.Error
Panic = sugar.Panic
Fatal = sugar.Fatal
}