How can I develop a gRPC plugin that handles the transmission of request ID through workflow

1,345 views
Skip to first unread message

artem.m...@gmail.com

unread,
Feb 21, 2017, 5:22:38 AM2/21/17
to grpc.io

I have many microservices en .net communicating with each other via gRPC (I use "protoc.exe" and "grpc_csharp_plugin.exe" to generate the client and server parts). 
Now I need that the gRPC request keeps the same correlationId passing through different microservices.

Please advise if I can add my own gRPC plugin that handle this automatically?

sai...@google.com

unread,
Feb 21, 2017, 7:25:31 PM2/21/17
to grpc.io, artem.m...@gmail.com
One one the options is - correlationId can be passed though different microservices via grpc metadata. 

Jan Tattermusch

unread,
Feb 24, 2017, 10:20:21 AM2/24/17
to Artem Miniailo, grpc.io
Hi, I am still not sure what your endgoal is. My understanding is that you have some kind of unique id (correlationId, not sure what correlation means here) and you want to attach it your calls, because that information is important for your logs. I can only guess that you might want to pass that Id along with your call graph (a call starts with some id and the server handling that rpc initiates new rpc, assigning them the same id) - i.e. you might want to come up with some very basic version of tracing. Also, I assume the correlation will be different each time a new end-user call is started.

Assuming tracing is the functionality you want, please be aware that gRPC team is working on fully-fledged tracing/stats support for gRPC that will be available in all languages (and will work cross-language) and will be based on a proven design. Tracing support should be available sometime within first half of 2017, so you might be better off just waiting for the real tracing functionality to be available instead of trying to hack it together yourself. Unfortunately, not much info about the tracing support is available publicly yet (for the time being, you can think of Census the same way you can about Zipkin or Opentracing).

If you need a short term solution for tracing purposes, just try adding a metadata entry that carries the "correlationId":

var request = YOUR_PROTOBUF_REQUEST
var requestHeaders = new Metadata
{
     { "tracingId", "UNIQUE_IDENTIFIER_74631984..." }
};
var call = client.FooCall(request, requestHeaders);

on the server side, you will be able to access the "tracingId" metadata entry through serverCallContext.RequestHeaders.
The advantage of using metadata API instead of adding an extra field to your protobuf definitions is that the tracingId doesn't pollute your service schema. Also, this makes more sense semantically as tracing functionality should be orthogonal to the contents of your requests and responses.

To some degree, you could automate instrumentation of new calls on the client side by adding a custom CallInvoker (and that way whenever you start a new call on a channel that uses that callInvoker, the custom callInvoker could add the tracingId to the logs for you).

Another response is inline


On Wed, Feb 22, 2017 at 9:56 AM, Artem Miniailo <artem.m...@gmail.com> wrote:
Hi Jan, thanks for your reply. In fact, I need to automatize the processus of assigning the same correlationId to all the gRPC calls within one workflow. I need this correlationId to be able to put it in my logs. For this purpose I thought that it was possible to add this logic (assigning of correlationId) while generating the code by protoc. As soon as I run this command 

protoc.exe -I../../protos --csharp_out Greeter  ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=\grpc_csharp_plugin.exe

I thought it was possible to add another parameter with my own plugin (or overwrite "grpc_csharp_plugin.exe") that would add this logic.
I found in GitHub repository the code for the plugin "grpc_csharp_plugin.exe", so I can add there my logic and recompile it... But it's dirty! I hope that exists some cleaner solution.

Yeah, I strongly recommend not to make any changes to the grpc_csharp_plugin to add tracing functionality. In short, it's a recipe for disaster. How would that work? Generating an extra "tracing" field in every protobuf message is wrong and you probably would be able to wire that into gRPC internals anyway. Of course, you can manually
add a field "tracingId" to every request message for each RPC you might want to trace and manually populate it when invoking the RPC. That would be legitimate if the field logically belonged to your protobuf schema, but for tracing that is not the case - as opposed to other situations (e.g. you have a bookstore application and your are passing bookId as part of your  PutBookInBasket and RemoveBookFromBasket RPCs - you see the difference)


 
Do you know what I can do ?

P.S. I also saw the tracing systems like Zipkin, Opentracing, but the idea is to do as simple as possible. In anyway I didn't find any info about "census", could you send me the link to read about it, please ?


Kind regards,
Artem Miniailo

