log_writer.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package internal
  2. import (
  3. "context"
  4. "log"
  5. "os"
  6. "v2ray.com/core/common/platform"
  7. )
  8. type LogEntry interface {
  9. String() string
  10. }
  11. type LogWriter interface {
  12. Log(LogEntry)
  13. Close()
  14. }
  15. type StdOutLogWriter struct {
  16. logger *log.Logger
  17. }
  18. func NewStdOutLogWriter() LogWriter {
  19. return &StdOutLogWriter{
  20. logger: log.New(os.Stdout, "", log.Ldate|log.Ltime),
  21. }
  22. }
  23. func (w *StdOutLogWriter) Log(log LogEntry) {
  24. w.logger.Print(log.String() + platform.LineSeparator())
  25. }
  26. func (*StdOutLogWriter) Close() {}
  27. type FileLogWriter struct {
  28. queue chan string
  29. logger *log.Logger
  30. file *os.File
  31. ctx context.Context
  32. cancel context.CancelFunc
  33. }
  34. func (w *FileLogWriter) Log(log LogEntry) {
  35. select {
  36. case <-w.ctx.Done():
  37. return
  38. case w.queue <- log.String():
  39. default:
  40. // We don't expect this to happen, but don't want to block main thread as well.
  41. }
  42. }
  43. func (w *FileLogWriter) run(ctx context.Context) {
  44. for {
  45. select {
  46. case <-ctx.Done():
  47. w.file.Close()
  48. return
  49. case entry := <-w.queue:
  50. w.logger.Print(entry + platform.LineSeparator())
  51. }
  52. }
  53. }
  54. func (w *FileLogWriter) Close() {
  55. w.cancel()
  56. }
  57. func NewFileLogWriter(path string) (*FileLogWriter, error) {
  58. file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
  59. if err != nil {
  60. return nil, err
  61. }
  62. ctx, cancel := context.WithCancel(context.Background())
  63. logger := &FileLogWriter{
  64. queue: make(chan string, 16),
  65. logger: log.New(file, "", log.Ldate|log.Ltime),
  66. file: file,
  67. ctx: ctx,
  68. cancel: cancel,
  69. }
  70. go logger.run(ctx)
  71. return logger, nil
  72. }