logger.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package logger
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "sort"
  7. "sync"
  8. "time"
  9. )
  10. // TimeFormatDay - format of the day for timestamps
  11. const TimeFormatDay = "2006-01-02"
  12. // TimeFormat - total time format
  13. const TimeFormat = "2006-01-02 15:04:05"
  14. // == fields ==
  15. var currentLogs = make(map[string]string)
  16. var mu sync.Mutex
  17. var program string
  18. func init() {
  19. fullpath, err := os.Executable()
  20. if err != nil {
  21. fullpath = ""
  22. }
  23. program = filepath.Base(fullpath)
  24. }
  25. // Log - handles adding logs
  26. func Log(verbosity int, message ...string) {
  27. mu.Lock()
  28. defer mu.Unlock()
  29. var currentTime = time.Now()
  30. var currentMessage = MakeString(" ", message...)
  31. if int32(verbosity) <= getVerbose() && getVerbose() >= 0 {
  32. fmt.Printf("[%s] %s %s \n", program, currentTime.Format(TimeFormat), currentMessage)
  33. }
  34. if program == "netmaker" {
  35. currentLogs[currentMessage] = currentTime.Format("2006-01-02 15:04:05.999999999")
  36. }
  37. }
  38. // Dump - dumps all logs into a formatted string
  39. func Dump() string {
  40. if program != "netmaker" {
  41. return ""
  42. }
  43. var dumpString = ""
  44. type keyVal struct {
  45. Key string
  46. Value time.Time
  47. }
  48. var mu sync.Mutex
  49. mu.Lock()
  50. defer mu.Unlock()
  51. var dumpLogs = make([]keyVal, 0, len(currentLogs))
  52. for key, value := range currentLogs {
  53. parsedTime, err := time.Parse(TimeFormat, value)
  54. if err == nil {
  55. dumpLogs = append(dumpLogs, keyVal{
  56. Key: key,
  57. Value: parsedTime,
  58. })
  59. }
  60. }
  61. sort.Slice(dumpLogs, func(i, j int) bool {
  62. return dumpLogs[i].Value.Before(dumpLogs[j].Value)
  63. })
  64. for i := range dumpLogs {
  65. var currLog = dumpLogs[i]
  66. dumpString += MakeString(" ", "[netmaker]", currLog.Value.Format(TimeFormat), currLog.Key, "\n")
  67. }
  68. resetLogs()
  69. return dumpString
  70. }
  71. // DumpFile - appends log dump log file
  72. func DumpFile(filePath string) {
  73. if program != "netmaker" {
  74. return
  75. }
  76. f, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
  77. if err != nil {
  78. fmt.Println(MakeString(" ", "could not open log file", filePath))
  79. return
  80. }
  81. defer f.Close()
  82. if _, err = f.WriteString(Dump()); err != nil {
  83. fmt.Println("could not dump logs")
  84. }
  85. }
  86. // Retrieve - retrieves logs from given file
  87. func Retrieve(filePath string) string {
  88. contents, err := os.ReadFile(filePath)
  89. if err != nil {
  90. panic(err)
  91. }
  92. return string(contents)
  93. }
  94. // FatalLog - exits os after logging
  95. func FatalLog(message ...string) {
  96. var mu sync.Mutex
  97. mu.Lock()
  98. defer mu.Unlock()
  99. fmt.Printf("[netmaker] Fatal: %s \n", MakeString(" ", message...))
  100. os.Exit(2)
  101. }
  102. // == private ==
  103. // resetLogs - reallocates logs map
  104. func resetLogs() {
  105. currentLogs = make(map[string]string)
  106. }