2017-02-21 15:27 GMT+01:00 Jan Tattermusch <jtatte...@google.com>:
If I understand your question correctly, but it seems that you'll need to add a field (e.g. "correlation_id") to all the requests and responses where you need them. gRPC itself doesn't support anything like "attaching the same field" to all requests and responses (besides metadata, but if your correlationId has the right semantics to become a metadata entry is impossible to decide without more context).

If by "plugin" you mean interceptor, currently with C# you can only intercept calls on the client side and you don't have access to messages themselves, only to metadata).

If your intention is to trace requests across your microservice stack, you might be interested in the gRPC tracing functionality ("census", currently in development).

-- 
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+unsubscribe@googlegroups.com.
To post to this group, send email to grp...@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/510def25-331a-42c0-8339-1c968faafb11%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+unsubscribe@googlegroups.com.
To post to this group, send email to grp...@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/510def25-331a-42c0-8339-1c968faafb11%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ryan Michela

unread,
Feb 26, 2017, 2:02:29 AM2/26/17
to grpc.io, artem.m...@gmail.com
I've done this using grpc-java. The theory should be similar for C#.

You need to use a custom header to propagate your correlation id over the wire. You will also need a place to store the correlation id between processing a service call and calling the next service in the chain, such as a thread local variable.

On the client side use an InterceptingCallInvoker to marshal the thread local correlation id into a header. On the server side, use a InterceptingCallInvoker to marshal the header into the thread local variable. Using this pattern you can chain multiple service calls while transparently preserving a single correlation id across the entire chain. This is called the Ambient Context pattern.

A three service chain would look something like this: 
Thread local -> Header -> Thread local -> Header -> Thread Local

If you are using asynchronous APIs you will have to do extra work to make sure your thread local context survives the thread hopping that happens with async/await.

On Tuesday, February 21, 2017 at 2:22:38 AM UTC-8, artem.m...@gmail.com wrote:

Jan Tattermusch

unread,
Feb 27, 2017, 3:19:13 AM2/27/17
to Ryan Michela, grpc.io, Artem Miniailo
Ryan is right in with the idea. Nevertheless, the server side interceptor piece doesn't exist in C#, so for now you need to extract the header in the server-side handler manually (and add it directly to the child call or to a custom call invoker.

Also, you need to be very careful about choosing the right context type, as just "thread local" context won't work with async/await.

--
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+unsubscribe@googlegroups.com.
To post to this group, send email to grp...@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.

artem.m...@gmail.com

unread,
Feb 27, 2017, 4:47:37 AM2/27/17
to grpc.io, artem.m...@gmail.com
Thanks a lot for you answers

Artem Miniailo

unread,
Feb 28, 2017, 3:18:16 AM2/28/17
to Jan Tattermusch, Ryan Michela, grpc.io
Hi Jan, where can I find more information about the data-tracing with "Census" ?
Also you told  that gRPC team is working on fully-fledged tracing/stats support for gRPC. I there already some information how it will look like ?


Bien à vous,
Artem Miniailo

Jan Tattermusch

unread,
Feb 28, 2017, 3:28:31 AM2/28/17
to Artem Miniailo, Ryan Michela, grpc.io
See my previous e-mails:

Assuming tracing is the functionality you want, please be aware that gRPC team is working on fully-fledged tracing/stats support for gRPC that will be available in all languages (and will work cross-language) and will be based on a proven design. Tracing support should be available sometime within first half of 2017, so you might be better off just waiting for the real tracing functionality to be available instead of trying to hack it together yourself. Unfortunately, not much info about the tracing support is available publicly yet (for the time being, you can think of Census the same way you can about Zipkin or Opentracing).


Artem Miniailo

unread,
Feb 28, 2017, 4:06:08 AM2/28/17
to Jan Tattermusch, Ryan Michela, grpc.io
And what is it Census ?


Bien à vous,
Artem Miniailo

Jan Tattermusch

unread,
Feb 28, 2017, 4:15:25 AM2/28/17
to Artem Miniailo, Ryan Michela, grpc.io
"Census" is the name of the new tracing functionality that we are planning to deliver. Also, that was mentioned in one of my previous e-mails (... gRPC tracing functionality ("census", currently in development) ...).


Artem Miniailo

unread,
Feb 28, 2017, 4:20:22 AM2/28/17
to Jan Tattermusch, Ryan Michela, grpc.io
Thanks Jan. Waiting with impatience this implementation


Bien à vous,
Artem Miniailo

Reply all
Reply to author
Forward
0 new messages