log_adapter.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package worker
  2. import (
  3. "fmt"
  4. wtasks "github.com/seaweedfs/seaweedfs/weed/worker/tasks"
  5. wtypes "github.com/seaweedfs/seaweedfs/weed/worker/types"
  6. )
  7. // taskLoggerAdapter adapts a tasks.TaskLogger to the types.Logger interface used by tasks
  8. // so that structured WithFields logs from task implementations are captured into file logs.
  9. type taskLoggerAdapter struct {
  10. base wtasks.TaskLogger
  11. fields map[string]interface{}
  12. }
  13. func newTaskLoggerAdapter(base wtasks.TaskLogger) *taskLoggerAdapter {
  14. return &taskLoggerAdapter{base: base}
  15. }
  16. // WithFields returns a new adapter instance that includes the provided fields.
  17. func (a *taskLoggerAdapter) WithFields(fields map[string]interface{}) wtypes.Logger {
  18. // copy fields to avoid mutation by caller
  19. copied := make(map[string]interface{}, len(fields))
  20. for k, v := range fields {
  21. copied[k] = v
  22. }
  23. return &taskLoggerAdapter{base: a.base, fields: copied}
  24. }
  25. // Info logs an info message, including any structured fields if present.
  26. func (a *taskLoggerAdapter) Info(msg string, args ...interface{}) {
  27. if a.base == nil {
  28. return
  29. }
  30. if len(a.fields) > 0 {
  31. a.base.LogWithFields("INFO", fmt.Sprintf(msg, args...), toStringMap(a.fields))
  32. return
  33. }
  34. a.base.Info(msg, args...)
  35. }
  36. func (a *taskLoggerAdapter) Warning(msg string, args ...interface{}) {
  37. if a.base == nil {
  38. return
  39. }
  40. if len(a.fields) > 0 {
  41. a.base.LogWithFields("WARNING", fmt.Sprintf(msg, args...), toStringMap(a.fields))
  42. return
  43. }
  44. a.base.Warning(msg, args...)
  45. }
  46. func (a *taskLoggerAdapter) Error(msg string, args ...interface{}) {
  47. if a.base == nil {
  48. return
  49. }
  50. if len(a.fields) > 0 {
  51. a.base.LogWithFields("ERROR", fmt.Sprintf(msg, args...), toStringMap(a.fields))
  52. return
  53. }
  54. a.base.Error(msg, args...)
  55. }
  56. func (a *taskLoggerAdapter) Debug(msg string, args ...interface{}) {
  57. if a.base == nil {
  58. return
  59. }
  60. if len(a.fields) > 0 {
  61. a.base.LogWithFields("DEBUG", fmt.Sprintf(msg, args...), toStringMap(a.fields))
  62. return
  63. }
  64. a.base.Debug(msg, args...)
  65. }
  66. // toStringMap converts map[string]interface{} to map[string]interface{} where values are printable.
  67. // The underlying tasks.TaskLogger handles arbitrary JSON values, but our gRPC conversion later
  68. // expects strings; we rely on existing conversion there. Here we keep interface{} to preserve detail.
  69. func toStringMap(in map[string]interface{}) map[string]interface{} {
  70. out := make(map[string]interface{}, len(in))
  71. for k, v := range in {
  72. out[k] = v
  73. }
  74. return out
  75. }