2024-11-26 18:30:44 +00:00
|
|
|
package diagnostic
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
2024-12-10 17:53:13 +00:00
|
|
|
"os/exec"
|
2024-11-26 18:30:44 +00:00
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2024-12-10 17:53:13 +00:00
|
|
|
linuxManagedLogsPath = "/var/log/cloudflared.err"
|
|
|
|
darwinManagedLogsPath = "/Library/Logs/com.cloudflare.cloudflared.err.log"
|
|
|
|
linuxServiceConfigurationPath = "/etc/systemd/system/cloudflared.service"
|
|
|
|
linuxSystemdPath = "/run/systemd/system"
|
2024-11-26 18:30:44 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type HostLogCollector struct {
|
|
|
|
client HTTPClient
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewHostLogCollector(client HTTPClient) *HostLogCollector {
|
|
|
|
return &HostLogCollector{
|
|
|
|
client,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-10 17:53:13 +00:00
|
|
|
func extractLogsFromJournalCtl(ctx context.Context) (*LogInformation, error) {
|
|
|
|
tmp := os.TempDir()
|
|
|
|
|
|
|
|
outputHandle, err := os.Create(filepath.Join(tmp, logFilename))
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("error opening output file: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
defer outputHandle.Close()
|
|
|
|
|
|
|
|
command := exec.CommandContext(
|
|
|
|
ctx,
|
|
|
|
"journalctl",
|
|
|
|
"--since",
|
|
|
|
"2 weeks ago",
|
|
|
|
"-u",
|
|
|
|
"cloudflared.service",
|
|
|
|
)
|
|
|
|
|
|
|
|
return PipeCommandOutputToFile(command, outputHandle)
|
|
|
|
}
|
|
|
|
|
2024-11-26 18:30:44 +00:00
|
|
|
func getServiceLogPath() (string, error) {
|
|
|
|
switch runtime.GOOS {
|
|
|
|
case "darwin":
|
|
|
|
{
|
|
|
|
path := darwinManagedLogsPath
|
|
|
|
if _, err := os.Stat(path); err == nil {
|
|
|
|
return path, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
userHomeDir, err := os.UserHomeDir()
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("error getting user home: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return filepath.Join(userHomeDir, darwinManagedLogsPath), nil
|
|
|
|
}
|
|
|
|
case "linux":
|
|
|
|
{
|
|
|
|
return linuxManagedLogsPath, nil
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return "", ErrManagedLogNotFound
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (collector *HostLogCollector) Collect(ctx context.Context) (*LogInformation, error) {
|
|
|
|
logConfiguration, err := collector.client.GetLogConfiguration(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("error getting log configuration: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if logConfiguration.uid == 0 {
|
2024-12-10 17:53:13 +00:00
|
|
|
_, statSystemdErr := os.Stat(linuxServiceConfigurationPath)
|
|
|
|
|
|
|
|
_, statServiceConfigurationErr := os.Stat(linuxServiceConfigurationPath)
|
|
|
|
if statSystemdErr == nil && statServiceConfigurationErr == nil && runtime.GOOS == "linux" {
|
|
|
|
return extractLogsFromJournalCtl(ctx)
|
|
|
|
}
|
|
|
|
|
2024-11-26 18:30:44 +00:00
|
|
|
path, err := getServiceLogPath()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return NewLogInformation(path, false, false), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if logConfiguration.logFile != "" {
|
|
|
|
return NewLogInformation(logConfiguration.logFile, false, false), nil
|
|
|
|
} else if logConfiguration.logDirectory != "" {
|
|
|
|
return NewLogInformation(logConfiguration.logDirectory, false, true), nil
|
|
|
|
}
|
|
|
|
|
2024-12-04 11:37:57 +00:00
|
|
|
return nil, ErrLogConfigurationIsInvalid
|
2024-11-26 18:30:44 +00:00
|
|
|
}
|