log_collector_host.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package diagnostic
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "os/exec"
  7. "path/filepath"
  8. "runtime"
  9. )
  10. const (
  11. linuxManagedLogsPath = "/var/log/cloudflared.err"
  12. darwinManagedLogsPath = "/Library/Logs/com.cloudflare.cloudflared.err.log"
  13. linuxServiceConfigurationPath = "/etc/systemd/system/cloudflared.service"
  14. linuxSystemdPath = "/run/systemd/system"
  15. )
  16. type HostLogCollector struct {
  17. client HTTPClient
  18. }
  19. func NewHostLogCollector(client HTTPClient) *HostLogCollector {
  20. return &HostLogCollector{
  21. client,
  22. }
  23. }
  24. func extractLogsFromJournalCtl(ctx context.Context) (*LogInformation, error) {
  25. tmp := os.TempDir()
  26. outputHandle, err := os.Create(filepath.Join(tmp, logFilename))
  27. if err != nil {
  28. return nil, fmt.Errorf("error opening output file: %w", err)
  29. }
  30. defer outputHandle.Close()
  31. command := exec.CommandContext(
  32. ctx,
  33. "journalctl",
  34. "--since",
  35. "2 weeks ago",
  36. "-u",
  37. "cloudflared.service",
  38. )
  39. return PipeCommandOutputToFile(command, outputHandle)
  40. }
  41. func getServiceLogPath() (string, error) {
  42. switch runtime.GOOS {
  43. case "darwin":
  44. {
  45. path := darwinManagedLogsPath
  46. if _, err := os.Stat(path); err == nil {
  47. return path, nil
  48. }
  49. userHomeDir, err := os.UserHomeDir()
  50. if err != nil {
  51. return "", fmt.Errorf("error getting user home: %w", err)
  52. }
  53. return filepath.Join(userHomeDir, darwinManagedLogsPath), nil
  54. }
  55. case "linux":
  56. {
  57. return linuxManagedLogsPath, nil
  58. }
  59. default:
  60. return "", ErrManagedLogNotFound
  61. }
  62. }
  63. func (collector *HostLogCollector) Collect(ctx context.Context) (*LogInformation, error) {
  64. logConfiguration, err := collector.client.GetLogConfiguration(ctx)
  65. if err != nil {
  66. return nil, fmt.Errorf("error getting log configuration: %w", err)
  67. }
  68. if logConfiguration.uid == 0 {
  69. _, statSystemdErr := os.Stat(linuxServiceConfigurationPath)
  70. _, statServiceConfigurationErr := os.Stat(linuxServiceConfigurationPath)
  71. if statSystemdErr == nil && statServiceConfigurationErr == nil && runtime.GOOS == "linux" {
  72. return extractLogsFromJournalCtl(ctx)
  73. }
  74. path, err := getServiceLogPath()
  75. if err != nil {
  76. return nil, err
  77. }
  78. return NewLogInformation(path, false, false), nil
  79. }
  80. if logConfiguration.logFile != "" {
  81. return NewLogInformation(logConfiguration.logFile, false, false), nil
  82. } else if logConfiguration.logDirectory != "" {
  83. return NewLogInformation(logConfiguration.logDirectory, false, true), nil
  84. }
  85. return nil, ErrLogConfigurationIsInvalid
  86. }