Skip to content

Commit d403902

Browse files
authored
Merge pull request #176 from flyingmutant/journal-bytes
sdjournal: add GetDataBytes() and GetDataValueBytes() to Journal
2 parents 5f8a27b + b141b6a commit d403902

File tree

2 files changed

+116
-22
lines changed

2 files changed

+116
-22
lines changed

sdjournal/journal.go

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ package sdjournal
257257
//
258258
import "C"
259259
import (
260+
"bytes"
260261
"fmt"
261262
"path/filepath"
262263
"strings"
@@ -614,12 +615,10 @@ func (j *Journal) PreviousSkip(skip uint64) (uint64, error) {
614615
return uint64(r), nil
615616
}
616617

617-
// GetData gets the data object associated with a specific field from the
618-
// current journal entry.
619-
func (j *Journal) GetData(field string) (string, error) {
618+
func (j *Journal) getData(field string) (unsafe.Pointer, C.int, error) {
620619
sd_journal_get_data, err := j.getFunction("sd_journal_get_data")
621620
if err != nil {
622-
return "", err
621+
return nil, 0, err
623622
}
624623

625624
f := C.CString(field)
@@ -633,12 +632,21 @@ func (j *Journal) GetData(field string) (string, error) {
633632
j.mu.Unlock()
634633

635634
if r < 0 {
636-
return "", fmt.Errorf("failed to read message: %d", syscall.Errno(-r))
635+
return nil, 0, fmt.Errorf("failed to read message: %d", syscall.Errno(-r))
637636
}
638637

639-
msg := C.GoStringN((*C.char)(d), C.int(l))
638+
return d, C.int(l), nil
639+
}
640+
641+
// GetData gets the data object associated with a specific field from the
642+
// current journal entry.
643+
func (j *Journal) GetData(field string) (string, error) {
644+
d, l, err := j.getData(field)
645+
if err != nil {
646+
return "", err
647+
}
640648

641-
return msg, nil
649+
return C.GoStringN((*C.char)(d), l), nil
642650
}
643651

644652
// GetDataValue gets the data object associated with a specific field from the
@@ -648,9 +656,32 @@ func (j *Journal) GetDataValue(field string) (string, error) {
648656
if err != nil {
649657
return "", err
650658
}
659+
651660
return strings.SplitN(val, "=", 2)[1], nil
652661
}
653662

663+
// GetDataBytes gets the data object associated with a specific field from the
664+
// current journal entry.
665+
func (j *Journal) GetDataBytes(field string) ([]byte, error) {
666+
d, l, err := j.getData(field)
667+
if err != nil {
668+
return nil, err
669+
}
670+
671+
return C.GoBytes(d, l), nil
672+
}
673+
674+
// GetDataValueBytes gets the data object associated with a specific field from the
675+
// current journal entry, returning only the value of the object.
676+
func (j *Journal) GetDataValueBytes(field string) ([]byte, error) {
677+
val, err := j.GetDataBytes(field)
678+
if err != nil {
679+
return nil, err
680+
}
681+
682+
return bytes.SplitN(val, []byte("="), 2)[1], nil
683+
}
684+
654685
// GetEntry returns a full representation of a journal entry with
655686
// all key-value pairs of data as well as address fields (cursor, realtime
656687
// timestamp and monotonic timestamp)

sdjournal/journal_test.go

Lines changed: 78 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -178,53 +178,116 @@ func TestNewJournalFromDir(t *testing.T) {
178178
j.Close()
179179
}
180180

181-
func TestJournalGetEntry(t *testing.T) {
181+
func setupJournalRoundtrip() (*Journal, map[string]string, error) {
182182
j, err := NewJournal()
183183
if err != nil {
184-
t.Fatalf("Error opening journal: %s", err)
184+
return nil, nil, fmt.Errorf("Error opening journal: %s", err)
185185
}
186186

187187
if j == nil {
188-
t.Fatal("Got a nil journal")
188+
return nil, nil, fmt.Errorf("Got a nil journal")
189189
}
190190

191-
defer j.Close()
192-
193191
j.FlushMatches()
194192

195-
matchField := "TESTJOURNALGETENTRY"
193+
matchField := "TESTJOURNALENTRY"
196194
matchValue := fmt.Sprintf("%d", time.Now().UnixNano())
197195
m := Match{Field: matchField, Value: matchValue}
198196
err = j.AddMatch(m.String())
199197
if err != nil {
200-
t.Fatalf("Error adding matches to journal: %s", err)
198+
return nil, nil, fmt.Errorf("Error adding matches to journal: %s", err)
201199
}
202200

203-
want := fmt.Sprintf("test journal get entry message %s", time.Now())
204-
err = journal.Send(want, journal.PriInfo, map[string]string{matchField: matchValue})
201+
msg := fmt.Sprintf("test journal get entry message %s", time.Now())
202+
data := map[string]string{matchField: matchValue}
203+
err = journal.Send(msg, journal.PriInfo, data)
205204
if err != nil {
206-
t.Fatalf("Error writing to journal: %s", err)
205+
return nil, nil, fmt.Errorf("Error writing to journal: %s", err)
207206
}
208207

209208
time.Sleep(time.Duration(1) * time.Second)
210209

211210
n, err := j.Next()
212211
if err != nil {
213-
t.Fatalf("Error reading to journal: %s", err)
212+
return nil, nil, fmt.Errorf("Error reading from journal: %s", err)
214213
}
215214

216215
if n == 0 {
217-
t.Fatalf("Error reading to journal: %s", io.EOF)
216+
return nil, nil, fmt.Errorf("Error reading from journal: %s", io.EOF)
218217
}
219218

219+
data["MESSAGE"] = msg
220+
221+
return j, data, nil
222+
}
223+
224+
func TestJournalGetData(t *testing.T) {
225+
j, wantEntry, err := setupJournalRoundtrip()
226+
if err != nil {
227+
t.Fatal(err.Error())
228+
}
229+
230+
defer j.Close()
231+
232+
for k, v := range wantEntry {
233+
data := fmt.Sprintf("%s=%s", k, v)
234+
235+
dataStr, err := j.GetData(k)
236+
if err != nil {
237+
t.Fatalf("GetData() error: %v", err)
238+
}
239+
240+
if dataStr != data {
241+
t.Fatalf("Invalid data for \"%s\": got %s, want %s", k, dataStr, data)
242+
}
243+
244+
dataBytes, err := j.GetDataBytes(k)
245+
if err != nil {
246+
t.Fatalf("GetDataBytes() error: %v", err)
247+
}
248+
249+
if string(dataBytes) != data {
250+
t.Fatalf("Invalid data bytes for \"%s\": got %s, want %s", k, string(dataBytes), data)
251+
}
252+
253+
valStr, err := j.GetDataValue(k)
254+
if err != nil {
255+
t.Fatalf("GetDataValue() error: %v", err)
256+
}
257+
258+
if valStr != v {
259+
t.Fatalf("Invalid data value for \"%s\": got %s, want %s", k, valStr, v)
260+
}
261+
262+
valBytes, err := j.GetDataValueBytes(k)
263+
if err != nil {
264+
t.Fatalf("GetDataValueBytes() error: %v", err)
265+
}
266+
267+
if string(valBytes) != v {
268+
t.Fatalf("Invalid data value bytes for \"%s\": got %s, want %s", k, string(valBytes), v)
269+
}
270+
}
271+
}
272+
273+
func TestJournalGetEntry(t *testing.T) {
274+
j, wantEntry, err := setupJournalRoundtrip()
275+
if err != nil {
276+
t.Fatal(err.Error())
277+
}
278+
279+
defer j.Close()
280+
220281
entry, err := j.GetEntry()
221282
if err != nil {
222283
t.Fatalf("Error getting the entry to journal: %s", err)
223284
}
224285

225-
got := entry.Fields["MESSAGE"]
226-
if got != want {
227-
t.Fatalf("Bad result for entry.Fields[\"MESSAGE\"]: got %s, want %s", got, want)
286+
for k, wantV := range wantEntry {
287+
gotV := entry.Fields[k]
288+
if gotV != wantV {
289+
t.Fatalf("Bad result for entry.Fields[\"%s\"]: got %s, want %s", k, gotV, wantV)
290+
}
228291
}
229292
}
230293

0 commit comments

Comments
 (0)