first
This commit is contained in:
commit
f4be03ceba
1826 changed files with 830924 additions and 0 deletions
88
backend/internal/mail/logs.go
Normal file
88
backend/internal/mail/logs.go
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
package mail
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type LogEntry struct {
|
||||
Timestamp string `json:"timestamp"`
|
||||
Priority string `json:"priority"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func GetLogs(hours int, filter string) ([]LogEntry, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
args := []string{
|
||||
"-u", "postfix",
|
||||
"--since", formatDuration(hours),
|
||||
"--no-pager",
|
||||
"-o", "short=false",
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, "journalctl", args...)
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var entries []LogEntry
|
||||
scanner := bufio.NewScanner(&out)
|
||||
priorityRegex := regexp.MustCompile(`\[([^\]]+)\]`)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
if filter != "" && !strings.Contains(strings.ToLower(line), strings.ToLower(filter)) {
|
||||
continue
|
||||
}
|
||||
|
||||
parts := strings.SplitN(line, " ", 4)
|
||||
if len(parts) < 4 {
|
||||
continue
|
||||
}
|
||||
|
||||
timestamp := parts[0] + " " + parts[1]
|
||||
|
||||
matches := priorityRegex.FindStringSubmatch(parts[2])
|
||||
priority := "info"
|
||||
if len(matches) > 1 {
|
||||
priority = matches[1]
|
||||
} else if strings.Contains(parts[2], "err") {
|
||||
priority = "err"
|
||||
} else if strings.Contains(parts[2], "warning") || strings.Contains(parts[2], "warn") {
|
||||
priority = "warning"
|
||||
}
|
||||
|
||||
message := parts[3]
|
||||
|
||||
if filter != "" && !strings.Contains(strings.ToLower(message), strings.ToLower(filter)) {
|
||||
continue
|
||||
}
|
||||
|
||||
entries = append(entries, LogEntry{
|
||||
Timestamp: timestamp,
|
||||
Priority: priority,
|
||||
Message: message,
|
||||
})
|
||||
}
|
||||
|
||||
if entries == nil {
|
||||
entries = []LogEntry{}
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func formatDuration(hours int) string {
|
||||
return time.Now().Add(-time.Duration(hours) * time.Hour).Format("15:04:05 2006-01-02")
|
||||
}
|
||||
123
backend/internal/mail/queue.go
Normal file
123
backend/internal/mail/queue.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package mail
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type QueueEntry struct {
|
||||
ID string `json:"id"`
|
||||
Sender string `json:"sender"`
|
||||
Recipients []string `json:"recipients"`
|
||||
Size int `json:"size"`
|
||||
Time string `json:"time"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
var queueLineRegex = regexp.MustCompile(`^([A-Fa-f0-9]+)\s+(\d+)\s+(\w+)\s+([A-Za-z]+\s+\d+\s+[\d:]+)\s+([^\s]+)\s+(.+)$`)
|
||||
|
||||
func GetQueue() ([]QueueEntry, error) {
|
||||
cmd := exec.Command("postqueue", "-p", "-j")
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var entries []QueueEntry
|
||||
scanner := bufio.NewScanner(&out)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if line == "" || !strings.HasPrefix(line, "{") {
|
||||
continue
|
||||
}
|
||||
|
||||
var entry struct {
|
||||
QueueID string `json:"queueid"`
|
||||
Sender string `json:"sender"`
|
||||
Recipients []struct {
|
||||
Address string `json:"address"`
|
||||
} `json:"recipients"`
|
||||
Size int64 `json:"size"`
|
||||
Arrival string `json:"arrival_timestamp"`
|
||||
Delay string `json:"delay_reason"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(line), &entry); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
recipients := make([]string, len(entry.Recipients))
|
||||
for i, r := range entry.Recipients {
|
||||
recipients[i] = r.Address
|
||||
}
|
||||
|
||||
entries = append(entries, QueueEntry{
|
||||
ID: entry.QueueID,
|
||||
Sender: entry.Sender,
|
||||
Recipients: recipients,
|
||||
Size: int(entry.Size),
|
||||
Time: entry.Arrival,
|
||||
Reason: entry.Delay,
|
||||
})
|
||||
}
|
||||
|
||||
if entries == nil {
|
||||
entries = []QueueEntry{}
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func RequeueMail(id string) error {
|
||||
cmd := exec.Command("postqueue", "-f", "-v")
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &out
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeleteFromQueue(id string) error {
|
||||
cmd := exec.Command("postsuper", "-d", id)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func GetQueueCount() (int, error) {
|
||||
cmd := exec.Command("postqueue", "-p")
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
count := 0
|
||||
scanner := bufio.NewScanner(&out)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.Contains(line, " mail queue") {
|
||||
parts := strings.Fields(line)
|
||||
for i, p := range parts {
|
||||
if n, err := strconv.Atoi(p); err == nil && n > 0 {
|
||||
count = n
|
||||
if i > 0 && parts[i-1] == "in" {
|
||||
return n, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue