mirror of https://github.com/v2ray/v2ray-core
				
				
				
			
		
			
				
	
	
		
			95 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
package internal
 | 
						|
 | 
						|
import (
 | 
						|
	"log"
 | 
						|
	"os"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/v2ray/v2ray-core/common/platform"
 | 
						|
	"github.com/v2ray/v2ray-core/common/signal"
 | 
						|
)
 | 
						|
 | 
						|
type LogWriter interface {
 | 
						|
	Log(LogEntry)
 | 
						|
	Close()
 | 
						|
}
 | 
						|
 | 
						|
type NoOpLogWriter struct {
 | 
						|
}
 | 
						|
 | 
						|
func (this *NoOpLogWriter) Log(entry LogEntry) {
 | 
						|
	entry.Release()
 | 
						|
}
 | 
						|
 | 
						|
func (this *NoOpLogWriter) Close() {
 | 
						|
}
 | 
						|
 | 
						|
type StdOutLogWriter struct {
 | 
						|
	logger *log.Logger
 | 
						|
	cancel *signal.CancelSignal
 | 
						|
}
 | 
						|
 | 
						|
func NewStdOutLogWriter() LogWriter {
 | 
						|
	return &StdOutLogWriter{
 | 
						|
		logger: log.New(os.Stdout, "", log.Ldate|log.Ltime),
 | 
						|
		cancel: signal.NewCloseSignal(),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (this *StdOutLogWriter) Log(log LogEntry) {
 | 
						|
	this.logger.Print(log.String() + platform.LineSeparator())
 | 
						|
	log.Release()
 | 
						|
}
 | 
						|
 | 
						|
func (this *StdOutLogWriter) Close() {
 | 
						|
	time.Sleep(500 * time.Millisecond)
 | 
						|
}
 | 
						|
 | 
						|
type FileLogWriter struct {
 | 
						|
	queue  chan string
 | 
						|
	logger *log.Logger
 | 
						|
	file   *os.File
 | 
						|
	cancel *signal.CancelSignal
 | 
						|
}
 | 
						|
 | 
						|
func (this *FileLogWriter) Log(log LogEntry) {
 | 
						|
	select {
 | 
						|
	case this.queue <- log.String():
 | 
						|
	default:
 | 
						|
		// We don't expect this to happen, but don't want to block main thread as well.
 | 
						|
	}
 | 
						|
	log.Release()
 | 
						|
}
 | 
						|
 | 
						|
func (this *FileLogWriter) run() {
 | 
						|
	for {
 | 
						|
		entry, open := <-this.queue
 | 
						|
		if !open {
 | 
						|
			break
 | 
						|
		}
 | 
						|
		this.logger.Print(entry + platform.LineSeparator())
 | 
						|
	}
 | 
						|
	this.cancel.Done()
 | 
						|
}
 | 
						|
 | 
						|
func (this *FileLogWriter) Close() {
 | 
						|
	close(this.queue)
 | 
						|
	<-this.cancel.WaitForDone()
 | 
						|
	this.file.Close()
 | 
						|
}
 | 
						|
 | 
						|
func NewFileLogWriter(path string) (*FileLogWriter, error) {
 | 
						|
	file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	logger := &FileLogWriter{
 | 
						|
		queue:  make(chan string, 16),
 | 
						|
		logger: log.New(file, "", log.Ldate|log.Ltime),
 | 
						|
		file:   file,
 | 
						|
		cancel: signal.NewCloseSignal(),
 | 
						|
	}
 | 
						|
	go logger.run()
 | 
						|
	return logger, nil
 | 
						|
}
 |