-
Notifications
You must be signed in to change notification settings - Fork 173
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
[skip ci] live streaming VCH creation log to VCH datastore folder #6403
[skip ci] live streaming VCH creation log to VCH datastore folder #6403
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems bufferedPipe.go
could be simplified by using an io.Pipe
and a bufio.Reader
instead of trying to replicate their functionality. Is there a reason that is not feasible?
cmd/vic-machine/main.go
Outdated
@@ -139,6 +140,12 @@ func main() { | |||
logs = append(logs, f) | |||
} | |||
|
|||
// create VCH logger for streaming creation logs to datastore folder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like the logging framework we're using, logrus, uses hooks as an extensibility model. Could our new logging functionality be simplified by following that pattern? (To be clear: I'm not asserting that we should use the hook pattern, just making sure we've considered it.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zjs hook is essentially callback function that gets called every time a log message is written. Datastore.Upload
provided by govmomi overwrites the original content, so we can't do upload in hook (every log.infof
, log.debugf
and the like will be followed with a upload, and the previous log message got overwritten by the next one, etc.)
Also, we know exactly what point of time the datastore folder is ready, and the callback hook is applied to all the log messages alike, it's better to signal at a specific point of time than putting it in a general callback hook.
(and yea I talked about it with Hasan before and experimented with adding a hook. And on datastore it ended up being just one line of log message in the log file. That's how I found out govmomi's Datastore.Upload
does not append)
@zjs write to the pipe is still blocked since before datastore path is ready, there's no read request (no |
Update: now the log file name contains a unique operation ID for every |
Isn't this the behavior we want? That is, don't we expect the upload process reading the stream to block between writes? (And isn't this blocking behavior what is implemented? https://github.com/vmware/vic/pull/6403/files/cb5c21cbe8e2ff8019595792d1d1f0bfaec50b13#diff-d6efab20244e6d6571da7b6b44edce17R45) |
@zjs I just edited the comments (my bad I didn't say that clear at first, sorry) - we want the writes to be buffered (to be not blocked), not the reads, so even we wrap the |
lib/install/vchlog/vchlogger.go
Outdated
// suffix the log file name with caller operation ID as vic-machine process identifier | ||
callerOp := trace.NewOperation(sig.Context, "vic-machine") | ||
opID := callerOp.ID() | ||
logFileNameWithOpID := sig.LogFileName + "_" + opID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we include a timestamp here for easy sorting of the log files? (Maybe a startTime
could be stored as a part of the operation created by trace.NewOperation
?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea. Operation
package currently does not have a timestamp field, but I can pass that as a signal to the logger along with the operation. Do we want the timestamp to be unix nano in msec, or year-month-day?
lib/install/vchlog/vchlogger.go
Outdated
sig := <-signalChan | ||
|
||
// suffix the log file name with caller operation ID as vic-machine process identifier | ||
callerOp := trace.NewOperation(sig.Context, "vic-machine") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like the wrong place to be calling trace.NewOperation
. Shouldn't this code be passed a context
where the operation has already been created? (That way the operation id in the log messages matches the operation id in the filename.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes you're right. I was not clear about the operation concept before. This is def not a good place to do trace.NewOperation
...
fixing it
lib/install/vchlog/vchlogger.go
Outdated
"github.com/vmware/vic/pkg/trace" | ||
) | ||
|
||
// VCHCreatedSignal serves as a signal struct indicating datastore folder path is available |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we come up with a more accurate name for this? (We're sending the datastore is created, not the VCH; we're only part of the way through the VCH creation process.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, good catch
92aa233
to
6e38a9b
Compare
81111c0
to
eb7171b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me!
Clarifications on the design of a self-implemented log package ( We have the following goals for the logger that streams VCH creation logs to VCH datastore folder:
The reasons being that:
According to 1. above, we must have a Why standard libraries by golang does not work:
|
lib/install/management/create.go
Outdated
datastoreReadySignal := vchlog.DatastoreReadySignal{ | ||
Datastore: d.session.Datastore, | ||
LogFileName: "vic-machine-create", | ||
Operation: trace.NewOperation(d.ctx, "vic-machine create"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't see much value for the operation ID here, because you're writing logs to different files for different operation in different time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there could be more than one vic machine processes at the same time, to prevent overwriting, we also included the operation ID together with the timestamp
9ecfbab
to
5511407
Compare
709af07
to
9ee460a
Compare
5511407
to
75bbbc0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you please add at least one integration test as well? should just need to do a govc call, maybe in the existing regression test?
11dac4a
to
f8ee03a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
…ware#6403) * clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
* clean up after rebase * integration test added to 6-04 * integration test md file modified * integration test md file change
Fixes #6036
Goal
Enable live VCH creation log streaming to VCH datastore folder
Design details
A new package called
vchlog
dealing with log streaming is added underlib/install/
vchlog has a
vchlog.Run()
function that blocks until the VCH datastore folder is available, then it uploads a buffered pipe readwriter (for log messages) to datastore folder via govmomi.vchlog is initialized and the
vchlog.Run()
is called in main.go bycmd/vic-machine
in a go routine.govmomi upload function spins in a loop reading from the stream until EOF. By the implementation of the buffered pipe within
vchlog
, the read is blocked until a write has done writing (when there's new data available). Thus log messages are concurrently read and uploaded to the datastore while they're being written ("real-time" stream).Remaining work
Currently only
vic-machine create
can live stream logs to VCH datastore folder. For other commands, this pr is a no-op.Can people please review this PR? Thanks! @zjs @andrewtchin @jzt