Skip to content

feature: add before/after InvocationRequest hooks #338

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

Closed

Conversation

markwolff
Copy link

@markwolff markwolff commented Oct 1, 2020

Adds two InvocationRequest hooks to WorkerChannel to enable context correlation and node.js worker APM instrumentation. Sample use case for Azure Monitor node.js SDK.

  • invocationRequestBefore: (context, userFunction) => contextWrappedUserFunction
  • invocationRequestAfter: () => void

note: workerChannel would need to be passed to app insights in some way, i.e. in nodejsWorker.ts:

if (shouldSetupAppInsightsFunctionsIntegration) {
  require("/path/to/applicationinsights/agent/functions")
    .setupFunctionsInvocationHooks(workerChannel);
}

In App Insights SDK, setupFunctionsInvocationHooks would be defined:

workerChannel.invocationRequestBefore = (context, userFunction) => {
    // Map Functions context to AppInsights context
    const correlationContext = appInsights.startOperation(context, "Functions.JavaScript.Trigger");

    // Wrap the Function runtime with correlationContext
    return appInsights.wrapWithCorrelationContext(userFunction, correlationContext);
}

workerChannel.invocationRequestAfter = () => {
    // Do any extra cleanup or flushing here
    appInsights.defaultClient.flush(); // can be async or sync
}

}

/**
* Initializes handlers for incoming gRPC messages on the client
*/
export class WorkerChannel implements IWorkerChannel {
public invocationRequestBefore?: (context: Context, userFn: Function) => Function;
public invocationRequestAfter?: Function;
Copy link
Member

Choose a reason for hiding this comment

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

Curious as to why context isn't exposed in After as well.

Copy link
Author

Choose a reason for hiding this comment

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

Agree. It seems like it would be required to correlate internal logging with the trace context

result.then(result => (<any>context.done)(null, result, true))
.catch(err => (<any>context.done)(err, null, true));
result.then(result => {
if (this.invocationRequestAfter) {
Copy link
Member

Choose a reason for hiding this comment

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

Are we able to call this.invocationRequestAfter(); at the end of this whole function? Instead of putting multiple separate calls for possible outcomes of the result (regular, catching errors, catch outstanding errors).

Copy link
Author

Choose a reason for hiding this comment

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

These are all happening in separate async paths which never converge on completion. I could see adding some this.finish() to each path to converge them. And within that we could call invocationRequestAfter(), but this would look pretty similar to what is already there. wdyt?

Copy link
Member

Choose a reason for hiding this comment

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

this.finish() would be more elegant but not really a blocking issue :)

@lzchen
Copy link
Member

lzchen commented Oct 6, 2020

note: workerChannel would need to be passed to app insights in some way, i.e. in nodejsWorker.ts:

Instead of needing to pass in the workerChannel, why not expose some api to add a callback which would BE the actual before/after functions?

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