log_writer.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package internal
  2. import (
  3. "log"
  4. "os"
  5. "github.com/v2ray/v2ray-core/common/platform"
  6. )
  7. type LogWriter interface {
  8. Log(LogEntry)
  9. }
  10. type NoOpLogWriter struct {
  11. }
  12. func (this *NoOpLogWriter) Log(entry LogEntry) {
  13. entry.Release()
  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 (this *StdOutLogWriter) Log(log LogEntry) {
  24. this.logger.Print(log.String() + platform.LineSeparator())
  25. log.Release()
  26. }
  27. type FileLogWriter struct {
  28. queue chan LogEntry
  29. logger *log.Logger
  30. file *os.File
  31. }
  32. func (this *FileLogWriter) Log(log LogEntry) {
  33. select {
  34. case this.queue <- log:
  35. default:
  36. log.Release()
  37. // We don't expect this to happen, but don't want to block main thread as well.
  38. }
  39. }
  40. func (this *FileLogWriter) run() {
  41. for {
  42. entry, open := <-this.queue
  43. if !open {
  44. break
  45. }
  46. this.logger.Print(entry.String() + platform.LineSeparator())
  47. entry.Release()
  48. entry = nil
  49. }
  50. }
  51. func (this *FileLogWriter) Close() {
  52. this.file.Close()
  53. }
  54. func NewFileLogWriter(path string) (*FileLogWriter, error) {
  55. file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
  56. if err != nil {
  57. return nil, err
  58. }
  59. logger := &FileLogWriter{
  60. queue: make(chan LogEntry, 16),
  61. logger: log.New(file, "", log.Ldate|log.Ltime),
  62. file: file,
  63. }
  64. go logger.run()
  65. return logger, nil
  66. }