forked from rs/zerolog
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JournalD writer decodes each log event and map fields to journald fields. The JSON payload is kept in the `JSON` field.
- Loading branch information
Showing
4 changed files
with
180 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// +build !windows | ||
|
||
package journald | ||
|
||
// This file provides a zerolog writer so that logs printed | ||
// using zerolog library can be sent to a journalD. | ||
|
||
// Zerolog's Top level key/Value Pairs are translated to | ||
// journald's args - all Values are sent to journald as strings. | ||
// And all key strings are converted to uppercase before sending | ||
// to journald (as required by journald). | ||
|
||
// In addition, entire log message (all Key Value Pairs), is also | ||
// sent to journald under the key "JSON". | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"github.com/coreos/go-systemd/journal" | ||
"github.com/rs/zerolog" | ||
"github.com/rs/zerolog/internal/cbor" | ||
"io" | ||
"strings" | ||
) | ||
|
||
const defaultJournalDPrio = journal.PriNotice | ||
|
||
// NewJournalDWriter returns a zerolog log destination | ||
// to be used as parameter to New() calls. Writing logs | ||
// to this writer will send the log messages to journalD | ||
// running in this system. | ||
func NewJournalDWriter() io.Writer { | ||
return journalWriter{} | ||
} | ||
|
||
type journalWriter struct { | ||
} | ||
|
||
// levelToJPrio converts zerolog Level string into | ||
// journalD's priority values. JournalD has more | ||
// priorities than zerolog. | ||
func levelToJPrio(zLevel string) journal.Priority { | ||
lvl, _ := zerolog.ParseLevel(zLevel) | ||
|
||
switch lvl { | ||
case zerolog.DebugLevel: | ||
return journal.PriDebug | ||
case zerolog.InfoLevel: | ||
return journal.PriInfo | ||
case zerolog.WarnLevel: | ||
return journal.PriWarning | ||
case zerolog.ErrorLevel: | ||
return journal.PriErr | ||
case zerolog.FatalLevel: | ||
return journal.PriCrit | ||
case zerolog.PanicLevel: | ||
return journal.PriEmerg | ||
case zerolog.NoLevel: | ||
return journal.PriNotice | ||
} | ||
return defaultJournalDPrio | ||
} | ||
|
||
func (w journalWriter) Write(p []byte) (n int, err error) { | ||
if !journal.Enabled() { | ||
err = fmt.Errorf("Cannot connect to journalD!!") | ||
return | ||
} | ||
var event map[string]interface{} | ||
p = cbor.DecodeIfBinaryToBytes(p) | ||
d := json.NewDecoder(bytes.NewReader(p)) | ||
d.UseNumber() | ||
err = d.Decode(&event) | ||
jPrio := defaultJournalDPrio | ||
args := make(map[string]string, 0) | ||
if err != nil { | ||
return | ||
} | ||
if l, ok := event[zerolog.LevelFieldName].(string); ok { | ||
jPrio = levelToJPrio(l) | ||
} | ||
|
||
msg := "" | ||
for key, value := range event { | ||
jKey := strings.ToUpper(key) | ||
switch key { | ||
case zerolog.LevelFieldName, zerolog.TimestampFieldName: | ||
continue | ||
case zerolog.MessageFieldName: | ||
msg, _ = value.(string) | ||
continue | ||
} | ||
|
||
switch value.(type) { | ||
case string: | ||
args[jKey], _ = value.(string) | ||
case json.Number: | ||
args[jKey] = fmt.Sprint(value) | ||
default: | ||
b, err := json.Marshal(value) | ||
if err != nil { | ||
args[jKey] = fmt.Sprintf("[error: %v]", err) | ||
} else { | ||
args[jKey] = string(b) | ||
} | ||
} | ||
} | ||
args["JSON"] = string(p) | ||
err = journal.Send(msg, jPrio, args) | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// +build !windows | ||
|
||
package journald_test | ||
|
||
import "github.com/rs/zerolog" | ||
import "github.com/rs/zerolog/journald" | ||
|
||
func ExampleNewJournalDWriter() { | ||
log := zerolog.New(journald.NewJournalDWriter()) | ||
log.Info().Str("foo", "bar").Uint64("small", 123).Float64("float", 3.14).Uint64("big", 1152921504606846976).Msg("Journal Test") | ||
// Output: | ||
} | ||
|
||
/* | ||
There is no automated way to verify the output - since the output is sent | ||
to journald process and method to retrieve is journalctl. Will find a way | ||
to automate the process and fix this test. | ||
$ journalctl -o verbose -f | ||
Thu 2018-04-26 22:30:20.768136 PDT [s=3284d695bde946e4b5017c77a399237f;i=329f0;b=98c0dca0debc4b98a5b9534e910e7dd6;m=7a702e35dd4;t=56acdccd2ed0a;x=4690034cf0348614] | ||
PRIORITY=6 | ||
_AUDIT_LOGINUID=1000 | ||
_BOOT_ID=98c0dca0debc4b98a5b9534e910e7dd6 | ||
_MACHINE_ID=926ed67eb4744580948de70fb474975e | ||
_HOSTNAME=sprint | ||
_UID=1000 | ||
_GID=1000 | ||
_CAP_EFFECTIVE=0 | ||
_SYSTEMD_SLICE=-.slice | ||
_TRANSPORT=journal | ||
_SYSTEMD_CGROUP=/ | ||
_AUDIT_SESSION=2945 | ||
MESSAGE=Journal Test | ||
FOO=bar | ||
BIG=1152921504606846976 | ||
_COMM=journald.test | ||
SMALL=123 | ||
FLOAT=3.14 | ||
JSON={"level":"info","foo":"bar","small":123,"float":3.14,"big":1152921504606846976,"message":"Journal Test"} | ||
_PID=27103 | ||
_SOURCE_REALTIME_TIMESTAMP=1524807020768136 | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters