Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

systemd journal support #66

Closed
pquerna opened this issue Sep 24, 2014 · 15 comments
Closed

systemd journal support #66

pquerna opened this issue Sep 24, 2014 · 15 comments

Comments

@pquerna
Copy link
Contributor

pquerna commented Sep 24, 2014

Systemd's journal support could be added by using the go-systemd lib:
https://github.com/coreos/go-systemd/blob/master/journal/send.go

It is kinda funny however to make it a "Hook" -- you kinda want it to be a log formatter, but the current interface for formatters assumes an io.Copy() interface, while for journal.Send you would want the 'formatter' to handle the 'write'.

A quick hack would be to allow Formatters to return nil, and in that case skip the io.Copy paths?

@sirupsen
Copy link
Owner

Doesn't systemd journal just fine from stdout/stderr? Is the advantage of using the API directly performance for super logging heavy applications, or what's your use-case?

@pquerna
Copy link
Contributor Author

pquerna commented Sep 25, 2014

@sirupsen: So, strictly speaking, systemd's journal can consume stdout / stderr, but it can also understand structure logs, eg sd_journal_send with key/values, and you can search the journal based on any key/value, and it can print them as JSON:

http://0pointer.de/blog/projects/journal-submit.html

@sirupsen
Copy link
Owner

For syslog we actually have it as a hook, but still log to stdout/stderr. Is the simplest approach here to pass an io.Writer to logrus that does nothing, rendering the formatter useless, and then using a hook?

Actually... that's not really great either, because hooks are fired before the formatter and ordering is not guaranteed so it quickly turns into a hack.

hm

@sirupsen
Copy link
Owner

For now I'd probably recommend doing that, and then being explicit about making it the last hook.

@mwhooker
Copy link

mwhooker commented Feb 5, 2015

going to be implementing this internally. The use-case for us is journald will only read up to LINE_MAX characters per line, and our lines are a bit longer. LMK if anyone's interested and will see about open sourcing it.

@sirupsen
Copy link
Owner

sirupsen commented Feb 7, 2015

@mwhooker how are you going implement it?

@mwhooker
Copy link

mwhooker commented Feb 8, 2015

@sirupsen it's actually pretty simple

func (hook *JournaldHook) Fire(entry *logrus.Entry) error {
    return journal.Send(entry.Message, severityMap[entry.Level], stringifyEntries(entry.Data))
}

where stringifyEntries has the signature func stringifyEntries(data map[string]interface{}) map[string]string

I didn't see the same points above about wanting a formatter since journal wants a string message and a map of key/values.

We also have to log.SetOutput(ioutil.Discard)

@mwhooker
Copy link

Here's the published library. https://github.com/wercker/journalhook

happy to take comments

@sirupsen
Copy link
Owner

Thanks @mwhooker!

Added to README 4d9b4f0

@pauldotknopf
Copy link

It looks like this was removed from the readme.

Is there any particular reason? Is this still a valid approach?

@davidnorthetal
Copy link

you can use stdout / stderr with systemd but systemd doesn't set the log-level accordingly
i.e. both stdout / stderr messages always have the same log-level for systemd

to circumvent that you have to do syslog or direct systemd journal logging

@pauldotknopf
Copy link

Yeah, I need the specific log levels implemented properly.

@gsauthof
Copy link

pauldotknopf wrote:

It looks like this was removed from the readme.

Is there any particular reason? Is this still a valid approach?

Well, the readme now links to a long hook list in the wiki which still includes the original systemd journald hook link.

I presume that at some point the hook list was moved to a separate page because it grew to long.

@potuz
Copy link

potuz commented Oct 19, 2020

I couldn't find a proper place to ask for help so I figured I'll try in this issue since the hook page is archived. Using the journalhook with logs with fields like in

log.WithFields(logrus.Fields{
                "att":      att,
                "dep":          dep,
                "lenatt": len(att),
        }).Info("Finished adding att")

Logging with the journalhook I'll see the message "Finshed adding att" but would not get the fields.

@gguridi
Copy link

gguridi commented Oct 19, 2020

@potuz the problem relies on the journalhook hook that you are using. If it's the same as the wiki references then the problem is that the code is old and the Fire method is not using any formatter but directly sending the message only to the journal.

If you can't find another journalhook that uses the formatter, then copy that hook code into your project and make it use the formatter in your Fire method, like:

func (hook *JournalHook) Fire(entry *logrus.Entry) error {
        message, err := entry.String()
	if err == nil {
		return journal.Send(message, severityMap[entry.Level], stringifyEntries(entry.Data))
	}
	return err
}

Logrus is not responsible for hooks not using the formatters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants