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

WIP - Support for logging from children processes #1861

Closed
wants to merge 2 commits into from

Conversation

marcov
Copy link
Contributor

@marcov marcov commented Aug 8, 2018

Add support for children processes logging (including nsexec).
A pipe is used to send logs from children to parent in JSON.
The JSON format used is the same used by logrus JSON formatted,
i.e. children process can use standard logrus APIs.

This improves debugging and can also be used to report warning messages from the children.

marcov added 2 commits August 8, 2018 13:29
Add support for children processes logging (including nsexec).
A pipe is used to send logs from children to parent in JSON.
The JSON format used is the same used by logrus JSON formatted,
i.e. children process can use standard logrus APIs.

Signed-off-by: Marco Vedovati <[email protected]>
Pipe close before exec is not necessary as os.Pipe() is calling pipe2
with O_CLOEXEC option.

Signed-off-by: Marco Vedovati <[email protected]>
@@ -187,6 +188,10 @@ func (l *linuxStandardInit) Init() error {
return newSystemErrorWithCause(err, "init seccomp")
}
}

logPipe, _ := (logrus.StandardLogger().Out).(*(os.File))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three things:

  • I'm not sure it's necessary to do (a).(*os.File) -- I think a.(*os.File) will work just as fine (and gofmt should complain at you because it's not idiomatic).

  • You shouldn't ignore the ok value here. Even if it is impossible to occur, you should either make it panic or you should check that logPipe != nil (which is the error case -- because that would also panic).

  • Also we should probably set logPipe to be O_CLOEXEC which would remove the requirement to close it like this.

if err != nil {
return nil, newSystemErrorWithCause(err, "creating new command template")
}
if !p.Init {
return c.newSetnsProcess(p, cmd, parentPipe, childPipe)
return c.newSetnsProcess(p, cmd, parentPipe, childPipe, &logPipe)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels unnecessary to pass a reference here -- since the members are pointers there's no real risk of accidentally copying something. The later *logPipe just makes it look confusing.

@@ -448,10 +456,10 @@ func (c *linuxContainer) newParentProcess(p *Process) (parentProcess, error) {
if err := c.includeExecFifo(cmd); err != nil {
return nil, newSystemErrorWithCause(err, "including execfifo in cmd.Exec setup")
}
return c.newInitProcess(p, cmd, parentPipe, childPipe)
return c.newInitProcess(p, cmd, parentPipe, childPipe, &logPipe)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto on the &logPipe comment here too.

logrus.WarnLevel: logrus.Warn,
logrus.InfoLevel: logrus.Info,
logrus.DebugLevel: logrus.Debug,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit ugly, but it looks like logrus gives us no choice (you can't call Entry.log with an explicit level -- it even looks like there's a race condition in the level check inside logrus!). (Not an actionable complaint, just something I noticed.)

"{\"level\":\"%s\", \"msg\": \"", strlevel[level]);

va_start(args, format);
len += vsnprintf(&jsonbuffer[len], sizeof(jsonbuffer) - len, format, args);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While not an immediate issue, this does mean that we cannot deal with " (or any special characters) inside of the JSON string. Hopefully we won't hit that problem, but it is something to keep in mind.

@@ -138,6 +138,12 @@ func main() {
updateCommand,
}
app.Before = func(context *cli.Context) error {

// do nothing if logrus was already initialized in init.go
if logrus.StandardLogger().Out != logrus.New().Out {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really a fan of this -- why not set up logging for init here (or setting a global flag) rather than doing it this way?

@@ -43,12 +43,20 @@ type parentProcess interface {
externalDescriptors() []string

setExternalDescriptors(fds []string)

getChildLogs()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like this name -- maybe forwardChildLogs or proxyChildLogs to make it clear that this method actually pipes directly to logrus.

@marcov marcov changed the title Support for logging from children processes WIP - Support for logging from children processes Aug 20, 2018
@cyphar
Copy link
Member

cyphar commented Apr 23, 2019

Closing in favour of #2034. Thanks @marcov for kicking this one off.

@cyphar cyphar closed this Apr 23, 2019
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

Successfully merging this pull request may close these issues.

2 participants