You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2019/04/09 02:04:50 UTC
[incubator-skywalking] 01/01: Add ALS proto and receiver in envoy
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch envoy-access-log
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git
commit 9949460e91a35349143fec2a35ec7f1f215da0a4
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Tue Apr 9 10:04:37 2019 +0800
Add ALS proto and receiver in envoy
---
.../envoy/AccessLogServiceGRPCHandler.java | 53 ++++
.../envoy/EnvoyMetricReceiverProvider.java | 1 +
.../src/main/proto/envoy/api/v2/core/address.proto | 121 ++++++++
.../src/main/proto/envoy/api/v2/core/base.proto | 176 +++++++++++
.../proto/envoy/data/accesslog/v2/accesslog.proto | 335 +++++++++++++++++++++
.../proto/envoy/service/accesslog/v2/als.proto | 73 +++++
6 files changed, 759 insertions(+)
diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/AccessLogServiceGRPCHandler.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/AccessLogServiceGRPCHandler.java
new file mode 100644
index 0000000..32de937
--- /dev/null
+++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/AccessLogServiceGRPCHandler.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.server.receiver.envoy;
+
+import io.envoyproxy.envoy.service.accesslog.v2.*;
+import io.grpc.stub.StreamObserver;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.slf4j.*;
+
+public class AccessLogServiceGRPCHandler extends AccessLogServiceGrpc.AccessLogServiceImplBase {
+ private static final Logger logger = LoggerFactory.getLogger(AccessLogServiceGRPCHandler.class);
+
+ public AccessLogServiceGRPCHandler(ModuleManager manager) {
+
+ }
+
+ public StreamObserver<StreamAccessLogsMessage> streamAccessLogs(
+ StreamObserver<StreamAccessLogsResponse> responseObserver) {
+ return new StreamObserver<StreamAccessLogsMessage>() {
+ @Override public void onNext(StreamAccessLogsMessage message) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Received msg {}", message);
+ }
+ }
+
+ @Override public void onError(Throwable throwable) {
+ logger.error("Error in receiving access log from envoy", throwable);
+ responseObserver.onCompleted();
+ }
+
+ @Override public void onCompleted() {
+ responseObserver.onNext(StreamAccessLogsResponse.newBuilder().build());
+ responseObserver.onCompleted();
+ }
+ };
+ }
+}
diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/EnvoyMetricReceiverProvider.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/EnvoyMetricReceiverProvider.java
index 1631615..fce929e 100644
--- a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/EnvoyMetricReceiverProvider.java
+++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/EnvoyMetricReceiverProvider.java
@@ -46,6 +46,7 @@ public class EnvoyMetricReceiverProvider extends ModuleProvider {
@Override public void start() throws ServiceNotProvidedException, ModuleStartException {
GRPCHandlerRegister service = getManager().find(CoreModule.NAME).provider().getService(GRPCHandlerRegister.class);
service.addHandler(new MetricServiceGRPCHandler(getManager()));
+ service.addHandler(new AccessLogServiceGRPCHandler(getManager()));
}
@Override public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException {
diff --git a/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/api/v2/core/address.proto b/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/api/v2/core/address.proto
new file mode 100644
index 0000000..6e76f5b
--- /dev/null
+++ b/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/api/v2/core/address.proto
@@ -0,0 +1,121 @@
+syntax = "proto3";
+
+package envoy.api.v2.core;
+
+option java_outer_classname = "AddressProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.core";
+
+import "envoy/api/v2/core/base.proto";
+
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Network addresses]
+
+message Pipe {
+ // Unix Domain Socket path. On Linux, paths starting with '@' will use the
+ // abstract namespace. The starting '@' is replaced by a null byte by Envoy.
+ // Paths starting with '@' will result in an error in environments other than
+ // Linux.
+ string path = 1 [(validate.rules).string.min_bytes = 1];
+}
+
+message SocketAddress {
+ enum Protocol {
+ option (gogoproto.goproto_enum_prefix) = false;
+ TCP = 0;
+ // [#not-implemented-hide:]
+ UDP = 1;
+ }
+ Protocol protocol = 1 [(validate.rules).enum.defined_only = true];
+ // The address for this socket. :ref:`Listeners <config_listeners>` will bind
+ // to the address. An empty address is not allowed. Specify ``0.0.0.0`` or ``::``
+ // to bind to any address. [#comment:TODO(zuercher) reinstate when implemented:
+ // It is possible to distinguish a Listener address via the prefix/suffix matching
+ // in :ref:`FilterChainMatch <envoy_api_msg_listener.FilterChainMatch>`.] When used
+ // within an upstream :ref:`BindConfig <envoy_api_msg_core.BindConfig>`, the address
+ // controls the source address of outbound connections. For :ref:`clusters
+ // <envoy_api_msg_Cluster>`, the cluster type determines whether the
+ // address must be an IP (*STATIC* or *EDS* clusters) or a hostname resolved by DNS
+ // (*STRICT_DNS* or *LOGICAL_DNS* clusters). Address resolution can be customized
+ // via :ref:`resolver_name <envoy_api_field_core.SocketAddress.resolver_name>`.
+ string address = 2 [(validate.rules).string.min_bytes = 1];
+ oneof port_specifier {
+ option (validate.required) = true;
+ uint32 port_value = 3 [(validate.rules).uint32.lte = 65535];
+ // This is only valid if :ref:`resolver_name
+ // <envoy_api_field_core.SocketAddress.resolver_name>` is specified below and the
+ // named resolver is capable of named port resolution.
+ string named_port = 4;
+ }
+ // The name of the resolver. This must have been registered with Envoy. If this is
+ // empty, a context dependent default applies. If address is a hostname this
+ // should be set for resolution other than DNS. If the address is a concrete
+ // IP address, no resolution will occur.
+ string resolver_name = 5;
+
+ // When binding to an IPv6 address above, this enables `IPv4 compatibility
+ // <https://tools.ietf.org/html/rfc3493#page-11>`_. Binding to ``::`` will
+ // allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into
+ // IPv6 space as ``::FFFF:<IPv4-address>``.
+ bool ipv4_compat = 6;
+}
+
+message TcpKeepalive {
+ // Maximum number of keepalive probes to send without response before deciding
+ // the connection is dead. Default is to use the OS level configuration (unless
+ // overridden, Linux defaults to 9.)
+ google.protobuf.UInt32Value keepalive_probes = 1;
+ // The number of seconds a connection needs to be idle before keep-alive probes
+ // start being sent. Default is to use the OS level configuration (unless
+ // overridden, Linux defaults to 7200s (ie 2 hours.)
+ google.protobuf.UInt32Value keepalive_time = 2;
+ // The number of seconds between keep-alive probes. Default is to use the OS
+ // level configuration (unless overridden, Linux defaults to 75s.)
+ google.protobuf.UInt32Value keepalive_interval = 3;
+}
+
+message BindConfig {
+ // The address to bind to when creating a socket.
+ SocketAddress source_address = 1
+ [(validate.rules).message.required = true, (gogoproto.nullable) = false];
+
+ // Whether to set the *IP_FREEBIND* option when creating the socket. When this
+ // flag is set to true, allows the :ref:`source_address
+ // <envoy_api_field_UpstreamBindConfig.source_address>` to be an IP address
+ // that is not configured on the system running Envoy. When this flag is set
+ // to false, the option *IP_FREEBIND* is disabled on the socket. When this
+ // flag is not set (default), the socket is not modified, i.e. the option is
+ // neither enabled nor disabled.
+ google.protobuf.BoolValue freebind = 2;
+
+ // Additional socket options that may not be present in Envoy source code or
+ // precompiled binaries.
+ repeated SocketOption socket_options = 3;
+}
+
+// Addresses specify either a logical or physical address and port, which are
+// used to tell Envoy where to bind/listen, connect to upstream and find
+// management servers.
+message Address {
+ oneof address {
+ option (validate.required) = true;
+
+ SocketAddress socket_address = 1;
+ Pipe pipe = 2;
+ }
+}
+
+// CidrRange specifies an IP Address and a prefix length to construct
+// the subnet mask for a `CIDR <https://tools.ietf.org/html/rfc4632>`_ range.
+message CidrRange {
+ // IPv4 or IPv6 address, e.g. ``192.0.0.0`` or ``2001:db8::``.
+ string address_prefix = 1 [(validate.rules).string.min_bytes = 1];
+ // Length of prefix, e.g. 0, 32.
+ google.protobuf.UInt32Value prefix_len = 2 [(validate.rules).uint32.lte = 128];
+}
diff --git a/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/api/v2/core/base.proto b/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/api/v2/core/base.proto
index 3be09cd..6b4e931 100644
--- a/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/api/v2/core/base.proto
+++ b/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/api/v2/core/base.proto
@@ -17,6 +17,7 @@ import "gogoproto/gogo.proto";
import "envoy/type/percent.proto";
option (gogoproto.equal_all) = true;
+option (gogoproto.stable_marshaler_all) = true;
// [#protodoc-title: Common types]
@@ -78,3 +79,178 @@ message Node {
// by Envoy in management server RPCs.
string build_version = 5;
}
+
+// Metadata provides additional inputs to filters based on matched listeners,
+// filter chains, routes and endpoints. It is structured as a map, usually from
+// filter name (in reverse DNS format) to metadata specific to the filter. Metadata
+// key-values for a filter are merged as connection and request handling occurs,
+// with later values for the same key overriding earlier values.
+//
+// An example use of metadata is providing additional values to
+// http_connection_manager in the envoy.http_connection_manager.access_log
+// namespace.
+//
+// Another example use of metadata is to per service config info in cluster metadata, which may get
+// consumed by multiple filters.
+//
+// For load balancing, Metadata provides a means to subset cluster endpoints.
+// Endpoints have a Metadata object associated and routes contain a Metadata
+// object to match against. There are some well defined metadata used today for
+// this purpose:
+//
+// * ``{"envoy.lb": {"canary": <bool> }}`` This indicates the canary status of an
+// endpoint and is also used during header processing
+// (x-envoy-upstream-canary) and for stats purposes.
+message Metadata {
+ // Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.*
+ // namespace is reserved for Envoy's built-in filters.
+ map<string, google.protobuf.Struct> filter_metadata = 1;
+}
+
+// Runtime derived uint32 with a default when not specified.
+message RuntimeUInt32 {
+ // Default value if runtime value is not available.
+ uint32 default_value = 2;
+
+ // Runtime key to get value for comparison. This value is used if defined.
+ string runtime_key = 3 [(validate.rules).string.min_bytes = 1];
+}
+
+// Envoy supports :ref:`upstream priority routing
+// <arch_overview_http_routing_priority>` both at the route and the virtual
+// cluster level. The current priority implementation uses different connection
+// pool and circuit breaking settings for each priority level. This means that
+// even for HTTP/2 requests, two physical connections will be used to an
+// upstream host. In the future Envoy will likely support true HTTP/2 priority
+// over a single upstream connection.
+enum RoutingPriority {
+ DEFAULT = 0;
+ HIGH = 1;
+}
+
+// HTTP request method.
+enum RequestMethod {
+ option (gogoproto.goproto_enum_prefix) = false;
+ METHOD_UNSPECIFIED = 0;
+ GET = 1;
+ HEAD = 2;
+ POST = 3;
+ PUT = 4;
+ DELETE = 5;
+ CONNECT = 6;
+ OPTIONS = 7;
+ TRACE = 8;
+}
+
+// Header name/value pair.
+message HeaderValue {
+ // Header name.
+ string key = 1 [(validate.rules).string = {min_bytes: 1, max_bytes: 16384}];
+
+ // Header value.
+ //
+ // The same :ref:`format specifier <config_access_log_format>` as used for
+ // :ref:`HTTP access logging <config_access_log>` applies here, however
+ // unknown header values are replaced with the empty string instead of `-`.
+ string value = 2 [(validate.rules).string.max_bytes = 16384];
+}
+
+// Header name/value pair plus option to control append behavior.
+message HeaderValueOption {
+ // Header name/value pair that this option applies to.
+ HeaderValue header = 1 [(validate.rules).message.required = true];
+
+ // Should the value be appended? If true (default), the value is appended to
+ // existing values.
+ google.protobuf.BoolValue append = 2;
+}
+
+// Wrapper for a set of headers.
+message HeaderMap {
+ repeated HeaderValue headers = 1;
+}
+
+// Data source consisting of either a file or an inline value.
+message DataSource {
+ oneof specifier {
+ option (validate.required) = true;
+
+ // Local filesystem data source.
+ string filename = 1 [(validate.rules).string.min_bytes = 1];
+
+ // Bytes inlined in the configuration.
+ bytes inline_bytes = 2 [(validate.rules).bytes.min_len = 1];
+
+ // String inlined in the configuration.
+ string inline_string = 3 [(validate.rules).string.min_bytes = 1];
+ }
+}
+
+// Configuration for transport socket in :ref:`listeners <config_listeners>` and
+// :ref:`clusters <envoy_api_msg_Cluster>`. If the configuration is
+// empty, a default transport socket implementation and configuration will be
+// chosen based on the platform and existence of tls_context.
+message TransportSocket {
+ // The name of the transport socket to instantiate. The name must match a supported transport
+ // socket implementation.
+ string name = 1 [(validate.rules).string.min_bytes = 1];
+
+ // Implementation specific configuration which depends on the implementation being instantiated.
+ // See the supported transport socket implementations for further documentation.
+ oneof config_type {
+ google.protobuf.Struct config = 2;
+
+ google.protobuf.Any typed_config = 3;
+ }
+}
+
+// Generic socket option message. This would be used to set socket options that
+// might not exist in upstream kernels or precompiled Envoy binaries.
+message SocketOption {
+ // An optional name to give this socket option for debugging, etc.
+ // Uniqueness is not required and no special meaning is assumed.
+ string description = 1;
+ // Corresponding to the level value passed to setsockopt, such as IPPROTO_TCP
+ int64 level = 2;
+ // The numeric name as passed to setsockopt
+ int64 name = 3;
+ oneof value {
+ option (validate.required) = true;
+
+ // Because many sockopts take an int value.
+ int64 int_value = 4;
+ // Otherwise it's a byte buffer.
+ bytes buf_value = 5;
+ }
+ enum SocketState {
+ option (gogoproto.goproto_enum_prefix) = false;
+ // Socket options are applied after socket creation but before binding the socket to a port
+ STATE_PREBIND = 0;
+ // Socket options are applied after binding the socket to a port but before calling listen()
+ STATE_BOUND = 1;
+ // Socket options are applied after calling listen()
+ STATE_LISTENING = 2;
+ }
+ // The state in which the option will be applied. When used in BindConfig
+ // STATE_PREBIND is currently the only valid value.
+ SocketState state = 6
+ [(validate.rules).message.required = true, (validate.rules).enum.defined_only = true];
+}
+
+// Runtime derived FractionalPercent with defaults for when the numerator or denominator is not
+// specified via a runtime key.
+message RuntimeFractionalPercent {
+ // Default value if the runtime value's for the numerator/denominator keys are not available.
+ envoy.type.FractionalPercent default_value = 1 [(validate.rules).message.required = true];
+
+ // Runtime key for a YAML representation of a FractionalPercent.
+ string runtime_key = 2;
+}
+
+// Identifies a specific ControlPlane instance that Envoy is connected to.
+message ControlPlane {
+ // An opaque control plane identifier that uniquely identifies an instance
+ // of control plane. This can be used to identify which control plane instance,
+ // the Envoy is connected to.
+ string identifier = 1;
+}
diff --git a/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/data/accesslog/v2/accesslog.proto b/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/data/accesslog/v2/accesslog.proto
new file mode 100644
index 0000000..b387433
--- /dev/null
+++ b/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/data/accesslog/v2/accesslog.proto
@@ -0,0 +1,335 @@
+syntax = "proto3";
+
+package envoy.data.accesslog.v2;
+
+option java_outer_classname = "AccesslogProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.data.accesslog.v2";
+
+import "envoy/api/v2/core/address.proto";
+import "envoy/api/v2/core/base.proto";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+import "gogoproto/gogo.proto";
+import "validate/validate.proto";
+
+option (gogoproto.stable_marshaler_all) = true;
+
+// [#protodoc-title: gRPC access logs]
+// Envoy access logs describe incoming interaction with Envoy over a fixed
+// period of time, and typically cover a single request/response exchange,
+// (e.g. HTTP), stream (e.g. over HTTP/gRPC), or proxied connection (e.g. TCP).
+// Access logs contain fields defined in protocol-specific protobuf messages.
+//
+// Except where explicitly declared otherwise, all fields describe
+// *downstream* interaction between Envoy and a connected client.
+// Fields describing *upstream* interaction will explicitly include ``upstream``
+// in their name.
+
+// [#not-implemented-hide:]
+message TCPAccessLogEntry {
+ // Common properties shared by all Envoy access logs.
+ AccessLogCommon common_properties = 1;
+}
+
+message HTTPAccessLogEntry {
+ // Common properties shared by all Envoy access logs.
+ AccessLogCommon common_properties = 1;
+
+ // HTTP version
+ enum HTTPVersion {
+ PROTOCOL_UNSPECIFIED = 0;
+ HTTP10 = 1;
+ HTTP11 = 2;
+ HTTP2 = 3;
+ }
+ HTTPVersion protocol_version = 2;
+
+ // Description of the incoming HTTP request.
+ HTTPRequestProperties request = 3;
+
+ // Description of the outgoing HTTP response.
+ HTTPResponseProperties response = 4;
+}
+
+// Defines fields that are shared by all Envoy access logs.
+message AccessLogCommon {
+ // [#not-implemented-hide:]
+ // This field indicates the rate at which this log entry was sampled.
+ // Valid range is (0.0, 1.0].
+ double sample_rate = 1 [(validate.rules).double.gt = 0.0, (validate.rules).double.lte = 1.0];
+
+ // This field is the remote/origin address on which the request from the user was received.
+ // Note: This may not be the physical peer. E.g, if the remote address is inferred from for
+ // example the x-forwarder-for header, proxy protocol, etc.
+ envoy.api.v2.core.Address downstream_remote_address = 2;
+
+ // This field is the local/destination address on which the request from the user was received.
+ envoy.api.v2.core.Address downstream_local_address = 3;
+
+ // If the connection is secure,S this field will contain TLS properties.
+ TLSProperties tls_properties = 4;
+
+ // The time that Envoy started servicing this request. This is effectively the time that the first
+ // downstream byte is received.
+ google.protobuf.Timestamp start_time = 5 [(gogoproto.stdtime) = true];
+
+ // Interval between the first downstream byte received and the last
+ // downstream byte received (i.e. time it takes to receive a request).
+ google.protobuf.Duration time_to_last_rx_byte = 6 [(gogoproto.stdduration) = true];
+
+ // Interval between the first downstream byte received and the first upstream byte sent. There may
+ // by considerable delta between *time_to_last_rx_byte* and this value due to filters.
+ // Additionally, the same caveats apply as documented in *time_to_last_downstream_tx_byte* about
+ // not accounting for kernel socket buffer time, etc.
+ google.protobuf.Duration time_to_first_upstream_tx_byte = 7 [(gogoproto.stdduration) = true];
+
+ // Interval between the first downstream byte received and the last upstream byte sent. There may
+ // by considerable delta between *time_to_last_rx_byte* and this value due to filters.
+ // Additionally, the same caveats apply as documented in *time_to_last_downstream_tx_byte* about
+ // not accounting for kernel socket buffer time, etc.
+ google.protobuf.Duration time_to_last_upstream_tx_byte = 8 [(gogoproto.stdduration) = true];
+
+ // Interval between the first downstream byte received and the first upstream
+ // byte received (i.e. time it takes to start receiving a response).
+ google.protobuf.Duration time_to_first_upstream_rx_byte = 9 [(gogoproto.stdduration) = true];
+
+ // Interval between the first downstream byte received and the last upstream
+ // byte received (i.e. time it takes to receive a complete response).
+ google.protobuf.Duration time_to_last_upstream_rx_byte = 10 [(gogoproto.stdduration) = true];
+
+ // Interval between the first downstream byte received and the first downstream byte sent.
+ // There may be a considerable delta between the *time_to_first_upstream_rx_byte* and this field
+ // due to filters. Additionally, the same caveats apply as documented in
+ // *time_to_last_downstream_tx_byte* about not accounting for kernel socket buffer time, etc.
+ google.protobuf.Duration time_to_first_downstream_tx_byte = 11 [(gogoproto.stdduration) = true];
+
+ // Interval between the first downstream byte received and the last downstream byte sent.
+ // Depending on protocol, buffering, windowing, filters, etc. there may be a considerable delta
+ // between *time_to_last_upstream_rx_byte* and this field. Note also that this is an approximate
+ // time. In the current implementation it does not include kernel socket buffer time. In the
+ // current implementation it also does not include send window buffering inside the HTTP/2 codec.
+ // In the future it is likely that work will be done to make this duration more accurate.
+ google.protobuf.Duration time_to_last_downstream_tx_byte = 12 [(gogoproto.stdduration) = true];
+
+ // The upstream remote/destination address that handles this exchange. This does not include
+ // retries.
+ envoy.api.v2.core.Address upstream_remote_address = 13;
+
+ // The upstream local/origin address that handles this exchange. This does not include retries.
+ envoy.api.v2.core.Address upstream_local_address = 14;
+
+ // The upstream cluster that *upstream_remote_address* belongs to.
+ string upstream_cluster = 15;
+
+ // Flags indicating occurrences during request/response processing.
+ ResponseFlags response_flags = 16;
+
+ // All metadata encountered during request processing, including endpoint
+ // selection.
+ //
+ // This can be used to associate IDs attached to the various configurations
+ // used to process this request with the access log entry. For example, a
+ // route created from a higher level forwarding rule with some ID can place
+ // that ID in this field and cross reference later. It can also be used to
+ // determine if a canary endpoint was used or not.
+ envoy.api.v2.core.Metadata metadata = 17;
+
+ // If upstream connection failed due to transport socket (e.g. TLS handshake), provides the
+ // failure reason from the transport socket. The format of this field depends on the configured
+ // upstream transport socket. Common TLS failures are in
+ // :ref:`TLS trouble shooting <arch_overview_ssl_trouble_shooting>`.
+ string upstream_transport_failure_reason = 18;
+}
+
+// Flags indicating occurrences during request/response processing.
+message ResponseFlags {
+ // Indicates local server healthcheck failed.
+ bool failed_local_healthcheck = 1;
+
+ // Indicates there was no healthy upstream.
+ bool no_healthy_upstream = 2;
+
+ // Indicates an there was an upstream request timeout.
+ bool upstream_request_timeout = 3;
+
+ // Indicates local codec level reset was sent on the stream.
+ bool local_reset = 4;
+
+ // Indicates remote codec level reset was received on the stream.
+ bool upstream_remote_reset = 5;
+
+ // Indicates there was a local reset by a connection pool due to an initial connection failure.
+ bool upstream_connection_failure = 6;
+
+ // Indicates the stream was reset due to an upstream connection termination.
+ bool upstream_connection_termination = 7;
+
+ // Indicates the stream was reset because of a resource overflow.
+ bool upstream_overflow = 8;
+
+ // Indicates no route was found for the request.
+ bool no_route_found = 9;
+
+ // Indicates that the request was delayed before proxying.
+ bool delay_injected = 10;
+
+ // Indicates that the request was aborted with an injected error code.
+ bool fault_injected = 11;
+
+ // Indicates that the request was rate-limited locally.
+ bool rate_limited = 12;
+
+ message Unauthorized {
+ // Reasons why the request was unauthorized
+ enum Reason {
+ REASON_UNSPECIFIED = 0;
+ // The request was denied by the external authorization service.
+ EXTERNAL_SERVICE = 1;
+ }
+
+ Reason reason = 1;
+ }
+
+ // Indicates if the request was deemed unauthorized and the reason for it.
+ Unauthorized unauthorized_details = 13;
+
+ // Indicates that the request was rejected because there was an error in rate limit service.
+ bool rate_limit_service_error = 14;
+
+ // Indicates the stream was reset due to a downstream connection termination.
+ bool downstream_connection_termination = 15;
+
+ // Indicates that the upstream retry limit was exceeded, resulting in a downstream error.
+ bool upstream_retry_limit_exceeded = 16;
+
+ // Indicates that the stream idle timeout was hit, resulting in a downstream 408.
+ bool stream_idle_timeout = 17;
+}
+
+// Properties of a negotiated TLS connection.
+message TLSProperties {
+ // [#not-implemented-hide:]
+ enum TLSVersion {
+ VERSION_UNSPECIFIED = 0;
+ TLSv1 = 1;
+ TLSv1_1 = 2;
+ TLSv1_2 = 3;
+ TLSv1_3 = 4;
+ }
+ // [#not-implemented-hide:]
+ // Version of TLS that was negotiated.
+ TLSVersion tls_version = 1;
+
+ // [#not-implemented-hide:]
+ // TLS cipher suite negotiated during handshake. The value is a
+ // four-digit hex code defined by the IANA TLS Cipher Suite Registry
+ // (e.g. ``009C`` for ``TLS_RSA_WITH_AES_128_GCM_SHA256``).
+ //
+ // Here it is expressed as an integer.
+ google.protobuf.UInt32Value tls_cipher_suite = 2;
+
+ // SNI hostname from handshake.
+ string tls_sni_hostname = 3;
+
+ message CertificateProperties {
+ message SubjectAltName {
+ oneof san {
+ string uri = 1;
+ // [#not-implemented-hide:]
+ string dns = 2;
+ }
+ }
+
+ // SANs present in the certificate.
+ repeated SubjectAltName subject_alt_name = 1;
+
+ // The subject field of the certificate.
+ string subject = 2;
+ }
+
+ // Properties of the local certificate used to negotiate TLS.
+ CertificateProperties local_certificate_properties = 4;
+
+ // Properties of the peer certificate used to negotiate TLS.
+ CertificateProperties peer_certificate_properties = 5;
+}
+
+message HTTPRequestProperties {
+ // The request method (RFC 7231/2616).
+ // [#comment:TODO(htuch): add (validate.rules).enum.defined_only = true once
+ // https://github.com/lyft/protoc-gen-validate/issues/42 is resolved.]
+ envoy.api.v2.core.RequestMethod request_method = 1;
+
+ // The scheme portion of the incoming request URI.
+ string scheme = 2;
+
+ // HTTP/2 ``:authority`` or HTTP/1.1 ``Host`` header value.
+ string authority = 3;
+
+ // The port of the incoming request URI
+ // (unused currently, as port is composed onto authority).
+ google.protobuf.UInt32Value port = 4;
+
+ // The path portion from the incoming request URI.
+ string path = 5;
+
+ // Value of the ``User-Agent`` request header.
+ string user_agent = 6;
+
+ // Value of the ``Referer`` request header.
+ string referer = 7;
+
+ // Value of the ``X-Forwarded-For`` request header.
+ string forwarded_for = 8;
+
+ // Value of the ``X-Request-Id`` request header
+ //
+ // This header is used by Envoy to uniquely identify a request.
+ // It will be generated for all external requests and internal requests that
+ // do not already have a request ID.
+ string request_id = 9;
+
+ // Value of the ``X-Envoy-Original-Path`` request header.
+ string original_path = 10;
+
+ // Size of the HTTP request headers in bytes.
+ //
+ // This value is captured from the OSI layer 7 perspective, i.e. it does not
+ // include overhead from framing or encoding at other networking layers.
+ uint64 request_headers_bytes = 11;
+
+ // Size of the HTTP request body in bytes.
+ //
+ // This value is captured from the OSI layer 7 perspective, i.e. it does not
+ // include overhead from framing or encoding at other networking layers.
+ uint64 request_body_bytes = 12;
+
+ // Map of additional headers that have been configured to be logged.
+ map<string, string> request_headers = 13;
+}
+
+message HTTPResponseProperties {
+ // The HTTP response code returned by Envoy.
+ google.protobuf.UInt32Value response_code = 1;
+
+ // Size of the HTTP response headers in bytes.
+ //
+ // This value is captured from the OSI layer 7 perspective, i.e. it does not
+ // include overhead from framing or encoding at other networking layers.
+ uint64 response_headers_bytes = 2;
+
+ // Size of the HTTP response body in bytes.
+ //
+ // This value is captured from the OSI layer 7 perspective, i.e. it does not
+ // include overhead from framing or encoding at other networking layers.
+ uint64 response_body_bytes = 3;
+
+ // Map of additional headers configured to be logged.
+ map<string, string> response_headers = 4;
+
+ // Map of trailers configured to be logged.
+ map<string, string> response_trailers = 5;
+}
diff --git a/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/service/accesslog/v2/als.proto b/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/service/accesslog/v2/als.proto
new file mode 100644
index 0000000..1ee6ccd
--- /dev/null
+++ b/oap-server/server-receiver-plugin/receiver-proto/src/main/proto/envoy/service/accesslog/v2/als.proto
@@ -0,0 +1,73 @@
+syntax = "proto3";
+
+package envoy.service.accesslog.v2;
+
+option java_outer_classname = "AlsProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.service.accesslog.v2";
+option go_package = "v2";
+option java_generic_services = true;
+
+import "envoy/api/v2/core/base.proto";
+import "envoy/data/accesslog/v2/accesslog.proto";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: gRPC Access Log Service (ALS)]
+
+// Service for streaming access logs from Envoy to an access log server.
+service AccessLogService {
+ // Envoy will connect and send StreamAccessLogsMessage messages forever. It does not expect any
+ // response to be sent as nothing would be done in the case of failure. The server should
+ // disconnect if it expects Envoy to reconnect. In the future we may decide to add a different
+ // API for "critical" access logs in which Envoy will buffer access logs for some period of time
+ // until it gets an ACK so it could then retry. This API is designed for high throughput with the
+ // expectation that it might be lossy.
+ rpc StreamAccessLogs(stream StreamAccessLogsMessage) returns (StreamAccessLogsResponse) {
+ }
+}
+
+// Empty response for the StreamAccessLogs API. Will never be sent. See below.
+message StreamAccessLogsResponse {
+}
+
+// Stream message for the StreamAccessLogs API. Envoy will open a stream to the server and stream
+// access logs without ever expecting a response.
+message StreamAccessLogsMessage {
+ message Identifier {
+ // The node sending the access log messages over the stream.
+ envoy.api.v2.core.Node node = 1 [(validate.rules).message.required = true];
+
+ // The friendly name of the log configured in :ref:`CommonGrpcAccessLogConfig
+ // <envoy_api_msg_config.accesslog.v2.CommonGrpcAccessLogConfig>`.
+ string log_name = 2 [(validate.rules).string.min_bytes = 1];
+ }
+
+ // Identifier data that will only be sent in the first message on the stream. This is effectively
+ // structured metadata and is a performance optimization.
+ Identifier identifier = 1;
+
+ // Wrapper for batches of HTTP access log entries.
+ message HTTPAccessLogEntries {
+ repeated envoy.data.accesslog.v2.HTTPAccessLogEntry log_entry = 1
+ [(validate.rules).repeated .min_items = 1];
+ }
+
+ // [#not-implemented-hide:]
+ // Wrapper for batches of TCP access log entries.
+ message TCPAccessLogEntries {
+ repeated envoy.data.accesslog.v2.TCPAccessLogEntry log_entry = 1
+ [(validate.rules).repeated .min_items = 1];
+ }
+
+ // Batches of log entries of a single type. Generally speaking, a given stream should only
+ // ever include one type of log entry.
+ oneof log_entries {
+ option (validate.required) = true;
+
+ HTTPAccessLogEntries http_logs = 2;
+
+ // [#not-implemented-hide:]
+ TCPAccessLogEntries tcp_logs = 3;
+ }
+}