Skip to content

Commit a3e6e53

Browse files
authored
Apply grpc tracing interceptor on Feast SDK (#1243)
* Apply grpc tracing interceptor on Golang and Java SDK Signed-off-by: Khor Shu Heng <khor.heng@gojek.com> * Apply grpc tracing interceptor on Python SDK Signed-off-by: Khor Shu Heng <khor.heng@gojek.com> Co-authored-by: Khor Shu Heng <khor.heng@gojek.com>
1 parent 0fd1031 commit a3e6e53

8 files changed

Lines changed: 60 additions & 14 deletions

File tree

sdk/go/client.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77

88
"github.com/feast-dev/feast/sdk/go/protos/feast/serving"
9+
"github.com/opentracing-contrib/go-grpc"
910
"github.com/opentracing/opentracing-go"
1011
"go.opencensus.io/plugin/ocgrpc"
1112
"google.golang.org/grpc"
@@ -88,6 +89,11 @@ func NewSecureGrpcClientWithDialOptions(host string, port int, security Security
8889
options = append(options, grpc.WithPerRPCCredentials(security.Credential))
8990
}
9091

92+
// Enable tracing if a global tracer is registered
93+
tracingInterceptor := grpc.WithUnaryInterceptor(
94+
otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer()))
95+
options = append(options, tracingInterceptor)
96+
9197
conn, err := grpc.Dial(adr, options...)
9298
if err != nil {
9399
return nil, err
@@ -100,9 +106,6 @@ func NewSecureGrpcClientWithDialOptions(host string, port int, security Security
100106
// GetOnlineFeatures gets the latest values of the request features from the Feast serving instance provided.
101107
func (fc *GrpcClient) GetOnlineFeatures(ctx context.Context, req *OnlineFeaturesRequest) (
102108
*OnlineFeaturesResponse, error) {
103-
span, ctx := opentracing.StartSpanFromContext(ctx, "get_online_features")
104-
defer span.Finish()
105-
106109
featuresRequest, err := req.buildRequest()
107110
if err != nil {
108111
return nil, err
@@ -122,9 +125,6 @@ func (fc *GrpcClient) GetOnlineFeatures(ctx context.Context, req *OnlineFeatures
122125
// GetFeastServingInfo gets information about the feast serving instance this client is connected to.
123126
func (fc *GrpcClient) GetFeastServingInfo(ctx context.Context, in *serving.GetFeastServingInfoRequest) (
124127
*serving.GetFeastServingInfoResponse, error) {
125-
span, ctx := opentracing.StartSpanFromContext(ctx, "get_info")
126-
defer span.Finish()
127-
128128
return fc.cli.GetFeastServingInfo(ctx, in)
129129
}
130130

sdk/go/client_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"github.com/feast-dev/feast/sdk/go/protos/feast/types"
1010
"github.com/golang/mock/gomock"
1111
"github.com/google/go-cmp/cmp"
12-
"github.com/opentracing/opentracing-go"
1312
)
1413

1514
func TestGetOnlineFeatures(t *testing.T) {
@@ -59,10 +58,9 @@ func TestGetOnlineFeatures(t *testing.T) {
5958
defer ctrl.Finish()
6059
cli := mock_serving.NewMockServingServiceClient(ctrl)
6160
ctx := context.Background()
62-
_, traceCtx := opentracing.StartSpanFromContext(ctx, "get_online_features")
6361
rawRequest, _ := tc.req.buildRequest()
6462
resp := tc.want.RawResponse
65-
cli.EXPECT().GetOnlineFeaturesV2(traceCtx, rawRequest).Return(resp, nil).Times(1)
63+
cli.EXPECT().GetOnlineFeaturesV2(ctx, rawRequest).Return(resp, nil).Times(1)
6664

6765
client := &GrpcClient{
6866
cli: cli,

sdk/go/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/golang/mock v1.4.3
77
github.com/golang/protobuf v1.4.2
88
github.com/google/go-cmp v0.5.1
9+
github.com/opentracing-contrib/go-grpc v0.0.0-20200813121455-4a6760c71486
910
github.com/opentracing/opentracing-go v1.1.0
1011
go.opencensus.io v0.22.4
1112
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d

sdk/go/go.sum

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,20 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
108108
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
109109
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
110110
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
111+
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
111112
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
112113
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
113114
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
114115
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
115116
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
116117
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
118+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
117119
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
118120
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
121+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
119122
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
123+
github.com/opentracing-contrib/go-grpc v0.0.0-20200813121455-4a6760c71486 h1:K35HCWaOTJIPW6cDHK4yj3QfRY/NhE0pBbfoc0M2NMQ=
124+
github.com/opentracing-contrib/go-grpc v0.0.0-20200813121455-4a6760c71486/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo=
120125
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
121126
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
122127
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -131,8 +136,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
131136
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
132137
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
133138
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
134-
go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50=
135-
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
136139
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
137140
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
138141
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
@@ -186,6 +189,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwL
186189
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
187190
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
188191
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
192+
golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
189193
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
190194
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
191195
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -320,6 +324,7 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
320324
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
321325
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
322326
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
327+
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
323328
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
324329
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
325330
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -357,6 +362,7 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
357362
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
358363
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
359364
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
365+
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
360366
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
361367
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
362368
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
@@ -381,6 +387,7 @@ google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4
381387
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
382388
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
383389
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
390+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
384391
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
385392
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
386393
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=

sdk/java/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<!-- TODO: Standardize other modules on JUnit 5 and move this to parent -->
2020
<junit.version>5.5.2</junit.version>
2121
<mockito.version>2.28.2</mockito.version>
22+
<opentracing.version>0.33.0</opentracing.version>
2223
</properties>
2324

2425
<dependencies>
@@ -60,6 +61,23 @@
6061
<artifactId>protobuf-java</artifactId>
6162
</dependency>
6263

64+
<!-- Tracing -->
65+
<dependency>
66+
<groupId>io.opentracing.contrib</groupId>
67+
<artifactId>opentracing-grpc</artifactId>
68+
<version>0.2.3</version>
69+
</dependency>
70+
<dependency>
71+
<groupId>io.opentracing</groupId>
72+
<artifactId>opentracing-api</artifactId>
73+
<version>${opentracing.version}</version>
74+
</dependency>
75+
<dependency>
76+
<groupId>io.opentracing</groupId>
77+
<artifactId>opentracing-noop</artifactId>
78+
<version>${opentracing.version}</version>
79+
</dependency>
80+
6381
<!-- Logging -->
6482
<dependency>
6583
<groupId>org.slf4j</groupId>

sdk/java/src/main/java/com/gojek/feast/FeastClient.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import io.grpc.ManagedChannelBuilder;
3030
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
3131
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
32+
import io.opentracing.contrib.grpc.TracingClientInterceptor;
33+
import io.opentracing.util.GlobalTracer;
3234
import java.io.File;
3335
import java.util.HashSet;
3436
import java.util.List;
@@ -96,6 +98,7 @@ public static FeastClient createSecure(String host, int port, SecurityConfig sec
9698
// Disable TLS
9799
channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();
98100
}
101+
99102
return new FeastClient(channel, securityConfig.getCredentials());
100103
}
101104

@@ -187,10 +190,16 @@ public List<Row> getOnlineFeatures(List<String> featureRefs, List<Row> rows, Str
187190

188191
protected FeastClient(ManagedChannel channel, Optional<CallCredentials> credentials) {
189192
this.channel = channel;
190-
ServingServiceBlockingStub servingStub = ServingServiceGrpc.newBlockingStub(channel);
193+
TracingClientInterceptor tracingInterceptor =
194+
TracingClientInterceptor.newBuilder().withTracer(GlobalTracer.get()).build();
195+
196+
ServingServiceBlockingStub servingStub =
197+
ServingServiceGrpc.newBlockingStub(tracingInterceptor.intercept(channel));
198+
191199
if (credentials.isPresent()) {
192200
servingStub = servingStub.withCallCredentials(credentials.get());
193201
}
202+
194203
this.stub = servingStub;
195204
}
196205

sdk/python/feast/client.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,9 @@ def _core_service(self):
170170
@property
171171
def _serving_service(self):
172172
"""
173-
Creates or returns the gRPC Feast Serving Service Stub
173+
Creates or returns the gRPC Feast Serving Service Stub. If both `opentracing`
174+
and `grpcio-opentracing` are installed, an opentracing interceptor will be
175+
instantiated based on the global tracer.
174176
175177
Returns: ServingServiceStub
176178
"""
@@ -183,6 +185,17 @@ def _serving_service(self):
183185
auth_metadata_plugin=self._auth_metadata,
184186
timeout=self._config.getint(opt.GRPC_CONNECTION_TIMEOUT),
185187
)
188+
try:
189+
import opentracing
190+
from grpc_opentracing import open_tracing_client_interceptor
191+
from grpc_opentracing.grpcext import intercept_channel
192+
193+
interceptor = open_tracing_client_interceptor(
194+
opentracing.global_tracer()
195+
)
196+
channel = intercept_channel(channel, interceptor)
197+
except ImportError:
198+
pass
186199
self._serving_service_stub = ServingServiceStub(channel)
187200
return self._serving_service_stub
188201

sdk/python/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
# Install dev requirements with: pip install -e .[dev]
8080
extras_require={
8181
"dev": ["mypy-protobuf==1.*", "grpcio-testing==1.*"],
82-
"validation": ["great_expectations==0.13.2", "pyspark==3.0.1"]
82+
"validation": ["great_expectations==0.13.2", "pyspark==3.0.1"],
8383
},
8484
include_package_data=True,
8585
license="Apache",

0 commit comments

Comments
 (0)