Logwrite sync with memlogd (#3890)

* sync logwrite with memlogd

Signed-off-by: Avi Deitcher <avi@deitcher.net>

* update linuxkit/logwrite and linuxkit/memlogd dependencies

Signed-off-by: Avi Deitcher <avi@deitcher.net>

Signed-off-by: Avi Deitcher <avi@deitcher.net>
This commit is contained in:
Avi Deitcher 2023-01-03 10:47:42 +02:00 committed by GitHub
parent 6062f91648
commit a91c4a77b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 55 deletions

View File

@ -7,7 +7,7 @@ init:
- linuxkit/runc:f01b88c7033180d50ae43562d72707c6881904e4 - linuxkit/runc:f01b88c7033180d50ae43562d72707c6881904e4
- linuxkit/containerd:de1b18eed76a266baa3092e5c154c84f595e56da - linuxkit/containerd:de1b18eed76a266baa3092e5c154c84f595e56da
- linuxkit/ca-certificates:c1c73ef590dffb6a0138cf758fe4a4305c9864f4 - linuxkit/ca-certificates:c1c73ef590dffb6a0138cf758fe4a4305c9864f4
- linuxkit/memlogd:014f86dce2ea4bb2ec13e92ae5c1e854bcefec40 - linuxkit/memlogd:36758a7ab239943852c4f849283e28ba975413c6
onboot: onboot:
- name: sysctl - name: sysctl
image: linuxkit/sysctl:bdc99eeedc224439ff237990ee06e5b992c8c1ae image: linuxkit/sysctl:bdc99eeedc224439ff237990ee06e5b992c8c1ae
@ -25,6 +25,6 @@ services:
image: alpine:3.13 image: alpine:3.13
command: ["/bin/sh", "-c", "while /bin/true; do echo hello $(date); sleep 1; done" ] command: ["/bin/sh", "-c", "while /bin/true; do echo hello $(date); sleep 1; done" ]
- name: write-and-rotate-logs - name: write-and-rotate-logs
image: linuxkit/logwrite:4d8aa07d4a7130239fc62b09f33e3401ecf62a38 image: linuxkit/logwrite:6100d207d36a089f322defb60e86032c6f66078c
- name: kmsg - name: kmsg
image: linuxkit/kmsg:b2f6cd4ce9041120e30a4b5ab36bb8db4f5eb458 image: linuxkit/kmsg:b2f6cd4ce9041120e30a4b5ab36bb8db4f5eb458

View File

@ -3,8 +3,7 @@ package main
// Write logs to files and perform rotation. // Write logs to files and perform rotation.
import ( import (
"bufio" "encoding/json"
"errors"
"flag" "flag"
"fmt" "fmt"
"io" "io"
@ -27,36 +26,13 @@ const mb = 1024 * 1024
// LogMessage is a message received from memlogd. // LogMessage is a message received from memlogd.
type LogMessage struct { type LogMessage struct {
Time time.Time // time message was received by memlogd Time time.Time `json:"time"` // time message was received by memlogd
Name string // name of the service that wrote the message Source string `json:"source"` // name of the service that wrote the message
Message string // body of the message Msg string `json:"msg"` // body of the message
} }
func (m *LogMessage) String() string { func (m *LogMessage) String() string {
return m.Time.Format(time.RFC3339) + " " + m.Name + " " + m.Message return m.Time.Format(time.RFC3339) + " " + m.Source + " " + m.Msg
}
// ParseLogMessage reconstructs a LogMessage from a line of text which looks like:
// <timestamp>,<origin>;<body>
func ParseLogMessage(line string) (*LogMessage, error) {
bits := strings.SplitN(line, ";", 2)
if len(bits) != 2 {
return nil, errors.New("Failed to parse log message: " + line)
}
bits2 := strings.Split(bits[0], ",")
if len(bits2) < 2 {
// There could be more parameters in future
return nil, errors.New("Failed to parse log message: " + line)
}
Time, err := time.Parse(time.RFC3339, bits2[0])
if err != nil {
return nil, err
}
return &LogMessage{
Time: Time,
Name: bits2[1],
Message: bits[1],
}, nil
} }
// LogFile is where we write LogMessages to // LogFile is where we write LogMessages to
@ -87,7 +63,7 @@ func NewLogFile(dir, name string) (*LogFile, error) {
// Write appends a message to the log file // Write appends a message to the log file
func (l *LogFile) Write(m *LogMessage) error { func (l *LogFile) Write(m *LogMessage) error {
s := m.String() s := m.String() + "\n"
_, err := io.WriteString(l.File, s) _, err := io.WriteString(l.File, s)
if err == nil { if err == nil {
l.BytesWritten += len(s) l.BytesWritten += len(s)
@ -157,41 +133,34 @@ func main() {
// map of service name to active log file // map of service name to active log file
logs := make(map[string]*LogFile) logs := make(map[string]*LogFile)
r := bufio.NewReader(conn) var msg LogMessage
decoder := json.NewDecoder(conn)
for { for {
line, err := r.ReadString('\n') if err := decoder.Decode(&msg); err != nil {
if err == io.EOF {
return
}
if err != nil {
log.Fatalf("Failed to read from memlogd: %v", err)
}
msg, err := ParseLogMessage(line)
if err != nil {
log.Println(err) log.Println(err)
continue continue
} }
if strings.HasPrefix(msg.Name, "logwrite") { if strings.HasPrefix(msg.Source, "logwrite") {
// don't log our own output in a loop // don't log our own output in a loop
continue continue
} }
var logF *LogFile var logF *LogFile
var ok bool var ok bool
if logF, ok = logs[msg.Name]; !ok { if logF, ok = logs[msg.Source]; !ok {
logF, err = NewLogFile(*logDir, msg.Name) logF, err = NewLogFile(*logDir, msg.Source)
if err != nil { if err != nil {
log.Printf("Failed to create log file %s: %v", msg.Name, err) log.Printf("Failed to create log file %s: %v", msg.Source, err)
continue continue
} }
logs[msg.Name] = logF logs[msg.Source] = logF
} }
if err = logF.Write(msg); err != nil { if err = logF.Write(&msg); err != nil {
log.Printf("Failed to write to log file %s: %v", msg.Name, err) log.Printf("Failed to write to log file %s: %v", msg.Source, err)
if err := logF.Close(); err != nil { if err := logF.Close(); err != nil {
log.Printf("Failed to close log file %s: %v", msg.Name, err) log.Printf("Failed to close log file %s: %v", msg.Source, err)
} }
delete(logs, msg.Name) delete(logs, msg.Source)
continue continue
} }
if logF.BytesWritten > *maxLogSize { if logF.BytesWritten > *maxLogSize {

View File

@ -6,12 +6,12 @@ init:
- linuxkit/runc:f01b88c7033180d50ae43562d72707c6881904e4 - linuxkit/runc:f01b88c7033180d50ae43562d72707c6881904e4
- linuxkit/containerd:de1b18eed76a266baa3092e5c154c84f595e56da - linuxkit/containerd:de1b18eed76a266baa3092e5c154c84f595e56da
- linuxkit/ca-certificates:c1c73ef590dffb6a0138cf758fe4a4305c9864f4 - linuxkit/ca-certificates:c1c73ef590dffb6a0138cf758fe4a4305c9864f4
- linuxkit/memlogd:014f86dce2ea4bb2ec13e92ae5c1e854bcefec40 - linuxkit/memlogd:36758a7ab239943852c4f849283e28ba975413c6
services: services:
- name: kmsg - name: kmsg
image: linuxkit/kmsg:b2f6cd4ce9041120e30a4b5ab36bb8db4f5eb458 image: linuxkit/kmsg:b2f6cd4ce9041120e30a4b5ab36bb8db4f5eb458
- name: write-and-rotate-logs - name: write-and-rotate-logs
image: linuxkit/logwrite:4d8aa07d4a7130239fc62b09f33e3401ecf62a38 image: linuxkit/logwrite:6100d207d36a089f322defb60e86032c6f66078c
- name: check-the-logs - name: check-the-logs
image: alpine:3.13 image: alpine:3.13
binds: binds:

View File

@ -6,14 +6,14 @@ init:
- linuxkit/runc:f01b88c7033180d50ae43562d72707c6881904e4 - linuxkit/runc:f01b88c7033180d50ae43562d72707c6881904e4
- linuxkit/containerd:de1b18eed76a266baa3092e5c154c84f595e56da - linuxkit/containerd:de1b18eed76a266baa3092e5c154c84f595e56da
- linuxkit/ca-certificates:c1c73ef590dffb6a0138cf758fe4a4305c9864f4 - linuxkit/ca-certificates:c1c73ef590dffb6a0138cf758fe4a4305c9864f4
- linuxkit/memlogd:014f86dce2ea4bb2ec13e92ae5c1e854bcefec40 - linuxkit/memlogd:36758a7ab239943852c4f849283e28ba975413c6
services: services:
# A service which generates logs of log messages # A service which generates logs of log messages
- name: fill-the-logs - name: fill-the-logs
image: alpine image: alpine
command: ["/bin/sh", "-c", "while /bin/true; do echo hello $(date); done" ] command: ["/bin/sh", "-c", "while /bin/true; do echo hello $(date); done" ]
- name: write-and-rotate-logs - name: write-and-rotate-logs
image: linuxkit/logwrite:4d8aa07d4a7130239fc62b09f33e3401ecf62a38 image: linuxkit/logwrite:6100d207d36a089f322defb60e86032c6f66078c
command: ["/usr/bin/logwrite", "-max-log-size", "1024"] command: ["/usr/bin/logwrite", "-max-log-size", "1024"]
- name: check-the-logs - name: check-the-logs
image: alpine:3.13 image: alpine:3.13