logger.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package logging
  2. import (
  3. "fmt"
  4. "log/slog"
  5. "os"
  6. "runtime/debug"
  7. "time"
  8. )
  9. func Info(msg string, args ...any) {
  10. slog.Info(msg, args...)
  11. }
  12. func Debug(msg string, args ...any) {
  13. slog.Debug(msg, args...)
  14. }
  15. func Warn(msg string, args ...any) {
  16. slog.Warn(msg, args...)
  17. }
  18. func Error(msg string, args ...any) {
  19. slog.Error(msg, args...)
  20. }
  21. func InfoPersist(msg string, args ...any) {
  22. args = append(args, persistKeyArg, true)
  23. slog.Info(msg, args...)
  24. }
  25. func DebugPersist(msg string, args ...any) {
  26. args = append(args, persistKeyArg, true)
  27. slog.Debug(msg, args...)
  28. }
  29. func WarnPersist(msg string, args ...any) {
  30. args = append(args, persistKeyArg, true)
  31. slog.Warn(msg, args...)
  32. }
  33. func ErrorPersist(msg string, args ...any) {
  34. args = append(args, persistKeyArg, true)
  35. slog.Error(msg, args...)
  36. }
  37. // RecoverPanic is a common function to handle panics gracefully.
  38. // It logs the error, creates a panic log file with stack trace,
  39. // and executes an optional cleanup function before returning.
  40. func RecoverPanic(name string, cleanup func()) {
  41. if r := recover(); r != nil {
  42. // Log the panic
  43. ErrorPersist(fmt.Sprintf("Panic in %s: %v", name, r))
  44. // Create a timestamped panic log file
  45. timestamp := time.Now().Format("20060102-150405")
  46. filename := fmt.Sprintf("opencode-panic-%s-%s.log", name, timestamp)
  47. file, err := os.Create(filename)
  48. if err != nil {
  49. ErrorPersist(fmt.Sprintf("Failed to create panic log: %v", err))
  50. } else {
  51. defer file.Close()
  52. // Write panic information and stack trace
  53. fmt.Fprintf(file, "Panic in %s: %v\n\n", name, r)
  54. fmt.Fprintf(file, "Time: %s\n\n", time.Now().Format(time.RFC3339))
  55. fmt.Fprintf(file, "Stack Trace:\n%s\n", debug.Stack())
  56. InfoPersist(fmt.Sprintf("Panic details written to %s", filename))
  57. }
  58. // Execute cleanup function if provided
  59. if cleanup != nil {
  60. cleanup()
  61. }
  62. }
  63. }