// Copyright 2016 Google Inc.
//
// 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 google.tracing.v1;

import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";

option go_package = "google.golang.org/genproto/googleapis/tracing/v1;tracing";
option java_multiple_files = true;
option java_outer_classname = "TraceProto";
option java_package = "com.google.tracing.v1";


// A TraceId uniquely identifies a Trace. It is conceptually a 128-bit value,
// represented as a string, containing the hex-encoded value.
message TraceId {
  // Trace ID specified as a hex-encoded string. *Must* be 32 bytes long.
  string hex_encoded = 1;
}

message Module {
  // Binary module.
  // E.g. main binary, kernel modules, and dynamic libraries
  // such as libc.so, sharedlib.so
  string module = 1;

  // Build_id is a unique identifier for the module,
  // probably a hash of its contents
  string build_id = 2;
}

message StackTrace {
  // Presents a single stack frame in a stack trace.
  message StackFrame {
    // Fully qualified names which uniquely identify function/method/etc.
    string function_name = 1;

    // Used when function name is ‘mangled’. Not guaranteed to be fully
    // qualified but usually it is.
    string orig_function_name = 2;

    // File name of the frame.
    string file_name = 3;

    // Line number of the frame.
    int64 line_number = 4;

    // Column number is important in JavaScript(anonymous functions),
    // Might not be available in some languages.
    int64 column_number = 5;

    // Binary module the code is loaded from.
    Module load_module = 6;

    // source_version is deployment specific. It might be
    // better to be stored in deployment metadata.
    // However, in distributed tracing, it’s hard to keep track of
    // source/binary versions at one place for all spans.
    string source_version = 7;
  }

  // Stack frames of this stack trace.
  repeated StackFrame stack_frame = 1;

  // User can choose to use his own hash function to hash large labels to save
  // network bandwidth and storage.
  // Typical usage is to pass both initially to inform the storage of the
  // mapping. And in subsequent calls, pass in stack_trace_hash_id only.
  // User shall verify the hash value is successfully stored.
  uint64 stack_trace_hash_id = 2;
}

// Allowed label values.
message LabelValue {
  // The value of the label.
  oneof value {
    // A string value.
    string string_value = 1;

    // An integer value.
    int64 int_value = 2;

    // A boolean value.
    bool bool_value = 3;
  }
}

// A span represents a single operation within a trace. Spans can be nested
// and form a trace tree. Often, a trace contains a root span that describes the
// end-to-end latency and, optionally, one or more subspans for
// its sub-operations. Spans do not need to be contiguous. There may be gaps
// between spans in a trace.
message Span {
  // A time-stamped annotation in the Span.
  message TimeEvent {
    // Text annotation with a set of labels.
    message Annotation {
      // A user-supplied message describing the event.
      string description = 1;

      // A set of labels on the annotation.
      map<string, LabelValue> labels = 2;
    }

    // An event describing an RPC message sent/received on the network.
    message NetworkEvent {
      // The type of the network event. SENT or RECV event.
      enum Type {
        UNSPECIFIED = 0;

        SENT = 1;

        RECV = 2;
      }

      // If available, this is the kernel time:
      // For sent messages, this is the time at which the first bit was sent.
      // For received messages, this is the time at which the last bit was
      // received.
      google.protobuf.Timestamp kernel_time = 1;

      Type type = 2;

      // Every message has an identifier, that must be different from all the
      // network messages in this span.
      // This is very important when the request/response are streamed.
      uint64 message_id = 3;

      // Number of bytes send/receive.
      uint64 message_size = 4;
    }

    // The local machine absolute timestamp when this event happened.
    google.protobuf.Timestamp local_time = 1;

    oneof value {
      // Optional field for user supplied <string, LabelValue> map
      Annotation annotation = 2;

      // Optional field that can be used only for network events.
      NetworkEvent network_event = 3;
    }
  }

  // Link one span with another which may be in a different Trace. Used (for
  // example) in batching operations, where a single batch handler processes
  // multiple requests from different traces.
  message Link {
    // The type of the link.
    enum Type {
      UNSPECIFIED = 0;

      CHILD = 1;

      PARENT = 2;
    }

    // The trace and span identifier of the linked span.
    TraceId trace_id = 1;

    fixed64 span_id = 2;

    Type type = 3;
  }

  // Identifier for the span. Must be a 64-bit integer other than 0 and
  // unique within a trace.
  fixed64 id = 1;

  // Name of the span. The span name is sanitized and displayed in the
  // Stackdriver Trace tool in the {% dynamic print site_values.console_name %}.
  // The name may be a method name or some other per-call site name.
  // For the same executable and the same call point, a best practice is
  // to use a consistent name, which makes it easier to correlate
  // cross-trace spans.
  string name = 2;

  // ID of parent span. 0 or missing if this is a root span.
  fixed64 parent_id = 3;

  // Local machine clock in nanoseconds from the UNIX epoch,
  // at which span execution started.
  // On the server side these are the times when the server application
  // handler starts running.
  google.protobuf.Timestamp local_start_time = 4;

  // Local machine clock in nanoseconds from the UNIX epoch,
  // at which span execution ended.
  // On the server side these are the times when the server application
  // handler finishes running.
  google.protobuf.Timestamp local_end_time = 5;

  // Properties of a span. Labels at the span level.
  // E.g.
  // "/instance_id": "my-instance"
  // "/zone": "us-central1-a"
  // "/grpc/peer_address": "ip:port" (dns, etc.)
  // "/grpc/deadline": "Duration"
  // "/http/user_agent"
  // "/http/request_bytes": 300
  // "/http/response_bytes": 1200
  // "/http/url": google.com/apis
  // "/pid"
  // "abc.com/mylabel": "my label value"
  map<string, LabelValue> labels = 6;

  // Stack trace captured at the start of the span. This is optional.
  StackTrace stack_trace = 7;

  // A collection of time-stamped events.
  repeated TimeEvent time_events = 8;

  // A collection of links.
  repeated Link links = 9;

  // The final status of the Span. This is optional.
  google.rpc.Status status = 10;

  // True if this Span has a remote parent (is an RPC server Span).
  bool has_remote_parent = 11;
}

// A trace describes how long it takes for an application to perform some
// operations. It consists of a tree of spans, each of which contains details
// about an operation with time information and operation details.
message Trace {
  // Globally unique identifier for the trace. Common to all the spans.
  TraceId trace_id = 1;

  // Collection of spans in the trace. The root span has parent_id == 0.
  repeated Span spans = 2;
}
