Skip to content

Commit

Permalink
api: add ProtoMessageLogging http filter proto (#31735)
Browse files Browse the repository at this point in the history
---------

Signed-off-by: Xuyang Tao <[email protected]>

Mirrored from https://github.com/envoyproxy/envoy @ 0be80ca74b4d1c195d785337c8d44aff2d43e55a
  • Loading branch information
update-envoy[bot] committed Jan 18, 2024
1 parent 5011a1f commit 6de4caa
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 0 deletions.
1 change: 1 addition & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ proto_library(
"//envoy/extensions/filters/http/oauth2/v3:pkg",
"//envoy/extensions/filters/http/on_demand/v3:pkg",
"//envoy/extensions/filters/http/original_src/v3:pkg",
"//envoy/extensions/filters/http/proto_message_logging/v3:pkg",
"//envoy/extensions/filters/http/rate_limit_quota/v3:pkg",
"//envoy/extensions/filters/http/ratelimit/v3:pkg",
"//envoy/extensions/filters/http/rbac/v3:pkg",
Expand Down
13 changes: 13 additions & 0 deletions envoy/extensions/filters/http/proto_message_logging/v3/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.

load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")

licenses(["notice"]) # Apache 2

api_proto_package(
deps = [
"//envoy/config/core/v3:pkg",
"@com_github_cncf_xds//udpa/annotations:pkg",
"@com_github_cncf_xds//xds/annotations/v3:pkg",
],
)
255 changes: 255 additions & 0 deletions envoy/extensions/filters/http/proto_message_logging/v3/config.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
syntax = "proto3";

package envoy.extensions.filters.http.proto_message_logging.v3;

import "envoy/config/core/v3/base.proto";

import "xds/annotations/v3/status.proto";

import "udpa/annotations/status.proto";

option java_package = "io.envoyproxy.envoy.extensions.filters.http.proto_message_logging.v3";
option java_outer_classname = "ConfigProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/proto_message_logging/v3;proto_message_loggingv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;
option (xds.annotations.v3.file_status).work_in_progress = true;

// [#not-implemented-hide:]
// [#protodoc-title: Proto Message Logging]
// Proto Message Logging :ref:`configuration overview
// <config_http_filters_proto_message_logging>`.
// [#extension: envoy.filters.http.proto_message_logging]
//
// ProtoMessageLogging filter supports logging scrubbed gRPC requests/responses(proto messages)
// as google.protobuf.Struct and storing results
// in the dynamic metadata `envoy.filters.http.proto_message_logging` for later access.
//
// # Assumptions
// This filter assumes it is only applicable for gRPC with Protobuf as payload.
//
// # Process Flow
// On the request path, it will check
//
// 1. if the incoming gRPC request is configured, the filter tries to:
//
// a. buffer the incoming data to complete protobuf messages
// b. log individual protobuf messages according to directives
// c. write the result into the dynamic metadata.
// d. pass through the request data
//
// 2. otherwise, pass through the request.
//
// On the response path, it will check
//
// 1. if the incoming gRPC request is configured, the filter tries to:
//
// a. buffer the incoming data to complete protobuf messages
// b. log individual protobuf messages according to directives
// c. write the result into the dynamic metadata.
// d. pass through the response data
//
// 2. otherwise, pass through the response.
//
// # Config Requirements
// Here are config requirements
//
// 1. the log target field should be among the following primitive types: `string`, `uint32`, `uint64`, `int32`, `int64`, `sint32`, `sint64`, `fixed32`, `fixed64`, `sfixed32`, `sfixed64`, `float`, `double`.
//
// 2. the target field could be repeated.
//
// 3. the intermediate type could also be repeated.
//
// # Output Format
// The logged requests and responses will be will be added in the dynamic ``metadata<google.protobuf.Struct>`` with the same layout of the message.
//
// For the default `FIRST_AND_LAST` mode, it will be like:
// {
// "requests":{
// "first":{
// "foo": "val_foo1",
// ...
// }
// "last":{
// "foo": "val_foo3",
// ...
// }
// },
// "responses":{
// "first":{
// "baz": "val_baz1",
// ...
// }
// "last":{
// "baz": "val_foo3",
// ...
// }
// }
// }
//
//
// # Example for `FIRST_AND_LAST` mode
// Let's say we have the following definition for the bi-streaming request
// `pkg.svc.Method`.
//
// .. code-block:: proto
//
// message MethodRequest {
// string foo = 1;
// Nested nested = 2;
// Msg redacted = 3;
// ...
// }
//
// message MethodResponse {
// string baz = 1;
// }
//
// message Nested {
// Msg double_nested = 2;
// }
//
// message Msg {
// string bar = 1;
// string not_logged = 2;
// }
//
// This is the filter config in JSON.
//
// .. code-block:: json
//
// {
// "descriptor_set":{},
// "mode": "FIRST_AND_LAST",
// "logging_by_method":{
// "pkg.svc.Method":{
// "request_logging_by_field":{
// "foo":"LOG",
// "nested.doubled_nested.bar":"LOG",
// "redacted":"LOG_REDACT"
// },
// "response_logging_by_field":{
// "bar":"LOG",
// }
// }
// }
// }
//
// During runtime, the filter receives the following `MethodRequest` message in
// JSON.
//
// .. code-block:: json
//
// {
// "foo": "val_foo1",
// "nested": { "double_nested": {"bar": "val_bar1", "not_logged": "val_not_logged1"},
// "redacted": { "bar": "val_redacted_bar1"}
// }
// {
// "foo": "val_foo2",
// "nested": { "double_nested": {"bar": "val_bar2", "not_logged": "val_not_logged2"},
// "redacted": { "bar": "val_redacted_bar2"}
// }
// {
// "foo": "val_foo3",
// "nested": { "double_nested": {"bar": "val_bar3", "not_logged": "val_not_logged3"},
// "redacted": { "bar": "val_redacted_bar3"}
// }
//
// the filter receives the following `MethodResponse` message in
// JSON.
//
// .. code-block:: json
//
// {
// "baz": "val_baz1",
// }
// {
// "baz": "val_baz2",
// }
// {
// "baz": "val_baz3",
// }
//
// The filter will write the following dynamic
// metadata(`envoy.filters.http.proto_message_logging`) in JSON.
//
// .. code-block:: json
//
// {
// "requests":{
// "first":{
// "foo": "val_foo1",
// "nested": { "double_nested": {"bar": "val_bar1"}},
// "redacted": {}
// }
// "last":{
// "foo": "val_foo3",
// "nested": { "double_nested": {"bar": "val_bar3"}},
// "redacted": {}
// }
// },
// "responses":{
// "first":{
// "baz": "val_baz1"
// }
// "last":{
// "baz": "val_foo3"
// }
// }
// }

message ProtoMessageLoggingConfig {
enum LogMode {
LogMode_UNSPECIFIED = 0;

// The filter will log the first and the last message for
// for streaming cases, containing
// client-side streaming, server-side streaming or bi-directional streaming.
FIRST_AND_LAST = 1;
}

// The proto descriptor set binary for the gRPC services.
oneof descriptor_set {
// It could be passed by a local file through ``Datasource.filename`` or
// embedded in the ``Datasource.inline_bytes``.
config.core.v3.DataSource data_source = 1;

// Unimplemented, the key of proto descriptor TypedMetadata.
// Among filters depending on the proto descriptor, we can have a TypedMetadata
// for proto descriptors, so that these filters can share one copy of proto
// descriptor in memory.
string proto_descriptor_typed_metadata = 2;
}

LogMode mode = 3;

// Specify the message logging info.
// The key is the fully qualified gRPC method name.
// ``${package}.${Service}.${Method}``, like
// ``endpoints.examples.bookstore.BookStore.GetShelf``
//
// The value is the message logging information for individual gRPC methods.
map<string, MethodLogging> logging_by_method = 4;
}

// This message can be used to support per route config approach later even
// though the Istio doesn't support that so far.
message MethodLogging {
enum LogDirective {
LogDirective_UNSPECIFIED = 0;

// The value of this field will be logged.
LOG = 1;

// It should be only annotated on Message type fields so if the field isn't
// empty, an empty Struct will be logged.
LOG_REDACT = 2;
}

// The mapping of field path to its LogDirective for request messages
map<string, LogDirective> request_logging_by_field = 2;

// The mapping of field path to its LogDirective for response messages
map<string, LogDirective> response_logging_by_field = 3;
}
1 change: 1 addition & 0 deletions versioning/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ proto_library(
"//envoy/extensions/filters/http/oauth2/v3:pkg",
"//envoy/extensions/filters/http/on_demand/v3:pkg",
"//envoy/extensions/filters/http/original_src/v3:pkg",
"//envoy/extensions/filters/http/proto_message_logging/v3:pkg",
"//envoy/extensions/filters/http/rate_limit_quota/v3:pkg",
"//envoy/extensions/filters/http/ratelimit/v3:pkg",
"//envoy/extensions/filters/http/rbac/v3:pkg",
Expand Down

0 comments on commit 6de4caa

Please sign in to comment.