Skip to content

client: add --grpc-mode unary for gRPC load with grpc-status scoring - #1602

Open
bpalermo wants to merge 2 commits into
envoyproxy:mainfrom
bpalermo:up/grpc-unary
Open

client: add --grpc-mode unary for gRPC load with grpc-status scoring#1602
bpalermo wants to merge 2 commits into
envoyproxy:mainfrom
bpalermo:up/grpc-unary

Conversation

@bpalermo

@bpalermo bpalermo commented Sep 7, 2026

Copy link
Copy Markdown

Description

This PR is related to #24

Adds --grpc-mode unary for gRPC unary load generation with grpc-status scoring. Nighthawk has no gRPC awareness today: a gRPC request had to be assembled by hand (framing, headers), and a failed RPC that comes back as HTTP 200 with grpc-status: 13 is counted as http_2xx because decodeTrailers() only keeps trailers for the tracing span.

--grpc-mode unary:

  • Implies --protocol http2 (h2c prior knowledge on http:// URIs) and --request-method POST; sets content-type: application/grpc and te: trailers; no Content-Length.
  • Wraps the --request-body-file bytes (one serialized protobuf message) in the gRPC length-prefixed frame, so users supply only the message. The method is the URI path, e.g. http://host:8080/pkg.Service/Method (a :path request header still overrides).
  • Scoring: grpc-status is read from the trailers, or from the headers on trailers-only responses. Status 0 is a success and feeds the new benchmark_http_client.latency_grpc_ok statistic; any other or missing status increments benchmark.grpc_error and benchmark.grpc_status.<code> (.missing when absent) and is not counted as benchmark.http_2xx. HTTP-level counters and latency_* statistics keep their meaning, so non-gRPC runs are unaffected.
  • Validation: requires HTTP/2 and POST; not combined with --request-source.

Notes for Reviewers

… body

Nighthawk could only send a synthetic body ('a' repeated --request-body-size
times) or, through a request source plugin, a UTF-8 json_body string. Add
--request-body-file, which reads the whole file and sends its bytes
verbatim on every request (binary safe), carried over the gRPC service API
in the new RequestOptions.request_body bytes field. Content-Length is set
from the body size; no Content-Type is assumed, supply one with
--request-header. Mutually exclusive with --request-body-size.

StaticRequestSourceImpl gains an optional body so the static request source
can yield it; the plugin and remote request sources are unchanged.

Signed-off-by: Bruno Palermo <[email protected]>
Nighthawk had no gRPC awareness: a request with a gRPC body had to be
assembled by hand and a failed RPC (HTTP 200 + grpc-status 13) counted
as a 2xx success because decodeTrailers() only kept trailers for
tracing.

--grpc-mode unary issues gRPC unary calls:
- implies --protocol http2 (h2c prior knowledge on http:// URIs) and
  --request-method POST; sets content-type: application/grpc and
  te: trailers; no content-length;
- wraps the --request-body-file bytes (a serialized protobuf message) in
  the gRPC length-prefixed frame, so users supply only the message;
- the method comes from the URI path (/pkg.Service/Method), or a :path
  request header;
- reads grpc-status from the trailers, or from the headers on
  trailers-only responses. Status 0 is a success and feeds the new
  benchmark_http_client.latency_grpc_ok statistic; any other or missing
  status increments benchmark.grpc_error and benchmark.grpc_status.<code>
  (.missing when absent) and is not counted as benchmark.http_2xx. HTTP
  level counters and latency_* statistics keep their meaning.

StreamDecoderCompletionCallback::onComplete()/exportLatency() now pass the
observed grpc-status through. Fixes envoyproxy#24 for unary calls; streaming is a
follow-up: --grpc-mode is an enum-valued flag (GrpcMode in options.proto)
so that streaming becomes --grpc-mode bidi-stream rather than a second
boolean flag.

Signed-off-by: Bruno Palermo <[email protected]>
@bpalermo bpalermo changed the title client: add --grpc for gRPC unary load with grpc-status scoring client: add --grpc-mode unary for gRPC load with grpc-status scoring Sep 7, 2026
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.

1 participant