|  | @@ -5,13 +5,63 @@ import (
 | 
	
		
			
				|  |  |  	"io"
 | 
	
		
			
				|  |  |  	"log"
 | 
	
		
			
				|  |  |  	"net"
 | 
	
		
			
				|  |  | +	"os"
 | 
	
		
			
				|  |  |  	"path/filepath"
 | 
	
		
			
				|  |  | +	"strings"
 | 
	
		
			
				|  |  | +	"sync"
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const (
 | 
	
		
			
				|  |  |  	ServerMaxSize = 4194304 // 4MB
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +type ServerWriter struct {
 | 
	
		
			
				|  |  | +	Filepath string
 | 
	
		
			
				|  |  | +	W        map[string]io.Writer
 | 
	
		
			
				|  |  | +	Run      io.Writer
 | 
	
		
			
				|  |  | +	Err      io.Writer
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	mu sync.Mutex
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// trim ÒÆ³ý [] ÖÐÀ¨ºÅ
 | 
	
		
			
				|  |  | +func (l *ServerWriter) trim(s string) string {
 | 
	
		
			
				|  |  | +	s = strings.TrimPrefix(s, "[")
 | 
	
		
			
				|  |  | +	s = strings.TrimSuffix(s, "[ ")
 | 
	
		
			
				|  |  | +	return s
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func (l *ServerWriter) Write(p []byte) (n int, err error) {
 | 
	
		
			
				|  |  | +	level := string(p[:4])
 | 
	
		
			
				|  |  | +	if logs, ok := l.W[level]; ok {
 | 
	
		
			
				|  |  | +		return logs.Write(p)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	switch level {
 | 
	
		
			
				|  |  | +	case PrefixDebug, PrefixInfo, PrefixWarning, PrefixError:
 | 
	
		
			
				|  |  | +		if level == PrefixWarning || level == PrefixError {
 | 
	
		
			
				|  |  | +			n, err = l.Err.Write(p)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		n, err = l.Run.Write(p)
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		w, err := NewWriter(l.trim(level), ".log", filepath.Join(l.Filepath, l.trim(level)))
 | 
	
		
			
				|  |  | +		if err == nil {
 | 
	
		
			
				|  |  | +			l.mu.Lock()
 | 
	
		
			
				|  |  | +			l.W[level] = w
 | 
	
		
			
				|  |  | +			l.mu.Unlock()
 | 
	
		
			
				|  |  | +			n, err = w.Write(p)
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			_, _ = os.Stdout.Write(p)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func NewServerWriter() *ServerWriter {
 | 
	
		
			
				|  |  | +	sw := new(ServerWriter)
 | 
	
		
			
				|  |  | +	sw.W = make(map[string]io.Writer)
 | 
	
		
			
				|  |  | +	return sw
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  type Server struct {
 | 
	
		
			
				|  |  |  	W    io.Writer
 | 
	
		
			
				|  |  |  	Conn net.PacketConn
 | 
	
	
		
			
				|  | @@ -20,8 +70,7 @@ type Server struct {
 | 
	
		
			
				|  |  |  func (c *Server) handle(b []byte) {
 | 
	
		
			
				|  |  |  	_, err := c.W.Write(b)
 | 
	
		
			
				|  |  |  	if err != nil {
 | 
	
		
			
				|  |  | -		log.Println("handle err:", err)
 | 
	
		
			
				|  |  | -		log.Println("handle text:", string(b))
 | 
	
		
			
				|  |  | +		_, _ = os.Stdout.Write(b)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -45,19 +94,19 @@ func (c *Server) ListenAndServe() error {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func NewServer(address, path string) (*Server, error) {
 | 
	
		
			
				|  |  | -	l := new(LevelWriter)
 | 
	
		
			
				|  |  | -	l.Console = false
 | 
	
		
			
				|  |  | +	sw := NewServerWriter()
 | 
	
		
			
				|  |  | +	sw.Filepath = path
 | 
	
		
			
				|  |  |  	var err error
 | 
	
		
			
				|  |  | -	l.Run, err = NewWriter("r", ".log", filepath.Join(address, path, "run"))
 | 
	
		
			
				|  |  | +	sw.Run, err = NewWriter("r", ".log", filepath.Join(path, "run"))
 | 
	
		
			
				|  |  |  	if err != nil {
 | 
	
		
			
				|  |  |  		return nil, err
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	l.Err, err = NewWriter("e", ".log", filepath.Join(address, path, "err"))
 | 
	
		
			
				|  |  | +	sw.Err, err = NewWriter("e", ".log", filepath.Join(path, "err"))
 | 
	
		
			
				|  |  |  	if err != nil {
 | 
	
		
			
				|  |  |  		return nil, err
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	s := new(Server)
 | 
	
		
			
				|  |  | -	s.W = l
 | 
	
		
			
				|  |  | +	s.W = sw
 | 
	
		
			
				|  |  |  	s.Conn, err = net.ListenPacket("udp", address)
 | 
	
		
			
				|  |  |  	if err != nil {
 | 
	
		
			
				|  |  |  		return nil, err
 | 
	
	
		
			
				|  | @@ -105,11 +154,10 @@ func NewClient(address string) (*Client, error) {
 | 
	
		
			
				|  |  |  		return nil, err
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	c := new(Client)
 | 
	
		
			
				|  |  | -	w := &LevelWriter{Run: conn, Err: conn, Console: c.Console}
 | 
	
		
			
				|  |  |  	c.conn = conn
 | 
	
		
			
				|  |  | -	c.debug = log.New(w, prefixDebug, Flag)
 | 
	
		
			
				|  |  | -	c.info = log.New(w, prefixInfo, Flag)
 | 
	
		
			
				|  |  | -	c.warning = log.New(w, prefixWarning, Flag)
 | 
	
		
			
				|  |  | -	c.error = log.New(w, prefixError, Flag)
 | 
	
		
			
				|  |  | +	c.debug = log.New(conn, PrefixDebug, Flag)
 | 
	
		
			
				|  |  | +	c.info = log.New(conn, PrefixInfo, Flag)
 | 
	
		
			
				|  |  | +	c.warning = log.New(conn, PrefixWarning, Flag)
 | 
	
		
			
				|  |  | +	c.error = log.New(conn, PrefixError, Flag)
 | 
	
		
			
				|  |  |  	return c, nil
 | 
	
		
			
				|  |  |  }
 |