-
Notifications
You must be signed in to change notification settings - Fork 222
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
Use component method calls for multi deployer logging. #630
Conversation
We plan to make it easier to create deployers by providing pluggable system facilities (logging for example). We will achieve this by using component method calls to communicate between a weavelet and its envelope. This change starts us on this path by adding a logging component and changing the multi deployer to collect log entries via method calls made by the weavelet: 1. The weavelet contains a Logger component that logs to stderr. 2. The multi deployer has a different component multiLogger that has the same set of methods as the Logger component, but writes log entries to the multi deployer's database. 3. This multiLogger component is made available over a unix domain socket. 4. The multi deployer passes configuration information to the weavelet asking it to redirect calls made to the Logger component to the multiLogger component. 5. The weavelet calls a Logger method to write log entries (though for the benefit of other deployers, it falls back to using the envelope pipe protocol if a Logger redirect is not available). Other related improvements -------------------------- The multi deplopyer could previously lose log messages since the process could exit before the log messages written to the logs database could be read and printed to stderr. We now write log messages to stderr as soon as they arrive instead of routing them through the logs database. Other Details ------------- * Fix generator so it can handle components defined in the weaver package. * multi deployer creates a temporary directory and a unix domain socket inside it. * The Logger component method accepts a batch of log entries, which should help efficiency when the rate of logging is high. * Fixed comment with outdated example of logging output. * Added a list of redirects to `EnvelopeInfo` proto. Added helpers ------------- * `call.NewHandlerMap()` provides a single place to register ready method. * `FixedListener` provides a call.Listener that serves a fixed set of components that are not subject to any communication graph constraints. * `reflection.ComponentName[T]` returns the name of component T. * `codegen.Find` returns registration by name. * `dirs.NewTempDir` makes a provate temporary directory. * `logger.IsSystemGenerated` determines whether a log entry is system generated.
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 job fitting this in so nicely.
internal/net/call/handlers.go
Outdated
fp := MakeMethodKey(component, method) | ||
hm.handlers[fp] = handler | ||
hm.names[fp] = component + "." + method | ||
} | ||
|
||
// addHandlers adds handlers for all methods of the component with the | ||
// specified name, The handlers invoke methods on the specified impl. |
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 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.
Done.
internal/net/call/listener.go
Outdated
Addr() net.Addr | ||
} | ||
|
||
// FixedListener returns a listener allows all calls to supplied |
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 sentence doesn't parse.
Also, I'm not sure what listener to compare this one to, to understand what is its distinctive property. "Fixed" by itself doesn't describe that property. (I'm guessing the distinctive property is that it allows any/all clients to invoke it, without security checks.)
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.
Fixed sentence.
I had intended "Fixed" to mean that a fixed set of components were being served, not the dynamic set in our normal mTLS based protocol.
I am happy to adopt a different name if that helps.
In the meantime I extended the comment:
// FixedListener returns a listener that allows all calls to supplied
// components. FixedListener is intended for local system services and access
// control happens at the net.Listener level (e.g., by using Unix domain
// sockets).
//
// Note that this differs from the normal listener used for application
// components (that listener only allows component A to call component B if A
// has an edge to B in the component graph).
//
// Each components map entry has the full component name as the key, and the
// component implementation as the value.
internal/weaver/logger.go
Outdated
"github.com/ServiceWeaver/weaver/runtime/protos" | ||
) | ||
|
||
// remoteLogger sends log entries to a specified component method. |
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.
specified component method dst
.
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.
Redid comments on the type and on run().
internal/weaver/remoteweavelet.go
Outdated
const loggerPath = "github.com/ServiceWeaver/weaver/Logger" | ||
r, ok := w.redirects[loggerPath] | ||
if !ok { | ||
// For now fall back to sending over the pipe to the weavelet. |
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.
Nit: comma after now
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.
Done.
runtime/dir.go
Outdated
@@ -53,3 +53,19 @@ func DataDir() (string, error) { | |||
|
|||
return regDir, nil | |||
} | |||
|
|||
// NewTempDir returns a new directory, e.g., to hold Unix domain sockets for | |||
// internal communication. The new directory is not accessible by others. |
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.
nit: others
seems too generic
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.
Done.
internal/weaver/logger.go
Outdated
return rl | ||
} | ||
|
||
func (rl *remoteLogger) send(entry *protos.LogEntry) { |
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.
send -> log
? (since we aren't sending yet.)
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.
Done.
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!
internal/net/call/handlers.go
Outdated
fp := MakeMethodKey(component, method) | ||
hm.handlers[fp] = handler | ||
hm.names[fp] = component + "." + method | ||
} | ||
|
||
// addHandlers adds handlers for all methods of the component with the | ||
// specified name, The handlers invoke methods on the specified impl. |
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.
Done.
internal/net/call/listener.go
Outdated
Addr() net.Addr | ||
} | ||
|
||
// FixedListener returns a listener allows all calls to supplied |
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.
Fixed sentence.
I had intended "Fixed" to mean that a fixed set of components were being served, not the dynamic set in our normal mTLS based protocol.
I am happy to adopt a different name if that helps.
In the meantime I extended the comment:
// FixedListener returns a listener that allows all calls to supplied
// components. FixedListener is intended for local system services and access
// control happens at the net.Listener level (e.g., by using Unix domain
// sockets).
//
// Note that this differs from the normal listener used for application
// components (that listener only allows component A to call component B if A
// has an edge to B in the component graph).
//
// Each components map entry has the full component name as the key, and the
// component implementation as the value.
internal/weaver/logger.go
Outdated
"github.com/ServiceWeaver/weaver/runtime/protos" | ||
) | ||
|
||
// remoteLogger sends log entries to a specified component method. |
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.
Redid comments on the type and on run().
internal/weaver/logger.go
Outdated
return rl | ||
} | ||
|
||
func (rl *remoteLogger) send(entry *protos.LogEntry) { |
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.
Done.
internal/weaver/remoteweavelet.go
Outdated
const loggerPath = "github.com/ServiceWeaver/weaver/Logger" | ||
r, ok := w.redirects[loggerPath] | ||
if !ok { | ||
// For now fall back to sending over the pipe to the weavelet. |
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.
Done.
runtime/dir.go
Outdated
@@ -53,3 +53,19 @@ func DataDir() (string, error) { | |||
|
|||
return regDir, nil | |||
} | |||
|
|||
// NewTempDir returns a new directory, e.g., to hold Unix domain sockets for | |||
// internal communication. The new directory is not accessible by others. |
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.
Done.
We plan to make it easier to create deployers by providing pluggable system facilities (logging for example). We will achieve this by using component method calls to communicate between a weavelet and its envelope.
This change starts us on this path by adding a logging component and changing the multi deployer to collect log entries via method calls made by the weavelet:
Other related improvements
The multi deplopyer could previously lose log messages since the process could exit before the log messages written to the logs database could be read and printed to stderr. We now write log messages to stderr as soon as they arrive instead of routing them through the logs database.
Other Details
EnvelopeInfo
proto.Added helpers
call.NewHandlerMap()
provides a single place to register ready method.FixedListener
provides a call.Listener that serves a fixed set of components that are not subject to any communication graph constraints.reflection.ComponentName[T]
returns the name of component T.codegen.Find
returns registration by name.dirs.NewTempDir
makes a provate temporary directory.logger.IsSystemGenerated
determines whether a log entry is system generated.