feat(aa-log): add support dbus session log using journactl.
This commit is contained in:
parent
a2fa2421cb
commit
c0356e92e5
3 changed files with 212 additions and 11 deletions
|
|
@ -1,16 +1,19 @@
|
|||
// aa-log - Review AppArmor generated messages
|
||||
// Copyright (C) 2021 Alexandre Pujol <alexandre@pujol.io>
|
||||
// Copyright (C) 2021-2022 Alexandre Pujol <alexandre@pujol.io>
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
|
@ -18,8 +21,9 @@ import (
|
|||
|
||||
// Command line options
|
||||
var (
|
||||
help bool
|
||||
path string
|
||||
dbus bool
|
||||
help bool
|
||||
path string
|
||||
)
|
||||
|
||||
// LogFile is the default path to the file to query
|
||||
|
|
@ -45,6 +49,11 @@ type AppArmorLog map[string]string
|
|||
// AppArmorLogs describes all apparmor log entries
|
||||
type AppArmorLogs []AppArmorLog
|
||||
|
||||
// SystemdLog is a simplified systemd json log representation.
|
||||
type SystemdLog struct {
|
||||
Message string `json:"MESSAGE"`
|
||||
}
|
||||
|
||||
var (
|
||||
quoted bool
|
||||
isHexa = regexp.MustCompile("^[0-9A-Fa-f]+$")
|
||||
|
|
@ -84,6 +93,40 @@ func removeDuplicateLog(logs []string) []string {
|
|||
return list
|
||||
}
|
||||
|
||||
// getJournalctlDbusSessionLogs return a reader with the logs entries
|
||||
func getJournalctlDbusSessionLogs(file io.Reader, useFile bool) (io.Reader, error) {
|
||||
var logs []SystemdLog
|
||||
var stdout bytes.Buffer
|
||||
var value string
|
||||
|
||||
if useFile {
|
||||
content, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value = string(content)
|
||||
} else {
|
||||
cmd := exec.Command("journalctl", "--user", "-b", "-u", "dbus.service", "-o", "json")
|
||||
cmd.Stdout = &stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value = stdout.String()
|
||||
}
|
||||
|
||||
value = strings.Replace(value, "\n", ",\n", -1)
|
||||
value = strings.TrimSuffix(value, ",\n")
|
||||
value = `[` + value + `]`
|
||||
if err := json.Unmarshal([]byte(value), &logs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := ""
|
||||
for _, log := range logs {
|
||||
res += log.Message + "\n"
|
||||
}
|
||||
return strings.NewReader(res), nil
|
||||
}
|
||||
|
||||
// NewApparmorLogs return a new ApparmorLogs list of map from a log file
|
||||
func NewApparmorLogs(file io.Reader, profile string) AppArmorLogs {
|
||||
log := ""
|
||||
|
|
@ -198,7 +241,7 @@ func (aaLogs AppArmorLogs) String() string {
|
|||
return res
|
||||
}
|
||||
|
||||
func aaLog(path string, profile string) error {
|
||||
func aaLog(path string, profile string, dbus bool) error {
|
||||
file, err := os.Open(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -210,21 +253,31 @@ func aaLog(path string, profile string) error {
|
|||
}
|
||||
}()
|
||||
|
||||
aaLogs := NewApparmorLogs(file, profile)
|
||||
fmt.Print(aaLogs.String())
|
||||
return err
|
||||
if dbus {
|
||||
file, err := getJournalctlDbusSessionLogs(file, path != LogFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aaLogs := NewApparmorLogs(file, profile)
|
||||
fmt.Print(aaLogs.String())
|
||||
} else {
|
||||
aaLogs := NewApparmorLogs(file, profile)
|
||||
fmt.Print(aaLogs.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
flag.BoolVar(&help, "h", false, "Show this help message and exit.")
|
||||
flag.StringVar(&path, "f", LogFile,
|
||||
"Set a log`file` or a suffix to the default log file.")
|
||||
flag.BoolVar(&dbus, "d", false, "Show dbus session event.")
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if help {
|
||||
fmt.Printf(`aa-log [-h] [-f file] [profile]
|
||||
fmt.Printf(`aa-log [-h] [-d] [-f file] [profile]
|
||||
|
||||
Review AppArmor generated messages in a colorful way.
|
||||
It can be given an optional profile name to filter the output with.
|
||||
|
|
@ -244,7 +297,7 @@ func main() {
|
|||
logfile = path
|
||||
}
|
||||
|
||||
err := aaLog(logfile, profile)
|
||||
err := aaLog(logfile, profile, dbus)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue