//go:build linux package logger import ( "os" "strconv" "strings" "syscall" ) // stderrIsJournal reports whether os.Stderr is currently connected to // the systemd journal. systemd.exec(5) sets JOURNAL_STREAM to // ":" of the journal stream at service start. Detection // must fstat(2) the actual stderr and compare — a child process may // redirect stderr while inheriting the env var, so presence of the // variable alone is not sufficient. func stderrIsJournal() bool { dev, ino, ok := parseJournalStream(os.Getenv("JOURNAL_STREAM")) if !ok { return false } var st syscall.Stat_t if err := syscall.Fstat(int(os.Stderr.Fd()), &st); err != nil { return false } return uint64(st.Dev) == dev && uint64(st.Ino) == ino } func parseJournalStream(v string) (dev, ino uint64, ok bool) { sep := strings.IndexByte(v, ':') if sep <= 0 || sep == len(v)-1 { return 0, 0, false } d, err1 := strconv.ParseUint(v[:sep], 10, 64) n, err2 := strconv.ParseUint(v[sep+1:], 10, 64) if err1 != nil || err2 != nil { return 0, 0, false } return d, n, true }