/*
 * Copyright 2022 The gRPC Authors
 *
 * Licensed 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.
 */

syntax = "proto3";

package grpc.observabilitylog.v1;

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/code.proto";

option java_multiple_files = true;
option java_package = "io.grpc.observabilitylog.v1";
option java_outer_classname = "ObservabilityLogProto";

message GrpcLogRecord {
  // List of event types
  enum EventType {
    EVENT_TYPE_UNKNOWN = 0;
    // Header sent from client to server
    CLIENT_HEADER = 1;
    // Header sent from server to client
    SERVER_HEADER = 2;
    // Message sent from client to server
    CLIENT_MESSAGE = 3;
    // Message sent from server to client
    SERVER_MESSAGE = 4;
    // A signal that client is done sending
    CLIENT_HALF_CLOSE = 5;
    // Trailer indicates the end of the gRPC call
    SERVER_TRAILER = 6;
    // A signal that the rpc is canceled
    CANCEL = 7;
  }

  // The entity that generates the log entry
  enum EventLogger {
    LOGGER_UNKNOWN = 0;
    CLIENT = 1;
    SERVER = 2;
  }

  // Uniquely identifies a call.
  // Each call may have several log entries. They will all have the same call_id.
  // Nothing is guaranteed about their value other than they are unique across
  // different RPCs in the same gRPC process.
  string call_id = 2;

  // The entry sequence ID for this call. The first message has a value of 1,
  // to disambiguate from an unset value. The purpose of this field is to
  // detect missing entries in environments where durability or ordering is
  // not guaranteed.
  uint64 sequence_id = 3;

  EventType type = 4;      // one of the above EventType enum
  EventLogger logger = 5;  // one of the above EventLogger enum

  // Payload for log entry.
  // It can include a combination of {metadata, message, status based on type of
  // the event event being logged and config options.
  Payload payload = 6;

  // true if message or metadata field is either truncated or omitted due
  // to config options
  bool payload_truncated = 7;
  // Peer address information. On client side, peer is logged on server
  // header event or trailer event (if trailer-only). On server side, peer
  // is always logged on the client header event.
  Address peer = 8;

  // A single process may be used to run multiple virtual servers with
  // different identities.
  // The authority is the name of such a server identify. It is typically a
  // portion of the URI in the form of <host> or <host>:<port>.
  string authority = 10;
  // the name of the service
  string service_name = 11;
  // the name of the RPC method
  string method_name = 12;
}

message Payload {
  // A list of metadata pairs
  map<string, string> metadata = 1;
  // the RPC timeout value
  google.protobuf.Duration timeout = 2;
  // The gRPC status code
  google.rpc.Code status_code = 3;
  // The gRPC status message
  string status_message = 4;
  // The value of the grpc-status-details-bin metadata key, if any.
  // This is always an encoded google.rpc.Status message
  bytes status_details = 5;
  // Size of the message or metadata, depending on the event type,
  // regardless of whether the full message or metadata is being logged
  // (i.e. could be truncated or omitted).
  uint32 message_length = 6;
  // Used by message event
  bytes message = 7;
}

// Address information
message Address {
  enum Type {
    TYPE_UNKNOWN = 0;
    IPV4 = 1;  // in 1.2.3.4 form
    IPV6 = 2;  // IPv6 canonical form (RFC5952 section 4)
    UNIX = 3;  // UDS string
  }
  Type type = 1;
  string address = 2;
  // only for TYPE_IPV4 and TYPE_IPV6
  uint32 ip_port = 3;
}
