log_writer.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package log
  2. import (
  3. "io"
  4. "log"
  5. "os"
  6. "github.com/v2ray/v2ray-core/common/platform"
  7. "github.com/v2ray/v2ray-core/common/serial"
  8. )
  9. func createLogger(writer io.Writer) *log.Logger {
  10. return log.New(writer, "", log.Ldate|log.Ltime)
  11. }
  12. type logWriter interface {
  13. Log(serial.String)
  14. }
  15. type noOpLogWriter struct {
  16. }
  17. func (this *noOpLogWriter) Log(serial.String) {
  18. // Swallow
  19. }
  20. type stdOutLogWriter struct {
  21. logger *log.Logger
  22. }
  23. func newStdOutLogWriter() logWriter {
  24. return &stdOutLogWriter{
  25. logger: createLogger(os.Stdout),
  26. }
  27. }
  28. func (this *stdOutLogWriter) Log(log serial.String) {
  29. this.logger.Print(log.String() + platform.LineSeparator())
  30. }
  31. type fileLogWriter struct {
  32. queue chan serial.String
  33. logger *log.Logger
  34. file *os.File
  35. }
  36. func (this *fileLogWriter) Log(log serial.String) {
  37. select {
  38. case this.queue <- log:
  39. default:
  40. // We don't expect this to happen, but don't want to block main thread as well.
  41. }
  42. }
  43. func (this *fileLogWriter) run() {
  44. for entry := range this.queue {
  45. this.logger.Print(entry.String() + platform.LineSeparator())
  46. }
  47. }
  48. func (this *fileLogWriter) close() {
  49. this.file.Close()
  50. }
  51. func newFileLogWriter(path string) (*fileLogWriter, error) {
  52. file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
  53. if err != nil {
  54. return nil, err
  55. }
  56. logger := &fileLogWriter{
  57. queue: make(chan serial.String, 16),
  58. logger: log.New(file, "", log.Ldate|log.Ltime),
  59. file: file,
  60. }
  61. go logger.run()
  62. return logger, nil
  63. }