/ pkg / system / journal.go
journal.go
 1  package system
 2  
 3  import (
 4  	"context"
 5  	"fmt"
 6  	"time"
 7  
 8  	"github.com/coreos/go-systemd/sdjournal"
 9  	dogeboxd "github.com/dogeorg/dogeboxd/pkg"
10  )
11  
12  func NewJournalReader(config dogeboxd.ServerConfig) JournalReader {
13  	return JournalReader{
14  		config: config,
15  	}
16  }
17  
18  type JournalReader struct {
19  	config dogeboxd.ServerConfig
20  }
21  
22  func (t JournalReader) GetJournalChan(service string) (context.CancelFunc, chan string, error) {
23  	ctx, cancel := context.WithCancel(context.Background())
24  
25  	out := make(chan string, 10)
26  
27  	go func() {
28  		j, err := sdjournal.NewJournal()
29  		if err != nil {
30  			fmt.Println(err)
31  			return
32  		}
33  		defer j.Close()
34  
35  		// Add a match for the specific service
36  		err = j.AddMatch(fmt.Sprintf("_SYSTEMD_UNIT=%s", service))
37  		if err != nil {
38  			fmt.Println(err)
39  			return
40  		}
41  
42  		// Seek to the end of the journal
43  		err = j.SeekTail()
44  		if err != nil {
45  			fmt.Println(err)
46  			return
47  		}
48  
49  		// skip back 50 lines..
50  		_, err = j.PreviousSkip(50)
51  		if err != nil {
52  			fmt.Println(err)
53  			return
54  		}
55  
56  		for {
57  			select {
58  			case <-ctx.Done():
59  				break
60  			default:
61  				i, err := j.Next()
62  				if err != nil {
63  					fmt.Println("!!", err)
64  					continue
65  				}
66  
67  				if i == 0 {
68  					time.Sleep(time.Second)
69  					continue
70  				}
71  
72  				entry, err := j.GetEntry()
73  				if err != nil {
74  					continue
75  				}
76  
77  				out <- entry.Fields["MESSAGE"]
78  			}
79  		}
80  	}()
81  	return cancel, out, nil
82  }