log_writer.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package log
  2. import (
  3. "io"
  4. "log"
  5. "os"
  6. "github.com/v2ray/v2ray-core/common/platform"
  7. )
  8. func createLogger(writer io.Writer) *log.Logger {
  9. return log.New(writer, "", log.Ldate|log.Ltime)
  10. }
  11. type logWriter interface {
  12. Log(LogEntry)
  13. }
  14. type noOpLogWriter struct {
  15. }
  16. func (this *noOpLogWriter) Log(LogEntry) {
  17. // Swallow
  18. }
  19. type stdOutLogWriter struct {
  20. logger *log.Logger
  21. }
  22. func newStdOutLogWriter() logWriter {
  23. return &stdOutLogWriter{
  24. logger: createLogger(os.Stdout),
  25. }
  26. }
  27. func (this *stdOutLogWriter) Log(log LogEntry) {
  28. this.logger.Print(log.String() + platform.LineSeparator())
  29. log.Release()
  30. }
  31. type fileLogWriter struct {
  32. queue chan LogEntry
  33. logger *log.Logger
  34. file *os.File
  35. }
  36. func (this *fileLogWriter) Log(log LogEntry) {
  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. entry.Release()
  47. }
  48. }
  49. func (this *fileLogWriter) close() {
  50. this.file.Close()
  51. }
  52. func newFileLogWriter(path string) (*fileLogWriter, error) {
  53. file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
  54. if err != nil {
  55. return nil, err
  56. }
  57. logger := &fileLogWriter{
  58. queue: make(chan LogEntry, 16),
  59. logger: log.New(file, "", log.Ldate|log.Ltime),
  60. file: file,
  61. }
  62. go logger.run()
  63. return logger, nil
  64. }