groups:
  - id: metric_attributes.http.server
    type: attribute_group
    brief: 'HTTP server attributes'
    extends: attributes.http.server
    attributes:
      - ref: server.address
        requirement_level: opt_in
        note: |
          See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).
          > **Warning**
          > Since this attribute is based on HTTP headers, opting in to it may allow an attacker
          > to trigger cardinality limits, degrading the usefulness of the metric.
      - ref: server.port
        requirement_level: opt_in
        note: |
          See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).
          > **Warning**
          > Since this attribute is based on HTTP headers, opting in to it may allow an attacker
          > to trigger cardinality limits, degrading the usefulness of the metric.
      - ref: user_agent.synthetic.type
        requirement_level: opt_in
  - id: metric_attributes.http.client
    type: attribute_group
    brief: 'HTTP client attributes'
    extends: attributes.http.client

  - id: metric_attributes.http.client.experimental
    type: attribute_group
    brief: 'HTTP client experimental attributes'
    extends: metric_attributes.http.client
    attributes:
      - ref: url.template
        requirement_level:
          conditionally_required: If available.
        note: >
          The `url.template` MUST have low cardinality. It is not usually available on HTTP clients, but may be known by the application or specialized HTTP instrumentation.

  - id: metric.http.server.request.duration
    type: metric
    metric_name: http.server.request.duration
    brief: "Duration of HTTP server requests."
    instrument: histogram
    unit: "s"
    stability: stable
    extends: metric_attributes.http.server

  - id: metric.http.server.active_requests
    type: metric
    metric_name: http.server.active_requests
    stability: experimental
    brief: "Number of active HTTP server requests."
    instrument: updowncounter
    unit: "{request}"
    attributes:
      - ref: http.request.method
        requirement_level: required
      - ref: url.scheme
        requirement_level: required
        examples: ["http", "https"]
      - ref: server.address
        requirement_level: opt_in
        brief: >
          Name of the local HTTP server that received the request.
        note: |
          See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).
          > **Warning**
          > Since this attribute is based on HTTP headers, opting in to it may allow an attacker
          > to trigger cardinality limits, degrading the usefulness of the metric.
      - ref: server.port
        requirement_level: opt_in
        brief: >
          Port of the local HTTP server that received the request.
        note: |
          See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).
          > **Warning**
          > Since this attribute is based on HTTP headers, opting in to it may allow an attacker
          > to trigger cardinality limits, degrading the usefulness of the metric.

  - id: metric.http.server.request.body.size
    type: metric
    metric_name: http.server.request.body.size
    stability: experimental
    brief: "Size of HTTP server request bodies."
    instrument: histogram
    unit: "By"
    note: >
      The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and
      is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)
      header. For requests using transport encoding, this should be the compressed size.
    extends: metric_attributes.http.server

  - id: metric.http.server.response.body.size
    type: metric
    metric_name: http.server.response.body.size
    stability: experimental
    brief: "Size of HTTP server response bodies."
    instrument: histogram
    unit: "By"
    note: >
      The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and
      is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)
      header. For requests using transport encoding, this should be the compressed size.
    extends: metric_attributes.http.server

  - id: metric.http.client.request.duration
    type: metric
    metric_name: http.client.request.duration
    brief: "Duration of HTTP client requests."
    instrument: histogram
    unit: "s"
    stability: stable
    extends: metric_attributes.http.client

  - id: metric.http.client.request.body.size
    type: metric
    metric_name: http.client.request.body.size
    stability: experimental
    brief: "Size of HTTP client request bodies."
    instrument: histogram
    unit: "By"
    note: >
      The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and
      is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)
      header. For requests using transport encoding, this should be the compressed size.
    extends: metric_attributes.http.client.experimental

  - id: metric.http.client.response.body.size
    type: metric
    metric_name: http.client.response.body.size
    stability: experimental
    brief: "Size of HTTP client response bodies."
    instrument: histogram
    unit: "By"
    note: >
      The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and
      is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)
      header. For requests using transport encoding, this should be the compressed size.
    extends: metric_attributes.http.client.experimental

  - id: metric.http.client.open_connections
    type: metric
    metric_name: http.client.open_connections
    stability: experimental
    brief: "Number of outbound HTTP connections that are currently active or idle on the client."
    instrument: updowncounter
    unit: "{connection}"
    attributes:
      - ref: http.connection.state
        requirement_level: required
      - ref: network.peer.address
        requirement_level: recommended
      - ref: network.protocol.version
        requirement_level: recommended
      - ref: server.address
        requirement_level: required
      - ref: server.port
        requirement_level: required
        brief: >
          Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to.
      - ref: url.scheme
        requirement_level: opt_in
        examples: ["http", "https"]

  - id: metric.http.client.connection.duration
    type: metric
    metric_name: http.client.connection.duration
    stability: experimental
    brief: "The duration of the successfully established outbound HTTP connections."
    instrument: histogram
    unit: "s"
    attributes:
      - ref: network.peer.address
        requirement_level: recommended
      - ref: network.protocol.version
        requirement_level: recommended
      - ref: server.address
        requirement_level: required
      - ref: server.port
        requirement_level: required
        brief: >
          Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to.
      - ref: url.scheme
        requirement_level: opt_in
        examples: ["http", "https"]

  - id: metric.http.client.active_requests
    type: metric
    metric_name: http.client.active_requests
    stability: experimental
    brief: "Number of active HTTP requests."
    instrument: updowncounter
    unit: "{request}"
    attributes:
      - ref: http.request.method
        requirement_level: recommended
      - ref: server.address
        requirement_level: required
      - ref: server.port
        requirement_level: required
        brief: >
          Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to.
      - ref: url.scheme
        requirement_level: opt_in
        examples: ["http", "https"]
      - ref: url.template
        requirement_level:
          conditionally_required: If available.
        note: >
          The `url.template` MUST have low cardinality. It is not usually available on HTTP clients, but may be known by the application or specialized HTTP instrumentation.
