log_writer.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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(entry LogEntry) {
  17. entry.Release()
  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. log.Release()
  41. // We don't expect this to happen, but don't want to block main thread as well.
  42. }
  43. }
  44. func (this *fileLogWriter) run() {
  45. for entry := range this.queue {
  46. this.logger.Print(entry.String() + platform.LineSeparator())
  47. entry.Release()
  48. }
  49. }
  50. func (this *fileLogWriter) close() {
  51. this.file.Close()
  52. }
  53. func newFileLogWriter(path string) (*fileLogWriter, error) {
  54. file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
  55. if err != nil {
  56. return nil, err
  57. }
  58. logger := &fileLogWriter{
  59. queue: make(chan LogEntry, 16),
  60. logger: log.New(file, "", log.Ldate|log.Ltime),
  61. file: file,
  62. }
  63. go logger.run()
  64. return logger, nil
  65. }