Skip to content

Commit 6359d18

Browse files
committed
respect grpc standard status
1 parent da7e32f commit 6359d18

File tree

4 files changed

+50
-16
lines changed

4 files changed

+50
-16
lines changed

app/victoria-traces/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func httpRequestHandler(w http.ResponseWriter, r *http.Request) bool {
123123
}
124124

125125
func http2RequestHandler(w http.ResponseWriter, r *http.Request) {
126-
vtinsert.GrpcInsertHandler(w, r)
126+
vtinsert.GrpcExportHandler(w, r)
127127
}
128128

129129
func usage() {

app/vtinsert/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ func RequestHandler(w http.ResponseWriter, r *http.Request) bool {
5050
return false
5151
}
5252

53-
func GrpcInsertHandler(w http.ResponseWriter, r *http.Request) {
54-
opentelemetry.GrpcRequestHandler(r, w)
53+
func GrpcExportHandler(w http.ResponseWriter, r *http.Request) {
54+
opentelemetry.GrpcExportHandler(r, w)
5555
}
5656

5757
func insertHandler(w http.ResponseWriter, r *http.Request, path string) bool {

app/vtinsert/opentelemetry/grpc.go

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,31 @@ import (
1010
"net/http"
1111
)
1212

13+
// https://grpc.github.io/grpc/core/md_doc_statuscodes.html
14+
const (
15+
GrpcOk = "0"
16+
GrpcCancelled = "1"
17+
GrpcUnknown = "2"
18+
GrpcInvalidArgument = "3"
19+
GrpcDeadlineExceeded = "4"
20+
GrpcNotFound = "5"
21+
GrpcAlreadyExist = "6"
22+
GrpcPermissionDenied = "7"
23+
GrpcResourceExhausted = "8"
24+
GrpcFailedPrecondition = "9"
25+
GrpcAbort = "10"
26+
GrpcOutOfRange = "11"
27+
GrpcUnimplemented = "12"
28+
GrpcInternal = "13"
29+
GrpcUnavailable = "14"
30+
GrpcDataLoss = "15"
31+
GrpcUnauthenticated = "16"
32+
)
33+
1334
func getProtobufData(r *http.Request) ([]byte, error) {
1435
reqBody, err := io.ReadAll(r.Body)
1536
if err != nil {
16-
return nil, &httpserver.ErrorWithStatusCode{StatusCode: http.StatusBadRequest, Err: fmt.Errorf("cannot read request body: %s", err)}
37+
return nil, &httpserver.ErrorWithStatusCode{StatusCode: http.StatusInternalServerError, Err: fmt.Errorf("cannot read request body: %s", err)}
1738
}
1839
// +--------+-------------------------------------------------+
1940
// | 1 byte | 4 bytes |
@@ -26,6 +47,7 @@ func getProtobufData(r *http.Request) ([]byte, error) {
2647
// | (variable length) |
2748
// | |
2849
// +----------------------------------------------------------+
50+
// See https://grpc.github.io/grpc/core/md_doc__p_r_o_t_o_c_o_l-_h_t_t_p2.html
2951
if len(reqBody) < 5 {
3052
return nil, &httpserver.ErrorWithStatusCode{StatusCode: http.StatusBadRequest, Err: fmt.Errorf("invalid grpc header length: %d", len(reqBody))}
3153
}
@@ -40,17 +62,27 @@ func getProtobufData(r *http.Request) ([]byte, error) {
4062
return reqBody[5:], nil
4163
}
4264

65+
func writeErrorGrpcResponse(w http.ResponseWriter, grpcErrorCode, grpcErrorMessage string) {
66+
w.Header().Set("Content-Type", "application/grpc+proto")
67+
w.Header().Set("Trailer", "grpc-status, grpc-message")
68+
w.Header().Set("Grpc-Status", grpcErrorCode)
69+
w.Header().Set("Grpc-Message", grpcErrorMessage)
70+
}
71+
4372
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#message-encoding
44-
func writeExportTraceResponses(w http.ResponseWriter, rejectedSpans int64, errorMessage string) {
73+
func writeExportTracesGrpcResponse(w http.ResponseWriter, rejectedSpans int64, errorMessage string) {
4574
resp := pb.ExportTraceServiceResponse{
4675
ExportTracePartialSuccess: pb.ExportTracePartialSuccess{
4776
RejectedSpans: rejectedSpans,
4877
ErrorMessage: errorMessage,
4978
},
5079
}
5180
respData := resp.MarshalProtobuf(nil)
81+
5282
grpcRespData := make([]byte, 5+len(respData))
83+
// Compressed flag
5384
grpcRespData[0] = 0
85+
// Message Length
5486
binary.BigEndian.PutUint32(grpcRespData[1:5], uint32(len(respData)))
5587
copy(grpcRespData[5:], respData)
5688
w.Header().Set("Content-Type", "application/grpc+proto")
@@ -61,12 +93,14 @@ func writeExportTraceResponses(w http.ResponseWriter, rejectedSpans int64, error
6193
logger.Errorf("unexpected write of %d bytes in replying OLTP export grpc request, expected:%d", writtenLen, len(grpcRespData))
6294
return
6395
}
96+
grpcStatus := GrpcOk
97+
6498
if err != nil {
65-
logger.Errorf("failed to reply OLTP export grpc request , error:%s", err)
66-
return
99+
grpcStatus = GrpcInternal
100+
grpcErrorMessage := fmt.Sprintf("failed to reply OLTP export grpc request , error:%s", err)
101+
logger.Errorf(grpcErrorMessage)
102+
w.Header().Set("Grpc-Message", grpcErrorMessage)
67103
}
68104

69-
w.Header().Set("Grpc-Status", "0")
70-
w.Header().Set("Grpc-Message", "")
71-
105+
w.Header().Set("Grpc-Status", grpcStatus)
72106
}

app/vtinsert/opentelemetry/opentelemetry.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,14 @@ func handleJSONRequest(r *http.Request, w http.ResponseWriter) {
161161
requestJSONDuration.UpdateDuration(startTime)
162162
}
163163

164-
func GrpcRequestHandler(r *http.Request, w http.ResponseWriter) {
164+
func GrpcExportHandler(r *http.Request, w http.ResponseWriter) {
165165
if r.URL.Path != OLTPExportTracesGrpcPath {
166166
httpserver.Errorf(w, r, "failed to process grpc request:%s", &httpserver.ErrorWithStatusCode{Err: fmt.Errorf("grpc method not found: %s", r.URL.Path), StatusCode: http.StatusNotFound})
167167
return
168168
}
169169
cp, err := insertutil.GetCommonParams(r)
170170
if err != nil {
171-
httpserver.Errorf(w, r, "cannot parse common params from request: %s", err)
171+
writeErrorGrpcResponse(w, GrpcInternal, fmt.Sprintf("cannot parse common params from request: %s", err))
172172
return
173173
}
174174
// stream fields must contain the service name and span name.
@@ -177,13 +177,13 @@ func GrpcRequestHandler(r *http.Request, w http.ResponseWriter) {
177177
cp.StreamFields = append(mandatoryStreamFields, cp.StreamFields...)
178178

179179
if err = insertutil.CanWriteData(); err != nil {
180-
httpserver.Errorf(w, r, "%s", err)
180+
writeErrorGrpcResponse(w, GrpcInternal, err.Error())
181181
return
182182
}
183183

184184
protobufData, err := getProtobufData(r)
185185
if err != nil {
186-
httpserver.Errorf(w, r, "failed to get protobuf data from request, error: %s", err)
186+
writeErrorGrpcResponse(w, GrpcInvalidArgument, fmt.Sprintf("failed to get protobuf data from request, error: %s", err))
187187
return
188188
}
189189
encoding := r.Header.Get("grpc-encoding")
@@ -203,11 +203,11 @@ func GrpcRequestHandler(r *http.Request, w http.ResponseWriter) {
203203
})
204204

205205
if err != nil {
206-
httpserver.Errorf(w, r, "cannot read OpenTelemetry protocol data: %s", err)
206+
writeErrorGrpcResponse(w, GrpcInternal, fmt.Sprintf("cannot read OpenTelemetry protocol data: %s", err))
207207
return
208208
}
209209

210-
writeExportTraceResponses(w, 0, "")
210+
writeExportTracesGrpcResponse(w, 0, "")
211211
return
212212
}
213213

0 commit comments

Comments
 (0)