| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | package logimport (	"io"	"log"	"net"	"os"	"path/filepath"	"sync")const (	ServerMaxSize = 4194304 // 4MB)type ServerWriter struct {	Filepath string	W        map[string]io.Writer	Run      io.Writer	Err      io.Writer	mu sync.Mutex}func (l *ServerWriter) Write(p []byte) (n int, err error) {	l.mu.Lock()	defer l.mu.Unlock()	prefix := spitPrefix(string(p))	if lg, ok := l.W[prefix]; ok {		return lg.Write(p)	}	level := buildPrefix(prefix)	switch level {	case LevelsError, LevelsWarn, LevelsInfo, LevelsDebug:		if level == LevelsError || level == LevelsWarn {			n, err = l.Err.Write(p)		}		n, err = l.Run.Write(p)	default:		w := NewFileWriter(prefix, filepath.Join(l.Filepath, prefix))		n, err = w.Write(p)		l.W[prefix] = w	}	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}func (c *Server) handle(b []byte) {	_, err := c.W.Write(b)	if err != nil {		_, _ = os.Stdout.Write(b)	}}func (c *Server) Close() error {	return c.Conn.Close()}func (c *Server) ListenAndServe() error {	defer func() {		_ = c.Close()	}()	for {		b := make([]byte, ServerMaxSize)		n, _, err := c.Conn.ReadFrom(b)		if err != nil {			log.Println("ReadFrom:", err)			continue		}		go c.handle(b[:n])	}}func NewServer(address, path string) (*Server, error) {	sw := NewServerWriter()	sw.Filepath = path	sw.Run = NewFileWriter("r", filepath.Join(path, "run"))	sw.Err = NewFileWriter("e", filepath.Join(path, "err"))	s := new(Server)	s.W = sw	var err error	s.Conn, err = net.ListenPacket("udp", address)	if err != nil {		return nil, err	}	return s, nil}func NewClientLogger(address string) (Logger, error) {	udpAddr, err := net.ResolveUDPAddr("udp", address)	if err != nil {		return nil, err	}	conn, err := net.DialUDP("udp", nil, udpAddr)	if err != nil {		return nil, err	}	return NewLog(LevelDebug, []io.Writer{conn}, "", 1, 0), nil}func NewClientPrinter(prefix, address string) (Printer, error) {	udpAddr, err := net.ResolveUDPAddr("udp", address)	if err != nil {		return nil, err	}	conn, err := net.DialUDP("udp", nil, udpAddr)	if err != nil {		return nil, err	}	return NewLog(LevelDebug, []io.Writer{conn}, prefix, 1, 0), nil}
 |