# 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.

# This will parse a textual representation of a duration. The formats
# accepted are based on the ISO-8601 duration format {@code PnDTnHnMn.nS}
# with days considered to be exactly 24 hours.
# <p>
# Examples:
# <pre>
#    "PT20.345S" -- parses as "20.345 seconds"
#    "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
#    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
#    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
#    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
#    "P-6H3M"    -- parses as "-6 hours and +3 minutes"
#    "-P6H3M"    -- parses as "-6 hours and -3 minutes"
#    "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"
# </pre>
expSuffix: tag({tags -> tags.cluster = 'istio-ctrl::' + tags.cluster}).service(['cluster', 'app'], Layer.MESH_CP)
metricPrefix: meter_istio
metricsRules:
  ## Resource usage
  # Pilot Versions
  - name: pilot_version
    exp: istio_build.tagEqual('component', 'pilot').sum(['cluster', 'app', 'tag'])
  # Memory
  - name: virtual_memory
    exp: process_virtual_memory_bytes.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: resident_memory
    exp: process_resident_memory_bytes.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: go_alloc
    exp: go_memstats_alloc_bytes.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: go_heap_inuse
    exp: go_memstats_heap_inuse_bytes.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: go_stack_inuse
    exp: go_memstats_stack_inuse_bytes.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  # CPU
  - name: cpu
    exp: (process_cpu_seconds_total * 100).tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
  # Goroutines
  - name: go_goroutines
    exp: go_goroutines.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  ## Pilot push info
  # Pilot pushes
  - name: pilot_xds_pushes
    exp: pilot_xds_pushes.tagMatch('type', 'lds|cds|rds|eds').sum(['cluster', 'app', 'type']).irate()
  # Pilot Errors
  - name: pilot_xds_cds_reject
    exp: pilot_xds_cds_reject.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: pilot_xds_eds_reject
    exp: pilot_xds_eds_reject.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: pilot_xds_rds_reject
    exp: pilot_xds_rds_reject.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: pilot_xds_lds_reject
    exp: pilot_xds_lds_reject.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: pilot_xds_write_timeout
    exp: pilot_xds_write_timeout.tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
  - name: pilot_total_xds_internal_errors
    exp: pilot_total_xds_internal_errors.tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
  - name: pilot_total_xds_rejects
    exp: pilot_total_xds_rejects.tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
  - name: pilot_xds_push_context_errors
    exp: pilot_xds_push_context_errors.tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
  - name: pilot_xds_push_timeout
    exp: pilot_xds_push_timeout.tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
  # Proxy Push Time
  - name: pilot_proxy_push_percentile
    exp: pilot_proxy_convergence_time.sum(['cluster', 'app', 'le']).rate('PT1M').histogram().histogram_percentile([50,90,99])
  # Conflicts
  - name: pilot_conflict_il
    exp: pilot_conflict_inbound_listener.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: pilot_conflict_ol_http_tcp
    exp: pilot_conflict_outbound_listener_http_over_current_tcp.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: pilot_conflict_ol_tcp_tcp
    exp: pilot_conflict_outbound_listener_tcp_over_current_tcp.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: pilot_conflict_ol_tcp_http
    exp: pilot_conflict_outbound_listener_tcp_over_current_http.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  # ADS Monitoring
  - name: pilot_virt_services
    exp: pilot_virt_services.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: pilot_services
    exp: pilot_services.tagEqual('app', 'istiod').sum(['cluster', 'app'])
  - name: pilot_xds
    exp: pilot_xds.tagEqual('app', 'istiod').sum(['cluster', 'app'])

  ## Webhooks
  # Configuration Validation
  - name: galley_validation_passed
    exp: galley_validation_passed.tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
  - name: galley_validation_failed
    exp: galley_validation_failed.tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
  # Sidecar Injection
  - name: sidecar_injection_success_total
    exp: sidecar_injection_success_total.tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
  - name: sidecar_injection_failure_total
    exp: sidecar_injection_failure_total.tagEqual('app', 'istiod').sum(['cluster', 'app']).rate('PT1M')
