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