TUN-8783: fix log collectors for the diagnostic procedure

## Summary

* The host log collector now verifies if the OS is linux and has systemd if so it will use journalctl to get the logs
* In linux systems docker will write the output of the command logs to the stderr therefore the function that handles the execution of the process will copy both the contents of stdout and stderr; this also affect the k8s collector

Closes TUN-8783
This commit is contained in:
Luis Neto 2024-12-10 09:53:13 -08:00
parent e7dcb6edca
commit 29f0cf354c
2 changed files with 55 additions and 4 deletions

View File

@ -4,13 +4,16 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
) )
const ( const (
linuxManagedLogsPath = "/var/log/cloudflared.err" linuxManagedLogsPath = "/var/log/cloudflared.err"
darwinManagedLogsPath = "/Library/Logs/com.cloudflare.cloudflared.err.log" darwinManagedLogsPath = "/Library/Logs/com.cloudflare.cloudflared.err.log"
linuxServiceConfigurationPath = "/etc/systemd/system/cloudflared.service"
linuxSystemdPath = "/run/systemd/system"
) )
type HostLogCollector struct { type HostLogCollector struct {
@ -23,6 +26,28 @@ func NewHostLogCollector(client HTTPClient) *HostLogCollector {
} }
} }
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)
}
func getServiceLogPath() (string, error) { func getServiceLogPath() (string, error) {
switch runtime.GOOS { switch runtime.GOOS {
case "darwin": case "darwin":
@ -55,6 +80,13 @@ func (collector *HostLogCollector) Collect(ctx context.Context) (*LogInformation
} }
if logConfiguration.uid == 0 { if logConfiguration.uid == 0 {
_, statSystemdErr := os.Stat(linuxServiceConfigurationPath)
_, statServiceConfigurationErr := os.Stat(linuxServiceConfigurationPath)
if statSystemdErr == nil && statServiceConfigurationErr == nil && runtime.GOOS == "linux" {
return extractLogsFromJournalCtl(ctx)
}
path, err := getServiceLogPath() path, err := getServiceLogPath()
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -12,7 +12,16 @@ func PipeCommandOutputToFile(command *exec.Cmd, outputHandle *os.File) (*LogInfo
stdoutReader, err := command.StdoutPipe() stdoutReader, err := command.StdoutPipe()
if err != nil { if err != nil {
return nil, fmt.Errorf( return nil, fmt.Errorf(
"error retrieving output from command '%s': %w", "error retrieving stdout from command '%s': %w",
command.String(),
err,
)
}
stderrReader, err := command.StderrPipe()
if err != nil {
return nil, fmt.Errorf(
"error retrieving stderr from command '%s': %w",
command.String(), command.String(),
err, err,
) )
@ -29,7 +38,17 @@ func PipeCommandOutputToFile(command *exec.Cmd, outputHandle *os.File) (*LogInfo
_, err = io.Copy(outputHandle, stdoutReader) _, err = io.Copy(outputHandle, stdoutReader)
if err != nil { if err != nil {
return nil, fmt.Errorf( return nil, fmt.Errorf(
"error copying output from %s to file %s: %w", "error copying stdout from %s to file %s: %w",
command.String(),
outputHandle.Name(),
err,
)
}
_, err = io.Copy(outputHandle, stderrReader)
if err != nil {
return nil, fmt.Errorf(
"error copying stderr from %s to file %s: %w",
command.String(), command.String(),
outputHandle.Name(), outputHandle.Name(),
err, err,