logger.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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]entry)
  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] = entry{
  36. Time: currentTime.Format("2006-01-02 15:04:05.999999999"),
  37. Count: currentLogs[currentMessage].Count + 1,
  38. }
  39. }
  40. }
  41. // Dump - dumps all logs into a formatted string
  42. func Dump() string {
  43. if program != "netmaker" {
  44. return ""
  45. }
  46. var dumpString = ""
  47. type keyVal struct {
  48. Key string
  49. Value time.Time
  50. Count int
  51. }
  52. var dumpLogs = make([]keyVal, 0, len(currentLogs))
  53. for key := range currentLogs {
  54. currentEntry := currentLogs[key]
  55. parsedTime, err := time.Parse(TimeFormat, currentEntry.Time)
  56. if err == nil {
  57. dumpLogs = append(dumpLogs, keyVal{
  58. Key: key,
  59. Value: parsedTime,
  60. Count: currentEntry.Count,
  61. })
  62. }
  63. }
  64. sort.Slice(dumpLogs, func(i, j int) bool {
  65. return dumpLogs[i].Value.Before(dumpLogs[j].Value)
  66. })
  67. for i := range dumpLogs {
  68. var currLog = dumpLogs[i]
  69. dumpString += MakeString(" ", "[netmaker]", currLog.Value.Format(TimeFormat), currLog.Key, fmt.Sprintf("(%d)", currLog.Count), "\n")
  70. }
  71. resetLogs()
  72. return dumpString
  73. }
  74. // DumpFile - appends log dump log file
  75. func DumpFile(filePath string) {
  76. if program != "netmaker" {
  77. return
  78. }
  79. f, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
  80. if err != nil {
  81. fmt.Println(MakeString(" ", "could not open log file", filePath))
  82. return
  83. }
  84. defer f.Close()
  85. if _, err = f.WriteString(Dump()); err != nil {
  86. fmt.Println("could not dump logs")
  87. }
  88. }
  89. // Retrieve - retrieves logs from given file
  90. func Retrieve(filePath string) string {
  91. contents, err := os.ReadFile(filePath)
  92. if err != nil {
  93. panic(err)
  94. }
  95. return string(contents)
  96. }
  97. // FatalLog - exits os after logging
  98. func FatalLog(message ...string) {
  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. mu.Lock()
  106. defer mu.Unlock()
  107. currentLogs = make(map[string]entry)
  108. }