master cbafcecb8da1 cached
202 files
836.9 KB
234.6k tokens
584 symbols
1 requests
Download .txt
Showing preview only (894K chars total). Download the full file or copy to clipboard to get everything.
Repository: ivx/yet-another-cloudwatch-exporter
Branch: master
Commit: cbafcecb8da1
Files: 202
Total size: 836.9 KB

Directory structure:
gitextract_8d8x638_/

├── .dockerignore
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   └── feature.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── container_description.yml
│       └── golangci-lint.yml
├── .gitignore
├── .golangci.yml
├── .promu.yml
├── .yamllint
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTE.md
├── Dockerfile
├── LICENSE
├── MAINTAINERS.md
├── Makefile
├── Makefile.common
├── NOTICE
├── README.md
├── SECURITY.md
├── VERSION
├── cmd/
│   └── yace/
│       ├── main.go
│       ├── main_test.go
│       └── scraper.go
├── docker-compose/
│   ├── README.md
│   ├── docker-compose.yaml
│   ├── grafana/
│   │   └── datasource.yaml
│   ├── prometheus.yaml
│   └── yace-config.yaml
├── docs/
│   ├── configuration.md
│   ├── embedding.md
│   ├── feature_flags.md
│   └── installation.md
├── examples/
│   ├── alb.yml
│   ├── apigw.yml
│   ├── apprunner.yaml
│   ├── appstream.yml
│   ├── backup.yml
│   ├── cwagent.yml
│   ├── ds.yml
│   ├── dx.yml
│   ├── ebs.yml
│   ├── ec.yml
│   ├── ec2.yml
│   ├── ecs.yml
│   ├── elb.yml
│   ├── es.yml
│   ├── historic-data.yml
│   ├── kafka.yml
│   ├── kinesis.yml
│   ├── kms.yml
│   ├── lambda.yml
│   ├── lambda_edge.yml
│   ├── logs.yml
│   ├── mq.yml
│   ├── networkmanager.yml
│   ├── ngw.yml
│   ├── nlb.yml
│   ├── private-link-endpoints.yaml
│   ├── private-link-services.yaml
│   ├── qldb.yml
│   ├── quicksight.yml
│   ├── rds.yml
│   ├── redshift-serverless.yml
│   ├── s3.yml
│   ├── ses.yaml
│   ├── sns.yml
│   ├── sqs.yml
│   ├── usage.yml
│   └── vpn.yml
├── go.mod
├── go.sum
├── mixin/
│   ├── README.md
│   ├── config.libsonnet
│   ├── dashboards/
│   │   ├── all.libsonnet
│   │   ├── common.libsonnet
│   │   ├── ebs.libsonnet
│   │   ├── ec2.libsonnet
│   │   ├── lambda.libsonnet
│   │   ├── rds.libsonnet
│   │   └── s3.libsonnet
│   ├── jsonnetfile.json
│   ├── jsonnetfile.lock.json
│   ├── mixin.libsonnet
│   └── util.libsonnet
└── pkg/
    ├── clients/
    │   ├── README.md
    │   ├── account/
    │   │   └── client.go
    │   ├── cloudwatch/
    │   │   ├── client.go
    │   │   ├── client_test.go
    │   │   ├── concurrency_client.go
    │   │   └── input.go
    │   ├── factory.go
    │   ├── factory_test.go
    │   └── tagging/
    │       ├── client.go
    │       ├── concurrency_client.go
    │       ├── filters.go
    │       └── filters_test.go
    ├── config/
    │   ├── config.go
    │   ├── config_test.go
    │   ├── feature_flags.go
    │   ├── feature_flags_test.go
    │   ├── services.go
    │   ├── services_test.go
    │   └── testdata/
    │       ├── config_test.yml
    │       ├── custom_namespace.ok.yml
    │       ├── custom_namespace_without_name.bad.yml
    │       ├── custom_namespace_without_namespace.bad.yml
    │       ├── custom_namespace_without_region.bad.yml
    │       ├── discovery_job_exported_tags_alias.bad.yml
    │       ├── discovery_job_exported_tags_mismatch.bad.yml
    │       ├── discovery_job_type_alias.bad.yml
    │       ├── discovery_job_type_unknown.bad.yml
    │       ├── empty_rolearn.ok.yml
    │       ├── externalid_with_empty_rolearn.bad.yml
    │       ├── externalid_without_rolearn.bad.yml
    │       ├── multiple_roles.ok.yml
    │       ├── sts_region.ok.yml
    │       └── unknown_version.bad.yml
    ├── exporter.go
    ├── exporter_enhancedmetrics_test.go
    ├── exporter_test.go
    ├── internal/
    │   └── enhancedmetrics/
    │       ├── config/
    │       │   └── provider.go
    │       ├── registry.go
    │       ├── registry_test.go
    │       ├── service/
    │       │   ├── dynamodb/
    │       │   │   ├── client.go
    │       │   │   ├── client_test.go
    │       │   │   ├── service.go
    │       │   │   └── service_test.go
    │       │   ├── elasticache/
    │       │   │   ├── client.go
    │       │   │   ├── client_test.go
    │       │   │   ├── service.go
    │       │   │   └── service_test.go
    │       │   ├── lambda/
    │       │   │   ├── client.go
    │       │   │   ├── client_test.go
    │       │   │   ├── service.go
    │       │   │   └── service_test.go
    │       │   ├── rds/
    │       │   │   ├── client.go
    │       │   │   ├── client_test.go
    │       │   │   ├── service.go
    │       │   │   └── service_test.go
    │       │   └── services.go
    │       ├── service.go
    │       └── service_test.go
    ├── job/
    │   ├── cloudwatchrunner/
    │   │   ├── customnamespace.go
    │   │   ├── discovery.go
    │   │   └── runner.go
    │   ├── custom.go
    │   ├── discovery.go
    │   ├── discovery_test.go
    │   ├── getmetricdata/
    │   │   ├── compact.go
    │   │   ├── compact_test.go
    │   │   ├── iterator.go
    │   │   ├── iterator_test.go
    │   │   ├── processor.go
    │   │   ├── processor_test.go
    │   │   ├── windowcalculator.go
    │   │   └── windowcalculator_test.go
    │   ├── listmetrics/
    │   │   └── processor.go
    │   ├── maxdimassociator/
    │   │   ├── associator.go
    │   │   ├── associator_api_gateway_test.go
    │   │   ├── associator_client_vpn_test.go
    │   │   ├── associator_ddosprotection_test.go
    │   │   ├── associator_directoryservice_test.go
    │   │   ├── associator_dx_test.go
    │   │   ├── associator_ec2_test.go
    │   │   ├── associator_ec_test.go
    │   │   ├── associator_ecs_test.go
    │   │   ├── associator_event_roles_test.go
    │   │   ├── associator_globalaccelerator_test.go
    │   │   ├── associator_gwlb_test.go
    │   │   ├── associator_ipam_test.go
    │   │   ├── associator_kms_test.go
    │   │   ├── associator_lambda_test.go
    │   │   ├── associator_logging_test.go
    │   │   ├── associator_logs_test.go
    │   │   ├── associator_mediaconvert_test.go
    │   │   ├── associator_memorydb_test.go
    │   │   ├── associator_mq_test.go
    │   │   ├── associator_qldb_test.go
    │   │   ├── associator_redshift_serverless_test.go
    │   │   ├── associator_sagemaker_endpoint_test.go
    │   │   ├── associator_sagemaker_inf_component_test.go
    │   │   ├── associator_sagemaker_inf_rec_test.go
    │   │   ├── associator_sagemaker_pipeline_test.go
    │   │   ├── associator_sagemaker_processing_test.go
    │   │   ├── associator_sagemaker_test.go
    │   │   ├── associator_sagemaker_training_test.go
    │   │   └── associator_sagemaker_transform_test.go
    │   ├── resourcemetadata/
    │   │   └── resource.go
    │   ├── scrape.go
    │   ├── scraper.go
    │   ├── scraper_test.go
    │   └── static.go
    ├── model/
    │   ├── model.go
    │   └── model_test.go
    └── promutil/
        ├── migrate.go
        ├── migrate_test.go
        ├── prometheus.go
        └── prometheus_test.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
data/
.build/
.tarballs/

!.build/linux-amd64/
!.build/linux-arm64/
!.build/linux-armv7/
!.build/linux-ppc64le/
!.build/linux-riscv64/
!.build/linux-s390x/


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms


patreon: thomaspeitz


================================================
FILE: .github/ISSUE_TEMPLATE/bug.yml
================================================
name: 🐞 Bug
description: File a bug report
title: "[BUG] <title>"
labels: [bug]
body:
- type: checkboxes
  attributes:
    label: Is there an existing issue for this?
    description: Please search to see if an issue already exists for the bug you encountered.
    options:
    - label: I have searched the existing issues
      required: true
- type: textarea
  attributes:
    label: YACE version
    description: The output of running `yace version`.
  validations:
    required: false
- type: textarea
  attributes:
    label: Config file
    description: The config file passed to the `--config.file` option.
  validations:
    required: false
- type: textarea
  attributes:
    label: Current Behavior
    description: A concise description of what you're experiencing.
  validations:
    required: false
- type: textarea
  attributes:
    label: Expected Behavior
    description: A concise description of what you expected to happen.
  validations:
    required: false
- type: textarea
  attributes:
    label: Steps To Reproduce
    description: Steps to reproduce the behavior.
    placeholder: |
      1. In this environment...
      2. With this config...
      3. Run '...'
      4. See error...
  validations:
    required: false
- type: textarea
  attributes:
    label: Anything else?
    description: |
      Links? References? Anything that will give us more context about the issue you are encountering!

      Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
  validations:
    required: false


================================================
FILE: .github/ISSUE_TEMPLATE/feature.yml
================================================
name: 🆕 Feature
description: Request a new feature
title: "[FEATURE] <title>"
labels: [enhancement]
body:
- type: checkboxes
  attributes:
    label: Is there an existing issue for this?
    description: Please search to see if an issue already exists for the feature you are requesting.
    options:
    - label: I have searched the existing issues
      required: true
- type: textarea
  attributes:
    label: Feature description
    description: A concise description of what you're expecting.
  validations:
    required: true
- type: textarea
  attributes:
    label: What might the configuration look like?
    description: Example configuration (useful as a baseline during development).
    placeholder: |
      ```yml
      discovery:
        jobs:
        - type: <name of service>
          period: 30
          length: 600
          metrics:
          - name: SomeExportedMetric
            statistics: [Minimum, Maximum]
      ```
  validations:
    required: false
- type: textarea
  attributes:
    label: Anything else?
    description: |
      Links? References? Anything that will give us more context about the issue you are encountering!

      Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
  validations:
    required: false


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: gomod
    directory: /
    schedule:
      interval: monthly
    open-pull-requests-limit: 10
    groups:
      aws-sdk-v2:
        patterns:
          - "github.com/aws/aws-sdk-go-v2*"
  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: monthly
    open-pull-requests-limit: 10


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  push:
    tags:
      - 'v*'
    branches:
      - master
  pull_request:
  workflow_call:

jobs:
  test_go:
    name: Go tests
    runs-on: ubuntu-latest
    container:
      image: quay.io/prometheus/golang-builder:1.26-base
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: prometheus/promci-setup@5af30ba8c199a91d6c04ebdc3c48e630e355f62d # v0.1.0
      - run: make test

  build:
    name: Build for common architectures
    runs-on: ubuntu-latest
    if: |
      !(github.event_name == 'push' && github.event.ref == 'refs/heads/master')
      &&
      !(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
    strategy:
      matrix:
        thread: [ 0, 1, 2 ]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: prometheus/promci/build@769ee18070cd21cfc2a24fa912349fd3e48dee58 # v0.6.0
        with:
          promu_opts: "-p linux/amd64 -p windows/amd64 -p darwin/amd64 -p linux/arm64 -p windows/arm64 -p darwin/arm64"
          parallelism: 3
          thread: ${{ matrix.thread }}

  build_all:
    name: Build for all architectures
    runs-on: ubuntu-latest
    if: |
      (github.event_name == 'push' && github.event.ref == 'refs/heads/master')
      ||
      (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
    strategy:
      matrix:
        thread: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: prometheus/promci/build@769ee18070cd21cfc2a24fa912349fd3e48dee58 # v0.6.0
        with:
          parallelism: 12
          thread: ${{ matrix.thread }}

  verify-example-configs:
    name: Verify
    runs-on: ubuntu-latest
    container:
      image: quay.io/prometheus/golang-builder:1.26-base
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - run: make build
      - name: Verify example configs
        run: find ./examples -name "*.yml" -print0 | xargs -0 -I % ./yace verify-config -config.file %

  publish_master:
    name: Publish master branch artifacts
    runs-on: ubuntu-latest
    needs: [test_go, build_all, verify-example-configs]
    if: |
      (github.repository == 'prometheus-community/yet-another-cloudwatch-exporter')
      &&
      (github.event_name == 'push' && github.event.ref == 'refs/heads/master')
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: prometheus/promci/publish_main@769ee18070cd21cfc2a24fa912349fd3e48dee58 # v0.6.0
        with:
          docker_hub_organization: prometheuscommunity
          docker_hub_login: ${{ secrets.docker_hub_login }}
          docker_hub_password: ${{ secrets.docker_hub_password }}
          quay_io_organization: prometheuscommunity
          quay_io_login: ${{ secrets.quay_io_login }}
          quay_io_password: ${{ secrets.quay_io_password }}

  publish_release:
    name: Publish release artifacts
    runs-on: ubuntu-latest
    needs: [test_go, build_all, verify-example-configs]
    if: |
      (github.repository == 'prometheus-community/yet-another-cloudwatch-exporter')
      &&
      (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v0.'))
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: prometheus/promci/publish_release@769ee18070cd21cfc2a24fa912349fd3e48dee58 # v0.6.0
        with:
          docker_hub_organization: prometheuscommunity
          docker_hub_login: ${{ secrets.docker_hub_login }}
          docker_hub_password: ${{ secrets.docker_hub_password }}
          quay_io_organization: prometheuscommunity
          quay_io_login: ${{ secrets.quay_io_login }}
          quay_io_password: ${{ secrets.quay_io_password }}
          github_token: ${{ secrets.PROMBOT_GITHUB_TOKEN }}


================================================
FILE: .github/workflows/container_description.yml
================================================
---
name: Push README to Docker Hub
on:
  push:
    paths:
      - "README.md"
      - "README-containers.md"
      - ".github/workflows/container_description.yml"
    branches: [ main, master ]

permissions:
  contents: read

jobs:
  PushDockerHubReadme:
    runs-on: ubuntu-latest
    name: Push README to Docker Hub
    if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
    steps:
      - name: git checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Set docker hub repo name
        run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV
      - name: Push README to Dockerhub
        uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1
        env:
          DOCKER_USER: ${{ secrets.DOCKER_HUB_LOGIN }}
          DOCKER_PASS: ${{ secrets.DOCKER_HUB_PASSWORD }}
        with:
          destination_container_repo: ${{ env.DOCKER_REPO_NAME }}
          provider: dockerhub
          short_description: ${{ env.DOCKER_REPO_NAME }}
          # Empty string results in README-containers.md being pushed if it
          # exists. Otherwise, README.md is pushed.
          readme_file: ''

  PushQuayIoReadme:
    runs-on: ubuntu-latest
    name: Push README to quay.io
    if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
    steps:
      - name: git checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Set quay.io org name
        run: echo "DOCKER_REPO=$(echo quay.io/${GITHUB_REPOSITORY_OWNER} | tr -d '-')" >> $GITHUB_ENV
      - name: Set quay.io repo name
        run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV
      - name: Push README to quay.io
        uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1
        env:
          DOCKER_APIKEY: ${{ secrets.QUAY_IO_API_TOKEN }}
        with:
          destination_container_repo: ${{ env.DOCKER_REPO_NAME }}
          provider: quay
          # Empty string results in README-containers.md being pushed if it
          # exists. Otherwise, README.md is pushed.
          readme_file: ''


================================================
FILE: .github/workflows/golangci-lint.yml
================================================
---
# This action is synced from https://github.com/prometheus/prometheus
name: golangci-lint
on:
  push:
    branches: [main, master, 'release-*']
    paths:
      - "go.sum"
      - "go.mod"
      - "**.go"
      - "scripts/errcheck_excludes.txt"
      - ".github/workflows/golangci-lint.yml"
      - ".golangci.yml"
    tags: ['v*']
  pull_request:

permissions:  # added using https://github.com/step-security/secure-repo
  contents: read

jobs:
  golangci:
    permissions:
      contents: read  # for actions/checkout to fetch code
      pull-requests: read  # for golangci/golangci-lint-action to fetch pull requests
    name: lint
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - name: Install Go
        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
        with:
          go-version: 1.26.x
      - name: Install snmp_exporter/generator dependencies
        run: sudo apt-get update && sudo apt-get -y install libsnmp-dev
        if: github.repository == 'prometheus/snmp_exporter'
      - name: Get golangci-lint version
        id: golangci-lint-version
        run: echo "version=$(make print-golangci-lint-version)" >> $GITHUB_OUTPUT
      - name: Lint
        uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
        with:
          args: --verbose
          version: ${{ steps.golangci-lint-version.outputs.version }}


================================================
FILE: .gitignore
================================================
.build
yet-another-cloudwatch-exporter
!charts/yet-another-cloudwatch-exporter
vendor
dist
/yace
*.tar.gz


================================================
FILE: .golangci.yml
================================================
version: "2"
output:
  formats:
    text:
      path: stderr
      colors: false
linters:
  default: none
  enable:
    - asasalint
    - bodyclose
    - copyloopvar
    - errcheck
    - errorlint
    - exhaustive
    - govet
    - ineffassign
    - misspell
    - nilerr
    - nolintlint
    - nonamedreturns
    - predeclared
    - revive
    - sloglint
    - staticcheck
    - unconvert
    - unused
  exclusions:
    generated: lax
    presets:
      - comments
      - common-false-positives
      - legacy
      - std-error-handling
    paths:
      - third_party$
      - builtin$
      - examples$
formatters:
  enable:
    - gofmt
    - gofumpt
    - goimports
  settings:
    goimports:
      local-prefixes:
        - github.com/prometheus-community/yet-another-cloudwatch-exporter
  exclusions:
    generated: lax
    paths:
      - third_party$
      - builtin$
      - examples$


================================================
FILE: .promu.yml
================================================
go:
    # This must match .circle/config.yml.
    version: 1.26
repository:
    path: github.com/prometheus-community/yet-another-cloudwatch-exporter
build:
    binaries:
        - name: yace
          path: ./cmd/yace
    ldflags: |
        -X github.com/prometheus/common/version.Version={{.Version}}
        -X github.com/prometheus/common/version.Revision={{.Revision}}
        -X github.com/prometheus/common/version.Branch={{.Branch}}
        -X github.com/prometheus/common/version.BuildUser={{user}}@{{host}}
        -X github.com/prometheus/common/version.BuildDate={{date "20060102-15:04:05"}}
tarball:
    files:
        - LICENSE
        - NOTICE


================================================
FILE: .yamllint
================================================
---
extends: default
ignore: |
  **/node_modules
  web/api/v1/testdata/openapi_*_golden.yaml

rules:
  braces:
    max-spaces-inside: 1
    level: error
  brackets:
    max-spaces-inside: 1
    level: error
  commas: disable
  comments: disable
  comments-indentation: disable
  document-start: disable
  indentation:
    spaces: consistent
    indent-sequences: consistent
  key-duplicates:
    ignore: |
      config/testdata/section_key_dup.bad.yml
  line-length: disable
  truthy:
    check-keys: false


================================================
FILE: CHANGELOG.md
================================================
## main / (unreleased)

## 0.64.0 / 2026-03-27

**Important news and breaking changes**

- BREAKING CHANGE: AWS SDK v1 support has been removed. The `aws-sdk-v1` feature flag is now a no-op and will be silently ignored. AWS SDK v1 reached end-of-support on July 31, 2025. SDK v2 has been the default since v0.63.0 (September 2025). Users who were passing `--enable-feature aws-sdk-v1` should remove the flag, as it no longer has any effect. If you use YACE as a library, the `v1` and `v2` sub-packages under `pkg/clients/` have been removed. All client implementations now live directly in their parent packages (e.g. `pkg/clients/cloudwatch`, `pkg/clients/tagging`, `pkg/clients/account`). Import paths like `pkg/clients/v1`, `pkg/clients/cloudwatch/v2`, etc. must be updated accordingly.

* [CHANGE] Remove AWS SDK v1 support and deprecate `aws-sdk-v1` feature flag by @tristanburgess. #1825
* [CHANGE] Add Andrii Kushch and Tristan Burgess as maintainers by @cristiangreco. #1788
* [FEATURE] Implement Enhanced Metrics framework and initial set of metrics by @andriikushch. #1795
* [FEATURE] Add support for `AWS/EKS` namespace by @LS80. #1760
* [FEATURE] Split out Bedrock metrics into all needed namespaces by @tristanburgess. #1766
* [FEATURE] Separate aliases for Bedrock namespaces by @tristanburgess. #1767
* [ENHANCEMENT] Update Go build to 1.26, replace `gopkg.in/yaml.v2` with supported fork, sync upstream Prometheus files and migrate PromCI tooling by @SuperQ. #1831
* [ENHANCEMENT] Add AWS/Bedrock GuardrailArn dimension-based resource tagging by @tristanburgess. #1761
* [ENHANCEMENT] Add DimensionRegexps support for AWS Backup service by @amitshl. #1775
* [ENHANCEMENT] Add DimensionRegexps for AWS/Cassandra by @bdeore. #1693
* [ENHANCEMENT] Add DimensionRegexp to ElasticBeanstalk by @benbridts. #1690
* [ENHANCEMENT] Test exporter with mocked clients by @jeschkies. #1791
* [ENHANCEMENT] Add privatelink examples to docs by @cuscal-brad. #1765
* [BUGFIX] Fix AWS SageMaker dimension name handling for case sensitivity by @andriikushch. #1793
* [BUGFIX] Fix Docker configuration paths for AWS credentials by @andriikushch. #1804

## 0.63.0 / 2025-09-25

**Important news and breaking changes**

- NOTE: As of Prometheus 3.0, UTF-8 strings are valid for metric names and label names. However, for backward compatibility, this release of YACE still uses the old, stricter legacy validation scheme. UTF-8 validation will be enabled in a feature version of YACE, thus requiring that your remote destination is compatible with UTF-8 support.

- BREAKING CHANGE: the AWS SDK v2 is now the default in YACE. Use the flag `aws-sdk-v1` to switch back to SDK v2. Flag `aws-sdk-v2` has been removed.

- NEW FEATURE: `exportAllDataPoints`, enables the inclusion of past metric data points from the CloudWatch response if available.

* [CHANGE] Make aws sdk v2 the default choice by @cristiangreco
* [FEATURE] Support history data export by @woehrl01
* [FEATURE] Add AWS/Transfer as available service by @thepalbi
* [FEATURE] Add auto-discovery for Directory Services(MicrosoftAD) by @RuslanMustaev
* [FEATURE] Add support for Redshift-Serverless by @nickbazinet
* [FEATURE] Add db connections avg panel to RDS dashboard by @yduartep
* [FEATURE] Add example for lambda_edge by @tyagian
* [FEATURE] sagemaker: additional InferenceComponent support by @tristanburgess
* [ENHANCEMENT] Update Go version by @SuperQ
* [ENHANCEMENT] Use Prometheus common version library by @SuperQ
* [ENHANCEMENT] Update container repositories by @SuperQ
* [ENHANCEMENT] Speed up build metric name by @jeschkies
* [ENHANCEMENT] Add guard to hot logging location in associator by @thepalbi
* [ENHANCEMENT] Update resource association logic to try both with and without dimension fixes by @tristanburgess
* [ENHANCEMENT] Change discovery runtime model field from Type -> Namespace by @kgeckhart
* [BUGFIX] Fix `CachingFactory` concurrent usage issues by @andriikushch
* [BUGFIX] Correctly run tests in CI and fix failing tests by @jeschkies
* [BUGFIX] Fix doc about non-existing `debug` flag by @zipkid
* [BUGFIX] Update URL to Helm Chart in docs by @koralowiec
* [BUGFIX] Add missing license header to `associator_logging_test.go` by @cristiangreco
* [BUGFIX] Dashboards: replace `scrape_job` label with `job` by @yduartep
* [BUGFIX] RDS dashboard: use average for cpu utilization to align with AWS best practices by @yduartep

## 0.62.1 / 2025-01-03

**Important news and breaking changes**

Bugfix release to address artifacts build error. The most important news is the same as 0.62.0: as of November 2024, YACE is part of prometheus-community. Read more about it in these announcement posts:
- https://prometheus.io/blog/2024/11/19/yace-joining-prometheus-community/
- https://grafana.com/blog/2024/11/19/yace-moves-to-prometheus-community/

* [ENHANCEMENT] Adopt log/slog, drop custom logging pkg by @tjhop
* [ENHANCEMENT] Bump github.com/prometheus/common from 0.60.1 to 0.61.0
* [ENHANCEMENT] Bump golang.org/x/sync from 0.9.0 to 0.10.0
* [ENHANCEMENT] Bump the aws-sdk-v2 group
* [ENHANCEMENT] Synchronize common files from prometheus/prometheus
* [ENHANCEMENT] Update CHANGELOG format by @SuperQ
* [BUGFIX] Fix artifact publishing by @SuperQ

## 0.62.0 / 2024-12-19

**Important news and breaking changes**

* As of November 2024, YACE is part of prometheus-community. Read more about it in these announcement posts:
- https://prometheus.io/blog/2024/11/19/yace-joining-prometheus-community/
- https://grafana.com/blog/2024/11/19/yace-moves-to-prometheus-community/

**Bugfixes and features**

Features:
* Add ContainerInsights service by @JetSquirrel
* Add AWS/Scheduler and AWS/ECR services by @andriikushch
* Add AWS/VpcLattice service by @greymd
* Add AWS/QuickSight service by @choppedpork
* Add AWS/Timestream service by @andriikushch
* Add Network Manager / Cloud WAN support by @kylehodgetts
* RDS: include RDS Proxy metrics within the RDS namespace by @vitaliyf
* Mediapackage: include mediapackagev2 namespace by @henrylaiBrightcove

Bugs:
* Add parentheses to sanitize list to prevent invalid metric name generation by @nixargh

Docs:
* Review and update supported services in README by @cristiangreco
* Mention support for AWS/MediaPackage by @prathamesh-sonpatki
* Update README and MAINTAINERS files to mention the move to prometheus-community by @cristiangreco

Refactoring:
* Start a unified scraper by @kgeckhart
* Refactor prom metric creation by @kgeckhart
* Update for Prometheus Community by @SuperQ
* Update Docker build by @SuperQ
* Fix linting issues detected by golangci-lint 1.60.3 by @cristiangreco
* Update build tools and CI to Go 1.23 by @cristiangreco

**Dependencies**

* Bump actions/checkout from 4.2.0 to 4.2.2
* Bump alpine from 3.20.1 to 3.20.3
* Bump github.com/aws/aws-sdk-go from 1.54.7 to 1.55.5
* Bump github.com/aws/smithy-go from 1.22.0 to 1.22.1
* Bump github.com/prometheus/client_golang from 1.19.1 to 1.20.5
* Bump github.com/prometheus/common from 0.54.0 to 0.60.1
* Bump github.com/stretchr/testify from 1.9.0 to 1.10.0
* Bump github.com/urfave/cli/v2 from 2.27.2 to 2.27.5
* Bump golang from 1.22 to 1.23
* Bump golang.org/x/sync from 0.7.0 to 0.9.0
* Bump golangci/golangci-lint-action from 6.0.1 to 6.1.1
* Bump grafana/regexp to `20240607082908-2cb410fa05da`
* Bump the aws-sdk-v2 group

**New contributors**

* @prathamesh-sonpatki made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1465
* @JetSquirrel made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1463
* @greymd made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1506
* @choppedpork made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1477
* @SuperQ made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1568
* @prombot made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1570
* @nixargh made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1563
* @kylehodgetts made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1580
* @vitaliyf made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1501
* @henrylaiBrightcove made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1544

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.61.2...v0.62.0

## 0.61.2 / 2024-06-25

Bugfix release to update the `goreleaser` configuration (again!), please refer to the release notes for `0.61.0` for actual code changes.

https://github.com/prometheus-community/yet-another-cloudwatch-exporter/releases/tag/v0.61.0

## 0.61.1 / 2024-06-25

Bugfix release to update the `goreleaser` configuration, please refer to the release notes for `0.61.0` for actual code changes.

https://github.com/prometheus-community/yet-another-cloudwatch-exporter/releases/tag/v0.61.0

## 0.61.0 / 2024-06-25

**Important news and breaking changes**

* This release adds support for AWS account aliases (by @thepalbi). If the role used by YACE has `"iam:ListAccountAliases"` permission, the account alias (if any) is added as a label to the `aws_account_info` metric.

**Bugfixes and features**

Features:
* Add AWS/EC2CapacityReservations to the services list by @luismy
* Add support for MediaPackage metrics by @theunissenne
* Add AWS/AppRunner as supported service by @fabiiw05

Bugs:
* Fix association with gwlb by @vainiusd

Refactoring:
* Add support for batching by time params by @kgeckhart

**Dependencies**

* Bump alpine from 3.19.1 to 3.20.1
* Bump github.com/aws/aws-sdk-go from 1.53.1 to 1.54.7
* Bump github.com/aws/aws-sdk-go-v2/service/ec2 from 1.161.4 to 1.162.0 in the aws-sdk-v2 group
* Bump github.com/prometheus/common from 0.53.0 to 0.54.0
* Bump golangci/golangci-lint-action from 5.3.0 to 6.0.1
* Bump goreleaser/goreleaser-action from 5 to 6
* Bump the aws-sdk-v2 group

**New contributors**

* @luismy made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1341
* @fabiiw05 made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1433

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.60.0...v0.61.0

## 0.60.0 / 2024-05-14

**Bugfixes and features**

Features:
* add cloudwatch log metric support by @vainiusd
* feat: add AWS/RUM as supported service by @hexionas

Bugs:
* Fix all value for function_name variable in lambda dashboard by @thepalbi
* Fix rounding period deprecation notice by @cristiangreco

Docs:
* README: update config example by @cristiangreco
* Fix ElastiCache metric namespace typo on README by @Roberdvs

Refactoring:
* getmetricdata: Move batching to an iterator by @kgeckhart

**Dependencies**
* Bump github.com/aws/aws-sdk-go from 1.51.21 to 1.53.1
* Bump github.com/aws/aws-sdk-go-v2/service/ec2 from 1.156.0 to 1.160.0
* Bump github.com/prometheus/client_golang from 1.19.0 to 1.19.1
* Bump github.com/prometheus/common from 0.52.3 to 0.53.0
* Bump github.com/urfave/cli/v2 from 2.27.1 to 2.27.2
* Bump golangci/golangci-lint-action from 4.0.0 to 5.3.0
* Bump the aws-sdk-v2 group with 13 updates

**New contributors**

* @Roberdvs made their first contribution
* @hexionas made their first contribution

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.59.0...v0.60.0

## 0.59.0 / 2024-04-18

**Important news and breaking changes**

This release brings a bunch of breaking changes:
* Setting `roundingPeriod` for discovery jobs is deprecated, a warning will be logged at startup. This is being deprecated in favor of always using the metric period. The implementation for `roundingPeriod` can result in inconsistent Start and EndTime between batches. This negates its intent to ensure Start and EndTimes align with the metric period for [CloudWatch best practices](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricData.html). This has the potential to produce data which will look inaccurate when compared against CloudWatch itself driving a lot of confusion. See https://github.com/prometheus-community/yet-another-cloudwatch-exporter/issues/1290 for further context.
* Setting `delay` at the metric level is deprecated, a warning will be logged at startup. This `delay` configuration has existed for a long time but was never utilized. Deprecating it and eventually removing it was chosen to simplify the configuration. See https://github.com/prometheus-community/yet-another-cloudwatch-exporter/issues/1290#issuecomment-1948904375 for further context.
* For discovery jobs, the `type` field and the keys of `exportedTagsOnMetrics` must be the AWS namespace rather than the alias (the README contains an up-to-date list of namespaces). Aliases are not allowed anymore. An error will be thrown at startup in an invalid namespace or an alias is used.
* Some metric names have been changed to avoid duplicating the namespace. This includes:
  - `aws_es_esreporting_failed_request_sys_err_count` is `aws_es_reporting_failed_request_sys_err_count`
  - `aws_es_esreporting_failed_request_user_err_count` is `aws_es_reporting_failed_request_user_err_count`
  - `aws_es_esreporting_request_count` is `aws_es_reporting_request_count`
  - `aws_es_esreporting_success_count` is `aws_es_reporting_success_count`
  - `aws_kafka_kafka_app_logs_disk_used` is `aws_kafka_app_logs_disk_used`
  - `aws_kafka_kafka_data_logs_disk_used` is `aws_kafka_data_logs_disk_used`
  - `aws_rds_rdsto_aurora_postgre_sqlreplica_lag` is  `aws_rds_to_aurora_postgre_sqlreplica_lag`
  - `aws_glue_glue_.*` is `aws_glue_.*`

These breaking changes will allow making the configuration easier to understand and less error prone, and also to build better documentation around supported services.

**Bugfixes and features**

Features:
* Add AWS/SecretsManager to the services list by @taraspos
* Support partner events buses by @HristoStoyanovYotpo
* `discovery.exportedTagsOnMetrics`: validate that keys match one of the job types defined by @cristiangreco

Refactoring:
* Update comment in factory.go by @andriikushch
* getmetricdata: move window calculator to processor by @kgeckhart
* promutil: clean up prom metric names that duplicate parts of the namespace by @tristanburgess
* promutil: rewrite sanitisation funcs for memory optimisation by @cristiangreco
* Do not allow using aliases as job types in discovery jobs by @cristiangreco

**Dependencies**

* Bump github.com/aws/aws-sdk-go from 1.51.16 to 1.51.21
* Bump github.com/aws/aws-sdk-go-v2 group
* Bump github.com/prometheus/common from 0.52.2 to 0.52.3

**New contributors**

* @taraspos made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1330
* @HristoStoyanovYotpo made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1359

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.58.0...v0.59.0

## 0.58.0 / 2024-04-06

**Bugfixes and features**

Features:
* Simplify CloudWatch API call counters by @kgeckhart

Bugs:
* Fixed issue with generated Prometheus metric name when working with AWS namespaces which have a leading special character, like `/aws/sagemaker/TrainingJobs` by @tristanburgess

Refactoring:
* Add abstraction for `GetMetricsData` processing by @kgeckhart
* `GetMetricData`: refactor QueryID generation and result mapping by @kgeckhart
* Refactored out the name-building part of `promutil.BuildNamespaceInfoMetrics()` and `promutil.BuildMetrics()` into `promutil.BuildMetricName()` by @tristanburgess
* Set initial maps size in promutil/migrate by @cristiangreco

**Dependencies**

* Bump github.com/aws/aws-sdk-go from 1.50.30 to 1.51.16
* Bump github.com/prometheus/common from 0.49.0 to 0.52.2
* Bump golang.org/x/sync from 0.6.0 to 0.7.0
* Bump the aws-sdk-v2 group with 14 updates

**New contributors**

* @tristanburgess made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1351

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.57.1...v0.58.0


## 0.57.1 / 2024-03-07

**Important news and breaking changes**

* Reverted a change from 0.57.0 to fix scraping of ApiGateway resources.

**Bugfixes and features**

Bugs:
* ApiGateway: bugfix to restore FilterFunc for correct mapping of resources by @cristiangreco

**Dependencies**

## What's Changed
* Bump github.com/aws/aws-sdk-go from 1.50.26 to 1.50.30
* Bump github.com/prometheus/client_golang from 1.18.0 to 1.19.0
* Bump github.com/prometheus/common from 0.48.0 to 0.49.0
* Bump github.com/stretchr/testify from 1.8.4 to 1.9.0
* Bump the aws-sdk-v2 group

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.57.0...v0.57.1

# v0.57.0

**Important news and breaking changes**

* New job setting `includeContextOnInfoMetrics` can be used to include contextual information (account_id, region, and customTags) on "info" metrics and cloudwatch metrics. This can be particularly useful when cloudwatch metrics might not be present or when using "info" metrics to understand where your resources exist.
* No more need to add the `apigateway:GET` permissions for ApiGateway discovery jobs, as that API is not being used anymore.

**Bugfixes and features**

Features:
* Add serverless ElastiCache support by @pkubicsek-sb
* Add GWLB support by @vainiusd
* Add support for KMS metrics by @daharon
* Optionally include context labels (account, region, customTags) on info metrics with `includeContextOnInfoMetrics` by @kgeckhart
* Improve usability and performance of searchTags by @kgeckhart
* Add metric yace_cloudwatch_getmetricdata_metrics_total by @keyolk

Bugs:
* Fix race condition in scraper registry usage by @cristiangreco
* Restore default behaviour of returning nil/absent metrics as NaN by @nhinds
* Remove filtering of ApiGateway namespace resources by @cristiangreco

Refactoring:
* Refactor dimensions regexp usage for discovery jobs by @cristiangreco
* Simplify associator usage by @kgeckhart
* Update build tools and CI to go 1.22 by @cristiangreco
* Restructure fields on CloudwatchData by @kgeckhart

**Dependencies**

* Bump alpine from 3.19.0 to 3.19.1
* Bump github.com/aws/aws-sdk-go from 1.49.19 to 1.50.26
* Bump github.com/aws/smithy-go from 1.19.0 to 1.20.1
* Bump github.com/prometheus/common from 0.45.0 to 0.48.0
* Bump golang from 1.21 to 1.22
* Bump golangci/golangci-lint-action from 3.7.0 to 4.0.0
* Bump the aws-sdk-v2 group

**New contributors**

* @vainiusd made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1093
* @daharon made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/1306
* @keyolk made their first contribution in https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pull/939

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.56.0...v0.57.0

# v0.56.0

**Important news and breaking changes**

* Release v0.55.0 didn't include binaries artifact due to an issue with the release pipeline.
* The `list-metrics-callback` and `max-dimensions-associator` feature flags have been removed: their behaviour is now the new default.

**Bugfixes and features**

Features:
* Add new CloudWatch API concurrency limiter by @thepalbi
* Remove feature flag `list-metrics-callback` by @cristiangreco
* Remove feature flag `max-dimensions-associator` by @cristiangreco
* Add support for AWS/Bedrock metrics by @thepalbi
* Add support for AWS/Events by @raanand-dig
* Add support for AWS/DataSync by @wkneewalden
* Add support for AWS/IPAM by @pkubicsek-sb

Bugs:
* Remove unsupported MWAA resource filter by @matej-g
* DDoSProtection: Include regionless protectedResources in us-east-1 by @kgeckhart
* aws sdk v2: ensure region is respected for all aws clients by @kgeckhart
* SageMaker: Associator buildLabelsMap to lower case EndpointName to match ARN by @GGonzalezGomez
* Update goreleaser action by @cristiangreco

Refactoring:
* Decouple config models from internal models by @cristiangreco
* Change config Validate() signature to include model conversion by @cristiangreco

**Dependencies**

* Bump actions/setup-go from 4 to 5
* Bump alpine from 3.18.3 to 3.19.0
* Bump docker/setup-buildx-action from 2 to 3
* Bump docker/setup-qemu-action from 2 to 3
* Bump github.com/aws/aws-sdk-go from 1.45.24 to 1.49.19
* Bump github.com/aws/smithy-go from 1.17.0 to 1.19.0
* Bump github.com/prometheus/client_golang from 1.16.0 to 1.18.0
* Bump github.com/prometheus/common from 0.44.0 to 0.45.0
* Bump github.com/urfave/cli/v2 from 2.25.7 to 2.27.1
* Bump golang.org/x/sync from 0.3.0 to 0.6.0
* Bump goreleaser/goreleaser-action from 4 to 5
* Bump the aws-sdk-v2 group dependencies

**New contributors**

* @GGonzalezGomez
* @wkneewalden
* @pkubicsek-sb

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.55.0...v0.56.0

# v0.55.0

**Important news and breaking changes**

* jobs of type `customNamespace`, which were deprecated in `v0.51.0`, are now **un-deprecated** due to customers' feedback
* new feature flag `always-return-info-metrics`: return info metrics even if there are no CloudWatch metrics for the resource. This is useful if you want to get a complete picture of your estate, for example if you have some resources which have not yet been used.

**Bugfixes and features**

Features:
* Un-deprecate custom namespace jobs by @cristiangreco
* scrape: Return resources even if there are no metrics by @iainlane
* kinesisanalytics application: add tags support by @raanand-dig
* Add support for AWS/ClientVPN by @hc2p
* Add support for QLDB by @alexandre-alvarengazh

Bugs:
* main: Initialise logger when exiting if needed by @iainlane

Docs:
* Create sqs.yml example file by @dverzolla

Refactoring:
* Update code to go 1.21 by @cristiangreco
* aws sdk v2 use EndpointResolverV2 by @kgeckhart
* move duplicated fields from CloudwatchData to a new JobContext by @kgeckhart

**Dependencies**

* Bump github.com/aws/aws-sdk-go from 1.44.328 to 1.45.7
* Bump the aws-sdk-v2 group with 2 updates
* Bump actions/checkout from 3 to 4 by

**New Contributors**

* @raanand-dig
* @dverzolla
* @iainlane
* @hc2p
* @alexandre-alvarengazh

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.54.1...v0.55.0


# v0.54.1

Bugs:
* sdk v2: Set RetryMaxAttempts on root config instead client options by @kgeckhart
* Match FIPS implementation between sdk v1 and sdk v2 by @kgeckhart
* Fix regex for vpc-endpoint-service by @cristiangreco

**Dependencies**

* Bump golangci/golangci-lint-action from 3.6.0 to 3.7.0
* Bump github.com/aws/aws-sdk-go from 1.44.327 to 1.44.328

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.54.0...v0.54.1

# v0.54.0

**Bugfixes and features**

Features:
* Log features enabled at startup by @cristiangreco
* Use go-kit logger and add `log.format` flag by @cristiangreco

Bugs:
* Remove tagged resource requirement from TrustedAdvisor by @kgeckhart
* Fix: RDS dashboard filtering by job value by @andriikushch
* Review dimensions regexps for APIGateway by @cristiangreco
* Fix syntax in rds.libsonnet by @andriikushch
* Fix the `FilterId` label value selection for s3 dashboard by @andriikushch
* MaxDimAssociator: loop through all mappings by @cristiangreco
* MaxDimAssociator: wrap some expensive debug logs by @cristiangreco
* MaxDimAssociator: compile AmazonMQ broker suffix regex once by @cristiangreco
* Limit number of goroutines for GetMetricData calls by @cristiangreco
* Reduce uncessary pointer usage in getmetricdata code path by @kgeckhart
* Improve perf in discovery jobs metrics to data lookup by @thepalbi
* Improve FIPS endpoints resolve logic for sdk v1 by @thepalbi

Docs:
* Add more config examples (ApiGW, SES, SNS, ECS) by @cristiangreco

Refactoring:
* Refactor clients.Cache -> clients.Factory by @kgeckhart
* dependabot: use group updates for aws sdk v2 by @cristiangreco
* Add debug logging to maxdimassociator by @cristiangreco

**Dependencies**

New dependecies:
* github.com/go-kit/log v0.2.1

Updates:
* Docker image: bump alpine from 3.18.2 to 3.18.3
* Docker image: bump golang from 1.20 to 1.21
* Bump github.com/aws/smithy-go from 1.13.5 to 1.14.2
* Bump github.com/aws/aws-sdk-go and aws-sdk-go-v2 to latest versions

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.53.0...v0.54.0

# v0.53.0

**Bugfixes and features**

Services:
* Add Auto Discovery Support For Sagemaker by @charleschangdp
* Add support for AWS/TrustedAdvisor by @cristiangreco

Bugs:
* fix(kafkaconnect): update resource filter by @cgowthaman
* Validate should fail when no roles are configured by @thepalbi
* Fix default value for nilToZero and addCloudwatchTimestamp in static job by @cristiangreco
* ddos protection: Discover resources outside us-east-1

**Dependencies**
* Bump github.com/aws/aws-sdk-go from 1.44.284 to 1.44.290
* Bump github.com/aws/aws-sdk-go-v2/service/amp from 1.16.12 to 1.16.13
* Bump github.com/aws/aws-sdk-go-v2/service/apigatewayv2 from 1.13.12 to 1.13.13
* Bump github.com/aws/aws-sdk-go-v2/service/cloudwatch from 1.26.1 to 1.26.2
* Bump github.com/aws/aws-sdk-go-v2/service/ec2 from 1.100.0 to 1.102.0
* Bump github.com/prometheus/client_golang from 1.15.1 to 1.16.0
* Bump github.com/prometheus/common from 0.43.0 to 0.44.0
* Bump github.com/urfave/cli/v2 from 2.25.6 to 2.25.7

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.52.0...v0.53.0

# v0.52.0

**Important news and breaking changes**

This releases introduces the feature flag `aws-sdk-v2` (by @kgeckhart), which changes YACE networking layer to use the AWS sdk v2 package. Read on for more details and considerations.

  * The main benefit of sdk v2 is deserialization/serialization is done via code generation vs reflection which drastically lowers memory/cpu usage for large scrape jobs
  * Considerations before enabling sdk v2:
    1. FIPS is not supported in v2 as v2 delegates all URL resolution to the sdk and AWS does not have FIPS compliant endpoints for AutoScaling API and Tagging API. The v1 implementation worked around this by hard coding FIPS URLs where they existed and using non-FIPS URLs otherwise. This work around was not ported to v2 and is unlikely to be ported.
    2. sdk v2 uses regional sts endpoints by default vs global sts which is [considered legacy by aws](https://docs.aws.amazon.com/sdkref/latest/guide/feature-sts-regionalized-endpoints.html). The `sts-region` job configuration is still respected when setting the region for sts and will be used if provided. If you still require global sts instead of regional set the `sts-region` to `aws-global`.

**Bugfixes and features**

Features:
* Discovery jobs support `recentlyActiveOnly` parameter to reduce number of old metrics returned by CloudWatch API by @PerGon
* Feature flag `aws-sdk-v2`: use the more performant AWS sdk v2 (see above section) by @kgeckhart

Services:
* Add support for API Gateway V2 by @matej-g
* Add support for MediaConvert by @theunissenne
* Add support for CWAgent by @cristiangreco
* Add support for memorydb by @glebpom

Docs:
* ALB example: use Average for ConsumedLCUs by @cristiangreco
* Update configuration.md: deprecated custom namespace jobs by @wimsymons
* Update permissions examples and docs in readme by @kgeckhart
* Add example for ElastiCache by @cristiangreco
* Update mixin readme by @cristiangreco

Bugs:
* Fix AmazonMQ Broker name dimension match by @cristiangreco
* Fix invalid GH action file and broken test case by @cristiangreco
* Fix namespace case in metrics conversion by @cristiangreco
* Make exporter options a non-global type by @kgeckhart
* Fix debug logging in discovery jobs by @cristiangreco

Refactoring:
* Refactor AWS sdk client usage to hide behind new ClientCache by @kgeckhart
* Introduce model types to replace sdk types in cloudwatch client by @kgeckhart

**Dependencies**

New dependencies:
* github.com/aws/aws-sdk-go-v2/config 1.18.27
* github.com/aws/aws-sdk-go-v2/service/amp 1.16.11
* github.com/aws/aws-sdk-go-v2/service/apigateway 1.13.13
* github.com/aws/aws-sdk-go-v2/service/autoscaling 1.28.9
* github.com/aws/aws-sdk-go-v2/service/cloudwatch 1.26.1
* github.com/aws/aws-sdk-go-v2/service/databasemigrationservice 1.25.7
* github.com/aws/aws-sdk-go-v2/service/ec2 1.100.0
* github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi 1.14.14
* github.com/aws/aws-sdk-go-v2/service/storagegateway 1.18.14

Updates:
* Bump alpine from 3.17.3 to 3.18.2
* Bump github.com/aws/aws-sdk-go from 1.44.249 to 1.44.284
* Bump github.com/prometheus/common from 0.42.0 to 0.43.0
* Bump github.com/sirupsen/logrus from 1.9.0 to 1.9.3
* Bump github.com/stretchr/testify from 1.8.2 to 1.8.4
* Bump github.com/urfave/cli/v2 from 2.25.1 to 2.25.6
* Bump golang.org/x/sync from 0.1.0 to 0.3.0
* Bump golangci/golangci-lint-action from 3.4.0 to 3.6.0

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.51.0...v0.52.0

# v0.51.0

**Important breaking changes**
* Jobs of type `customNamespace` are **deprecated** and might be removed in a future release (please reach out if you're still using this feature)

**Bugfixes and features**

Features:
* Add feature flags support by @thepalbi
* Feature flag `max-dimensions-associator`: new resource-matching algorithm for discovery jobs. It fixes metrics attribution for ECS. Please test it out and report any issue!
* Feature flag `list-metrics-callback`: reduce memory usage of ListMetrics API requests

Services:
* Add support for AWS/Usage namespace by @cristiangreco
* Fix ECS regexes by @cristiangreco

Docs:
* Add docker compose support for easier development by @thepalbi
* Add more config examples by @cristiangreco
* Review docs about embedding yace by @cristiangreco

Bugs:
* Fix for Dockerfile smell DL3007 by @grosa1

Refactoring:
* Refactor Tagging/CloudWatch clients by @cristiangreco
* CloudWatch client: split out input builders into separate file by @cristiangreco
* Refactor promutils migrate functions by @cristiangreco
* Use grafana/regexp by @cristiangreco
* Refactor implementation of getFilteredMetricDatas by @cristiangreco
* Remove uneeded Describe implementation by @kgeckhart
* Add counter to see if duplicate metrics are still a problem by @kgeckhart
* Refactor label consistency and duplicates by @kgeckhart
* Refactor GetMetricData calls in discovery jobs by @cristiangreco

**Dependencies**
* Bump github.com/aws/aws-sdk-go from 1.44.235 to 1.44.249
* Bump github.com/prometheus/common from 0.41.0 to 0.42.0

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.50.0...v0.51.0

# v0.50.0

**Important breaking changes**
* Change `UpdateMetrics` signature to accept options and return error by @cristiangreco -- if you embed YACE as a Go library this is a breaking change.

**Bugfixes and features**
Features:
* Refactor API clients concurrency handling by @cristiangreco
* Add feature flags support by @thepalbi
* Allow discovery jobs to return result even if there are no resources by @kgeckhart
* Add flag to enable pprof profiling endpoints by @cristiangreco

Services:
* Add a ResourceFilter to ElasticBeanstalk by @benbridts

Docs:
* Update config docs format by @cristiangreco

Refactoring:
* Linting: fix revive issues by @cristiangreco
* Remove extra error log when no resources are found by @kgeckhart
* Wrap debug logging in FilterMetricData by @cristiangreco
* Minor internal refactorings by @cristiangreco

**Dependencies**
* Bump actions/setup-go from 3 to 4
* Bump github.com/aws/aws-sdk-go from 1.44.215 to 1.44.235
* Bump github.com/urfave/cli/v2 from 2.25.0 to 2.25.1

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.49.2...v0.50.0

# v0.49.2

## Bugfixes and features
* Update release action to use goreleaser docker image v1.16.0

# v0.49.1

## Bugfixes and features
* Update release action to use Go 1.20

# v0.49.0

## Important breaking changes
* From now on we're dropping the `-alpha` suffix from the version number. YACE will be considered alpha quality until v1.0.0.
* The helm chart is now hosted at https://github.com/nerdswords/helm-charts, please refer to the instructions in the new repo.

## Bugfixes and features
Helm chart:
* Move helm chart out of this repo by @cristiangreco
* Update helm repo link in README.md by @cristiangreco

New services:
* Add support for Container, queue, and database metrics for MWAA by @millin
* Add support for acm-pca service by @jutley

Docs updates:
* Docs review: move "install" and "configuration" in separate docs by @cristiangreco
* Docs: Fix example config link by @matej-g
* Add example config files by @cristiangreco

Internal refactoring:
* Code refactoring: split out job and api code by @cristiangreco
* Minor refactoring of pkg/apicloudwatch and pkg/apitagging by @cristiangreco
* Refactor CW metrics to resource association logic and add tests by @thepalbi
* Wrap service filter errors by @kgeckhart

## Dependencies
* Bump github.com/aws/aws-sdk-go from 1.44.194 to 1.44.215
* Bump github.com/prometheus/common from 0.37.0 to 0.41.0
* Bump github.com/stretchr/testify from 1.8.1 to 1.8.2
* Bump github.com/urfave/cli/v2 from 2.24.3 to 2.25.0
* Bump golang.org/x/sync from 0.0.0-20220722155255-886fb9371eb4 to 0.1.0

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.48.0-alpha...v0.49.0

# v0.48.0-alpha

**Bugfixes and features**:
* Revert "Publish helm chart before releasing binaries".

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.47.0-alpha...v0.48.0-alpha

# v0.47.0-alpha

**Bugfixes and features**:
* Add Elemental MediaLive, MediaConnect to supported services by @davemt
* Add support for OpenSearch Serverless by @Hussainoxious
* Makefile: always add build version ldflags by @cristiangreco
* Publish helm chart before releasing binaries by @cristiangreco
* Build with Go 1.20 by @cristiangreco

**Dependencies**:
* Bump github.com/aws/aws-sdk-go from 1.44.192 to 1.44.194
* Bump github.com/urfave/cli/v2 from 2.24.2 to 2.24.3

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.46.0-alpha...v0.47.0-alpha

## 0.46.0-alpha / 2023-02-02

**Breaking changes**:
- If you use Yace as a library: this release changes the package
  name `pkg/logger` to `pkg/logging`.

**Bugfixes and features**:
* Fix to set logging level correctly by @cristiangreco
* ct: disable validate-maintainers by @cristiangreco

**Dependencies**:
* Bump github.com/aws/aws-sdk-go from 1.44.189 to 1.44.192

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/helm-chart-0.11.0...v0.46.0-alpha

## 0.45.0-alpha / 2023-01-30

**Breaking changes**:
- Note if you use Yace as a library: this release changes the signature
  of `config.Load` method.

**Bugfixes and features**:
* Helm chart update to customize port name by @nikosmeds
* Clear up docs and re-organize sections by @thepalbi
* Helm: add README file template by @cristiangreco
* Config parsing: emit warning messages for invalid configs by @cristiangreco
* Pre-compile dimensions regexps for supported services by @cristiangreco
* AWS/DX: add more dimension regexps by @cristiangreco

**Dependencies**:
* Bump github.com/aws/aws-sdk-go from 1.44.182 to 1.44.189
* Bump github.com/urfave/cli/v2 from 2.23.7 to 2.24.2
* Bump golangci/golangci-lint-action from 3.3.1 to 3.4.0

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.44.0-alpha...v0.45.0-alpha

## 0.44.0-alpha / 2023-01-23

**Breaking changes**:
- Note if you use Yace as a library: this release changes the packages
  and funcs exported publicly, you will need to review the imports
  (although signatures are mostly unchanged)

**Bugfixes and features**:
* Refactor code into separate packages by @cristiangreco
* Refactor list of supported services and filter funcs by @cristiangreco
* Wrap debug logging to avoid expensive operations by @cristiangreco
* Fix to use length of metrics level on customNamespace by @masshash
* feat: bump helm chart by @rasta-rocket
* feat: release helm chart when Chart.yml is updated by @rasta-rocket
* Add test for configuration of services list by @cristiangreco
* GolangCI: review linters settings by @cristiangreco

**Dependencies**:
* Bump azure/setup-helm from 1 to 3
* Bump docker/setup-buildx-action from 1 to 2
* Bump docker/setup-qemu-action from 1 to 2
* Bump github.com/aws/aws-sdk-go from 1.44.175 to 1.44.182
* Bump github.com/prometheus/client_golang from 1.13.0 to 1.14.0
* Bump helm/chart-releaser-action from 1.4.1 to 1.5.0
* Bump helm/kind-action from 1.2.0 to 1.5.0

**Full Changelog**: https://github.com/prometheus-community/yet-another-cloudwatch-exporter/compare/v0.43.0-alpha...v0.44.0-alpha

## 0.43.0-alpha / 2023-01-02

* add support to custom namespaces with their dimensions (by @arielly-parussulo)
* Optimise support for custom namespaces to use GetMetricData API (by @code-haven)
* GH workflows: run "publish" workflows only in this repo. (by @cristiangreco)
* Bump Go version to 1.19 for CI and docker image. (by @cristiangreco)
* Fix not to refer to loop variable in a goroutine (by @masshash)
* Validate tags when converting to prometheus labels (by @cristiangreco)
* Bump github.com/aws/aws-sdk-go from 1.44.127 to 1.44.167
* Bump golangci/golangci-lint-action from 3.3.0 to 3.3.1
* Bump github.com/urfave/cli/v2 from 2.23.0 to 2.23.7

## 0.42.0-alpha / 2022-11-03

* Resolve logging issue (@datsabk)
* MediaTailor - Correct dimension regex for MT (@scott-mccracken)
* Helm chart update for optional test-connection pod (@nikosmeds)
* Helm chart update to set priorityClassName (@nikosmeds)
* Bump github.com/aws/aws-sdk-go from 1.44.122 to 1.44.127
* Bump github.com/urfave/cli/v2 from 2.20.3 to 2.23.0

## 0.41.0-alpha / 2022-10-27

* Clean up unused variables. (@cristiangreco)
* Fix typo: sts-endpoint should be sts-region. (@cristiangreco)
* Enabled Managed prometheus metrics (@datsabk)
* Add support for AWS Kafka Connect (@cgowthaman)
* Import CloudWatch mixin. (@jeschkies)
* main.go refactoring: define cmd action as a separate func. (@cristiangreco)
* Add support for EMR Serverless (@cgowthaman)

## 0.40.0-alpha / 2022-09-15
* Fix typo in Charts.yml (@yasharne)
* Subcommand `verify-config` actually validates the config file. (@cristiangreco)
* Add dimensions regex for AmazonMQ. (@cristiangreco)
* Fix metrics with additional dimensions being not being scraped. (@cristiangreco)
* Remove unused code, add test for RemoveDuplicateMetrics. (@cristiangreco)
* Bump github.com/sirupsen/logrus
* Bump github.com/urfave/cli/v2
* Bump github.com/aws/aws-sdk-go
* Bump actions/setup-python

## 0.39.0-alpha / 2022-09-08
* Improve code quality and unblock this release (cristiangreco)
* Add helm chart (vkobets)
* Fix DX metrics (paulojmdias)
* Fix searchTags and bad dimension name (femiagbabiaka)
* Handle empty list in filter metric tests (mtt88)
* Add AWS Elemental MediaTailor support (scott-mccracken)
* Support storagegateway metrics (sedan07)
* Filter api gateway resources to skip "stages" (ch4rms)
* Bump aws-sdk, urfave/cli, prometheus/client_golang

## 0.38.0-alpha / 2022-07-13

* Set max page size for tagging API requests (#617)
* Build with Go 1.18

## 0.37.0-alpha / 2022-07-05
* New config `dimensionNameRequirements` allows autodiscovery jobs to only
  fetch metrics that include specified dimensions (jutley)
* Update deps

## 0.36.2-alpha / 2022-06-29
* Cost Reduction - Use less API requests if no tagged resources are found (cristiangreco)
* Update deps

## 0.36.1-alpha / 2022-06-22
* Use structured logs for logging interface (kgeckhart)

## 0.36.0-alpha / 2022-06-20

* *BREAKING CHANGE FOR LIBRARY USERS* Major refactoring of usage of logging library (kgeckhart)
* Minor update of deps and security patches (urfave/cli/v2, golangci/golangci-lint-action, github.com/prometheus/client_golang, github.com/stretchr/testify, github.com/aws/aws-sdk-go
* Updates of Readme (markwallsgrove)

## 0.35.0-alpha / 2022-04-26
* Update dependencies
* Improve / Document way how to use the exporter as external library (kgeckhart)
* Refactor label consistency (kgeckhart)
* Add suppot for vpc-endpoint (AWS/PrivateLinkEndpoints) (aleslash)
* Add support for vpc-endpoint-service (AWS/PrivateLinkServices) (aleslash)

## 0.34.0-alpha / 2022-03-26
* Update dependencies
* Add weekly dependabot updates (jylitalo)
* Add support for regional sts endpoints (matt-mercer)
* Add multi-arch docker build (charlie-haley)

New services
* Add global accelerator support (charlie-haley)
* Add AppStream support (jhuesemann)
* Add Managed Apache Airflow support (sdenham)
* Add KinesisAnalytics support (gumpt)

Bug Fixes
* Fix targetgroup arn lookup (domcyrus)
* Fix WorkGroup Dimension are not showing in Athena Metrics (sahajavidya)
* Improve regex performance (kgeckhart)
* Fix prometheus reload causing a goroutine leak (gumpt / cristiangreco)

Docs
* Added help for new contributors (aleslash)

## 0.33.0-alpha / 2021-12-10
* Add /healthz route which allows to deploy more secure with helm (aleslash)
* Read DMS replication instance identifier from the DMS API (nhinds)

## 0.32.0-alpha / 2021-11-19
* [BREAKING] Fix the calculation of start and end times for GetMetricData (csquire)
```
floating-time-window is now replaced with roundingPeriod

Specifies how the current time is rounded before calculating start/end times for CloudWatch GetMetricData requests. This rounding is optimize performance of the CloudWatch request. This setting only makes sense to use if, for example, you specify a very long period (such as 1 day) but want your times rounded to a shorter time (such as 5 minutes). to For example, a value of 300 will round the current time to the nearest 5 minutes. If not specified, the roundingPeriod defaults to the same value as shortest period in the job.
```
* Improve testing / linting (cristiangreco)
* Verify cli parameters and improve cli parsing (a0s)
* Allow to configure yace cli parameters via env variables (a0s)
* Improve error handling of cloudwatch (matthewnolf)
* Add support for directconnect and route53 health checks
* Improve throttling handling to AWS APIs (anilkun)
* Add issue templates to improve support (NickLarsenNZ)
* Allow setting default values for statistics (surminus)
* Fix apigateway method and resouce dimension bug (aleslash)

Thanks a lot to all contributors! - Lovely to see so much efforts especially in testing
to get this project more and more stable. - I know we are far away from a nice tested
code base but we are improving in the right direction and I really love to see all
of your efforts there. It is really appreciated from my side.

I just contacted AWS to get some open source credits so we can build some kind of
end to end tests. This shoud allow us to find tricky bugs earlier and not only when we ship
things.

Love to all of you, Thomas!

## 0.31.0-alpha / 2021-09-23
* [BREAKING] Decoupled scraping is now default. Removed code which allowed to use scraper without it.
```
# Those flags are just ignored
-decoupled-scraping=false
-decoupled-scraping=true
```
* [BREAKING] Small timeframes of scraping can be used again now. In the past yace decided the scraping
  interval based on config. This magic was removed for simplicity.
```
# In the past this would have in some cases still set --scraping-interval 600
--scraping-interval 10
# Now it really would scrape every 10 seconds which could introduce big API costs. So please watch
# your API requests!
--scraping-interval 10
```
* Fix problems with start/endtime of scrapes (klarrio-dlamb)
* Add support for Database Migration Service metrics
* Allow to hotreload config via /reload (antoniomerlin)

## 0.30.1-alpha / 2021-09-13
* *SECURITY* Fix issue with building binaries. Please update to mitigate (https://nvd.nist.gov/vuln/detail/CVE-2020-14039)
* Thanks jeason81 for reporting this security incident!

## 0.30.0-alpha / 2021-09-07
* *BREAKING* Introduce new version field to config file (jylitalo)
```
# Before
discovery:
  jobs:
# After
apiVersion: v1alpha1
discovery:
  jobs:
```
* [BUG] Fix issues with nilToZero (eminugurkenar)
* [BUG] Fix race condition setting end time for discovery jobs (cristiangreco)
* Simplify session creation code (jylitalo)
* Major improvement of aws discovery code (jylitalo)
* Major rewrite of the async scraping logic (rabunkosar-dd)
* Add support for AWS/ElasticBeanstalk (andyzasl)
* Upgrade golang to 1.17
* Upgrade golang libraries to newest versions

## 0.29.0-alpha / 2021-09-01
Okay, private things settled. We have a new organisation for
the project. Lets boost it and get the open PRs merged!
This version is like 0.28.0-alpha but docker images hosted on ghcr.io
and published via new github organisation nerdswords. Find
details [here](https://medium.com/@IT_Supertramp/reorganizing-yace-79d7149b9584).

Thanks to all there waiting and using the product! :)

- *BREAKING CHANGE* Using a new docker registry / organisation:
```yaml
# Before
quay.io/invisionag/yet-another-cloudwatch-exporter:v0.29.0-alpha
# Now
ghcr.io/nerdswords/yet-another-cloudwatch-exporter:v0.29.0-alpha
```

## 0.28.0-alpha / 2021-07-09
Sorry folks, I currently struggle a little bit
to get things merged fast due to a lot of private
stuff. Really appreciate all your PRs and
hope to get the bigger ones (which are sadly
still not merged yet) into next release.

Really appreciate any person working on this
project! - Have a nice day :)

- *BREAKING CHANGE* Added support for specifying an External ID with IAM role Arns (cristiangreco)
```yaml
# Before
discovery:
  jobs:
  - type: rds
    roleArns:
    - "arn:aws:iam::123456789012:role/Prometheus"
# After
discovery:
  jobs:
  - type: rds
    roles:
    - roleArn: "arn:aws:iam::123456789012:role/Prometheus"
      externalId: "shared-external-identifier" # optional
```
- Add alias for AWS/Cognito service (tohjustin)
- Fix logic in dimensions for Transit Gateway Attachments (rhys-evans)
- Fix bug with scraping intervals (boazreicher)
- Support arm64 builds (alias-dev)
- Fix IgnoreLength logic (dctrwatson)
- Simplify code base (jylitalo)
- Simplify k8s deployments for new users (mahmoud-abdelhafez)
- Handle metrics with '%' in their name (darora)
- Fix classic elb name (nhinds)
- Skip metrics in edge cases (arvidsnet)

Freshly shipped new integrations:
- Certificate Manager (mksh)
- WorkSpaces (kl4w)
- DDoSProtection / Shield (arvidsnet)

## 0.27.0-alpha / 2021-05-07

- Make exporter a library. (jeschkies)
- Add CLI option to validate config file (zswanson)
- Fix multidimensional static metric (nmiculinic)
- Fix scrapes running in EKS fail after first scrape (rrusso1982)
- Fix Docker build (jeschkies)
- Allow to use this project in China (insectme)
- Fix error retrieving kafka metrics (friedrichg)

Freshly integrated:
- Add AWS/NetworkFirewall (rhys-evans)
- Add AWS/Cassandra (bjhaid)
- Add AWS/AmazonMQ (saez0pub)
- Add AWS/Athena (haarchri)
- Add AWS/Neptune (benjaminaaron)

Thanks to doc fixes: calvinbui

## 0.26.3-alpha / 2021-03-15
## 0.26.2-alpha / 2021-03-15

- Fix CI issue

## 0.26.0-alpha / 2021-03-15

- *BREAKING CHANGE* Removed a need to use static dimensions in dynamic jobs in cases, when they cannot be parsed from ARNs (AndrewChubatiuk)
    ```
      # Before
      metrics:
      - name: NumberOfObjects
        statistics:
          - Average
        additionalDimensions:
          - name: StorageType
            value: AllStorageTypes
      # After
      metrics:
      - name: NumberOfObjects
        statistics:
          - Average
    ```
* *BREAKING CHANGE* Use small case for searchTags config option (AndrewChubatiuk)
    ```
    # Before
    searchTags:
    - Key: type
      Value: public
    # After
    searchTags:
    - key: type
      value: public
      ```
* *BREAKING CHANGE* CloudFront renamed from `cf` to `cloudfront`
    ```
    # Before
    - type: cf
    # After
    - type: cloudfront
      ```

- Added regular expressions to parse dimensions from resources (AndrewChubatiuk)
- Added option to use floating time windows (zqad)
- Added CLI option to validate config file (zswanson)
- Added AWS network Firewall (rhys-evans)
- Fixed multidimensional static metric (nmiculinic)
- Tidy up code (jylitalo)

## 0.25.0-alpha / 2021-01-05

- *BREAKING CHANGE* Use NaN as default if AWS returns nil (arnitolog)
- Add autodiscovery for AWS/EC2Spot (singhjagmohan1000)
- Add autodiscovery for DocumentDB (haarchri)
- Add autodiscovery for GameLift (jp)
- Added support for fips compliant endpoints (smcavallo)
- Update deps and build with golang 1.15 (smcavallo)

## 0.24.0-alpha / 2020-12-07

- Add API Gateway IAM info to README (Botono)
- Fix sorting of datapoints, add test util functions (Botono)
- Fix missing DataPoints and improve yace in various ways (vishalraina)
- Added Github action file to basic validation of incoming PR (vishalraina)
- Fix info metrics missing (goya)
- Add rds db clusters (goya)
- Fix missing labels (goya)

## 0.23.0-alpha / 2020-10-02

- Add sampleCount statistics (udhos)
- Add WAFv2 support (mksh)

## 0.22.0-alpha / 2020-10-02

- Fix alb issues (reddoggad)
- Add nlb support (reddoggad)

## 0.21.0-alpha / 2020-09-21

- Big tidy up of code, remove old methods and refactor used ones (jylitalo)
- Fix crashes where labels are not collected correctly (rrusso1982)
- Fix pointer bug causing metrics to be missing (jylitalo)
- Allow more then 25 apigateways to be discovered (udhos)

## 0.20.0-alpha / 2020-07-31

- Add api-gateway support (smcavallo)
- Improve metrics validation (jylitalo)
- Fix metrics with '<', '>' chars

## 0.19.1-alpha / 2020-07-17

- Remove error during build

## 0.19.0-alpha / 2020-07-17
Wow what a release. Thanks to all contributors. This is
our biggest release and it made me a lot of fun to see all those
contributions. From small doc changes (love those) to major rewrites
of big components or new complex features. Thanks!

* *BREAKING CHANGE* Add support for multiple roleArns (jylitalo)
```yaml
# Before
---
discovery:
  jobs:
  - type: rds
    roleArn: "arn:aws:iam::123456789012:role/Prometheus"
# After
discovery:
  jobs:
  - type: rds
    roleArns:
    - "arn:aws:iam::123456789012:role/Prometheus"
```
* Upgrade golang from 1.12 to 1.14
* Major linting of code and improving global code quality. (jylitalo)
* Improve logging (jylitalo)
* Add config validation. (daviddetorres)
* Added support for tags with '@' char included (afroschauer )
* Added Transit Gateway Attachment Metrics (rhys-evans)
* Fix information gathering if no data is retrieved by cloudwatch (daviddetorres)
* Improve docs (calvinbui)
* Add redshift support (smcavallo)
* Allow easier configuration through adding period / addCloudwatchTimestamp setting additionally
  to job level. (rrusso1982)
* Add initial unit tests (smcavallo)
* Add new configuration to allow snake case labels (rrusso1982)
* Fix complex metric dimension bug (rrusso1982)
* Upgrade golang packages (smcavallo)
* Set up correct partition for ASG for AWS China and GovCloud Regions (smcavallo)
* Add ability to set custom tags to discovery job metrics (goya)

## 0.18.0-alpha / 2020-06-15
* *BREAKING CHANGE* Add support for multiple regions (goya)
```yaml
# Before
---
discovery:
  jobs:
  - type: rds
    region: eu-west-1
# After
discovery:
  jobs:
  - type: rds
    regions:
    - eu-west-1
```
* Fix missing alb target group metrics (abhi4890 )
* Added support for step functions (smcavallo)

## 0.17.0-alpha / 2020-05-14
* Added support for sns / firehose (rhys-evans)
* Added support for fsx / appsync (arnitolog)

## 0.16.0-alpha / 2020-04-06
* Hugh rewrite: Decouple scraping and serving metrics. Thanks so much daviddetorres!
* *BREAKING CHANGE* Decoupled scraping and set scraping interval to 5 minutes.
```
The flag 'decoupled-scraping' makes the exporter to scrape Cloudwatch metrics in background in fixed intervals, in stead of each time that the '/metrics' endpoint is fetched. This protects from the abuse of API requests that can cause extra billing in AWS account. This flag is activated by default.

If the flag 'decoupled-scraping' is activated, the flag 'scraping-interval' defines the seconds between scrapes. Its default value is 300.
```
* Hugh rewrite: Rewrite of metric gathering to reduce API Limit problems. Thanks so much daviddetorres!
* Improvment of ALB data gathering and filtering (daviddetorres)
* Detect and fix bug after merge (deanrock)
* Add cloudfront support (mentos1386)

## 0.15.0-alpha / 2020-02-21
* Fixed docker run command in README.md (daviddetorres)
* Added support for Nat Gateway / Transit Gateway / Route 53 Resolver (j-nix)
* Added support for ECS/ContainerInsights (daviddetorres)
* Fix pagination for getMetricList (eminugurkenar)

## 0.14.7-alpha / 2020-01-09
* Change logging to json format (bheight-Zymergen)

## 0.14.6-alpha / 2020-01-03
* Add support for kafka (eminugurkenar)
* Add structured json logging (bheight-Zymergen)
* Increase code readability (bheight-Zymergen)
* Fix ecs scraping bug (rabunkosar-dd)
* Fix aws cloudwatch period bug (rabunkosar-dd)

## 0.14.5-alpha / 2019-10-29
* Fix sts api calls without specifying a region (nhinds)
* Update aws-sdk to v1.25.21 (nhinds)

## 0.14.4-alpha / 2019-10-25
* Fix github actions (nhinds)
* Update aws-sdk-go (deanrock)
* Avoid appending to a shared dimensions variable from inside a loop (nhinds)
* Remove hardcoded StorageType dimension from S3 metric (nhinds)

## 0.14.3-alpha / 2019-10-11
* Fix problems and crashes with ALBs and ELBs (Deepak1100)

## 0.14.2-alpha / 2019-10-04
* **BREAKING** Changing user in Docker image to be non root to adhere to potential security requirements. (whitlekx)
* Fix prometheus metric bug with new services with '-' e.g. ecs-svc.

## 0.14.1-alpha / 2019-09-06
* Was accidentally with code from 01.14.0-alpha released.

## 0.14.0-alpha / 2019-08-24
* **BREAKING** Default command in Dockerfile is changed to yace. This removes the need to add yace as command.
```yaml
# Before
        command:
          - "yace"
          - "--config.file=/tmp/config.yml"
# After
        args:
          - "--config.file=/tmp/config.yml"
```
* Add support for Elastic MapReduce (nhinds)
* Add support for SQS - (alext)
* Add support for ECS Services as ecs-svc
* Add support for NLB
* Add retries to cloudwatch api calls (Deepak1100)
* Fix dimension labels for static jobs (alext)

## 0.13.7 / 2019-07-09
* Add region as exported label to metrics

## 0.13.6 / 2019-06-24
* Fix errors with "=" in tags (cdchris12)
* Add curl to container for easy debugging (cdchris12)

## 0.13.5-alpha / 2019-06-09
* Limit concurrency of aws calls

## 0.13.4 / 2019-06-03
* Add Autoscaling group support (wjam)
* Fix strange AWS namespace bug for static exports (AWS/EC2/API)
* Add warning if metric length of less than 300s is configured / Interminent metrics

## 0.13.3 / 2019-04-26
* Fix ALB problems. Target Group metrics are now exported as aws_albtg
```
aws_albtg_request_count_sum{dimension_LoadBalancer="app/Test-ALB/fec38de4cf0cacb1",dimension_TargetGroup="targetgroup/Test/708ecba11979327b",name="arn:aws:elasticloadbalancing:eu-west-1:237935892384916:targetgroup/Test/708dcba119793234"} 0
```

## 0.13.2 / 2019-04-26
* CI problem

## 0.13.1-alpha / 2019-04-03
* **BREAKING** For some metrics `cloudwatch:ListMetrics` iam permissions are needed. Please update your role!
* **BREAKING** Add 'v' to indicate it is a version number in docker tag / version output
```
# Before
 image: quay.io/invisionag/yet-another-cloudwatch-exporter:0.13.0
# After
 image: quay.io/invisionag/yet-another-cloudwatch-exporter:v0.13.0
```
* Use golang 1.12.0 to build
* Use goreleaser to release
* Update aws dependencies
* Use github actions as CI
* Migrate dependency management to golang modules

## 0.13.0-alpha / 2019-03-18
* **BREAKING** For some metrics `cloudwatch:ListMetrics` iam permissions are needed. Please update your role!
* **BREAKING** As adding cloudwatch timestamp breaks some metrics I decided to not set it as default anymore.
This should make it easier for new users to have fun with this project.
It fixes for some users `non-histogram and non-summary metrics should not have "_sum" suffix` bug.
```yaml
# Before
  metrics:
    - name: FreeStorageSpace
      disableTimestamp: true
# After
  metrics:
    - name: FreeStorageSpace

# Before
  metrics:
    - name: FreeStorageSpace
# After
  metrics:
    - name: FreeStorageSpace
      useCloudwatchTimestamp: true
```
* Add ability to specify additional dimensions on discovery jobs e.g. for BucketSizeBytes metrics on S3 (abuchananTW)
* Fix incorrect dimension value in case of alb in discovery config (GeeksWine)
* Add CLI command to debug output
* Add DynamoDB support

## 0.12.0 / 2019-02-04
* **BREAKING** Add the exact timestamps from CloudWatch to the exporter Prometheus metrics (LeePorte)
* Add a new option `disableTimestamp` to not include a timestamp for a specific metric (it can be useful for sparse metrics, e.g. from S3) (LeePorte)
* Add support for kinesis (AndrewChubatiuk)

## 0.11.0 / 2018-12-28
* **BREAKING** Add snake_case to prometheus metrics (sanchezpaco)
```yaml
# Before
aws_elb_requestcount_sum
# After
aws_elb_request_count_sum
```

* Add optional delay setting to scraping (Deepak1100)
```yaml
period: 60
length: 900
delay: 300
```

## 0.10.0 / 2018-12-03
* Reduce usage of listMetrics calls (nhinds)
* Add support of iam roles (nhinds)
* Add optional roleArn setting, which allows scraping with different roles e.g. pull data from mulitple AWS accounts using cross-acount roles (nhinds)
```yaml
    metrics:
      - name: FreeStorageSpace
        roleArn: xxx
        statistics:
        - 'Sum'
        period: 600
        length: 60
```

## 0.9.0 / 2018-11-16
* Add lambda support (nhinds)
* Fix support for listing multiple statistics per metric (nhinds)
* Add tag labels on metrics for easy querying (nhinds)
```
# Before
aws_ec2_cpuutilization_average + on (name) group_left(tag_Name) aws_ec2_info

# After, now name tags are on metrics and no grouping needed
aws_ec2_cpuutilization_average
```

* **BREAKING** Change config syntax. Now you can define tags which are exported as labels on metrics.
Before:

```yaml
discovery:
  - region: eu-west-1
    type: "es"
    searchTags:
      - Key: type
        Value: ^(easteregg|k8s)$
    metrics:
      - name: FreeStorageSpace
        statistics:
        - 'Sum'
        period: 600
        length: 60
```

New Syntax with optional exportedTagsOnMetrics:
```yaml
discovery:
  exportedTagsOnMetrics:
    ec2:
      - Name
  jobs:
    - region: eu-west-1
      type: "es"
      searchTags:
        - Key: type
          Value: ^(easteregg|k8s)$
      metrics:
        - name: FreeStorageSpace
          statistics:
          - 'Sum'
          period: 600
          length: 60
```

## 0.8.0 / 2018-11-02
* Added VPN connection metrics (AndrewChubatiuk)
* Added ExtendedStatistics / percentiles (linefeedse)
* Added Average Statistic (AndrewChubatiuk)

## 0.7.0-alpha / 2018-10-19
* ALB Support (linefeedse)
* Custom lables for static metrics

Example
```yaml
static:
  - namespace: AWS/AutoScaling
    region: eu-west-1
    dimensions:
     - name: AutoScalingGroupName
       value: Test
    customTags:
      - Key: CustomTag
        Value: CustomValue
    metrics:
      - name: GroupInServiceInstances
        statistics:
        - 'Minimum'
        period: 60
        length: 300
```

## 0.6.1 / 2018-10-09
* Sanitize colons in tags (linefeedse)

## 0.6.0 / 2018-09-20
* **BREAKING**: Period/length uses now seconds instead of minutes
* **BREAKING**: Config file uses new syntax to support static
* Support of --debug flag which outputs some dev debug informations
* Support of metrics who are not included in tags api (e.g. autoscaling metrics)

Before
```yaml
jobs:
  - discovery:
      region: eu-west-1
      metrics:
        - name: HealthyHostCount
          statistics:
          - 'Minimum'
          period: 60
          length: 300
```

New Syntax:
```yaml
discovery:
  - region: eu-west-1
    type: elb
    searchTags:
      - Key: KubernetesCluster
        Value: production
    metrics:
      - name: HealthyHostCount
        statistics:
        - 'Minimum'
        period: 60
        length: 300
static:
  - namespace: AWS/AutoScaling
    region: eu-west-1
    dimensions:
     - name: AutoScalingGroupName
       value: Test
    metrics:
      - name: GroupInServiceInstances
        statistics:
        - 'Minimum'
        period: 60
        length: 300
```

## 0.5.0 / 2018-08-07
* Support of EFS - Elastic File System
* Support of EBS - Elastic Block Storage

## 0.4.0 / 2018-08-07
* **BREAKING**: Config file uses list as statistics config option,
this should reduce api calls for more than one statistics.

Before:
```yaml
jobs:
  - discovery:
    metrics:
        statistics: 'Maximum'
```
After:
```yaml
jobs:
  - discovery:
    metrics:
        statistics:
        - 'Maximum'
```
* Start to track changes in CHANGELOG.md
* Better error handling (discordianfish)
* Increase speed, not only each jobs threaded but now each metric
* Add s3 support
* Fix potential race condition during cloudwatch access
* Fix bug ignoring period in cloudwatch config
* Use interfaces for aws access and prepare code for unit tests
* Implement minimum, average, maximum, sum for cloudwatch api
* Implement way to handle multiple data returned by cloudwatch
* Update go dependencies


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Prometheus Community Code of Conduct

Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).


================================================
FILE: CONTRIBUTE.md
================================================
# CONTRIBUTE

## Steps to Contribute

* We use [golangci-lint](https://github.com/golangci/golangci-lint) for linting the code. Make it sure to install it first.
* Check out repository running `git clone https://github.com/prometheus-community/yet-another-cloudwatch-exporter.git`
* For linting, please run `make lint`
* For building, please run `make build`
* For running locally, please run `./yace`
* Best practices:
  * commit should be as small as possible
  * branch from the *master* branch
  * add tests relevant to the fixed bug or new feature

## How to release
* `git tag v0.13.1-alpha && git push --tags`


================================================
FILE: Dockerfile
================================================
ARG ARCH="amd64"
ARG OS="linux"
FROM quay.io/prometheus/busybox-${OS}-${ARCH}:latest
LABEL maintainer="The Prometheus Authors <prometheus-developers@googlegroups.com>"

ARG ARCH="amd64"
ARG OS="linux"
COPY .build/${OS}-${ARCH}/yace /bin/yace

COPY examples/ec2.yml /etc/yace/config.yml

EXPOSE     5000
USER       nobody
ENTRYPOINT [ "/bin/yace" ]
CMD        [ "--config.file=/etc/yace/config.yml" ]


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2024 The Prometheus 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.


================================================
FILE: MAINTAINERS.md
================================================
# Maintainers

- Thomas Peitz (info@thomas-peitz.de / @thomaspeitz)
- Cristian Greco (cristian.greco@grafana.com / @cristiangreco)
- Andrii Kushch (andrii.kushch@grafana.com / @andriikushch)
- Tristan Burgess (tristan.burgess@grafana.com / @tristanburgess)


================================================
FILE: Makefile
================================================
# Copyright 2024 The Prometheus 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.

# Needs to be defined before including Makefile.common to auto-generate targets
DOCKER_ARCHS ?= amd64 armv7 arm64
DOCKER_REPO  ?= prometheuscommunity

include Makefile.common

STATICCHECK_IGNORE =

DOCKER_IMAGE_NAME ?= yet-another-cloudwatch-exporter


================================================
FILE: Makefile.common
================================================
# Copyright The Prometheus 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.


# A common Makefile that includes rules to be reused in different prometheus projects.
# !!! Open PRs only against the prometheus/prometheus/Makefile.common repository!

# Example usage :
# Create the main Makefile in the root project directory.
# include Makefile.common
# customTarget:
# 	@echo ">> Running customTarget"
#

# Ensure GOBIN is not set during build so that promu is installed to the correct path
unexport GOBIN

GO           ?= go
GOFMT        ?= $(GO)fmt
FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH)))
GOOPTS       ?=
GOHOSTOS     ?= $(shell $(GO) env GOHOSTOS)
GOHOSTARCH   ?= $(shell $(GO) env GOHOSTARCH)

GO_VERSION        ?= $(shell $(GO) version)
GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION))
PRE_GO_111        ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.')

PROMU        := $(FIRST_GOPATH)/bin/promu
pkgs          = ./...

ifeq (arm, $(GOHOSTARCH))
	GOHOSTARM ?= $(shell GOARM= $(GO) env GOARM)
	GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM)
else
	GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)
endif

GOTEST := $(GO) test
GOTEST_DIR :=
ifneq ($(CIRCLE_JOB),)
ifneq ($(shell command -v gotestsum 2> /dev/null),)
	GOTEST_DIR := test-results
	GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml --
endif
endif

PROMU_VERSION ?= 0.18.1
PROMU_URL     := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz

SKIP_GOLANGCI_LINT :=
GOLANGCI_LINT :=
GOLANGCI_LINT_OPTS ?=
GOLANGCI_LINT_VERSION ?= v2.11.4
GOLANGCI_FMT_OPTS ?=
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
# windows isn't included here because of the path separator being different.
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
	ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386 arm64))
		# If we're in CI and there is an Actions file, that means the linter
		# is being run in Actions, so we don't need to run it here.
		ifneq (,$(SKIP_GOLANGCI_LINT))
			GOLANGCI_LINT :=
		else ifeq (,$(CIRCLE_JOB))
			GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
		else ifeq (,$(wildcard .github/workflows/golangci-lint.yml))
			GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
		endif
	endif
endif

PREFIX                  ?= $(shell pwd)
BIN_DIR                 ?= $(shell pwd)
DOCKER_IMAGE_TAG        ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD))
DOCKERBUILD_CONTEXT     ?= ./
DOCKER_REPO             ?= prom

# Check if deprecated DOCKERFILE_PATH is set
ifdef DOCKERFILE_PATH
$(error DOCKERFILE_PATH is deprecated. Use DOCKERFILE_VARIANTS ?= $(DOCKERFILE_PATH) in the Makefile)
endif

DOCKER_ARCHS ?= amd64 arm64 armv7 ppc64le riscv64 s390x
DOCKERFILE_ARCH_EXCLUSIONS ?=
DOCKER_REGISTRY_ARCH_EXCLUSIONS ?= quay.io:riscv64
DOCKERFILE_VARIANTS     ?= $(wildcard Dockerfile Dockerfile.*)

# Function to extract variant from Dockerfile label.
# Returns the variant name from io.prometheus.image.variant label, or "default" if not found.
define dockerfile_variant
$(strip $(or $(shell sed -n 's/.*io\.prometheus\.image\.variant="\([^"]*\)".*/\1/p' $(1)),default))
endef

# Check for duplicate variant names (including default for Dockerfiles without labels).
DOCKERFILE_VARIANT_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)))
DOCKERFILE_VARIANT_NAMES_SORTED := $(sort $(DOCKERFILE_VARIANT_NAMES))
ifneq ($(words $(DOCKERFILE_VARIANT_NAMES)),$(words $(DOCKERFILE_VARIANT_NAMES_SORTED)))
$(error Duplicate variant names found. Each Dockerfile must have a unique io.prometheus.image.variant label, and only one can be without a label (default))
endif

# Build variant:dockerfile pairs for shell iteration.
DOCKERFILE_VARIANTS_WITH_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)):$(df))

# Shell helper to check whether a dockerfile/arch pair is excluded.
define dockerfile_arch_is_excluded
case " $(DOCKERFILE_ARCH_EXCLUSIONS) " in \
	*" $$dockerfile:$(1) "*) true ;; \
	*) false ;; \
esac
endef

# Shell helper to check whether a registry/arch pair is excluded.
# Extracts registry from DOCKER_REPO (e.g., quay.io/prometheus -> quay.io)
define registry_arch_is_excluded
registry=$$(echo "$(DOCKER_REPO)" | cut -d'/' -f1); \
case " $(DOCKER_REGISTRY_ARCH_EXCLUSIONS) " in \
	*" $$registry:$(1) "*) true ;; \
	*) false ;; \
esac
endef

BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS))
PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS))
TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS))

SANITIZED_DOCKER_IMAGE_TAG := $(subst +,-,$(DOCKER_IMAGE_TAG))

ifeq ($(GOHOSTARCH),amd64)
        ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows))
                # Only supported on amd64
                test-flags := -race
        endif
endif

# This rule is used to forward a target like "build" to "common-build".  This
# allows a new "build" target to be defined in a Makefile which includes this
# one and override "common-build" without override warnings.
%: common-% ;

.PHONY: common-all
common-all: precheck style check_license lint yamllint unused build test

.PHONY: common-style
common-style:
	@echo ">> checking code style"
	@fmtRes=$$($(GOFMT) -d $$(git ls-files '*.go' ':!:vendor/*' || find . -path ./vendor -prune -o -name '*.go' -print)); \
	if [ -n "$${fmtRes}" ]; then \
		echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \
		echo "Please ensure you are using $$($(GO) version) for formatting code."; \
		exit 1; \
	fi

.PHONY: common-check_license
common-check_license:
	@echo ">> checking license header"
	@licRes=$$(for file in $$(git ls-files '*.go' ':!:vendor/*' || find . -path ./vendor -prune -o -type f -iname '*.go' -print) ; do \
               awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \
       done); \
       if [ -n "$${licRes}" ]; then \
               echo "license header checking failed:"; echo "$${licRes}"; \
               exit 1; \
       fi
	@echo ">> checking for copyright years 2026 or later"
	@futureYearRes=$$(git grep -E 'Copyright (202[6-9]|20[3-9][0-9])' -- '*.go' ':!:vendor/*' || true); \
	if [ -n "$${futureYearRes}" ]; then \
		echo "Files with copyright year 2026 or later found (should use 'Copyright The Prometheus Authors'):"; echo "$${futureYearRes}"; \
		exit 1; \
	fi

.PHONY: common-deps
common-deps:
	@echo ">> getting dependencies"
	$(GO) mod download

.PHONY: update-go-deps
update-go-deps:
	@echo ">> updating Go dependencies"
	@for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \
		$(GO) get $$m; \
	done
	$(GO) mod tidy

.PHONY: common-test-short
common-test-short: $(GOTEST_DIR)
	@echo ">> running short tests"
	$(GOTEST) -short $(GOOPTS) $(pkgs)

.PHONY: common-test
common-test: $(GOTEST_DIR)
	@echo ">> running all tests"
	$(GOTEST) $(test-flags) $(GOOPTS) $(pkgs)

$(GOTEST_DIR):
	@mkdir -p $@

.PHONY: common-format
common-format: $(GOLANGCI_LINT)
	@echo ">> formatting code"
	$(GO) fmt $(pkgs)
ifdef GOLANGCI_LINT
	@echo ">> formatting code with golangci-lint"
	$(GOLANGCI_LINT) fmt $(GOLANGCI_FMT_OPTS)
endif

.PHONY: common-vet
common-vet:
	@echo ">> vetting code"
	$(GO) vet $(GOOPTS) $(pkgs)

.PHONY: common-lint
common-lint: $(GOLANGCI_LINT)
ifdef GOLANGCI_LINT
	@echo ">> running golangci-lint"
	$(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs)
endif

.PHONY: common-lint-fix
common-lint-fix: $(GOLANGCI_LINT)
ifdef GOLANGCI_LINT
	@echo ">> running golangci-lint fix"
	$(GOLANGCI_LINT) run --fix $(GOLANGCI_LINT_OPTS) $(pkgs)
endif

.PHONY: common-yamllint
common-yamllint:
	@echo ">> running yamllint on all YAML files in the repository"
ifeq (, $(shell command -v yamllint 2> /dev/null))
	@echo "yamllint not installed so skipping"
else
	yamllint .
endif

# For backward-compatibility.
.PHONY: common-staticcheck
common-staticcheck: lint

.PHONY: common-unused
common-unused:
	@echo ">> running check for unused/missing packages in go.mod"
	$(GO) mod tidy
	@git diff --exit-code -- go.sum go.mod

.PHONY: common-build
common-build: promu
	@echo ">> building binaries"
	$(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES)

.PHONY: common-tarball
common-tarball: promu
	@echo ">> building release tarball"
	$(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR)

.PHONY: common-docker-repo-name
common-docker-repo-name:
	@echo "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)"

.PHONY: common-docker $(BUILD_DOCKER_ARCHS)
common-docker: $(BUILD_DOCKER_ARCHS)
$(BUILD_DOCKER_ARCHS): common-docker-%:
	@for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
		dockerfile=$${variant#*:}; \
		variant_name=$${variant%%:*}; \
		if $(call dockerfile_arch_is_excluded,$*); then \
			echo "Skipping $$variant_name variant for linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
			continue; \
		fi; \
		distroless_arch="$*"; \
		if [ "$*" = "armv7" ]; then \
			distroless_arch="arm"; \
		fi; \
		if [ "$$dockerfile" = "Dockerfile" ]; then \
			echo "Building default variant ($$variant_name) for linux-$* using $$dockerfile"; \
			docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \
				-f $$dockerfile \
				--build-arg ARCH="$*" \
				--build-arg OS="linux" \
				--build-arg DISTROLESS_ARCH="$$distroless_arch" \
				$(DOCKERBUILD_CONTEXT); \
			if [ "$$variant_name" != "default" ]; then \
				echo "Tagging default variant with $$variant_name suffix"; \
				docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \
					"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
			fi; \
		else \
			echo "Building $$variant_name variant for linux-$* using $$dockerfile"; \
			docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" \
				-f $$dockerfile \
				--build-arg ARCH="$*" \
				--build-arg OS="linux" \
				--build-arg DISTROLESS_ARCH="$$distroless_arch" \
				$(DOCKERBUILD_CONTEXT); \
		fi; \
	done

.PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS)
common-docker-publish: $(PUBLISH_DOCKER_ARCHS)
$(PUBLISH_DOCKER_ARCHS): common-docker-publish-%:
	@for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
		dockerfile=$${variant#*:}; \
		variant_name=$${variant%%:*}; \
		if $(call dockerfile_arch_is_excluded,$*); then \
			echo "Skipping push for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
			continue; \
		fi; \
		if $(call registry_arch_is_excluded,$*); then \
			echo "Skipping push for $$variant_name variant on linux-$* to $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
			continue; \
		fi; \
		if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
			echo "Pushing $$variant_name variant for linux-$*"; \
			docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
		fi; \
		if [ "$$dockerfile" = "Dockerfile" ]; then \
			echo "Pushing default variant ($$variant_name) for linux-$*"; \
			docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)"; \
		fi; \
		if [ "$(DOCKER_IMAGE_TAG)" = "latest" ]; then \
			if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
				echo "Pushing $$variant_name variant version tags for linux-$*"; \
				docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
			fi; \
			if [ "$$dockerfile" = "Dockerfile" ]; then \
				echo "Pushing default variant version tag for linux-$*"; \
				docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"; \
			fi; \
		fi; \
	done

DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION)))
.PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS)
common-docker-tag-latest: $(TAG_DOCKER_ARCHS)
$(TAG_DOCKER_ARCHS): common-docker-tag-latest-%:
	@for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
		dockerfile=$${variant#*:}; \
		variant_name=$${variant%%:*}; \
		if $(call dockerfile_arch_is_excluded,$*); then \
			echo "Skipping tag for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
			continue; \
		fi; \
		if $(call registry_arch_is_excluded,$*); then \
			echo "Skipping tag for $$variant_name variant on linux-$* for $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
			continue; \
		fi; \
		if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
			echo "Tagging $$variant_name variant for linux-$* as latest"; \
			docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest-$$variant_name"; \
			docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
		fi; \
		if [ "$$dockerfile" = "Dockerfile" ]; then \
			echo "Tagging default variant ($$variant_name) for linux-$* as latest"; \
			docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest"; \
			docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"; \
		fi; \
	done

.PHONY: common-docker-manifest
common-docker-manifest:
	@for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
		dockerfile=$${variant#*:}; \
		variant_name=$${variant%%:*}; \
		if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
			echo "Creating manifest for $$variant_name variant"; \
			refs=""; \
			for arch in $(DOCKER_ARCHS); do \
				if $(call dockerfile_arch_is_excluded,$$arch); then \
					echo "  Skipping $$arch for $$variant_name (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
					continue; \
				fi; \
				if $(call registry_arch_is_excluded,$$arch); then \
					echo "  Skipping $$arch for $$variant_name on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
					continue; \
				fi; \
				refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
			done; \
			if [ -z "$$refs" ]; then \
				echo "Skipping manifest for $$variant_name variant (no supported architectures)"; \
				continue; \
			fi; \
			DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" $$refs; \
			DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
		fi; \
		if [ "$$dockerfile" = "Dockerfile" ]; then \
			echo "Creating default variant ($$variant_name) manifest"; \
			refs=""; \
			for arch in $(DOCKER_ARCHS); do \
				if $(call dockerfile_arch_is_excluded,$$arch); then \
					echo "  Skipping $$arch for default variant (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
					continue; \
				fi; \
				if $(call registry_arch_is_excluded,$$arch); then \
					echo "  Skipping $$arch for default variant on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
					continue; \
				fi; \
				refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)"; \
			done; \
			if [ -z "$$refs" ]; then \
				echo "Skipping default variant manifest (no supported architectures)"; \
				continue; \
			fi; \
			DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $$refs; \
			DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)"; \
		fi; \
		if [ "$(DOCKER_IMAGE_TAG)" = "latest" ]; then \
			if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
				echo "Creating manifest for $$variant_name variant version tag"; \
				refs=""; \
				for arch in $(DOCKER_ARCHS); do \
					if $(call dockerfile_arch_is_excluded,$$arch); then \
						echo "  Skipping $$arch for $$variant_name version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
						continue; \
					fi; \
					if $(call registry_arch_is_excluded,$$arch); then \
						echo "  Skipping $$arch for $$variant_name version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
						continue; \
					fi; \
					refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
				done; \
				if [ -z "$$refs" ]; then \
					echo "Skipping version-tag manifest for $$variant_name variant (no supported architectures)"; \
					continue; \
				fi; \
				DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name" $$refs; \
				DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
			fi; \
			if [ "$$dockerfile" = "Dockerfile" ]; then \
				echo "Creating default variant version tag manifest"; \
				refs=""; \
				for arch in $(DOCKER_ARCHS); do \
					if $(call dockerfile_arch_is_excluded,$$arch); then \
						echo "  Skipping $$arch for default variant version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
						continue; \
					fi; \
					if $(call registry_arch_is_excluded,$$arch); then \
						echo "  Skipping $$arch for default variant version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
						continue; \
					fi; \
					refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)"; \
				done; \
				if [ -z "$$refs" ]; then \
					echo "Skipping default variant version-tag manifest (no supported architectures)"; \
					continue; \
				fi; \
				DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)" $$refs; \
				DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)"; \
			fi; \
		fi; \
	done

.PHONY: promu
promu: $(PROMU)

$(PROMU):
	$(eval PROMU_TMP := $(shell mktemp -d))
	curl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP)
	mkdir -p $(FIRST_GOPATH)/bin
	cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu
	rm -r $(PROMU_TMP)

.PHONY: common-proto
common-proto:
	@echo ">> generating code from proto files"
	@./scripts/genproto.sh

ifdef GOLANGCI_LINT
$(GOLANGCI_LINT):
	mkdir -p $(FIRST_GOPATH)/bin
	curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \
		| sed -e '/install -d/d' \
		| sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION)
endif

.PHONY: common-print-golangci-lint-version
common-print-golangci-lint-version:
	@echo $(GOLANGCI_LINT_VERSION)

.PHONY: precheck
precheck::

define PRECHECK_COMMAND_template =
precheck:: $(1)_precheck

PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1)))
.PHONY: $(1)_precheck
$(1)_precheck:
	@if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \
		echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \
		exit 1; \
	fi
endef

govulncheck: install-govulncheck
	govulncheck ./...

install-govulncheck:
	command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest


================================================
FILE: NOTICE
================================================
Copyright 2018-2021 Invision AG
Copyright 2021-2024 NERDSWORDS
Copyright 2024 The Prometheus Authors


================================================
FILE: README.md
================================================
# YACE - yet another cloudwatch exporter

[![Container on Quay](https://quay.io/repository/prometheuscommunity/yet-another-cloudwatch-exporter/status)][quay]
[![Container on Docker Hub](https://img.shields.io/docker/pulls/prometheuscommunity/yet-another-cloudwatch-exporter.svg?maxAge=604800)][docker]

YACE, or `yet another cloudwatch exporter`, is a [Prometheus exporter](https://prometheus.io/docs/instrumenting/exporters/#exporters-and-integrations) for [AWS CloudWatch](http://aws.amazon.com/cloudwatch/) metrics. It is written in Go and uses the official AWS SDK.

## News

As of November 2024, YACE is part of [prometheus-community](https://github.com/prometheus-community). Read more about it in these announcement posts:

* https://prometheus.io/blog/2024/11/19/yace-joining-prometheus-community/
* https://grafana.com/blog/2024/11/19/yace-moves-to-prometheus-community/

## Alternatives

Consider using the official [CloudWatch Exporter](https://github.com/prometheus/cloudwatch_exporter) if you prefer a Java implementation.


## Project Status

While YACE is at version less than 1.0.0, expect that any new release might introduce breaking changes. We'll document changes in [CHANGELOG.md](CHANGELOG.md).

Where feasible, features will be deprecated instead of being immediately changed or removed. This means that YACE will continue to work but might log warning messages. Expect deprecated features to be permanently changed/removed within the next 2/3 releases.

## Security

Read more how to report a security vulnerability in [SECURITY.md](SECURITY.md).

### Supported Versions

Only the latest version gets security updates. We won't support older versions.

## Features

* Stop worrying about your AWS IDs - Auto discovery of resources via tags
* Structured logging (json and logfmt)
* Filter monitored resources via regex
* Automatic adding of tag labels to metrics
* Automatic adding of dimension labels to metrics
* Allows to export 0 even if CloudWatch returns nil
* Allows exports metrics with CloudWatch timestamps (disabled by default)
* Static metrics support for all cloudwatch metrics without auto discovery
* Pull data from multiple AWS accounts using cross-account roles
* Can be used as a library in an external application
* Support the scraping of custom namespaces metrics with the CloudWatch Dimensions.
* Supported services with auto discovery through tags:
  * `/aws/sagemaker/Endpoints` - Sagemaker Endpoints
  * `/aws/sagemaker/InferenceRecommendationsJobs` - Sagemaker Inference Recommender Jobs
  * `/aws/sagemaker/ProcessingJobs` - Sagemaker Processing Jobs
  * `/aws/sagemaker/TrainingJobs` - Sagemaker Training Jobs
  * `/aws/sagemaker/TransformJobs` - Sagemaker Batch Transform Jobs
  * `AmazonMWAA` - Managed Apache Airflow
  * `AWS/ACMPrivateCA` - ACM Private CA
  * `AWS/AmazonMQ` - Managed Message Broker Service
  * `AWS/AOSS` - OpenSearch Serverless
  * `AWS/ApiGateway` - ApiGateway (V1 and V2)
  * `AWS/ApplicationELB` - Application Load Balancer
  * `AWS/AppRunner` - Managed Container Apps Service
  * `AWS/AppStream` - AppStream
  * `AWS/AppSync` - AppSync
  * `AWS/Athena` - Athena
  * `AWS/AutoScaling` - Auto Scaling Group
  * `AWS/Backup` - Backup
  * `AWS/Bedrock` - GenerativeAI
  * `AWS/Billing` - Billing
  * `AWS/Cassandra` - Cassandra
  * `AWS/CertificateManager` - Certificate Manager
  * `AWS/ClientVPN` - Client-based VPN
  * `AWS/CloudFront` - Cloud Front
  * `AWS/Cognito` - Cognito
  * `AWS/DataSync` - DataSync
  * `AWS/DDoSProtection` - Distributed Denial of Service (DDoS) protection service
  * `AWS/DirectoryService` - Directory Services (MicrosoftAD)
  * `AWS/DMS` - Database Migration Service
  * `AWS/DocDB` - DocumentDB (with MongoDB compatibility)
  * `AWS/DX` - Direct Connect
  * `AWS/DynamoDB` - NoSQL Key-Value Database
  * `AWS/EBS` - Elastic Block Storage
  * `AWS/EC2` - Elastic Compute Cloud
  * `AWS/EC2Spot` - Elastic Compute Cloud for Spot Instances
  * `AWS/ECR` - Elastic Container Registry
  * `AWS/ECS` - Elastic Container Service (Service Metrics)
  * `AWS/EFS` - Elastic File System
  * `AWS/ElastiCache` - ElastiCache
  * `AWS/ElasticBeanstalk` - Elastic Beanstalk
  * `AWS/ElasticMapReduce` - Elastic MapReduce
  * `AWS/ELB` - Elastic Load Balancer
  * `AWS/EMRServerless` - Amazon EMR Serverless
  * `AWS/ES` - ElasticSearch
  * `AWS/Events` - EventBridge
  * `AWS/Firehose` - Managed Streaming Service
  * `AWS/FSx` - FSx File System
  * `AWS/GameLift` - GameLift
  * `AWS/GatewayELB` - Gateway Load Balancer
  * `AWS/GlobalAccelerator` - AWS Global Accelerator
  * `AWS/IoT` - IoT
  * `AWS/IPAM` - IP address manager
  * `AWS/Kafka` - Managed Apache Kafka
  * `AWS/KafkaConnect` - AWS MSK Connectors
  * `AWS/Kinesis` - Kinesis Data Stream
  * `AWS/KinesisAnalytics` - Kinesis Data Analytics for SQL Applications
  * `AWS/KMS` - Key Management Service
  * `AWS/Lambda` - Lambda Functions
  * `AWS/Logs` - CloudWatch Logs
  * `AWS/MediaConnect` - AWS Elemental MediaConnect
  * `AWS/MediaConvert` - AWS Elemental MediaConvert
  * `AWS/MediaLive` - AWS Elemental MediaLive
  * `AWS/MediaPackage` - AWS Elemental MediaPackage
  * `AWS/MediaTailor` - AWS Elemental MediaTailor
  * `AWS/MemoryDB` - AWS MemoryDB
  * `AWS/MWAA` - Managed Apache Airflow (Container, queue, and database metrics)
  * `AWS/NATGateway` - NAT Gateway
  * `AWS/Neptune` - Neptune
  * `AWS/NetworkELB` - Network Load Balancer
  * `AWS/NetworkFirewall` - Network Firewall
  * `AWS/Network Manager` - Network Manager
  * `AWS/PrivateLinkEndpoints` - VPC Endpoint
  * `AWS/PrivateLinkServices` - VPC Endpoint Service
  * `AWS/Prometheus` - Managed Service for Prometheus
  * `AWS/QLDB` - Quantum Ledger Database
  * `AWS/QuickSight` - QuickSight (Business Intelligence)
  * `AWS/RDS` - Relational Database Service
  * `AWS/Redshift` - Redshift Database
  * `AWS/Redshift-Serverless` - Redshift Serverless
  * `AWS/Route53` - Route53 Health Checks
  * `AWS/Route53Resolver` - Route53 Resolver
  * `AWS/RUM` - Real User Monitoring
  * `AWS/S3` - Object Storage
  * `AWS/Sagemaker/ModelBuildingPipeline` - Sagemaker Model Building Pipelines
  * `AWS/SageMaker` - Sagemaker invocations
  * `AWS/Scheduler` - EventBridge Scheduler
  * `AWS/SecretsManager` - Secrets Manager
  * `AWS/SES` - Simple Email Service
  * `AWS/SNS` - Simple Notification Service
  * `AWS/SQS` - Simple Queue Service
  * `AWS/States` - Step Functions
  * `AWS/StorageGateway` - On-premises access to cloud storage
  * `AWS/Timestream` - Time-series database service
  * `AWS/TransitGateway` - Transit Gateway
  * `AWS/TrustedAdvisor` - Trusted Advisor
  * `AWS/Usage` - Usage of some AWS resources and APIs
  * `AWS/VpcLattice` - VPC Lattice
  * `AWS/VPN` - VPN connection
  * `AWS/WAFV2` - Web Application Firewall v2
  * `AWS/WorkSpaces` - Workspaces
  * `ContainerInsights` - EKS ContainerInsights (Dependency on Cloudwatch agent)
  * `CWAgent` - CloudWatch agent
  * `ECS/ContainerInsights` - ECS/ContainerInsights (Fargate metrics)
  * `Glue` - AWS Glue Jobs

## Feature flags

To provide backwards compatibility, some of YACE's new features or breaking changes might be guarded under a feature flag. Refer to [docs/feature_flags.md](./docs/feature_flags.md) for details.

## Installing and running

Refer to the [installation guide](docs/installation.md).

## Authentication

The exporter will need to be running in an environment which has access to AWS. The exporter uses the [AWS SDK for Go](https://aws.github.io/aws-sdk-go-v2/docs/getting-started/) and supports providing authentication via [AWS's default credential chain](https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials). Regardless of the method used to acquire the credentials, some permissions are needed for the exporter to work.

As a quick start, the following IAM policy can be used to grant the all permissions required by YACE
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "tag:GetResources",
        "cloudwatch:GetMetricData",
        "cloudwatch:GetMetricStatistics",
        "cloudwatch:ListMetrics",
        "apigateway:GET",
        "aps:ListWorkspaces",
        "autoscaling:DescribeAutoScalingGroups",
        "dms:DescribeReplicationInstances",
        "dms:DescribeReplicationTasks",
        "ec2:DescribeTransitGatewayAttachments",
        "ec2:DescribeSpotFleetRequests",
        "shield:ListProtections",
        "storagegateway:ListGateways",
        "storagegateway:ListTagsForResource",
        "iam:ListAccountAliases"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```

If you would like to remove certain permissions based on your needs the policy can be adjusted based the CloudWatch namespaces you are scraping

These are the bare minimum permissions required to run Static and Discovery Jobs
```json
"tag:GetResources",
"cloudwatch:GetMetricData",
"cloudwatch:GetMetricStatistics",
"cloudwatch:ListMetrics"
```

This permission is required to discover resources for the AWS/ApiGateway namespace
```json
"apigateway:GET"
```

This permission is required to discover resources for the AWS/AutoScaling namespace
```json
"autoscaling:DescribeAutoScalingGroups"
```

These permissions are required to discover resources for the AWS/DMS namespace
```json
"dms:DescribeReplicationInstances",
"dms:DescribeReplicationTasks"
```


This permission is required to discover resources for the AWS/EC2Spot namespace
```json
"ec2:DescribeSpotFleetRequests"
```

This permission is required to discover resources for the AWS/Prometheus namespace
```json
"aps:ListWorkspaces"
```

These permissions are required to discover resources for the AWS/StorageGateway namespace
```json
"storagegateway:ListGateways",
"storagegateway:ListTagsForResource"
```

This permission is required to discover resources for the AWS/TransitGateway namespace
```json
"ec2:DescribeTransitGatewayAttachments"
```

This permission is required to discover protected resources for the AWS/DDoSProtection namespace
```json
"shield:ListProtections"
```

The AWS IAM API supports creating account aliases, which are human-friendly names that can be used to easily identify accounts. An account can have at most a single alias, see ([docs](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListAccountAliases.html)). Each alias must be unique across an AWS network partition ([docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html#AboutAccountAlias)). The following permission is required to get the alias for an account, which is exported as a label in the `aws_account_info` metric:
```json
"iam:ListAccountAliases"
```

If running YACE inside an AWS EC2 instance, the exporter will automatically attempt to assume the associated IAM Role. If this is undesirable behavior turn off the use the metadata endpoint by setting the environment variable `AWS_EC2_METADATA_DISABLED=true`.

## Configuration

Refer to the [configuration](docs/configuration.md) docs.

## Metrics Examples

```text
### Metrics with exportedTagsOnMetrics
aws_ec2_cpuutilization_maximum{dimension_InstanceId="i-someid", name="arn:aws:ec2:eu-west-1:472724724:instance/i-someid", tag_Name="jenkins"} 57.2916666666667

### Info helper with tags
aws_elb_info{name="arn:aws:elasticloadbalancing:eu-west-1:472724724:loadbalancer/a815b16g3417211e7738a02fcc13bbf9",tag_KubernetesCluster="production-19",tag_Name="",tag_kubernetes_io_cluster_production_19="owned",tag_kubernetes_io_service_name="nginx-ingress/private-ext",region="eu-west-1"} 0
aws_ec2_info{name="arn:aws:ec2:eu-west-1:472724724:instance/i-someid",tag_Name="jenkins"} 0

### Track cloudwatch requests to calculate costs
yace_cloudwatch_requests_total 168
```

## Query Examples without exportedTagsOnMetrics

```text
# CPUUtilization + Name tag of the instance id - No more instance id needed for monitoring
aws_ec2_cpuutilization_average + on (name) group_left(tag_Name) aws_ec2_info

# Free Storage in Megabytes + tag Type of the elasticsearch cluster
(aws_es_free_storage_space_sum + on (name) group_left(tag_Type) aws_es_info) / 1024

# Add kubernetes / kops tags on 4xx elb metrics
(aws_elb_httpcode_backend_4_xx_sum + on (name) group_left(tag_KubernetesCluster,tag_kubernetes_io_service_name) aws_elb_info)

# Availability Metric for ELBs (Successful requests / Total Requests) + k8s service name
# Use nilToZero on all metrics else it won't work
((aws_elb_request_count_sum - on (name) group_left() aws_elb_httpcode_backend_4_xx_sum) - on (name) group_left() aws_elb_httpcode_backend_5_xx_sum) + on (name) group_left(tag_kubernetes_io_service_name) aws_elb_info

# Forecast your elasticsearch disk size in 7 days and report metrics with tags type and version
predict_linear(aws_es_free_storage_space_minimum[2d], 86400 * 7) + on (name) group_left(tag_type, tag_version) aws_es_info

# Forecast your cloudwatch costs for next 32 days based on last 10 minutes
# 1.000.000 Requests free
# 0.01 Dollar for 1.000 GetMetricStatistics Api Requests (https://aws.amazon.com/cloudwatch/pricing/)
((increase(yace_cloudwatch_requests_total[10m]) * 6 * 24 * 32) - 100000) / 1000 * 0.01
```

## Override AWS endpoint urls
to support local testing all AWS urls can be overridden with by setting an environment variable `AWS_ENDPOINT_URL`
```shell
docker run -d --rm -v $PWD/credentials:/home/.aws/credentials -v $PWD/config.yml:/tmp/config.yml \
-e AWS_ENDPOINT_URL=http://localhost:4766 -p 5000:5000 --name yace quay.io/prometheuscommunity/yet-another-cloudwatch-exporter:latest
```

## Options
### RoleArns

Multiple roleArns are useful, when you are monitoring multi-account setup, where all accounts are using same AWS services. For example, you are running yace in monitoring account and you have number of accounts (for example newspapers, radio and television) running ECS clusters. Each account gives yace permissions to assume local IAM role, which has all the necessary permissions for Cloudwatch metrics. On this kind of setup, you could simply list:
```yaml
apiVersion: v1alpha1
sts-region: eu-west-1
discovery:
  jobs:
    - type: AWS/ECS
      regions:
        - eu-north-1
      roles:
        - roleArn: "arn:aws:iam::1111111111111:role/prometheus" # newspaper
        - roleArn: "arn:aws:iam::2222222222222:role/prometheus" # radio
        - roleArn: "arn:aws:iam::3333333333333:role/prometheus" # television
      metrics:
        - name: MemoryReservation
          statistics:
            - Average
            - Minimum
            - Maximum
          period: 600
          length: 600
```

Additionally, if the IAM role you want to assume requires an [External ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html?icmpid=docs_iam_console) you can specify it this way:

```yaml
  roles:
    - roleArn: "arn:aws:iam::1111111111111:role/prometheus"
      externalId: "shared-external-identifier"
```

### Requests concurrency
The flags 'cloudwatch-concurrency' and 'tag-concurrency' define the number of concurrent request to cloudwatch metrics and tags. Their default value is 5.

Setting a higher value makes faster scraping times but can incur in throttling and the blocking of the API.

### Decoupled scraping
The exporter scraped cloudwatch metrics in the background in fixed interval.
This protects from the abuse of API requests that can cause extra billing in AWS account.

The flag 'scraping-interval' defines the seconds between scrapes.
The default value is 300.

## Embedding YACE in your application

YACE can be used as a library and embedded into your application, see the [embedding guide](docs/embedding.md).

## Troubleshooting / Debugging

### Help my metrics are intermittent

* Please, try out a bigger length e.g. for elb try out a length of 600 and a period of 600. Then test how low you can
go without losing data. ELB metrics on AWS are written every 5 minutes (300) in default.

### My metrics only show new values after 5 minutes

* Please, try to set a lower value for the 'scraping-interval' flag or set the 'decoupled-scraping' to false.

## Contribute

[Development Setup / Guide](/CONTRIBUTE.md)

## Thank you

* [Justin Santa Barbara](https://github.com/justinsb) - For telling me about AWS tags api which simplified a lot - Thanks!
* [Brian Brazil](https://github.com/brian-brazil) - Who gave a lot of feedback regarding UX and prometheus lib - Thanks!

[quay]: https://quay.io/repository/prometheuscommunity/yet-another-cloudwatch-exporter
[docker]: https://hub.docker.com/r/prometheuscommunity/yet-another-cloudwatch-exporter


================================================
FILE: SECURITY.md
================================================
# Reporting a security issue

The Prometheus security policy, including how to report vulnerabilities, can be
found here:

[https://prometheus.io/docs/operating/security/](https://prometheus.io/docs/operating/security/)


================================================
FILE: VERSION
================================================
0.64.0


================================================
FILE: cmd/yace/main.go
================================================
// Copyright The Prometheus 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.
package main

import (
	"context"
	"fmt"
	"log/slog"
	"net/http"
	"net/http/pprof"
	"os"
	"slices"
	"strings"

	"github.com/prometheus/common/promslog"
	promslogflag "github.com/prometheus/common/promslog/flag"
	"github.com/prometheus/common/version"
	"github.com/urfave/cli/v2"
	"golang.org/x/sync/semaphore"

	exporter "github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg"
	"github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/clients"
	"github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/clients/cloudwatch"
	"github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/config"
)

const (
	enableFeatureFlag = "enable-feature"
	htmlVersion       = `<html>
<head><title>Yet Another CloudWatch Exporter</title></head>
<body>
<h1>Thanks for using YACE :)</h1>
Version: %s
<p><a href="/metrics">Metrics</a></p>
%s
</body>
</html>`
	htmlPprof = `<p><a href="/debug/pprof">Pprof</a><p>`
)

var sem = semaphore.NewWeighted(1)

const (
	defaultLogLevel  = "info"
	defaultLogFormat = "json"
)

var (
	addr                  string
	configFile            string
	logLevel              string
	logFormat             string
	fips                  bool
	cloudwatchConcurrency cloudwatch.ConcurrencyConfig
	tagConcurrency        int
	scrapingInterval      int
	metricsPerQuery       int
	labelsSnakeCase       bool
	profilingEnabled      bool

	logger *slog.Logger
)

func main() {
	app := NewYACEApp()
	if err := app.Run(os.Args); err != nil {
		// if we exit very early we'll not have set up the logger yet
		if logger == nil {
			jsonFmt := promslog.NewFormat()
			_ = jsonFmt.Set("json")
			logger = promslog.New(&promslog.Config{Format: jsonFmt})
		}
		logger.Error("Error running yace", "err", err)
		os.Exit(1)
	}
}

// NewYACEApp creates a new cli.App implementing the YACE entrypoints and CLI arguments.
func NewYACEApp() *cli.App {
	yace := cli.NewApp()
	yace.Name = "Yet Another CloudWatch Exporter"
	yace.Version = version.Version
	yace.Usage = "YACE configured to retrieve CloudWatch metrics through the AWS API"
	yace.Description = ""
	yace.Authors = []*cli.Author{
		{Name: "", Email: ""},
	}

	yace.Flags = []cli.Flag{
		&cli.StringFlag{
			Name:        "listen-address",
			Value:       ":5000",
			Usage:       "The address to listen on",
			Destination: &addr,
			EnvVars:     []string{"listen-address"},
		},
		&cli.StringFlag{
			Name:        "config.file",
			Value:       "config.yml",
			Usage:       "Path to configuration file",
			Destination: &configFile,
			EnvVars:     []string{"config.file"},
		},
		&cli.StringFlag{
			Name:        "log.level",
			Value:       defaultLogLevel,
			Usage:       promslogflag.LevelFlagHelp,
			Destination: &logLevel,
			Action: func(_ *cli.Context, s string) error {
				if !slices.Contains(promslog.LevelFlagOptions, s) {
					return fmt.Errorf("unrecognized log format %q", s)
				}
				return nil
			},
		},
		&cli.StringFlag{
			Name:        "log.format",
			Value:       defaultLogFormat,
			Usage:       promslogflag.FormatFlagHelp,
			Destination: &logFormat,
			Action: func(_ *cli.Context, s string) error {
				if !slices.Contains(promslog.FormatFlagOptions, s) {
					return fmt.Errorf("unrecognized log format %q", s)
				}
				return nil
			},
		},
		&cli.BoolFlag{
			Name:        "fips",
			Value:       false,
			Usage:       "Use FIPS compliant AWS API endpoints",
			Destination: &fips,
		},
		&cli.IntFlag{
			Name:        "cloudwatch-concurrency",
			Value:       exporter.DefaultCloudwatchConcurrency.SingleLimit,
			Usage:       "Maximum number of concurrent requests to CloudWatch API.",
			Destination: &cloudwatchConcurrency.SingleLimit,
		},
		&cli.BoolFlag{
			Name:        "cloudwatch-concurrency.per-api-limit-enabled",
			Value:       exporter.DefaultCloudwatchConcurrency.PerAPILimitEnabled,
			Usage:       "Whether to enable the per API CloudWatch concurrency limiter. When enabled, the concurrency `-cloudwatch-concurrency` flag will be ignored.",
			Destination: &cloudwatchConcurrency.PerAPILimitEnabled,
		},
		&cli.IntFlag{
			Name:        "cloudwatch-concurrency.list-metrics-limit",
			Value:       exporter.DefaultCloudwatchConcurrency.ListMetrics,
			Usage:       "Maximum number of concurrent requests to ListMetrics CloudWatch API. Used if the -cloudwatch-concurrency.per-api-limit-enabled concurrency limiter is enabled.",
			Destination: &cloudwatchConcurrency.ListMetrics,
		},
		&cli.IntFlag{
			Name:        "cloudwatch-concurrency.get-metric-data-limit",
			Value:       exporter.DefaultCloudwatchConcurrency.GetMetricData,
			Usage:       "Maximum number of concurrent requests to GetMetricData CloudWatch API. Used if the -cloudwatch-concurrency.per-api-limit-enabled concurrency limiter is enabled.",
			Destination: &cloudwatchConcurrency.GetMetricData,
		},
		&cli.IntFlag{
			Name:        "cloudwatch-concurrency.get-metric-statistics-limit",
			Value:       exporter.DefaultCloudwatchConcurrency.GetMetricStatistics,
			Usage:       "Maximum number of concurrent requests to GetMetricStatistics CloudWatch API. Used if the -cloudwatch-concurrency.per-api-limit-enabled concurrency limiter is enabled.",
			Destination: &cloudwatchConcurrency.GetMetricStatistics,
		},
		&cli.IntFlag{
			Name:        "tag-concurrency",
			Value:       exporter.DefaultTaggingAPIConcurrency,
			Usage:       "Maximum number of concurrent requests to Resource Tagging API.",
			Destination: &tagConcurrency,
		},
		&cli.IntFlag{
			Name:        "scraping-interval",
			Value:       300,
			Usage:       "Seconds to wait between scraping the AWS metrics",
			Destination: &scrapingInterval,
			EnvVars:     []string{"scraping-interval"},
		},
		&cli.IntFlag{
			Name:        "metrics-per-query",
			Value:       exporter.DefaultMetricsPerQuery,
			Usage:       "Number of metrics made in a single GetMetricsData request",
			Destination: &metricsPerQuery,
			EnvVars:     []string{"metrics-per-query"},
		},
		&cli.BoolFlag{
			Name:        "labels-snake-case",
			Value:       exporter.DefaultLabelsSnakeCase,
			Usage:       "Whether labels should be output in snake case instead of camel case",
			Destination: &labelsSnakeCase,
		},
		&cli.BoolFlag{
			Name:        "profiling.enabled",
			Value:       false,
			Usage:       "Enable pprof endpoints",
			Destination: &profilingEnabled,
		},
		&cli.StringSliceFlag{
			Name:  enableFeatureFlag,
			Usage: "Comma-separated list of enabled features",
		},
	}

	yace.Commands = []*cli.Command{
		{
			Name:    "verify-config",
			Aliases: []string{"vc"},
			Usage:   "Loads and attempts to parse config file, then exits. Useful for CI/CD validation",
			Flags: []cli.Flag{
				&cli.StringFlag{Name: "config.file", Value: "config.yml", Usage: "Path to configuration file.", Destination: &configFile},
			},
			Action: func(_ *cli.Context) error {
				logger = newLogger(logFormat, logLevel).With("version", version.Version)
				logger.Info("Parsing config")
				cfg := config.ScrapeConf{}
				if _, err := cfg.Load(configFile, logger); err != nil {
					logger.Error("Couldn't read config file", "err", err, "path", configFile)
					os.Exit(1)
				}
				logger.Info("Config file is valid", "path", configFile)
				os.Exit(0)
				return nil
			},
		},
		{
			Name:    "version",
			Aliases: []string{"v"},
			Usage:   "prints current yace version.",
			Action: func(_ *cli.Context) error {
				fmt.Println(version.Version)
				os.Exit(0)
				return nil
			},
		},
	}

	yace.Action = startScraper

	return yace
}

func startScraper(c *cli.Context) error {
	logger = newLogger(logFormat, logLevel).With("version", version.Version)

	// log warning if the two concurrency limiting methods are configured via CLI
	if c.IsSet("cloudwatch-concurrency") && c.IsSet("cloudwatch-concurrency.per-api-limit-enabled") {
		logger.Warn("Both `cloudwatch-concurrency` and `cloudwatch-concurrency.per-api-limit-enabled` are set. `cloudwatch-concurrency` will be ignored, and the per-api concurrency limiting strategy will be favoured.")
	}

	logger.Info("Parsing config")

	cfg := config.ScrapeConf{}
	jobsCfg, err := cfg.Load(configFile, logger)
	if err != nil {
		return fmt.Errorf("couldn't read %s: %w", configFile, err)
	}

	featureFlags := c.StringSlice(enableFeatureFlag)
	s := NewScraper(featureFlags)

	cachingFactory, err := clients.NewFactory(logger, jobsCfg, fips)
	if err != nil {
		return fmt.Errorf("failed to construct aws sdk v2 client cache: %w", err)
	}

	ctx, cancelRunningScrape := context.WithCancel(context.Background())
	go s.decoupled(ctx, logger, jobsCfg, cachingFactory)

	mux := http.NewServeMux()

	if profilingEnabled {
		mux.HandleFunc("/debug/pprof/", pprof.Index)
		mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
		mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
		mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
		mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
	}

	mux.HandleFunc("/metrics", s.makeHandler())

	mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
		pprofLink := ""
		if profilingEnabled {
			pprofLink = htmlPprof
		}

		_, _ = fmt.Fprintf(w, htmlVersion, version.Version, pprofLink)
	})

	mux.HandleFunc("/healthz", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		_, _ = w.Write([]byte("ok"))
	})

	mux.HandleFunc("/reload", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			w.WriteHeader(http.StatusNotFound)
			return
		}

		logger.Info("Parsing config")
		newCfg := config.ScrapeConf{}
		newJobsCfg, err := newCfg.Load(configFile, logger)
		if err != nil {
			logger.Error("Couldn't read config file", "err", err, "path", configFile)
			return
		}

		logger.Info("Reset clients cache")
		cache, err := clients.NewFactory(logger, newJobsCfg, fips)
		if err != nil {
			logger.Error("Failed to construct aws sdk v2 client cache", "err", err, "path", configFile)
			return
		}

		cancelRunningScrape()
		ctx, cancelRunningScrape = context.WithCancel(context.Background())
		go s.decoupled(ctx, logger, newJobsCfg, cache)
	})

	logger.Info("Yace startup completed", "build_info", version.Info(), "build_context", version.BuildContext(), "feature_flags", strings.Join(featureFlags, ","))

	srv := &http.Server{Addr: addr, Handler: mux}
	return srv.ListenAndServe()
}

func newLogger(format, level string) *slog.Logger {
	// If flag parsing was successful, then we know that format and level
	// are both valid options; no need to error check their returns, just
	// set their values.
	f := promslog.NewFormat()
	_ = f.Set(format)

	lvl := promslog.NewLevel()
	_ = lvl.Set(level)

	return promslog.New(&promslog.Config{Format: f, Level: lvl})
}


================================================
FILE: cmd/yace/main_test.go
================================================
// Copyright 2024 The Prometheus 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.
package main

import (
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/urfave/cli/v2"
)

func TestYACEApp_FeatureFlagsParsedCorrectly(t *testing.T) {
	app := NewYACEApp()

	// two feature flags
	app.Action = func(c *cli.Context) error {
		featureFlags := c.StringSlice(enableFeatureFlag)
		require.Equal(t, []string{"feature1", "feature2"}, featureFlags)
		return nil
	}

	require.NoError(t, app.Run([]string{"yace", "-enable-feature=feature1,feature2"}), "error running test command")

	// empty feature flags
	app.Action = func(c *cli.Context) error {
		featureFlags := c.StringSlice(enableFeatureFlag)
		require.Len(t, featureFlags, 0)
		return nil
	}

	require.NoError(t, app.Run([]string{"yace"}), "error running test command")
}


================================================
FILE: cmd/yace/scraper.go
================================================
// Copyright 2024 The Prometheus 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.
package main

import (
	"context"
	"log/slog"
	"net/http"
	"sync/atomic"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"

	exporter "github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg"
	"github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/clients"
	"github.com/prometheus-community/yet-another-cloudwatch-exporter/pkg/model"
)

type Scraper struct {
	registry     atomic.Pointer[prometheus.Registry]
	featureFlags []string
}

type cachingFactory interface {
	clients.Factory
	Refresh()
	Clear()
}

func NewScraper(featureFlags []string) *Scraper {
	s := &Scraper{
		registry:     atomic.Pointer[prometheus.Registry]{},
		featureFlags: featureFlags,
	}
	s.registry.Store(prometheus.NewRegistry())
	return s
}

func (s *Scraper) makeHandler() func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		handler := promhttp.HandlerFor(s.registry.Load(), promhttp.HandlerOpts{
			DisableCompression: false,
		})
		handler.ServeHTTP(w, r)
	}
}

func (s *Scraper) decoupled(ctx context.Context, logger *slog.Logger, jobsCfg model.JobsConfig, cache cachingFactory) {
	logger.Debug("Starting scraping async")
	s.scrape(ctx, logger, jobsCfg, cache)

	scrapingDuration := time.Duration(scrapingInterval) * time.Second
	ticker := time.NewTicker(scrapingDuration)
	logger.Debug("Initial scrape completed", "scraping_interval", scrapingInterval)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
			logger.Debug("Starting scraping async")
			go s.scrape(ctx, logger, jobsCfg, cache)
		}
	}
}

func (s *Scraper) scrape(ctx context.Context, logger *slog.Logger, jobsCfg model.JobsConfig, cache cachingFactory) {
	if !sem.TryAcquire(1) {
		// This shouldn't happen under normal use, users should adjust their configuration when this occurs.
		// Let them know by logging a warning.
		logger.Warn("Another scrape is already in process, will not start a new one. " +
			"Adjust your configuration to ensure the previous scrape completes first.")
		return
	}
	defer sem.Release(1)

	newRegistry := prometheus.NewRegistry()
	for _, metric := range exporter.Metrics {
		if err := newRegistry.Register(metric); err != nil {
			logger.Warn("Could not register cloudwatch api metric")
		}
	}

	// since we have called refresh, we have loaded all the credentials
	// into the clients and it is now safe to call concurrently. Defer the
	// clearing, so we always clear credentials before the next scrape
	cache.Refresh()
	defer cache.Clear()

	options := []exporter.OptionsFunc{
		exporter.MetricsPerQuery(metricsPerQuery),
		exporter.LabelsSnakeCase(labelsSnakeCase),
		exporter.EnableFeatureFlag(s.featureFlags...),
		exporter.TaggingAPIConcurrency(tagConcurrency),
	}

	if cloudwatchConcurrency.PerAPILimitEnabled {
		options = append(options, exporter.CloudWatchPerAPILimitConcurrency(cloudwatchConcurrency.ListMetrics, cloudwatchConcurrency.GetMetricData, cloudwatchConcurrency.GetMetricStatistics))
	} else {
		options = append(options, exporter.CloudWatchAPIConcurrency(cloudwatchConcurrency.SingleLimit))
	}

	err := exporter.UpdateMetrics(
		ctx,
		logger,
		jobsCfg,
		newRegistry,
		cache,
		options...,
	)
	if err != nil {
		logger.Error("error updating metrics", "err", err)
	}

	s.registry.Store(newRegistry)
	logger.Debug("Metrics scraped")
}


================================================
FILE: docker-compose/README.md
================================================
## Setting up a local docker-compose environment

This folder contains a [docker-compose](./docker-compose.yaml) configuration file to start a local development environment. 
This includes:
- YACE, using as config file [yace-config.yaml](./yace-config.yaml)
- Prometheus, with a scraping configuration targeting YACE
- Grafana, wih no login required and the Prometheus datasource configured

Docker will mount the `~/.aws` directory in order to re-utilize the host's AWS credentials. For selecting which region
and AWS profile to use, fill in the `AWS_REGION` and `AWS_PROFILE` variables passed to the `docker-compose up` command,
as shown below.

```bash
# Build the YACE docker image
docker-compose build

# Start all docker-compose resource
AWS_REGION=us-east-1 AWS_PROFILE=sandbox docker-compose up -d 
```

After that, Prometheus will be exposed at [http://localhost:9090](http://localhost:9090), and Grafana in [http://localhost:3000](http://localhost:3000).


================================================
FILE: docker-compose/docker-compose.yaml
================================================
version: '3.8'

networks:
  monitoring:
    driver: bridge

volumes:
  prometheus_data: {}

services:
  grafana:
    image: grafana/grafana:9.4.3
    ports:
      - 3000:3000/tcp
    volumes:
      - ./grafana/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yml
    environment:
      # configure no-login required access
      GF_AUTH_ANONYMOUS_ORG_ROLE: "Admin"
      GF_AUTH_ANONYMOUS_ENABLED: "true"
      GF_AUTH_BASIC_ENABLED: "false"
    networks:
      - monitoring

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus.yaml:/etc/prometheus/prometheus.yaml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yaml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'
    ports:
      - "9090:9090"
    expose:
      - 9090
    networks:
      - monitoring

  yace:
    build:
      context: ../
      dockerfile: Dockerfile
    restart: always
    environment:
      AWS_REGION: ${AWS_REGION}
      AWS_PROFILE: ${AWS_PROFILE}
    expose:
      - 8080
    volumes:
      - ./yace-config.yaml:/tmp/config.yml
      - $HOME/.aws:/home/.aws:ro
    command:
      - -listen-address=:8080
      - -config.file=/tmp/config.yml
    networks:
      - monitoring


================================================
FILE: docker-compose/grafana/datasource.yaml
================================================
apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    orgId: 1
    url: http://prometheus:9090
    basicAuth: false
    isDefault: true
    editable: true


================================================
FILE: docker-compose/prometheus.yaml
================================================
global:
  scrape_interval: 1m
scrape_configs:
  - job_name: prometheus
    scrape_interval: 1m
    static_configs:
      - targets:
          - localhost:9090
  - job_name: yace
    static_configs:
      - targets:
          - yace:8080


================================================
FILE: docker-compose/yace-config.yaml
================================================
apiVersion: v1alpha1
sts-region: us-east-1
discovery:
  jobs:
    - type: AWS/ECS
      regions: [us-east-1]
      period: 300
      length: 300
      metrics:
        - name: CPUReservation
          statistics:
            - Average
        - name: MemoryReservation
          statistics:
            - Average
        - name: CPUUtilization
          statistics:
            - Average
        - name: MemoryUtilization
          statistics:
            - Average
    - type: AWS/EC2
      regions: [us-east-1]
      includeContextOnInfoMetrics: true
      metrics:
        - name: CPUUtilization
          statistics:
            - Average


================================================
FILE: docs/configuration.md
================================================
# Configuration

YACE has two configuration mechanisms:

- [command-line flags](#command-line-flags)
- [yaml configuration file](#yaml-configuration-file)

The command-line flags configure things which cannot change at runtime, such as the listen port for the HTTP server. The yaml file is used to configure scrape jobs and can be reloaded at runtime. The configuration file path is passed to YACE through the `-config.file` command line flag.

## Command-line flags

Command-line flags are used to configure settings of the exporter which cannot be updated at runtime.

All flags may be prefixed with either one hypen or two (i.e., both `-config.file` and `--config.file` are valid).

| Flag | Description | Default value |
| --- | --- | --- |
| `-listen-address` | Network address to listen to | `127.0.0.1:5000` |
| `-config.file` | Path to the configuration file | `config.yml` |
| `-log.format` | Output format of log messages. One of: [logfmt, json] | `json` |
| `-log.level` | Log at selected level. One of: [debug, info, warn, error] | `info` |
| `-fips` | Use FIPS compliant AWS API | `false` |
| `-cloudwatch-concurrency` | Maximum number of concurrent requests to CloudWatch API | `5` |
| `-cloudwatch-concurrency.per-api-limit-enabled` | Enables a concurrency limiter, that has a specific limit per CloudWatch API call. | `false` |
| `-cloudwatch-concurrency.list-metrics-limit` | Maximum number of concurrent requests to CloudWatch `ListMetrics` API. Only applicable if `per-api-limit-enabled` is `true`. | `5` |
| `-cloudwatch-concurrency.get-metric-data-limit` | Maximum number of concurrent requests to CloudWatch `GetMetricsData` API. Only applicable if `per-api-limit-enabled` is `true`. | `5` |
| `-cloudwatch-concurrency.get-metric-statistics-limit` | Maximum number of concurrent requests to CloudWatch `GetMetricStatistics` API. Only applicable if `per-api-limit-enabled` is `true`. | `5` |
| `-tag-concurrency` | Maximum number of concurrent requests to Resource Tagging API | `5` |
| `-scraping-interval` | Seconds to wait between scraping the AWS metrics | `300` |
| `-metrics-per-query` | Number of metrics made in a single GetMetricsData request | `500` |
| `-labels-snake-case`  | Output labels on metrics in snake case instead of camel case | `false` |
| `-profiling.enabled` | Enable the /debug/pprof endpoints for profiling | `false` |

## YAML configuration file

To specify which configuration file to load, pass the `-config.file` flag at the command line. The file is written in the YAML format, defined by the scheme below. Brackets indicate that a parameter is optional.

Below are the top level fields of the YAML configuration file:

```yaml
# Configuration file version. Must be set to "v1alpha1" currently.
apiVersion: v1alpha1

# STS regional endpoint (optional)
[ sts-region: <string>]

# Note that at least one of the following blocks must be defined.

# Configurations for jobs of type "auto-discovery"
discovery: <discovery_jobs_list_config>

# Configurations for jobs of type "static"
static:
  [ - <static_job_config> ... ]

# Configurations for jobs of type "custom namespace"
customNamespace:
  [ - <custom_namespace_job_config> ... ]
```

Note that while the `discovery`, `static` and `customNamespace` blocks are all optionals, at least one of them must be defined.

### `discovery_jobs_list_config`

The `discovery_jobs_list_config` block configures jobs of type "auto-discovery".

> Note: Only [tagged resources](https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html) are discovered.

```yaml
# List of tags per service to export to all metrics
[exportedTagsOnMetrics: <exported_tags_config> ]

# List of "auto-discovery" jobs
jobs:
  [ - <discovery_job_config> ... ]
```

### `discovery_job_config`

The `discovery_job_config` block specifies the details of a job of type "auto-discovery".

```yaml
# List of AWS regions
regions:
  [ - <string> ... ]

# Cloudwatch service alias ("alb", "ec2", etc) or namespace name ("AWS/EC2", "AWS/S3", etc)
type: <string>

#  List of IAM roles to assume (optional)
roles:
  [ - <role_config> ... ]

# List of Key/Value pairs to use for tag filtering (all must match). 
# The key is the AWS Tag key and is case-sensitive  
# The value will be treated as a regex
searchTags:
  [ - <search_tags_config> ... ]

# Custom tags to be added as a list of Key/Value pairs
customTags:
  [ - <custom_tags_config> ... ]

# List of metric dimensions to query. Before querying metric values, the total list of metrics will be filtered to only those that contain exactly this list of dimensions. An empty or undefined list results in all dimension combinations being included.
dimensionNameRequirements:
  [ - <string> ... ]

# Specifies how the current time is rounded before calculating start/end times for CloudWatch GetMetricData requests.
# This rounding is optimize performance of the CloudWatch request.
# This setting only makes sense to use if, for example, you specify a very long period (such as 1 day) but want your times rounded to a shorter time (such as 5 minutes). For example, a value of 300 will round the current time to the nearest 5 minutes. If not specified, the roundingPeriod defaults to the same value as shortest period in the job.
[ roundingPeriod: <int> ]

# Passes down the flag `--recently-active PT3H` to the CloudWatch API. This will only return metrics that have been active in the last 3 hours.
# This is useful for reducing the number of metrics returned by CloudWatch, which can be very large for some services. See AWS Cloudwatch API docs for [ListMetrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html) for more details.
[ recentlyActiveOnly: <boolean> ]

# Can be used to include contextual information (account_id, region, and customTags) on info metrics and cloudwatch metrics. This can be particularly 
# useful when cloudwatch metrics might not be present or when using info metrics to understand where your resources exist
[ includeContextOnInfoMetrics: <boolean> ]

# (optional) This is an experimental feature that can be used to enable enhanced metrics for specific services within this discovery job. It might be subject to changes in future releases.
enhancedMetrics:
    [ - <enhanced_metrics_config> ... ]

# List of statistic types, e.g. "Minimum", "Maximum", etc (General Setting for all metrics in this job)
statistics:
  [ - <string> ... ]

# Statistic period in seconds (General Setting for all metrics in this job)
[ period: <int> ]

# How far back to request data for in seconds (General Setting for all metrics in this job)
[ length: <int> ]

# If set it will request metrics up until `current_time - delay` (General Setting for all metrics in this job)
[ delay: <int> ]

# Return 0 value if Cloudwatch returns no metrics at all. By default `NaN` will be reported (General Setting for all metrics in this job)
[ nilToZero: <boolean> ]

# Export the metric with the original CloudWatch timestamp (General Setting for all metrics in this job)
[ addCloudwatchTimestamp: <boolean> ]

# Enables the inclusion of past metric data points from the CloudWatch response if available.
# This is useful when a metric is configured with a 60-second period and a 300-second duration, ensuring that all
# five data points are exposed at the metrics endpoint instead of only the latest one.
# Note: This option requires `addCloudwatchTimestamp` to be enabled.
# The metric destination must support out of order timestamps, see https://prometheus.io/docs/prometheus/latest/configuration/configuration/#tsdb
# (General Setting for all metrics in this job)
[ exportAllDataPoints: <boolean> ]

# List of metric definitions
metrics:
  [ - <metric_config> ... ]
```

Example config file:

```yaml
apiVersion: v1alpha1
sts-region: eu-west-1
discovery:
  exportedTagsOnMetrics:
    kafka:
      - Name
  jobs:
  - type: kafka
    regions:
      - eu-west-1
    searchTags:
      - key: env
        value: dev
    metrics:
      - name: BytesOutPerSec
        statistics:
        - Average
        period: 600
        length: 600
```

### `static_job_config`

The `static_job_config` block configures jobs of type "static".

```yaml
# Name of the job (required)
name: <string>

# CloudWatch namespace
namespace: <string>

# List of AWS regions
regions:
  [ - <string> ...]

# List of IAM roles to assume (optional)
roles:
  [ - <role_config> ... ]

# Custom tags to be added as a list of Key/Value pairs
customTags:
  [ - <custom_tags_config> ... ]

# CloudWatch metric dimensions as a list of Name/Value pairs
dimensions: [ <dimensions_config> ]

# List of metric definitions
metrics:
  [ - <metric_config> ... ]
```

Example config file:

```yaml
apiVersion: v1alpha1
sts-region: eu-west-1
static:
  - namespace: AWS/AutoScaling
    name: must_be_set
    regions:
      - eu-west-1
    dimensions:
     - name: AutoScalingGroupName
       value: MyGroup
    customTags:
      - key: CustomTag
        value: CustomValue
    metrics:
      - name: GroupInServiceInstances
        statistics:
        - Minimum
        period: 60
        length: 300
```

### `custom_namespace_job_config`

The `custom_namespace_job_config` block configures jobs of type "custom namespace".

```yaml
# Name of the job (required)
name: <string>

# CloudWatch namespace
namespace: <string>

# List of AWS regions
regions:
  [ - <string> ...]

#  List of IAM roles to assume (optional)
roles:
  [ - <role_config> ... ]

# Custom tags to be added as a list of Key/Value pairs
customTags:
  [ - <custom_tags_config> ... ]

# List of metric dimensions to query. Before querying metric values, the total list of metrics will be filtered to only those that contain exactly this list of dimensions. An empty or undefined list results in all dimension combinations being included.
dimensionNameRequirements:
  [ - <string> ... ]

# Specifies how the current time is rounded before calculating start/end times for CloudWatch GetMetricData requests.
# This rounding is optimize performance of the CloudWatch request.
# This setting only makes sense to use if, for example, you specify a very long period (such as 1 day) but want your times rounded to a shorter time (such as 5 minutes). For example, a value of 300 will round the current time to the nearest 5 minutes. If not specified, the roundingPeriod defaults to the same value as shortest period in the job.
[ roundingPeriod: <int> ]

# Passes down the flag `--recently-active PT3H` to the CloudWatch API. This will only return metrics that have been active in the last 3 hours.
# This is useful for reducing the number of metrics returned by CloudWatch, which can be very large for some services. See AWS Cloudwatch API docs for [ListMetrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html) for more details.
[ recentlyActiveOnly: <boolean> ]

# List of statistic types, e.g. "Minimum", "Maximum", etc (General Setting for all metrics in this job)
statistics:
  [ - <string> ... ]

# Statistic period in seconds (General Setting for all metrics in this job)
[ period: <int> ]

# How far back to request data for in seconds (General Setting for all metrics in this job)
[ length: <int> ]

# If set it will request metrics up until `current_time - delay` (General Setting for all metrics in this job)
[ delay: <int> ]

# Return 0 value if Cloudwatch returns no metrics at all. By default `NaN` will be reported (General Setting for all metrics in this job)
[ nilToZero: <boolean> ]

# Export the metric with the original CloudWatch timestamp (General Setting for all metrics in this job)
[ addCloudwatchTimestamp: <boolean> ]

# Enables the inclusion of past metric data points from the CloudWatch response if available.
# This is useful when a metric is configured with a 60-second period and a 300-second duration, ensuring that all
# five data points are exposed at the metrics endpoint instead of only the latest one.
# Note: This option requires `addCloudwatchTimestamp` to be enabled.
# The metric destination must support out of order timestamps, see https://prometheus.io/docs/prometheus/latest/configuration/configuration/#tsdb
# (General Setting for all metrics in this job)
[ exportAllDataPoints: <boolean> ]

# List of metric definitions
metrics:
  [ - <metric_config> ... ]
```

Example config file:

```yaml
apiVersion: v1alpha1
sts-region: eu-west-1
customNamespace:
  - name: customEC2Metrics
    namespace: CustomEC2Metrics
    regions:
      - us-east-1
    metrics:
      - name: cpu_usage_idle
        statistics:
          - Average
        period: 300
        length: 300
        nilToZero: true
      - name: disk_free
        statistics:
          - Average
        period: 300
        length: 300
        nilToZero: true
```

### `metric_config`

Some settings at the job level are overridden by settings at the metric level.
This allows for a specific setting to override a general setting.

```yaml
# CloudWatch metric name
name: <string>

# List of statistic types, e.g. "Minimum", "Maximum", etc. (Overrides job level setting)
statistics:
  [ - <string> ... ]

# Statistic period in seconds (Overrides job level setting)
[ period: <int> ]

# How far back to request data for in seconds (Overrides job level setting)
[ length: <int> ]

# If set it will request metrics up until `current_time - delay` (Overrides job level setting)
[ delay: <int> ]

# Return 0 value if Cloudwatch returns no metrics at all. By default `NaN` will be reported (Overrides job level setting)
[ nilToZero: <boolean> ]

# Export the metric with the original CloudWatch timestamp (Overrides job level setting)
[ addCloudwatchTimestamp: <boolean> ]

# Enables the inclusion of past metric data points from the CloudWatch response if available.
# This is useful when a metric is configured with a 60-second period and a 300-second duration, ensuring that all
# five data points are exposed at the metrics endpoint instead of only the latest one.
# Note: This option requires `addCloudwatchTimestamp` to be enabled.
# The metric destination must support out of order timestamps, see https://prometheus.io/docs/prometheus/latest/configuration/configuration/#tsdb
# (General Setting for all metrics in this job)
[ exportAllDataPoints: <boolean> ]
```

Notes:
- Available statistics: `Maximum`, `Minimum`, `Sum`, `SampleCount`, `Average`, `pXX` (e.g. `p90`).

- Watch out using `addCloudwatchTimestamp` for sparse metrics, e.g from S3, since Prometheus won't scrape metrics containing timestamps older than 2-3 hours. Also the same applies when enabling `exportAllDataPoints` in any metric.

### `exported_tags_config`

This is an example of the `exported_tags_config` block:

```yaml
exportedTagsOnMetrics:
  ebs:
    - VolumeId
  kafka:
    - Name
```

### `role_config`

This is an example of the `role_config` block:

```yaml
roles:
  - roleArn: "arn:aws:iam::123456789012:role/Prometheus"
    externalId: "shared-external-identifier" # optional
```

### `search_tags_config`

This is an example of the `search_tags_config` block:

```yaml
searchTags:
  - key: env
    value: production
```

### `custom_tags_config`

This is an example of the `custom_tags_config` block:

```yaml
customTags:
  - key: CustomTag
    value: CustomValue
```

### `dimensions_config`

This is an example of the `dimensions_config` block:

```yaml
dimensions:
  - name: AutoScalingGroupName
    value: MyGroup
```

### `enhanced_metrics_config`

The `enhanced_metrics_config` block allows enabling enhanced metrics for specific metrics within a discovery job.

Currently supported enhanced metrics are:

- AWS/Lambda (Timeout) - The maximum execution duration permitted for the function before termination.
- AWS/DynamoDB (ItemCount) - The count of items in the table, updated approximately every six hours; may not reflect recent changes.
- AWS/RDS (AllocatedStorage) - The storage capacity in bytes allocated for the DB instance.
- AWS/ElastiCache (NumCacheNodes) - The count of cache nodes in the cluster; must be 1 for Valkey or Redis OSS clusters, or between 1 and 40 for Memcached clusters.

```yaml
enhancedMetrics:
    - name: ItemCount
```

================================================
FILE: docs/embedding.md
================================================
# Embedding YACE in your application

It is possible to embed YACE into an external Go application. This mode might be useful to you if you would like to scrape on demand or run in a stateless manner.

See [`exporter.UpdateMetrics()`](https://pkg.go.dev/github.com/prometheus-community/yet-another-cloudwatch-exporter@v0.50.0/pkg#UpdateMetrics) for the documentation of the exporter entrypoint.

Applications embedding YACE:
- [Grafana Agent](https://github.com/grafana/agent/tree/release-v0.33/pkg/integrations/cloudwatch_exporter)


================================================
FILE: docs/feature_flags.md
================================================
# Feature flags

List of features or changes that are disabled by default since they are breaking changes or are considered experimental. Their behavior can change in future releases which will be communicated via the release changelog.

You can enable them using the `-enable-feature` flag with a comma separated list of features. They may be enabled by default in future versions.

## Always return info metrics

`-enable-feature=always-return-info-metrics`

Return info metrics even if there are no CloudWatch metrics for the resource. This is useful if you want to get a complete picture of your estate, for example if you have some resources which have not yet been used.


================================================
FILE: docs/installation.md
================================================
# Installing and running YACE

There are various way to run YACE.

## Binaries

See the [Releases](https://github.com/prometheus-community/yet-another-cloudwatch-exporter/releases) page to download binaries for various OS and arch.

## Docker

Docker images are available on GitHub Container Registry [here](https://github.com/prometheus-community/yet-another-cloudwatch-exporter/pkgs/container/yet-another-cloudwatch-exporter).

The image name is `quay.io/prometheuscommunity/yet-another-cloudwatch-exporter` and we support tags of the form `vX.Y.Z`.

To pull and run the image locally use:

```shell
docker run -d --rm \
  -v $PWD/credentials:/home/.aws/credentials \
  -v $PWD/config.yml:/tmp/config.yml \
  -p 5000:5000 \
  --name yace quay.io/prometheuscommunity/yet-another-cloudwatch-exporter:latest
```

Do not forget the `v` prefix in the image version tag.

## Docker compose

See the [docker-compose directory](../docker-compose/README.md).

## Kubernetes

### Install with HELM

The official [HELM chart](https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus-yet-another-cloudwatch-exporter) is the recommended way to install YACE in a Kubernetes cluster.

### Install with manifests

Example:

```yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: yace
data:
  config.yml: |-
    ---
    # Start of config file
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: yace
spec:
  replicas: 1
  selector:
    matchLabels:
      name: yace
  template:
    metadata:
      labels:
        name: yace
    spec:
      containers:
      - name: yace
        image: quay.io/prometheuscommunity/yet-another-cloudwatch-exporter:vX.Y.Z # release version as tag - Do not forget the version 'v'
        imagePullPolicy: IfNotPresent
        args:
          - "--config.file=/tmp/config.yml"
        ports:
        - name: app
          containerPort: 5000
        volumeMounts:
        - name: config-volume
          mountPath: /tmp
      volumes:
      - name: config-volume
        configMap:
          name: yace
```


================================================
FILE: examples/alb.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/ApplicationELB
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: HealthyHostCount
          statistics: [Sum]
        - name: UnHealthyHostCount
          statistics: [Sum]
        - name: RequestCount
          statistics: [Average]
        - name: TargetResponseTime
          statistics: [Average]
        - name: ActiveConnectionCount
          statistics: [Sum]
        - name: NewConnectionCount
          statistics: [Sum]
        - name: RejectedConnectionCount
          statistics: [Sum]
        - name: TargetConnectionErrorCount
          statistics: [Sum]
        - name: IPv6RequestCount
          statistics: [Sum]
        - name: RequestCountPerTarget
          statistics: [Sum]
        - name: NonStickyRequestCount
          statistics: [Sum]
        - name: HTTPCode_Target_2XX_Count
          statistics: [Sum]
        - name: HTTPCode_Target_3XX_Count
          statistics: [Sum]
        - name: HTTPCode_Target_4XX_Count
          statistics: [Sum]
        - name: HTTPCode_Target_5XX_Count
          statistics: [Sum]
        - name: HTTPCode_ELB_3XX_Count
          statistics: [Sum]
        - name: HTTPCode_ELB_4XX_Count
          statistics: [Sum]
        - name: HTTPCode_ELB_5XX_Count
          statistics: [Sum]
        - name: ProcessedBytes
          statistics: [Sum]
        - name: IPv6ProcessedBytes
          statistics: [Sum]
        - name: ConsumedLCUs
          statistics: [Average]
        - name: ClientTLSNegotiationErrorCount
          statistics: [Sum]
        - name: TargetTLSNegotiationErrorCount
          statistics: [Sum]
        - name: RuleEvaluations
          statistics: [Sum]


================================================
FILE: examples/apigw.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/ApiGateway
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: Latency
          statistics: [Average, Maximum, p95, p99]
        - name: Count
          statistics: [SampleCount, Sum]
        - name: 4xx
          statistics: [Sum]
        - name: 5xx
          statistics: [Sum]


================================================
FILE: examples/apprunner.yaml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - regions:
        - us-east-1
      period: 300
      length: 300
      type: AWS/AppRunner
      metrics:
        - name: MemoryUtilization
          statistics:
            - Average
            - Maximum
        - name: CPUUtilization
          statistics:
            - Average
            - Maximum
        - name: 2xxStatusResponses
          statistics:
            - Sum
        - name: Requests
          statistics:
            - Sum
        - name: RequestLatency
          statistics:
            - Average
        - name: ActiveInstances
          statistics:
            - Maximum
        - name: 4xxStatusResponses
          statistics:
            - Sum
        - name: Concurrency
          statistics:
            - Maximum


================================================
FILE: examples/appstream.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/AppStream
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: ActualCapacity
          statistics: [Average]
        - name: AvailableCapacity
          statistics: [Average]
        - name: CapacityUtilization
          statistics: [Average]
        - name: DesiredCapacity
          statistics: [Average]
        - name: InUseCapacity
          statistics: [Average]
        - name: PendingCapacity
          statistics: [Average]
        - name: RunningCapacity
          statistics: [Average]
        - name: InsufficientCapacityError
          statistics: [Average]


================================================
FILE: examples/backup.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/Backup
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: NumberOfBackupJobsCompleted
          statistics: [Average]
        - name: NumberOfBackupJobsCreated
          statistics: [Average]
        - name: NumberOfBackupJobsPending
          statistics: [Average]
        - name: NumberOfBackupJobsRunning
          statistics: [Average]
        - name: NumberOfBackupJobsAborted
          statistics: [Average]
        - name: NumberOfBackupJobsCompleted
          statistics: [Average]
        - name: NumberOfBackupJobsFailed
          statistics: [Average]
        - name: NumberOfBackupJobsExpired
          statistics: [Average]


================================================
FILE: examples/cwagent.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: CWAgent
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: mem_used_percent
          statistics: [Average]
        - name: disk_used_percent
          statistics: [Average]


================================================
FILE: examples/ds.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/DirectoryService
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: "Bytes Sent/sec"
          statistics: [Average]
        - name: "% Processor Time"
          statistics: [Average]
        - name: "DS Directory Searches/Sec"
          statistics: [Average]
        - name: "Database Cache % Hit"
          statistics: [Average]
        - name: "% Free Space"
          statistics: [Sum]


================================================
FILE: examples/dx.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/DX
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: ConnectionState
          statistics: [Maximum]
        - name: VirtualInterfaceBpsIngress
          statistics: [Average]
        - name: VirtualInterfaceBpsEgress
          statistics: [Average]
        - name: VirtualInterfacePpsIngress
          statistics: [Average]
        - name: VirtualInterfacePpsEgress
          statistics: [Average]
        - name: ConnectionErrorCount
          statistics: [Minimum, Maximum, Sum]


================================================
FILE: examples/ebs.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/EBS
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: VolumeReadBytes
          statistics: [Sum]
        - name: VolumeWriteBytes
          statistics: [Sum]
        - name: VolumeReadOps
          statistics: [Average]
        - name: VolumeWriteOps
          statistics: [Average]
        - name: VolumeTotalReadTime
          statistics: [Average]
        - name: VolumeTotalWriteTime
          statistics: [Average]
        - name: VolumeIdleTime
          statistics: [Average]
        - name: VolumeQueueLength
          statistics: [Average]
        - name: VolumeThroughputPercentage
          statistics: [Average]
        - name: VolumeConsumedReadWriteOps
          statistics: [Average]
        - name: BurstBalance
          statistics: [Minimum]


================================================
FILE: examples/ec.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/ElastiCache
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: CPUUtilization
          statistics: [Average]
        - name: FreeableMemory
          statistics: [Average]
        - name: NetworkBytesIn
          statistics: [Average]
        - name: NetworkBytesOut
          statistics: [Average]
        - name: NetworkPacketsIn
          statistics: [Average]
        - name: NetworkPacketsOut
          statistics: [Average]
        - name: SwapUsage
          statistics: [Average]
        - name: CPUCreditUsage
          statistics: [Average]


================================================
FILE: examples/ec2.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/EC2
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: CPUUtilization
          statistics: [Average]
        - name: NetworkIn
          statistics: [Average, Sum]
        - name: NetworkOut
          statistics: [Average, Sum]
        - name: NetworkPacketsIn
          statistics: [Sum]
        - name: NetworkPacketsOut
          statistics: [Sum]
        - name: DiskReadBytes
          statistics: [Sum]
        - name: DiskWriteBytes
          statistics: [Sum]
        - name: DiskReadOps
          statistics: [Sum]
        - name: DiskWriteOps
          statistics: [Sum]
        - name: StatusCheckFailed
          statistics: [Sum]
        - name: StatusCheckFailed_Instance
          statistics: [Sum]
        - name: StatusCheckFailed_System
          statistics: [Sum]


================================================
FILE: examples/ecs.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/ECS
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: CPUReservation
          statistics: [Average, Maximum]
        - name: MemoryReservation
          statistics: [Average, Maximum]
        - name: CPUUtilization
          statistics: [Average, Maximum]
        - name: MemoryUtilization
          statistics: [Average, Maximum]


================================================
FILE: examples/elb.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/ELB
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: BackendConnectionErrors
          statistics: [Sum]
        - name: HTTPCode_Backend_2XX
          statistics: [Sum]
        - name: HTTPCode_Backend_3XX
          statistics: [Sum]
        - name: HTTPCode_Backend_4XX
          statistics: [Sum]
        - name: HTTPCode_Backend_5XX
          statistics: [Sum]
        - name: HTTPCode_ELB_4XX
          statistics: [Sum]
        - name: HTTPCode_ELB_5XX
          statistics: [Sum]
        - name: RequestCount
          statistics: [Sum]
        - name: Latency
          statistics: [Average]
        - name: SurgeQueueLength
          statistics: [Average]
        - name: SpilloverCount
          statistics: [Sum]
        - name: HealthyHostCount
          statistics: [Minimum, Maximum]
        - name: UnHealthyHostCount
          statistics: [Minimum, Maximum]


================================================
FILE: examples/es.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/ES
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: CPUUtilization
          statistics: [Average]
        - name: FreeStorageSpace
          statistics: [Sum]
        - name: ClusterStatus.green
          statistics: [Maximum]
        - name: ClusterStatus.yellow
          statistics: [Maximum]
        - name: ClusterStatus.red
          statistics: [Maximum]
        - name: Shards.active
          statistics: [Sum]
        - name: Shards.unassigned
          statistics: [Sum]
        - name: Shards.delayedUnassigned
          statistics: [Sum]
        - name: Shards.activePrimary
          statistics: [Sum]
        - name: Shards.initializing
          statistics: [Sum]
        - name: Shards.initializing
          statistics: [Sum]
        - name: Shards.relocating
          statistics: [Sum]
        - name: Nodes
          statistics: [Maximum]
        - name: SearchableDocuments
          statistics: [Maximum]
        - name: DeletedDocuments
          statistics: [Maximum]


================================================
FILE: examples/historic-data.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/SQS
      regions:
        - us-east-1
      period: 60
      length: 300
      addCloudwatchTimestamp: true
      exportAllDataPoints: true
      metrics:
        - name: NumberOfMessagesSent
          statistics: [Sum]
        - name: NumberOfMessagesReceived
          statistics: [Sum]
        - name: NumberOfMessagesDeleted
          statistics: [Sum]
        - name: ApproximateAgeOfOldestMessage
          statistics: [Average]
        - name: NumberOfEmptyReceives
          statistics: [Sum]
        - name: SentMessageSize
          statistics: [Average]
        - name: ApproximateNumberOfMessagesNotVisible
          statistics: [Sum]
        - name: ApproximateNumberOfMessagesDelayed
          statistics: [Sum]
        - name: ApproximateNumberOfMessagesVisible
          statistics: [Sum]


================================================
FILE: examples/kafka.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/Kafka
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: BytesInPerSec
          statistics: [Average]
        - name: BytesOutPerSec
          statistics: [Average]
        - name: RootDiskUsed
          statistics: [Average]
        - name: KafkaDataLogsDiskUsed
          statistics: [Average]
        - name: KafkaAppLogsDiskUsed
          statistics: [Average]
        - name: MemoryFree
          statistics: [Average]
        - name: MemoryUsed
          statistics: [Average]
        - name: NetworkRxPackets
          statistics: [Average]
        - name: NetworkTxPackets
          statistics: [Average]
        - name: SwapFree
          statistics: [Average]
        - name: SwapUsed
          statistics: [Average]
        - name: GlobalTopicCount
          statistics: [Maximum]
        - name: GlobalPartitionCount
          statistics: [Maximum]
        - name: CpuUser
          statistics: [Average]
        - name: CpuSystem
          statistics: [Average]
        - name: CpuIdle
          statistics: [Average]


================================================
FILE: examples/kinesis.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/Kinesis
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: PutRecord.Latency
          statistics: [Average]
        - name: PutRecord.Success
          statistics: [Sum]
        - name: PutRecord.Bytes
          statistics: [Sum]
        - name: PutRecords.Latency
          statistics: [Average]
        - name: PutRecords.Records
          statistics: [Sum]
        - name: PutRecords.Success
          statistics: [Sum]
        - name: PutRecords.Bytes
          statistics: [Sum]
        - name: GetRecords.Latency
          statistics: [Average]
        - name: GetRecords.Records
          statistics: [Sum]
        - name: GetRecords.Success
          statistics: [Sum]
        - name: GetRecords.Bytes
          statistics: [Sum]
        - name: GetRecords.IteratorAgeMilliseconds
          statistics: [Average]
        - name: IncomingBytes
          statistics: [Sum]
        - name: IncomingRecords
          statistics: [Sum]
        - name: OutgoingBytes
          statistics: [Sum]
        - name: OutgoingRecords
          statistics: [Sum]
        - name: WriteProvisionedThroughputExceeded
          statistics: [Average]
        - name: ReadProvisionedThroughputExceeded
          statistics: [Average]


================================================
FILE: examples/kms.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/KMS
      regions:
        - us-east-1
      period: 300
      metrics:
        - name: SecondsUntilKeyMaterialExpiration
          statistics: [Maximum, Minimum]


================================================
FILE: examples/lambda.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/Lambda
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: Invocations
          statistics: [Sum]
        - name: Errors
          statistics: [Sum]
        - name: Throttles
          statistics: [Sum]
        - name: Duration
          statistics: [Average, Maximum, Minimum, p90]


================================================
FILE: examples/lambda_edge.yml
================================================
  # We can't configure discovery job for edge lambda function but static works.,he region is always us-east-1.
  # Other regions can be added in use as edge locations
apiVersion: v1alpha1
static:
  - name: us-east-1.<edge_lambda_function_name>
    namespace: AWS/Lambda
    regions:
      - eu-central-1
      - us-east-1
      - us-west-2
      - ap-southeast-1
    period: 600
    length: 600
    metrics:
      - name: Invocations
        statistics: [Sum]
      - name: Errors
        statistics: [Sum]
      - name: Throttles
        statistics: [Sum]
      - name: Duration
        statistics: [Average, Maximum, Minimum, p90]


================================================
FILE: examples/logs.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/Logs
      regions:
        - us-east-1
      period: 60
      length: 60
      delay: 120
      statistics: [Sum]
      metrics:
        - name: DeliveryErrors
        - name: DeliveryThrottling
        - name: EMFParsingErrors
        - name: EMFValidationErrors
        - name: ForwardedBytes
        - name: ForwardedLogEvents
        - name: IncomingBytes
        - name: IncomingLogEvents


================================================
FILE: examples/mq.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/AmazonMQ
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: NetworkOut
          statistics: [Minimum, Maximum, Average]
        - name: NetworkIn
          statistics: [Minimum, Maximum, Average]
        - name: QueueSize
          statistics: [Minimum, Maximum, Average]
        - name: ConsumerCount
          statistics: [Minimum, Maximum, Average]
        - name: ProducerCount
          statistics: [Minimum, Maximum, Average]
        - name: EnqueueCount
          statistics: [Minimum, Maximum, Average]
        - name: DequeueCount
          statistics: [Minimum, Maximum, Average]
        - name: MemoryUsage
          statistics: [Minimum, Maximum, Average]
        - name: CpuUtilization
          statistics: [Minimum, Maximum, Average]


================================================
FILE: examples/networkmanager.yml
================================================
# https://docs.aws.amazon.com/network-manager/latest/cloudwan/cloudwan-metrics.html
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/Network Manager
      regions:
        - us-west-2
      period: 60
      length: 300
      metrics:
        - name: BytesDropCountBlackhole
          statistics: [Sum]
        - name: BytesDropCountNoRoute
          statistics: [Sum]
        - name: BytesIn
          statistics: [Sum]
        - name: BytesOut
          statistics: [Sum]
        - name: PacketsDropCountBlackhole
          statistics: [Sum]
        - name: PacketsDropCountNoRoute
          statistics: [Sum]
        - name: PacketDropCountTTLExpired
          statistics: [Sum]
        - name: PacketsIn
          statistics: [Sum]
        - name: PacketsOut
          statistics: [Sum]


================================================
FILE: examples/ngw.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/NATGateway
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: ActiveConnectionCount
          statistics: [Average, Minimum, Maximum, Sum]
        - name: BytesInFromDestination
          statistics: [Average, Minimum, Maximum, Sum]
        - name: BytesInFromSource
          statistics: [Average, Minimum, Maximum, Sum]
        - name: BytesOutToDestination
          statistics: [Average, Minimum, Maximum, Sum]
        - name: BytesOutToSource
          statistics: [Average, Minimum, Maximum, Sum]
        - name: ConnectionAttemptCount
          statistics: [Average, Minimum, Maximum, Sum]
        - name: ConnectionEstablishedCount
          statistics: [Average, Minimum, Maximum, Sum]
        - name: ErrorPortAllocation
          statistics: [Average, Minimum, Maximum, Sum]
        - name: IdleTimeoutCount
          statistics: [Average, Minimum, Maximum, Sum]
        - name: PacketsDropCount
          statistics: [Average, Minimum, Maximum, Sum]
        - name: PacketsInFromDestination
          statistics: [Average, Minimum, Maximum, Sum]
        - name: PacketsInFromSource
          statistics: [Average, Minimum, Maximum, Sum]
        - name: PacketsOutToDestination
          statistics: [Average, Minimum, Maximum, Sum]
        - name: PacketsOutToSource
          statistics: [Average, Minimum, Maximum, Sum]


================================================
FILE: examples/nlb.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/NetworkELB
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: ActiveFlowCount
          statistics: [Average, Minimum, Maximum]
        - name: ActiveFlowCount_TLS
          statistics: [Average, Minimum, Maximum]
        - name: ActiveFlowCount_UDP
          statistics: [Average, Minimum, Maximum]
        - name: PortAllocationErrorCount
          statistics: [Minimum, Maximum, Sum]
        - name: ProcessedBytes
          statistics: [Minimum, Maximum, Sum]
        - name: ProcessedPackets
          statistics: [Minimum, Maximum, Sum]


================================================
FILE: examples/private-link-endpoints.yaml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/PrivateLinkEndpoints
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: ActiveConnections
          statistics: [Average]
        - name: NewConnections
          statistics: [Average, Sum]
        - name: PacketsDropped
          statistics: [Average, Sum]
        - name: BytesProcessed
          statistics: [Sum]


================================================
FILE: examples/private-link-services.yaml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/PrivateLinkServices
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: ActiveConnections
          statistics: [Average]
        - name: NewConnections
          statistics: [Average, Sum]
        - name: PacketsDropped
          statistics: [Average, Sum]
        - name: BytesProcessed
          statistics: [Sum]


================================================
FILE: examples/qldb.yml
================================================
apiVersion: v1alpha1
discovery:
  exportedTagsOnMetrics:
    AWS/QLDB:
      - Name
  jobs:
    - type: AWS/QLDB
      regions:
        - us-east-2
      period: 300
      length: 300
      metrics:
        - name: JournalStorage
          statistics:
            - Average
        - name: IndexedStorage
          statistics:
            - Average
        - name: ReadIOs
          statistics:
            - Sum
        - name: WriteIOs
          statistics:
            - Sum
        - name: CommandLatency
          statistics:
            - Average
        - name: OccConflictExceptions
          statistics:
            - Sum
        - name: Session4xxExceptions
          statistics:
            - Sum
        - name: Session5xxExceptions
          statistics:
            - Sum
        - name: SessionRateExceededExceptions
          statistics:
            - Sum


================================================
FILE: examples/quicksight.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/QuickSight
      regions:
        - eu-west-2
      period: 30000
      length: 30000
      metrics:
        - name: IngestionErrorCount
          statistics: [Sum]
        - name: IngestionRowCount
          statistics: [Sum]
        - name: IngestionInvocationCount
          statistics: [Sum]


================================================
FILE: examples/rds.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/RDS
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: CPUUtilization
          statistics: [Maximum]
        - name: DatabaseConnections
          statistics: [Sum]
        - name: FreeableMemory
          statistics: [Average]
        - name: FreeStorageSpace
          statistics: [Average]
        - name: ReadThroughput
          statistics: [Average]
        - name: WriteThroughput
          statistics: [Average]
        - name: ReadLatency
          statistics: [Maximum]
        - name: WriteLatency
          statistics: [Maximum]
        - name: ReadIOPS
          statistics: [Average]
        - name: WriteIOPS
          statistics: [Average]


================================================
FILE: examples/redshift-serverless.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/Redshift-Serverless
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: DatabaseConnections
          statistics: [Average]
        - name: ComputeCapacity
          statistics: [Average]
        - name: QueryRuntimeBreakdown
          statistics: [Average]
        - name: QueriesRunning
          statistics: [Average]
        - name: QueriesQueued
          statistics: [Average]
        - name: QueryDuration
          statistics: [Average]


================================================
FILE: examples/s3.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/S3
      regions:
        - us-east-1
      period: 86400
      length: 86400
      metrics:
        - name: NumberOfObjects
          statistics: [Average]
        - name: BucketSizeBytes
          statistics: [Average]


================================================
FILE: examples/ses.yaml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/SES
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: Send
          statistics: [Sum]
        - name: Delivery
          statistics: [Sum]
        - name: Bounce
          statistics: [Sum]
        - name: Reputation.ComplaintRate
          statistics: [Sum]
        - name: Reputation.BounceRate
          statistics: [Sum]


================================================
FILE: examples/sns.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/SNS
      regions:
        - us-east-1
      period: 300
      length: 300
      metrics:
        - name: NumberOfMessagesPublished
          statistics: [Sum]
        - name: NumberOfNotificationsDelivered
          statistics: [Sum]
        - name: NumberOfNotificationsFailed
          statistics: [Sum]
        - name: NumberOfNotificationsFilteredOut
          statistics: [Sum]
        - name: PublishSize
          statistics: [Average]


================================================
FILE: examples/sqs.yml
================================================
apiVersion: v1alpha1
discovery:
  jobs:
    - type: AWS/SQS
      regions:
        - us-east-1
      period: 60
      length: 60
      metrics:
        - name: NumberOfMessagesSent
          statistics: [Sum]
        - name: NumberOfMessagesReceived
          statistics: [Sum]
        - name: NumberOfMessagesDeleted
          statistics: [Sum]
        - name: ApproximateAgeOfOldestMessage
          statistics: [Average]
        - name: NumberOfEmptyReceives
          statistics: [Sum]
        - name: SentMessageSize
          statistics: [Average]
        - name: ApproximateNumberOfMessagesNotVisible
          statistics: [Sum]
        - name: ApproximateNumberOfMessagesDelayed
          statistics: [Sum]
        - name: ApproximateNumberOfMessagesVisible
          statistics: [Sum]


========================================
Download .txt
gitextract_8d8x638_/

├── .dockerignore
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   └── feature.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── container_description.yml
│       └── golangci-lint.yml
├── .gitignore
├── .golangci.yml
├── .promu.yml
├── .yamllint
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTE.md
├── Dockerfile
├── LICENSE
├── MAINTAINERS.md
├── Makefile
├── Makefile.common
├── NOTICE
├── README.md
├── SECURITY.md
├── VERSION
├── cmd/
│   └── yace/
│       ├── main.go
│       ├── main_test.go
│       └── scraper.go
├── docker-compose/
│   ├── README.md
│   ├── docker-compose.yaml
│   ├── grafana/
│   │   └── datasource.yaml
│   ├── prometheus.yaml
│   └── yace-config.yaml
├── docs/
│   ├── configuration.md
│   ├── embedding.md
│   ├── feature_flags.md
│   └── installation.md
├── examples/
│   ├── alb.yml
│   ├── apigw.yml
│   ├── apprunner.yaml
│   ├── appstream.yml
│   ├── backup.yml
│   ├── cwagent.yml
│   ├── ds.yml
│   ├── dx.yml
│   ├── ebs.yml
│   ├── ec.yml
│   ├── ec2.yml
│   ├── ecs.yml
│   ├── elb.yml
│   ├── es.yml
│   ├── historic-data.yml
│   ├── kafka.yml
│   ├── kinesis.yml
│   ├── kms.yml
│   ├── lambda.yml
│   ├── lambda_edge.yml
│   ├── logs.yml
│   ├── mq.yml
│   ├── networkmanager.yml
│   ├── ngw.yml
│   ├── nlb.yml
│   ├── private-link-endpoints.yaml
│   ├── private-link-services.yaml
│   ├── qldb.yml
│   ├── quicksight.yml
│   ├── rds.yml
│   ├── redshift-serverless.yml
│   ├── s3.yml
│   ├── ses.yaml
│   ├── sns.yml
│   ├── sqs.yml
│   ├── usage.yml
│   └── vpn.yml
├── go.mod
├── go.sum
├── mixin/
│   ├── README.md
│   ├── config.libsonnet
│   ├── dashboards/
│   │   ├── all.libsonnet
│   │   ├── common.libsonnet
│   │   ├── ebs.libsonnet
│   │   ├── ec2.libsonnet
│   │   ├── lambda.libsonnet
│   │   ├── rds.libsonnet
│   │   └── s3.libsonnet
│   ├── jsonnetfile.json
│   ├── jsonnetfile.lock.json
│   ├── mixin.libsonnet
│   └── util.libsonnet
└── pkg/
    ├── clients/
    │   ├── README.md
    │   ├── account/
    │   │   └── client.go
    │   ├── cloudwatch/
    │   │   ├── client.go
    │   │   ├── client_test.go
    │   │   ├── concurrency_client.go
    │   │   └── input.go
    │   ├── factory.go
    │   ├── factory_test.go
    │   └── tagging/
    │       ├── client.go
    │       ├── concurrency_client.go
    │       ├── filters.go
    │       └── filters_test.go
    ├── config/
    │   ├── config.go
    │   ├── config_test.go
    │   ├── feature_flags.go
    │   ├── feature_flags_test.go
    │   ├── services.go
    │   ├── services_test.go
    │   └── testdata/
    │       ├── config_test.yml
    │       ├── custom_namespace.ok.yml
    │       ├── custom_namespace_without_name.bad.yml
    │       ├── custom_namespace_without_namespace.bad.yml
    │       ├── custom_namespace_without_region.bad.yml
    │       ├── discovery_job_exported_tags_alias.bad.yml
    │       ├── discovery_job_exported_tags_mismatch.bad.yml
    │       ├── discovery_job_type_alias.bad.yml
    │       ├── discovery_job_type_unknown.bad.yml
    │       ├── empty_rolearn.ok.yml
    │       ├── externalid_with_empty_rolearn.bad.yml
    │       ├── externalid_without_rolearn.bad.yml
    │       ├── multiple_roles.ok.yml
    │       ├── sts_region.ok.yml
    │       └── unknown_version.bad.yml
    ├── exporter.go
    ├── exporter_enhancedmetrics_test.go
    ├── exporter_test.go
    ├── internal/
    │   └── enhancedmetrics/
    │       ├── config/
    │       │   └── provider.go
    │       ├── registry.go
    │       ├── registry_test.go
    │       ├── service/
    │       │   ├── dynamodb/
    │       │   │   ├── client.go
    │       │   │   ├── client_test.go
    │       │   │   ├── service.go
    │       │   │   └── service_test.go
    │       │   ├── elasticache/
    │       │   │   ├── client.go
    │       │   │   ├── client_test.go
    │       │   │   ├── service.go
    │       │   │   └── service_test.go
    │       │   ├── lambda/
    │       │   │   ├── client.go
    │       │   │   ├── client_test.go
    │       │   │   ├── service.go
    │       │   │   └── service_test.go
    │       │   ├── rds/
    │       │   │   ├── client.go
    │       │   │   ├── client_test.go
    │       │   │   ├── service.go
    │       │   │   └── service_test.go
    │       │   └── services.go
    │       ├── service.go
    │       └── service_test.go
    ├── job/
    │   ├── cloudwatchrunner/
    │   │   ├── customnamespace.go
    │   │   ├── discovery.go
    │   │   └── runner.go
    │   ├── custom.go
    │   ├── discovery.go
    │   ├── discovery_test.go
    │   ├── getmetricdata/
    │   │   ├── compact.go
    │   │   ├── compact_test.go
    │   │   ├── iterator.go
    │   │   ├── iterator_test.go
    │   │   ├── processor.go
    │   │   ├── processor_test.go
    │   │   ├── windowcalculator.go
    │   │   └── windowcalculator_test.go
    │   ├── listmetrics/
    │   │   └── processor.go
    │   ├── maxdimassociator/
    │   │   ├── associator.go
    │   │   ├── associator_api_gateway_test.go
    │   │   ├── associator_client_vpn_test.go
    │   │   ├── associator_ddosprotection_test.go
    │   │   ├── associator_directoryservice_test.go
    │   │   ├── associator_dx_test.go
    │   │   ├── associator_ec2_test.go
    │   │   ├── associator_ec_test.go
    │   │   ├── associator_ecs_test.go
    │   │   ├── associator_event_roles_test.go
    │   │   ├── associator_globalaccelerator_test.go
    │   │   ├── associator_gwlb_test.go
    │   │   ├── associator_ipam_test.go
    │   │   ├── associator_kms_test.go
    │   │   ├── associator_lambda_test.go
    │   │   ├── associator_logging_test.go
    │   │   ├── associator_logs_test.go
    │   │   ├── associator_mediaconvert_test.go
    │   │   ├── associator_memorydb_test.go
    │   │   ├── associator_mq_test.go
    │   │   ├── associator_qldb_test.go
    │   │   ├── associator_redshift_serverless_test.go
    │   │   ├── associator_sagemaker_endpoint_test.go
    │   │   ├── associator_sagemaker_inf_component_test.go
    │   │   ├── associator_sagemaker_inf_rec_test.go
    │   │   ├── associator_sagemaker_pipeline_test.go
    │   │   ├── associator_sagemaker_processing_test.go
    │   │   ├── associator_sagemaker_test.go
    │   │   ├── associator_sagemaker_training_test.go
    │   │   └── associator_sagemaker_transform_test.go
    │   ├── resourcemetadata/
    │   │   └── resource.go
    │   ├── scrape.go
    │   ├── scraper.go
    │   ├── scraper_test.go
    │   └── static.go
    ├── model/
    │   ├── model.go
    │   └── model_test.go
    └── promutil/
        ├── migrate.go
        ├── migrate_test.go
        ├── prometheus.go
        └── prometheus_test.go
Download .txt
SYMBOL INDEX (584 symbols across 101 files)

FILE: cmd/yace/main.go
  constant enableFeatureFlag (line 38) | enableFeatureFlag = "enable-feature"
  constant htmlVersion (line 39) | htmlVersion       = `<html>
  constant htmlPprof (line 48) | htmlPprof = `<p><a href="/debug/pprof">Pprof</a><p>`
  constant defaultLogLevel (line 54) | defaultLogLevel  = "info"
  constant defaultLogFormat (line 55) | defaultLogFormat = "json"
  function main (line 74) | func main() {
  function NewYACEApp (line 89) | func NewYACEApp() *cli.App {
  function startScraper (line 250) | func startScraper(c *cli.Context) error {
  function newLogger (line 335) | func newLogger(format, level string) *slog.Logger {

FILE: cmd/yace/main_test.go
  function TestYACEApp_FeatureFlagsParsedCorrectly (line 22) | func TestYACEApp_FeatureFlagsParsedCorrectly(t *testing.T) {

FILE: cmd/yace/scraper.go
  type Scraper (line 30) | type Scraper struct
    method makeHandler (line 50) | func (s *Scraper) makeHandler() func(http.ResponseWriter, *http.Reques...
    method decoupled (line 59) | func (s *Scraper) decoupled(ctx context.Context, logger *slog.Logger, ...
    method scrape (line 78) | func (s *Scraper) scrape(ctx context.Context, logger *slog.Logger, job...
  type cachingFactory (line 35) | type cachingFactory interface
  function NewScraper (line 41) | func NewScraper(featureFlags []string) *Scraper {

FILE: pkg/clients/account/client.go
  type Client (line 24) | type Client interface
  type client (line 32) | type client struct
    method GetAccount (line 46) | func (c client) GetAccount(ctx context.Context) (string, error) {
    method GetAccountAlias (line 57) | func (c client) GetAccountAlias(ctx context.Context) (string, error) {
  function NewClient (line 38) | func NewClient(logger *slog.Logger, stsClient *sts.Client, iamClient *ia...

FILE: pkg/clients/cloudwatch/client.go
  type Client (line 28) | type Client interface
  type MetricDataResult (line 43) | type MetricDataResult struct
  type DataPoint (line 48) | type DataPoint struct
  type client (line 53) | type client struct
    method ListMetrics (line 65) | func (c client) ListMetrics(ctx context.Context, namespace string, met...
    method GetMetricData (line 123) | func (c client) GetMetricData(ctx context.Context, getMetricData []*mo...
    method GetMetricStatistics (line 197) | func (c client) GetMetricStatistics(ctx context.Context, logger *slog....
  function NewClient (line 58) | func NewClient(logger *slog.Logger, cloudwatchAPI *aws_cloudwatch.Client...
  function toModelMetric (line 98) | func toModelMetric(page *aws_cloudwatch.ListMetricsOutput) []*model.Metr...
  function toModelDimensions (line 111) | func toModelDimensions(dimensions []types.Dimension) []model.Dimension {
  function toMetricDataResult (line 175) | func toMetricDataResult(resp aws_cloudwatch.GetMetricDataOutput, exportA...
  function toModelDataPoints (line 222) | func toModelDataPoints(cwDataPoints []*types.Datapoint) []*model.MetricS...

FILE: pkg/clients/cloudwatch/client_test.go
  function Test_toMetricDataResult (line 26) | func Test_toMetricDataResult(t *testing.T) {

FILE: pkg/clients/cloudwatch/concurrency_client.go
  constant listMetricsCall (line 24) | listMetricsCall         = "ListMetrics"
  constant getMetricDataCall (line 25) | getMetricDataCall       = "GetMetricData"
  constant getMetricStatisticsCall (line 26) | getMetricStatisticsCall = "GetMetricStatistics"
  type ConcurrencyLimiter (line 33) | type ConcurrencyLimiter interface
  type limitedConcurrencyClient (line 43) | type limitedConcurrencyClient struct
    method ListMetrics (line 55) | func (c limitedConcurrencyClient) ListMetrics(ctx context.Context, nam...
    method GetMetricData (line 62) | func (c limitedConcurrencyClient) GetMetricData(ctx context.Context, g...
    method GetMetricStatistics (line 69) | func (c limitedConcurrencyClient) GetMetricStatistics(ctx context.Cont...
  function NewLimitedConcurrencyClient (line 48) | func NewLimitedConcurrencyClient(client Client, limiter ConcurrencyLimit...
  type ConcurrencyConfig (line 79) | type ConcurrencyConfig struct
    method NewLimiter (line 113) | func (cfg ConcurrencyConfig) NewLimiter() ConcurrencyLimiter {
  type semaphore (line 97) | type semaphore
    method Acquire (line 104) | func (s semaphore) Acquire() {
    method Release (line 108) | func (s semaphore) Release() {
  function newSemaphore (line 100) | func newSemaphore(limit int) semaphore {
  type perAPICallLimiter (line 123) | type perAPICallLimiter struct
    method Acquire (line 138) | func (l *perAPICallLimiter) Acquire(op string) {
    method Release (line 149) | func (l *perAPICallLimiter) Release(op string) {
  function NewPerAPICallLimiter (line 130) | func NewPerAPICallLimiter(listMetrics, getMetricData, getMetricStatistic...
  type singleLimiter (line 161) | type singleLimiter struct
    method Acquire (line 172) | func (sl *singleLimiter) Acquire(_ string) {
    method Release (line 176) | func (sl *singleLimiter) Release(_ string) {
  function NewSingleLimiter (line 166) | func NewSingleLimiter(limit int) ConcurrencyLimiter {

FILE: pkg/clients/cloudwatch/input.go
  function toCloudWatchDimensions (line 29) | func toCloudWatchDimensions(dimensions []model.Dimension) []types.Dimens...
  function createGetMetricStatisticsInput (line 42) | func createGetMetricStatisticsInput(logger *slog.Logger, dimensions []mo...
  function dimensionsToCliString (line 85) | func dimensionsToCliString(dimensions []model.Dimension) string {

FILE: pkg/clients/factory.go
  type Factory (line 50) | type Factory interface
  type CachingFactory (line 58) | type CachingFactory struct
    method GetCloudwatchClient (line 174) | func (c *CachingFactory) GetCloudwatchClient(region string, role model...
    method GetTaggingClient (line 187) | func (c *CachingFactory) GetTaggingClient(region string, role model.Ro...
    method GetAccountClient (line 211) | func (c *CachingFactory) GetAccountClient(region string, role model.Ro...
    method Refresh (line 227) | func (c *CachingFactory) Refresh() {
    method Clear (line 266) | func (c *CachingFactory) Clear() {
    method GetAWSRegionalConfig (line 291) | func (c *CachingFactory) GetAWSRegionalConfig(region string, role mode...
    method createCloudwatchClient (line 295) | func (c *CachingFactory) createCloudwatchClient(regionConfig *aws.Conf...
    method createTaggingClient (line 316) | func (c *CachingFactory) createTaggingClient(regionConfig *aws.Config)...
    method createAutoScalingClient (line 330) | func (c *CachingFactory) createAutoScalingClient(assumedConfig *aws.Co...
    method createAPIGatewayClient (line 346) | func (c *CachingFactory) createAPIGatewayClient(assumedConfig *aws.Con...
    method createAPIGatewayV2Client (line 360) | func (c *CachingFactory) createAPIGatewayV2Client(assumedConfig *aws.C...
    method createEC2Client (line 374) | func (c *CachingFactory) createEC2Client(assumedConfig *aws.Config) *e...
    method createDMSClient (line 388) | func (c *CachingFactory) createDMSClient(assumedConfig *aws.Config) *d...
    method createStorageGatewayClient (line 402) | func (c *CachingFactory) createStorageGatewayClient(assumedConfig *aws...
    method createPrometheusClient (line 416) | func (c *CachingFactory) createPrometheusClient(assumedConfig *aws.Con...
    method createStsClient (line 430) | func (c *CachingFactory) createStsClient(awsConfig *aws.Config) *sts.C...
    method createIAMClient (line 434) | func (c *CachingFactory) createIAMClient(awsConfig *aws.Config) *iam.C...
    method createShieldClient (line 438) | func (c *CachingFactory) createShieldClient(awsConfig *aws.Config) *sh...
  type cachedClients (line 69) | type cachedClients struct
  function NewFactory (line 84) | func NewFactory(logger *slog.Logger, jobsCfg model.JobsConfig, fips bool...
  function createStsOptions (line 452) | func createStsOptions(stsRegion string, isDebugLoggingEnabled bool, endp...
  function awsConfigForRegion (line 471) | func awsConfigForRegion(r model.Role, c *aws.Config, region awsRegion, s...

FILE: pkg/clients/factory_test.go
  function TestNewFactory_initializes_clients (line 52) | func TestNewFactory_initializes_clients(t *testing.T) {
  function TestNewFactory_respects_stsregion (line 158) | func TestNewFactory_respects_stsregion(t *testing.T) {
  function TestCachingFactory_Clear (line 176) | func TestCachingFactory_Clear(t *testing.T) {
  function TestCachingFactory_Refresh (line 204) | func TestCachingFactory_Refresh(t *testing.T) {
  function TestCachingFactory_GetAccountClient (line 247) | func TestCachingFactory_GetAccountClient(t *testing.T) {
  function TestCachingFactory_GetCloudwatchClient (line 286) | func TestCachingFactory_GetCloudwatchClient(t *testing.T) {
  function TestCachingFactory_GetTaggingClient (line 326) | func TestCachingFactory_GetTaggingClient(t *testing.T) {
  function TestCachingFactory_createTaggingClient_DoesNotEnableFIPS (line 366) | func TestCachingFactory_createTaggingClient_DoesNotEnableFIPS(t *testing...
  function TestCachingFactory_createAPIGatewayClient_EnablesFIPS (line 379) | func TestCachingFactory_createAPIGatewayClient_EnablesFIPS(t *testing.T) {
  function TestCachingFactory_createAPIGatewayV2Client_EnablesFIPS (line 392) | func TestCachingFactory_createAPIGatewayV2Client_EnablesFIPS(t *testing....
  function TestCachingFactory_createAutoScalingClient_DoesNotEnableFIPS (line 405) | func TestCachingFactory_createAutoScalingClient_DoesNotEnableFIPS(t *tes...
  function TestCachingFactory_createEC2Client_EnablesFIPS (line 418) | func TestCachingFactory_createEC2Client_EnablesFIPS(t *testing.T) {
  function TestCachingFactory_createDMSClient_EnablesFIPS (line 431) | func TestCachingFactory_createDMSClient_EnablesFIPS(t *testing.T) {
  function TestCachingFactory_createStorageGatewayClient_EnablesFIPS (line 444) | func TestCachingFactory_createStorageGatewayClient_EnablesFIPS(t *testin...
  function TestCachingFactory_createPrometheusClient_DoesNotEnableFIPS (line 457) | func TestCachingFactory_createPrometheusClient_DoesNotEnableFIPS(t *test...
  function TestRaceConditionRefreshClear (line 470) | func TestRaceConditionRefreshClear(t *testing.T) {
  function getOptions (line 511) | func getOptions[T any, V any](awsClient *T) V {
  type testClient (line 517) | type testClient struct
    method GetResources (line 519) | func (t testClient) GetResources(_ context.Context, _ model.DiscoveryJ...
    method GetAccount (line 523) | func (t testClient) GetAccount(_ context.Context) (string, error) {
    method GetAccountAlias (line 527) | func (t testClient) GetAccountAlias(_ context.Context) (string, error) {
    method ListMetrics (line 531) | func (t testClient) ListMetrics(_ context.Context, _ string, _ *model....
    method GetMetricData (line 535) | func (t testClient) GetMetricData(_ context.Context, _ []*model.Cloudw...
    method GetMetricStatistics (line 539) | func (t testClient) GetMetricStatistics(_ context.Context, _ *slog.Log...

FILE: pkg/clients/tagging/client.go
  type Client (line 38) | type Client interface
  type client (line 44) | type client struct
    method GetResources (line 83) | func (c client) GetResources(ctx context.Context, job model.DiscoveryJ...
  function NewClient (line 57) | func NewClient(

FILE: pkg/clients/tagging/concurrency_client.go
  type limitedConcurrencyClient (line 21) | type limitedConcurrencyClient struct
    method GetResources (line 33) | func (c limitedConcurrencyClient) GetResources(ctx context.Context, jo...
  function NewLimitedConcurrencyClient (line 26) | func NewLimitedConcurrencyClient(client Client, maxConcurrency int) Clie...

FILE: pkg/clients/tagging/filters.go
  type ServiceFilter (line 35) | type ServiceFilter struct

FILE: pkg/clients/tagging/filters_test.go
  function TestValidServiceFilterNames (line 34) | func TestValidServiceFilterNames(t *testing.T) {
  function mockAPIOption (line 48) | func mockAPIOption(responses map[string]interface{}) func(*middleware.St...
  function TestApiGatewayFilterFunc (line 65) | func TestApiGatewayFilterFunc(t *testing.T) {
  function TestDMSFilterFunc (line 191) | func TestDMSFilterFunc(t *testing.T) {

FILE: pkg/config/config.go
  type ScrapeConf (line 29) | type ScrapeConf struct
    method Load (line 130) | func (c *ScrapeConf) Load(file string, logger *slog.Logger) (model.Job...
    method Validate (line 163) | func (c *ScrapeConf) Validate(logger *slog.Logger) (model.JobsConfig, ...
    method toModelConfig (line 441) | func (c *ScrapeConf) toModelConfig() model.JobsConfig {
  type Discovery (line 37) | type Discovery struct
  type ExportedTagsOnMetrics (line 42) | type ExportedTagsOnMetrics
  type Tag (line 44) | type Tag struct
  type JobLevelMetricFields (line 49) | type JobLevelMetricFields struct
  type Job (line 59) | type Job struct
    method validateDiscoveryJob (line 223) | func (j *Job) validateDiscoveryJob(logger *slog.Logger, jobIdx int) er...
  type EnhancedMetric (line 74) | type EnhancedMetric struct
  type Static (line 78) | type Static struct
    method validateStaticJob (line 319) | func (j *Static) validateStaticJob(logger *slog.Logger, jobIdx int) er...
  type CustomNamespace (line 88) | type CustomNamespace struct
    method validateCustomNamespaceJob (line 283) | func (j *CustomNamespace) validateCustomNamespaceJob(logger *slog.Logg...
  type Metric (line 101) | type Metric struct
    method validateMetric (line 349) | func (m *Metric) validateMetric(logger *slog.Logger, metricIdx int, pa...
  type Dimension (line 112) | type Dimension struct
  type Role (line 117) | type Role struct
    method ValidateRole (line 122) | func (r *Role) ValidateRole(roleIdx int, parent string) error {
  function toModelTags (line 501) | func toModelTags(tags []Tag) []model.Tag {
  function toModelSearchTags (line 512) | func toModelSearchTags(tags []Tag) []model.SearchTag {
  function toModelRoles (line 525) | func toModelRoles(roles []Role) []model.Role {
  function toModelDimensions (line 536) | func toModelDimensions(dimensions []Dimension) []model.Dimension {
  function toModelMetricConfig (line 547) | func toModelMetricConfig(metrics []*Metric) []*model.MetricConfig {
  function logConfigErrors (line 565) | func logConfigErrors(cfg []byte, logger *slog.Logger) {

FILE: pkg/config/config_test.go
  function TestConfLoad (line 24) | func TestConfLoad(t *testing.T) {
  function TestBadConfigs (line 44) | func TestBadConfigs(t *testing.T) {
  function TestValidateConfigFailuresWhenUsingAsLibrary (line 106) | func TestValidateConfigFailuresWhenUsingAsLibrary(t *testing.T) {

FILE: pkg/config/feature_flags.go
  type flagsCtxKey (line 17) | type flagsCtxKey struct
  constant AlwaysReturnInfoMetrics (line 20) | AlwaysReturnInfoMetrics = "always-return-info-metrics"
  type FeatureFlags (line 23) | type FeatureFlags interface
  function CtxWithFlags (line 29) | func CtxWithFlags(ctx context.Context, ctrl FeatureFlags) context.Context {
  function FlagsFromCtx (line 34) | func FlagsFromCtx(ctx context.Context) FeatureFlags {
  type noFeatureFlags (line 42) | type noFeatureFlags struct
    method IsFeatureEnabled (line 44) | func (nff noFeatureFlags) IsFeatureEnabled(_ string) bool {

FILE: pkg/config/feature_flags_test.go
  function TestFeatureFlagsInContext_DefaultsToNonEnabled (line 22) | func TestFeatureFlagsInContext_DefaultsToNonEnabled(t *testing.T) {
  type flags (line 28) | type flags struct
    method IsFeatureEnabled (line 30) | func (f flags) IsFeatureEnabled(_ string) bool {
  function TestFeatureFlagsInContext_RetrievesFlagsFromContext (line 34) | func TestFeatureFlagsInContext_RetrievesFlagsFromContext(t *testing.T) {

FILE: pkg/config/services.go
  type ServiceConfig (line 25) | type ServiceConfig struct
    method ToModelDimensionsRegexp (line 43) | func (sc ServiceConfig) ToModelDimensionsRegexp() []model.DimensionsRe...
    method toModelEnhancedMetricsConfig (line 65) | func (sc ServiceConfig) toModelEnhancedMetricsConfig(ems []*EnhancedMe...
  type serviceConfigs (line 77) | type serviceConfigs
    method GetService (line 79) | func (sc serviceConfigs) GetService(serviceType string) *ServiceConfig {
    method getServiceByAlias (line 88) | func (sc serviceConfigs) getServiceByAlias(alias string) *ServiceConfig {

FILE: pkg/config/services_test.go
  function TestSupportedServices (line 23) | func TestSupportedServices(t *testing.T) {

FILE: pkg/exporter.go
  constant DefaultMetricsPerQuery (line 49) | DefaultMetricsPerQuery       = 500
  constant DefaultLabelsSnakeCase (line 50) | DefaultLabelsSnakeCase       = false
  constant DefaultTaggingAPIConcurrency (line 51) | DefaultTaggingAPIConcurrency = 5
  type featureFlagsMap (line 66) | type featureFlagsMap
    method IsFeatureEnabled (line 77) | func (ff featureFlagsMap) IsFeatureEnabled(flag string) bool {
  type options (line 68) | type options struct
  type OptionsFunc (line 82) | type OptionsFunc
  function MetricsPerQuery (line 84) | func MetricsPerQuery(metricsPerQuery int) OptionsFunc {
  function LabelsSnakeCase (line 95) | func LabelsSnakeCase(labelsSnakeCase bool) OptionsFunc {
  function CloudWatchAPIConcurrency (line 102) | func CloudWatchAPIConcurrency(maxConcurrency int) OptionsFunc {
  function CloudWatchPerAPILimitConcurrency (line 113) | func CloudWatchPerAPILimitConcurrency(listMetrics, getMetricData, getMet...
  function TaggingAPIConcurrency (line 133) | func TaggingAPIConcurrency(maxConcurrency int) OptionsFunc {
  function EnableFeatureFlag (line 145) | func EnableFeatureFlag(flags ...string) OptionsFunc {
  function defaultOptions (line 154) | func defaultOptions() options {
  function UpdateMetrics (line 178) | func UpdateMetrics(

FILE: pkg/exporter_enhancedmetrics_test.go
  type mockFactoryForEnhancedMetrics (line 36) | type mockFactoryForEnhancedMetrics struct
    method GetAccountClient (line 44) | func (m *mockFactoryForEnhancedMetrics) GetAccountClient(string, model...
    method GetCloudwatchClient (line 49) | func (m *mockFactoryForEnhancedMetrics) GetCloudwatchClient(string, mo...
    method GetTaggingClient (line 54) | func (m *mockFactoryForEnhancedMetrics) GetTaggingClient(string, model...
    method GetAWSRegionalConfig (line 59) | func (m *mockFactoryForEnhancedMetrics) GetAWSRegionalConfig(string, m...
  type mockRDSClient (line 64) | type mockRDSClient struct
    method DescribeDBInstances (line 69) | func (m *mockRDSClient) DescribeDBInstances(context.Context, *slog.Log...
  type mockLambdaClient (line 77) | type mockLambdaClient struct
    method ListAllFunctions (line 82) | func (m *mockLambdaClient) ListAllFunctions(context.Context, *slog.Log...
  type mockElastiCacheClient (line 90) | type mockElastiCacheClient struct
    method DescribeAllCacheClusters (line 95) | func (m *mockElastiCacheClient) DescribeAllCacheClusters(context.Conte...
  type mockDynamoDBClient (line 103) | type mockDynamoDBClient struct
    method DescribeTables (line 108) | func (m *mockDynamoDBClient) DescribeTables(context.Context, *slog.Log...
  function TestUpdateMetrics_WithEnhancedMetrics_RDS (line 115) | func TestUpdateMetrics_WithEnhancedMetrics_RDS(t *testing.T) {
  function TestUpdateMetrics_WithEnhancedMetrics_Lambda (line 216) | func TestUpdateMetrics_WithEnhancedMetrics_Lambda(t *testing.T) {
  function TestUpdateMetrics_WithEnhancedMetrics_ElastiCache (line 318) | func TestUpdateMetrics_WithEnhancedMetrics_ElastiCache(t *testing.T) {
  function TestUpdateMetrics_WithEnhancedMetrics_DynamoDB (line 420) | func TestUpdateMetrics_WithEnhancedMetrics_DynamoDB(t *testing.T) {

FILE: pkg/exporter_test.go
  type mockFactory (line 37) | type mockFactory struct
    method GetCloudwatchClient (line 43) | func (f *mockFactory) GetCloudwatchClient(_ string, _ model.Role, _ cl...
    method GetTaggingClient (line 47) | func (f *mockFactory) GetTaggingClient(_ string, _ model.Role, _ int) ...
    method GetAccountClient (line 51) | func (f *mockFactory) GetAccountClient(_ string, _ model.Role) account...
  type mockAccountClient (line 56) | type mockAccountClient struct
    method GetAccount (line 62) | func (m mockAccountClient) GetAccount(_ context.Context) (string, erro...
    method GetAccountAlias (line 69) | func (m mockAccountClient) GetAccountAlias(_ context.Context) (string,...
  type mockTaggingClient (line 77) | type mockTaggingClient struct
    method GetResources (line 82) | func (m mockTaggingClient) GetResources(_ context.Context, _ model.Dis...
  type mockCloudwatchClient (line 90) | type mockCloudwatchClient struct
    method ListMetrics (line 96) | func (m *mockCloudwatchClient) ListMetrics(_ context.Context, _ string...
    method GetMetricData (line 106) | func (m *mockCloudwatchClient) GetMetricData(_ context.Context, _ []*m...
    method GetMetricStatistics (line 110) | func (m *mockCloudwatchClient) GetMetricStatistics(_ context.Context, ...
  function TestUpdateMetrics_StaticJob (line 122) | func TestUpdateMetrics_StaticJob(t *testing.T) {
  function TestUpdateMetrics_DiscoveryJob (line 173) | func TestUpdateMetrics_DiscoveryJob(t *testing.T) {

FILE: pkg/internal/enhancedmetrics/config/provider.go
  type RegionalConfigProvider (line 23) | type RegionalConfigProvider interface

FILE: pkg/internal/enhancedmetrics/registry.go
  type MetricsService (line 39) | type MetricsService interface
  type Registry (line 45) | type Registry struct
    method Register (line 52) | func (receiver *Registry) Register(t MetricsService) *Registry {
    method GetEnhancedMetricsService (line 65) | func (receiver *Registry) GetEnhancedMetricsService(namespace string) ...

FILE: pkg/internal/enhancedmetrics/registry_test.go
  type registryMockMetricsServiceWrapper (line 27) | type registryMockMetricsServiceWrapper struct
    method GetNamespace (line 32) | func (m *registryMockMetricsServiceWrapper) GetNamespace() string {
    method Instance (line 36) | func (m *registryMockMetricsServiceWrapper) Instance() service.Enhance...
  function TestRegistry_Register (line 43) | func TestRegistry_Register(t *testing.T) {
  function TestRegistry_GetEnhancedMetricsService (line 109) | func TestRegistry_GetEnhancedMetricsService(t *testing.T) {
  function TestRegistry_ConcurrentAccess (line 183) | func TestRegistry_ConcurrentAccess(t *testing.T) {
  function TestDefaultRegistry (line 247) | func TestDefaultRegistry(t *testing.T) {
  function TestRegistry_ChainedRegistration (line 296) | func TestRegistry_ChainedRegistration(t *testing.T) {
  function TestRegistry_ServiceFactory (line 319) | func TestRegistry_ServiceFactory(t *testing.T) {

FILE: pkg/internal/enhancedmetrics/service.go
  type MetricsServiceRegistry (line 26) | type MetricsServiceRegistry interface
  type Service (line 31) | type Service struct
    method GetMetrics (line 37) | func (ep *Service) GetMetrics(
  function NewService (line 84) | func NewService(

FILE: pkg/internal/enhancedmetrics/service/dynamodb/client.go
  type awsClient (line 25) | type awsClient interface
  type AWSDynamoDBClient (line 30) | type AWSDynamoDBClient struct
    method describeTable (line 42) | func (c *AWSDynamoDBClient) describeTable(ctx context.Context, tableAR...
    method DescribeTables (line 55) | func (c *AWSDynamoDBClient) DescribeTables(ctx context.Context, logger...
  function NewDynamoDBClientWithConfig (line 35) | func NewDynamoDBClientWithConfig(cfg aws.Config) Client {

FILE: pkg/internal/enhancedmetrics/service/dynamodb/client_test.go
  function TestAWSDynamoDBClient_DescribeAllTables (line 27) | func TestAWSDynamoDBClient_DescribeAllTables(t *testing.T) {
  type mockDynamoDBClient (line 100) | type mockDynamoDBClient struct
    method DescribeTable (line 104) | func (m *mockDynamoDBClient) DescribeTable(ctx context.Context, params...

FILE: pkg/internal/enhancedmetrics/service/dynamodb/service.go
  constant awsDynamoDBNamespace (line 29) | awsDynamoDBNamespace = "AWS/DynamoDB"
  type Client (line 31) | type Client interface
  type buildCloudwatchDataFunc (line 36) | type buildCloudwatchDataFunc
  type supportedMetric (line 38) | type supportedMetric struct
    method buildCloudwatchData (line 44) | func (sm *supportedMetric) buildCloudwatchData(resource *model.TaggedR...
  type DynamoDB (line 48) | type DynamoDB struct
    method GetNamespace (line 77) | func (s *DynamoDB) GetNamespace() string {
    method loadMetricsMetadata (line 81) | func (s *DynamoDB) loadMetricsMetadata(
    method IsMetricSupported (line 105) | func (s *DynamoDB) IsMetricSupported(metricName string) bool {
    method GetMetrics (line 110) | func (s *DynamoDB) GetMetrics(ctx context.Context, logger *slog.Logger...
    method ListRequiredPermissions (line 166) | func (s *DynamoDB) ListRequiredPermissions() map[string][]string {
    method ListSupportedEnhancedMetrics (line 174) | func (s *DynamoDB) ListSupportedEnhancedMetrics() []string {
    method Instance (line 182) | func (s *DynamoDB) Instance() service.EnhancedMetricsService {
  function NewDynamoDBService (line 53) | func NewDynamoDBService(buildClientFunc func(cfg aws.Config) Client) *Dy...
  function buildItemCountMetric (line 190) | func buildItemCountMetric(resource *model.TaggedResource, table *types.T...

FILE: pkg/internal/enhancedmetrics/service/dynamodb/service_test.go
  function TestNewDynamoDBService (line 28) | func TestNewDynamoDBService(t *testing.T) {
  function TestDynamoDB_GetNamespace (line 54) | func TestDynamoDB_GetNamespace(t *testing.T) {
  function TestDynamoDB_ListRequiredPermissions (line 60) | func TestDynamoDB_ListRequiredPermissions(t *testing.T) {
  function TestDynamoDB_ListSupportedEnhancedMetrics (line 70) | func TestDynamoDB_ListSupportedEnhancedMetrics(t *testing.T) {
  function TestDynamoDB_GetMetrics (line 78) | func TestDynamoDB_GetMetrics(t *testing.T) {
  type mockServiceDynamoDBClient (line 251) | type mockServiceDynamoDBClient struct
    method DescribeTables (line 256) | func (m *mockServiceDynamoDBClient) DescribeTables(context.Context, *s...
  type mockConfigProvider (line 263) | type mockConfigProvider struct
    method GetAWSRegionalConfig (line 267) | func (m *mockConfigProvider) GetAWSRegionalConfig(_ string, _ model.Ro...

FILE: pkg/internal/enhancedmetrics/service/elasticache/client.go
  type awsClient (line 25) | type awsClient interface
  type AWSElastiCacheClient (line 30) | type AWSElastiCacheClient struct
    method describeCacheClusters (line 42) | func (c *AWSElastiCacheClient) describeCacheClusters(ctx context.Conte...
    method DescribeAllCacheClusters (line 52) | func (c *AWSElastiCacheClient) DescribeAllCacheClusters(ctx context.Co...
  function NewElastiCacheClientWithConfig (line 35) | func NewElastiCacheClientWithConfig(cfg aws.Config) Client {

FILE: pkg/internal/enhancedmetrics/service/elasticache/client_test.go
  function TestAWSElastiCacheClient_DescribeAllCacheClusters (line 27) | func TestAWSElastiCacheClient_DescribeAllCacheClusters(t *testing.T) {
  type mockElastiCacheClient (line 110) | type mockElastiCacheClient struct
    method DescribeCacheClusters (line 114) | func (m *mockElastiCacheClient) DescribeCacheClusters(ctx context.Cont...

FILE: pkg/internal/enhancedmetrics/service/elasticache/service.go
  constant awsElastiCacheNamespace (line 29) | awsElastiCacheNamespace = "AWS/ElastiCache"
  type Client (line 31) | type Client interface
  type buildCloudwatchDataFunc (line 35) | type buildCloudwatchDataFunc
  type supportedMetric (line 37) | type supportedMetric struct
    method buildCloudwatchData (line 43) | func (sm *supportedMetric) buildCloudwatchData(resource *model.TaggedR...
  type ElastiCache (line 47) | type ElastiCache struct
    method GetNamespace (line 74) | func (s *ElastiCache) GetNamespace() string {
    method loadMetricsMetadata (line 78) | func (s *ElastiCache) loadMetricsMetadata(ctx context.Context, logger ...
    method IsMetricSupported (line 95) | func (s *ElastiCache) IsMetricSupported(metricName string) bool {
    method GetMetrics (line 100) | func (s *ElastiCache) GetMetrics(ctx context.Context, logger *slog.Log...
    method ListRequiredPermissions (line 150) | func (s *ElastiCache) ListRequiredPermissions() map[string][]string {
    method ListSupportedEnhancedMetrics (line 158) | func (s *ElastiCache) ListSupportedEnhancedMetrics() []string {
    method Instance (line 166) | func (s *ElastiCache) Instance() service.EnhancedMetricsService {
  function NewElastiCacheService (line 52) | func NewElastiCacheService(buildClientFunc func(cfg aws.Config) Client) ...
  function buildNumCacheNodesMetric (line 174) | func buildNumCacheNodesMetric(resource *model.TaggedResource, cacheClust...

FILE: pkg/internal/enhancedmetrics/service/elasticache/service_test.go
  function TestNewElastiCacheService (line 28) | func TestNewElastiCacheService(t *testing.T) {
  function TestElastiCache_GetNamespace (line 54) | func TestElastiCache_GetNamespace(t *testing.T) {
  function TestElastiCache_ListRequiredPermissions (line 60) | func TestElastiCache_ListRequiredPermissions(t *testing.T) {
  function TestElastiCache_ListSupportedEnhancedMetrics (line 68) | func TestElastiCache_ListSupportedEnhancedMetrics(t *testing.T) {
  function TestElastiCache_GetMetrics (line 76) | func TestElastiCache_GetMetrics(t *testing.T) {
  type mockServiceElastiCacheClient (line 206) | type mockServiceElastiCacheClient struct
    method DescribeAllCacheClusters (line 211) | func (m *mockServiceElastiCacheClient) DescribeAllCacheClusters(_ cont...
  type mockConfigProvider (line 218) | type mockConfigProvider struct
    method GetAWSRegionalConfig (line 222) | func (m *mockConfigProvider) GetAWSRegionalConfig(_ string, _ model.Ro...

FILE: pkg/internal/enhancedmetrics/service/lambda/client.go
  type awsClient (line 25) | type awsClient interface
  type AWSLambdaClient (line 30) | type AWSLambdaClient struct
    method listFunctions (line 42) | func (c *AWSLambdaClient) listFunctions(ctx context.Context, input *la...
    method ListAllFunctions (line 52) | func (c *AWSLambdaClient) ListAllFunctions(ctx context.Context, logger...
  function NewLambdaClientWithConfig (line 35) | func NewLambdaClientWithConfig(cfg aws.Config) Client {

FILE: pkg/internal/enhancedmetrics/service/lambda/client_test.go
  function TestAWSLambdaClient_ListAllFunctions (line 27) | func TestAWSLambdaClient_ListAllFunctions(t *testing.T) {
  type mockLambdaClient (line 110) | type mockLambdaClient struct
    method ListFunctions (line 114) | func (m *mockLambdaClient) ListFunctions(ctx context.Context, params *...

FILE: pkg/internal/enhancedmetrics/service/lambda/service.go
  constant awsLambdaNamespace (line 29) | awsLambdaNamespace = "AWS/Lambda"
  type Client (line 31) | type Client interface
  type buildCloudwatchDataFunc (line 35) | type buildCloudwatchDataFunc
  type supportedMetric (line 37) | type supportedMetric struct
    method buildCloudwatchData (line 43) | func (sm *supportedMetric) buildCloudwatchData(resource *model.TaggedR...
  type Lambda (line 47) | type Lambda struct
    method GetNamespace (line 74) | func (s *Lambda) GetNamespace() string {
    method loadMetricsMetadata (line 78) | func (s *Lambda) loadMetricsMetadata(ctx context.Context, logger *slog...
    method IsMetricSupported (line 95) | func (s *Lambda) IsMetricSupported(metricName string) bool {
    method GetMetrics (line 100) | func (s *Lambda) GetMetrics(ctx context.Context, logger *slog.Logger, ...
    method ListRequiredPermissions (line 150) | func (s *Lambda) ListRequiredPermissions() map[string][]string {
    method ListSupportedEnhancedMetrics (line 158) | func (s *Lambda) ListSupportedEnhancedMetrics() []string {
    method Instance (line 166) | func (s *Lambda) Instance() service.EnhancedMetricsService {
  function NewLambdaService (line 52) | func NewLambdaService(buildClientFunc func(cfg aws.Config) Client) *Lamb...
  function buildTimeoutMetric (line 174) | func buildTimeoutMetric(resource *model.TaggedResource, fn *types.Functi...

FILE: pkg/internal/enhancedmetrics/service/lambda/service_test.go
  function TestNewLambdaService (line 28) | func TestNewLambdaService(t *testing.T) {
  function TestLambda_GetNamespace (line 54) | func TestLambda_GetNamespace(t *testing.T) {
  function TestLambda_ListRequiredPermissions (line 60) | func TestLambda_ListRequiredPermissions(t *testing.T) {
  function TestLambda_ListSupportedEnhancedMetrics (line 68) | func TestLambda_ListSupportedEnhancedMetrics(t *testing.T) {
  function TestLambda_GetMetrics (line 76) | func TestLambda_GetMetrics(t *testing.T) {
  type mockServiceLambdaClient (line 169) | type mockServiceLambdaClient struct
    method ListAllFunctions (line 173) | func (m *mockServiceLambdaClient) ListAllFunctions(_ context.Context, ...
  type mockConfigProvider (line 177) | type mockConfigProvider struct
    method GetAWSRegionalConfig (line 181) | func (m *mockConfigProvider) GetAWSRegionalConfig(_ string, _ model.Ro...

FILE: pkg/internal/enhancedmetrics/service/rds/client.go
  type awsClient (line 25) | type awsClient interface
  type AWSRDSClient (line 30) | type AWSRDSClient struct
    method describeDBInstances (line 42) | func (c *AWSRDSClient) describeDBInstances(ctx context.Context, input ...
    method DescribeDBInstances (line 51) | func (c *AWSRDSClient) DescribeDBInstances(ctx context.Context, logger...
  function NewRDSClientWithConfig (line 35) | func NewRDSClientWithConfig(cfg aws.Config) Client {

FILE: pkg/internal/enhancedmetrics/service/rds/client_test.go
  function TestAWSRDSClient_DescribeDBInstances (line 27) | func TestAWSRDSClient_DescribeDBInstances(t *testing.T) {
  type mockRDSClient (line 123) | type mockRDSClient struct
    method DescribeDBInstances (line 127) | func (m *mockRDSClient) DescribeDBInstances(ctx context.Context, param...

FILE: pkg/internal/enhancedmetrics/service/rds/service.go
  constant awsRdsNamespace (line 29) | awsRdsNamespace = "AWS/RDS"
  type Client (line 31) | type Client interface
  type buildCloudwatchData (line 35) | type buildCloudwatchData
  type supportedMetric (line 37) | type supportedMetric struct
    method buildCloudwatchData (line 43) | func (sm *supportedMetric) buildCloudwatchData(resource *model.TaggedR...
  type RDS (line 47) | type RDS struct
    method GetNamespace (line 75) | func (s *RDS) GetNamespace() string {
    method loadMetricsMetadata (line 80) | func (s *RDS) loadMetricsMetadata(
    method IsMetricSupported (line 104) | func (s *RDS) IsMetricSupported(metricName string) bool {
    method GetMetrics (line 109) | func (s *RDS) GetMetrics(ctx context.Context, logger *slog.Logger, res...
    method ListRequiredPermissions (line 165) | func (s *RDS) ListRequiredPermissions() map[string][]string {
    method ListSupportedEnhancedMetrics (line 173) | func (s *RDS) ListSupportedEnhancedMetrics() []string {
    method Instance (line 181) | func (s *RDS) Instance() service.EnhancedMetricsService {
  function NewRDSService (line 52) | func NewRDSService(buildClientFunc func(cfg aws.Config) Client) *RDS {
  function buildAllocatedStorageMetric (line 189) | func buildAllocatedStorageMetric(resource *model.TaggedResource, instanc...

FILE: pkg/internal/enhancedmetrics/service/rds/service_test.go
  function TestNewRDSService (line 28) | func TestNewRDSService(t *testing.T) {
  function TestRDS_GetNamespace (line 54) | func TestRDS_GetNamespace(t *testing.T) {
  function TestRDS_ListRequiredPermissions (line 60) | func TestRDS_ListRequiredPermissions(t *testing.T) {
  function TestRDS_ListSupportedEnhancedMetrics (line 68) | func TestRDS_ListSupportedEnhancedMetrics(t *testing.T) {
  function TestRDS_GetMetrics (line 76) | func TestRDS_GetMetrics(t *testing.T) {
  type mockServiceRDSClient (line 187) | type mockServiceRDSClient struct
    method DescribeDBInstances (line 192) | func (m *mockServiceRDSClient) DescribeDBInstances(context.Context, *s...
  type mockConfigProvider (line 199) | type mockConfigProvider struct
    method GetAWSRegionalConfig (line 203) | func (m *mockConfigProvider) GetAWSRegionalConfig(_ string, _ model.Ro...
  function makeTestDBInstance (line 209) | func makeTestDBInstance(name string, storage int32) *types.DBInstance {
  function newTestRDSService (line 220) | func newTestRDSService(regionalData map[string]*types.DBInstance) *RDS {
  function convertRegionalDataToInstances (line 229) | func convertRegionalDataToInstances(regionalData map[string]*types.DBIns...

FILE: pkg/internal/enhancedmetrics/service/services.go
  type EnhancedMetricsService (line 23) | type EnhancedMetricsService interface

FILE: pkg/internal/enhancedmetrics/service_test.go
  type mockConfigProvider (line 31) | type mockConfigProvider struct
    method GetAWSRegionalConfig (line 35) | func (m *mockConfigProvider) GetAWSRegionalConfig(region string, _ mod...
  type mockMetricsService (line 46) | type mockMetricsService struct
    method GetMetrics (line 53) | func (m *mockMetricsService) GetMetrics(context.Context, *slog.Logger,...
    method IsMetricSupported (line 60) | func (m *mockMetricsService) IsMetricSupported(_ string) bool {
    method getGetMetricsCalled (line 64) | func (m *mockMetricsService) getGetMetricsCalled() int {
  type mockMetricsServiceRegistry (line 71) | type mockMetricsServiceRegistry struct
    method GetEnhancedMetricsService (line 76) | func (m *mockMetricsServiceRegistry) GetEnhancedMetricsService(namespa...
  function TestNewService (line 86) | func TestNewService(t *testing.T) {
  function TestService_GetMetrics (line 92) | func TestService_GetMetrics(t *testing.T) {

FILE: pkg/job/cloudwatchrunner/customnamespace.go
  type CustomNamespaceJob (line 20) | type CustomNamespaceJob struct
    method Namespace (line 24) | func (c CustomNamespaceJob) Namespace() string {
    method listMetricsParams (line 28) | func (c CustomNamespaceJob) listMetricsParams() listmetrics.Processing...
    method CustomTags (line 37) | func (c CustomNamespaceJob) CustomTags() []model.Tag {
    method resourceEnrichment (line 41) | func (c CustomNamespaceJob) resourceEnrichment() ResourceEnrichment {

FILE: pkg/job/cloudwatchrunner/discovery.go
  type DiscoveryJob (line 20) | type DiscoveryJob struct
    method Namespace (line 25) | func (d DiscoveryJob) Namespace() string {
    method CustomTags (line 29) | func (d DiscoveryJob) CustomTags() []model.Tag {
    method listMetricsParams (line 33) | func (d DiscoveryJob) listMetricsParams() listmetrics.ProcessingParams {
    method resourceEnrichment (line 42) | func (d DiscoveryJob) resourceEnrichment() ResourceEnrichment {

FILE: pkg/job/cloudwatchrunner/runner.go
  type ResourceEnrichment (line 23) | type ResourceEnrichment interface
  type Job (line 27) | type Job interface

FILE: pkg/job/custom.go
  function runCustomNamespaceJob (line 24) | func runCustomNamespaceJob(
  function getMetricDataForQueriesForCustomNamespace (line 47) | func getMetricDataForQueriesForCustomNamespace(

FILE: pkg/job/discovery.go
  type resourceAssociator (line 30) | type resourceAssociator interface
  type getMetricDataProcessor (line 34) | type getMetricDataProcessor interface
  type enhancedMetricsService (line 38) | type enhancedMetricsService interface
  function runDiscoveryJob (line 51) | func runDiscoveryJob(
  function getMetricDataForQueries (line 123) | func getMetricDataForQueries(
  type nopAssociator (line 170) | type nopAssociator struct
    method AssociateMetricToResource (line 172) | func (ns nopAssociator) AssociateMetricToResource(_ *model.Metric) (*m...
  function getFilteredMetricDatas (line 176) | func getFilteredMetricDatas(
  function metricDimensionsMatchNames (line 237) | func metricDimensionsMatchNames(metric *model.Metric, dimensionNameRequi...

FILE: pkg/job/discovery_test.go
  function Test_getFilteredMetricDatas (line 26) | func Test_getFilteredMetricDatas(t *testing.T) {

FILE: pkg/job/getmetricdata/compact.go
  function compact (line 18) | func compact[T any](input []*T, keep func(el *T) bool) []*T {

FILE: pkg/job/getmetricdata/compact_test.go
  function TestCompact (line 21) | func TestCompact(t *testing.T) {

FILE: pkg/job/getmetricdata/iterator.go
  type iteratorFactory (line 21) | type iteratorFactory struct
    method Build (line 25) | func (b iteratorFactory) Build(data []*model.CloudwatchData) Iterator {
  function mapProcessingParams (line 62) | func mapProcessingParams(data []*model.CloudwatchData) (periodDelayToBat...
  type nothingToIterate (line 86) | type nothingToIterate struct
    method Next (line 88) | func (n nothingToIterate) Next() ([]*model.CloudwatchData, StartAndEnd...
    method HasMore (line 92) | func (n nothingToIterate) HasMore() bool {
  type simpleBatchingIterator (line 96) | type simpleBatchingIterator struct
    method Next (line 104) | func (s *simpleBatchingIterator) Next() ([]*model.CloudwatchData, Star...
    method HasMore (line 124) | func (s *simpleBatchingIterator) HasMore() bool {
  function NewSimpleBatchIterator (line 129) | func NewSimpleBatchIterator(metricsPerQuery int, data []*model.Cloudwatc...
  type timeParameterBatchingIterator (line 138) | type timeParameterBatchingIterator struct
    method Next (line 143) | func (t *timeParameterBatchingIterator) Next() ([]*model.CloudwatchDat...
    method HasMore (line 164) | func (t *timeParameterBatchingIterator) HasMore() bool {
  function NewVaryingTimeParameterBatchingIterator (line 168) | func NewVaryingTimeParameterBatchingIterator(

FILE: pkg/job/getmetricdata/iterator_test.go
  function TestIteratorFactory_Build (line 25) | func TestIteratorFactory_Build(t *testing.T) {
  function TestSimpleBatchingIterator_SetsLengthAndDelay (line 83) | func TestSimpleBatchingIterator_SetsLengthAndDelay(t *testing.T) {
  function TestSimpleBatchingIterator_IterateFlow (line 97) | func TestSimpleBatchingIterator_IterateFlow(t *testing.T) {
  function TestVaryingTimeParameterBatchingIterator_IterateFlow (line 151) | func TestVaryingTimeParameterBatchingIterator_IterateFlow(t *testing.T) {

FILE: pkg/job/getmetricdata/processor.go
  type Client (line 29) | type Client interface
  type IteratorFactory (line 33) | type IteratorFactory interface
  type Iterator (line 38) | type Iterator interface
  type StartAndEndTimeParams (line 49) | type StartAndEndTimeParams struct
  type Processor (line 55) | type Processor struct
    method Run (line 77) | func (p Processor) Run(ctx context.Context, namespace string, requests...
  function NewDefaultProcessor (line 63) | func NewDefaultProcessor(logger *slog.Logger, client Client, metricsPerQ...
  function NewProcessor (line 67) | func NewProcessor(logger *slog.Logger, client Client, concurrency int, w...
  function addQueryIDsToBatch (line 117) | func addQueryIDsToBatch(batch []*model.CloudwatchData) []*model.Cloudwat...
  function mapResultsToBatch (line 125) | func mapResultsToBatch(logger *slog.Logger, results []cloudwatch.MetricD...
  function indexToQueryID (line 151) | func indexToQueryID(i int) string {
  function queryIDToIndex (line 155) | func queryIDToIndex(queryID string) (int, error) {
  function toSecondDuration (line 161) | func toSecondDuration(i int64) time.Duration {

FILE: pkg/job/getmetricdata/processor_test.go
  type cloudwatchDataInput (line 30) | type cloudwatchDataInput struct
  type cloudwatchDataOutput (line 35) | type cloudwatchDataOutput struct
  type metricDataResultForMetric (line 40) | type metricDataResultForMetric struct
  type testClient (line 45) | type testClient struct
    method GetMetricData (line 50) | func (t testClient) GetMetricData(ctx context.Context, getMetricData [...
  function TestProcessor_Run (line 66) | func TestProcessor_Run(t *testing.T) {
  function ToCloudwatchData (line 216) | func ToCloudwatchData(input []*cloudwatchDataInput) []*model.CloudwatchD...
  function getSampleMetricDatas (line 234) | func getSampleMetricDatas(id string) *model.CloudwatchData {
  function BenchmarkProcessorRun (line 273) | func BenchmarkProcessorRun(b *testing.B) {
  function doBench (line 303) | func doBench(b *testing.B, metricsPerQuery, testResourcesCount int, conc...

FILE: pkg/job/getmetricdata/windowcalculator.go
  constant TimeFormat (line 17) | TimeFormat = "2006-01-02T15:04:05.999999-07:00"
  type Clock (line 20) | type Clock interface
  type TimeClock (line 25) | type TimeClock struct
    method Now (line 27) | func (tc TimeClock) Now() time.Time {
  type MetricWindowCalculator (line 31) | type MetricWindowCalculator struct
    method Calculate (line 38) | func (m MetricWindowCalculator) Calculate(period time.Duration, length...

FILE: pkg/job/getmetricdata/windowcalculator_test.go
  type StubClock (line 22) | type StubClock struct
    method Now (line 26) | func (mt StubClock) Now() time.Time {
  function Test_MetricWindow (line 30) | func Test_MetricWindow(t *testing.T) {

FILE: pkg/job/listmetrics/processor.go
  type ProcessingParams (line 17) | type ProcessingParams struct

FILE: pkg/job/maxdimassociator/associator.go
  type Associator (line 36) | type Associator struct
    method AssociateMetricToResource (line 145) | func (assoc Associator) AssociateMetricToResource(cwMetric *model.Metr...
  type dimensionsRegexpMapping (line 44) | type dimensionsRegexpMapping struct
    method toString (line 55) | func (rm dimensionsRegexpMapping) toString() string {
  function NewAssociator (line 73) | func NewAssociator(logger *slog.Logger, dimensionsRegexps []model.Dimens...
  function buildLabelsMap (line 228) | func buildLabelsMap(cwMetric *model.Metric, regexpMapping *dimensionsReg...
  function fixDimension (line 247) | func fixDimension(namespace string, dim model.Dimension) (model.Dimensio...
  function containsAll (line 269) | func containsAll(a, b []string) bool {

FILE: pkg/job/maxdimassociator/associator_api_gateway_test.go
  function TestAssociatorAPIGateway (line 47) | func TestAssociatorAPIGateway(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_client_vpn_test.go
  function TestAssociatorClientVPN (line 30) | func TestAssociatorClientVPN(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_ddosprotection_test.go
  function TestAssociatorDDoSProtection (line 40) | func TestAssociatorDDoSProtection(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_directoryservice_test.go
  function TestAssociatorDirectoryService (line 30) | func TestAssociatorDirectoryService(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_dx_test.go
  function TestAssociatorDX (line 30) | func TestAssociatorDX(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_ec2_test.go
  function TestAssociatorEC2 (line 40) | func TestAssociatorEC2(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_ec_test.go
  function TestAssociatorEC (line 40) | func TestAssociatorEC(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_ecs_test.go
  function TestAssociatorECS (line 46) | func TestAssociatorECS(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_event_roles_test.go
  function TestAssociatorEventRule (line 39) | func TestAssociatorEventRule(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_globalaccelerator_test.go
  function TestAssociatorGlobalAccelerator (line 46) | func TestAssociatorGlobalAccelerator(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_gwlb_test.go
  function TestAssociatorGwlb (line 46) | func TestAssociatorGwlb(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_ipam_test.go
  function TestAssociatorIpam (line 34) | func TestAssociatorIpam(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_kms_test.go
  function TestAssociatorKMS (line 30) | func TestAssociatorKMS(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_lambda_test.go
  function TestAssociatorLambda (line 32) | func TestAssociatorLambda(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_logging_test.go
  function TestAssociatorLogging (line 26) | func TestAssociatorLogging(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_logs_test.go
  function TestAssociatorLogs (line 40) | func TestAssociatorLogs(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_mediaconvert_test.go
  function TestAssociatorMediaConvert (line 40) | func TestAssociatorMediaConvert(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_memorydb_test.go
  function TestAssociatorMemoryDB (line 40) | func TestAssociatorMemoryDB(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_mq_test.go
  function TestAssociatorMQ (line 40) | func TestAssociatorMQ(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_qldb_test.go
  function TestAssociatorQLDB (line 30) | func TestAssociatorQLDB(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_redshift_serverless_test.go
  function TestAssociatorRedshiftServerless (line 40) | func TestAssociatorRedshiftServerless(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_sagemaker_endpoint_test.go
  function TestAssociatorSagemakerEndpoint (line 40) | func TestAssociatorSagemakerEndpoint(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_sagemaker_inf_component_test.go
  function TestAssociatorSagemakerInfComponentJob (line 34) | func TestAssociatorSagemakerInfComponentJob(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_sagemaker_inf_rec_test.go
  function TestAssociatorSagemakerInfRecJob (line 34) | func TestAssociatorSagemakerInfRecJob(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_sagemaker_pipeline_test.go
  function TestAssociatorSagemakerPipeline (line 40) | func TestAssociatorSagemakerPipeline(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_sagemaker_processing_test.go
  function TestAssociatorSagemakerProcessingJob (line 34) | func TestAssociatorSagemakerProcessingJob(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_sagemaker_test.go
  function TestAssociatorSagemaker (line 58) | func TestAssociatorSagemaker(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_sagemaker_training_test.go
  function TestAssociatorSagemakerTrainingJob (line 34) | func TestAssociatorSagemakerTrainingJob(t *testing.T) {

FILE: pkg/job/maxdimassociator/associator_sagemaker_transform_test.go
  function TestAssociatorSagemakerTransformJob (line 34) | func TestAssociatorSagemakerTransformJob(t *testing.T) {

FILE: pkg/job/resourcemetadata/resource.go
  type Resource (line 21) | type Resource struct
  type Resources (line 31) | type Resources struct
  type MetricResourceEnricher (line 36) | type MetricResourceEnricher interface

FILE: pkg/job/scrape.go
  function ScrapeAwsData (line 30) | func ScrapeAwsData(

FILE: pkg/job/scraper.go
  type Scraper (line 27) | type Scraper struct
    method Scrape (line 71) | func (s Scraper) Scrape(ctx context.Context) ([]model.TaggedResourceRe...
  type runnerFactory (line 33) | type runnerFactory interface
  type ResourceMetadataRunner (line 39) | type ResourceMetadataRunner interface
  type CloudwatchRunner (line 43) | type CloudwatchRunner interface
  function NewScraper (line 47) | func NewScraper(logger *slog.Logger,
  type ErrorType (line 58) | type ErrorType
  type Account (line 66) | type Account struct
  function jobConfigVisitor (line 205) | func jobConfigVisitor(jobsCfg model.JobsConfig, action func(job any, rol...
  function jobAction (line 224) | func jobAction(logger *slog.Logger, job any, discovery func(job model.Di...
  type JobContext (line 240) | type JobContext struct
    method ToScrapeContext (line 247) | func (jc JobContext) ToScrapeContext(customTags []model.Tag) *model.Sc...
  type Error (line 256) | type Error struct
    method ToLoggerKeyVals (line 270) | func (e Error) ToLoggerKeyVals() []interface{} {
  function NewError (line 262) | func NewError(context JobContext, errorType ErrorType, err error) Error {

FILE: pkg/job/scraper_test.go
  type testRunnerFactory (line 34) | type testRunnerFactory struct
    method GetAccountAlias (line 41) | func (t *testRunnerFactory) GetAccountAlias(context.Context) (string, ...
    method GetAccount (line 45) | func (t *testRunnerFactory) GetAccount(context.Context) (string, error) {
    method Run (line 49) | func (t *testRunnerFactory) Run(ctx context.Context, region string, jo...
    method GetAccountClient (line 53) | func (t *testRunnerFactory) GetAccountClient(string, model.Role) accou...
    method NewResourceMetadataRunner (line 57) | func (t *testRunnerFactory) NewResourceMetadataRunner(*slog.Logger, st...
    method NewCloudWatchRunner (line 61) | func (t *testRunnerFactory) NewCloudWatchRunner(_ *slog.Logger, _ stri...
  type testMetadataRunner (line 65) | type testMetadataRunner struct
    method Run (line 69) | func (t testMetadataRunner) Run(ctx context.Context, region string, jo...
  type testCloudwatchRunner (line 73) | type testCloudwatchRunner struct
    method Run (line 78) | func (t testCloudwatchRunner) Run(ctx context.Context) ([]*model.Cloud...
  function TestScrapeRunner_Run (line 82) | func TestScrapeRunner_Run(t *testing.T) {

FILE: pkg/job/static.go
  function runStaticJob (line 24) | func runStaticJob(
  function createStaticDimensions (line 71) | func createStaticDimensions(dimensions []model.Dimension) []model.Dimens...

FILE: pkg/model/model.go
  constant DefaultPeriodSeconds (line 22) | DefaultPeriodSeconds = int64(300)
  constant DefaultLengthSeconds (line 23) | DefaultLengthSeconds = int64(300)
  type JobsConfig (line 26) | type JobsConfig struct
  type DiscoveryJob (line 33) | type DiscoveryJob struct
    method HasEnhancedMetrics (line 51) | func (d *DiscoveryJob) HasEnhancedMetrics() bool {
  type EnhancedMetricConfig (line 55) | type EnhancedMetricConfig struct
  type StaticJob (line 59) | type StaticJob struct
  type CustomNamespaceJob (line 69) | type CustomNamespaceJob struct
  type Role (line 81) | type Role struct
  type MetricConfig (line 86) | type MetricConfig struct
  type DimensionsRegexp (line 97) | type DimensionsRegexp struct
  type LabelSet (line 102) | type LabelSet
  type Tag (line 104) | type Tag struct
  type SearchTag (line 109) | type SearchTag struct
  type Dimension (line 114) | type Dimension struct
  type Metric (line 119) | type Metric struct
  type CloudwatchMetricResult (line 126) | type CloudwatchMetricResult struct
  type TaggedResourceResult (line 131) | type TaggedResourceResult struct
  type ScrapeContext (line 136) | type ScrapeContext struct
  type CloudwatchData (line 145) | type CloudwatchData struct
  type GetMetricStatisticsResult (line 168) | type GetMetricStatisticsResult struct
  type MetricStatisticsResult (line 173) | type MetricStatisticsResult struct
  type GetMetricDataProcessingParams (line 197) | type GetMetricDataProcessingParams struct
  type MetricMigrationParams (line 210) | type MetricMigrationParams struct
  type GetMetricDataResult (line 216) | type GetMetricDataResult struct
  type DataPoint (line 221) | type DataPoint struct
  type TaggedResource (line 227) | type TaggedResource struct
    method FilterThroughTags (line 243) | func (r TaggedResource) FilterThroughTags(filterTags []SearchTag) bool {
    method MetricTags (line 272) | func (r TaggedResource) MetricTags(exportedTags []string) []Tag {

FILE: pkg/model/model_test.go
  function Test_FilterThroughTags (line 22) | func Test_FilterThroughTags(t *testing.T) {
  function Test_MetricTags (line 186) | func Test_MetricTags(t *testing.T) {

FILE: pkg/promutil/migrate.go
  function BuildMetricName (line 32) | func BuildMetricName(namespace, metricName, statistic string) string {
  function BuildNamespaceInfoMetrics (line 70) | func BuildNamespaceInfoMetrics(tagData []model.TaggedResourceResult, met...
  function BuildMetrics (line 102) | func BuildMetrics(results []model.CloudwatchMetricResult, labelsSnakeCas...
  function statisticsInCloudwatchData (line 174) | func statisticsInCloudwatchData(d *model.CloudwatchData) []string {
  function getDataPoints (line 184) | func getDataPoints(cwd *model.CloudwatchData, statistic string) ([]model...
  function sortByTimestamp (line 253) | func sortByTimestamp(dataPoints []*model.MetricStatisticsResult) []*mode...
  function createPrometheusLabels (line 261) | func createPrometheusLabels(cwd *model.CloudwatchData, labelsSnakeCase b...
  function contextToLabels (line 289) | func contextToLabels(context *model.ScrapeContext, labelsSnakeCase bool,...
  function recordLabelsForMetric (line 316) | func recordLabelsForMetric(metricName string, promLabels map[string]stri...
  function EnsureLabelConsistencyAndRemoveDuplicates (line 332) | func EnsureLabelConsistencyAndRemoveDuplicates(metrics []*PrometheusMetr...

FILE: pkg/promutil/migrate_test.go
  function TestBuildNamespaceInfoMetrics (line 27) | func TestBuildNamespaceInfoMetrics(t *testing.T) {
  function TestBuildMetrics (line 288) | func TestBuildMetrics(t *testing.T) {
  function Benchmark_BuildMetrics (line 1105) | func Benchmark_BuildMetrics(b *testing.B) {
  function TestBuildMetricName (line 1254) | func TestBuildMetricName(t *testing.T) {
  function Benchmark_BuildMetricName (line 1302) | func Benchmark_BuildMetricName(b *testing.B) {
  function replaceNaNValues (line 1345) | func replaceNaNValues(metrics []*PrometheusMetric) []*PrometheusMetric {
  function TestSortByTimeStamp (line 1355) | func TestSortByTimeStamp(t *testing.T) {
  function Test_EnsureLabelConsistencyAndRemoveDuplicates (line 1389) | func Test_EnsureLabelConsistencyAndRemoveDuplicates(t *testing.T) {

FILE: pkg/promutil/prometheus.go
  type PrometheusMetric (line 109) | type PrometheusMetric struct
  type PrometheusCollector (line 117) | type PrometheusCollector struct
    method Describe (line 127) | func (p *PrometheusCollector) Describe(_ chan<- *prometheus.Desc) {
    method Collect (line 135) | func (p *PrometheusCollector) Collect(metrics chan<- prometheus.Metric) {
  function NewPrometheusCollector (line 121) | func NewPrometheusCollector(metrics []*PrometheusMetric) *PrometheusColl...
  function toConstMetrics (line 141) | func toConstMetrics(metrics []*PrometheusMetric) []prometheus.Metric {
  function PromString (line 181) | func PromString(text string) string {
  function PromStringToBuilder (line 187) | func PromStringToBuilder(text string, buf *strings.Builder) {
  function PromStringTag (line 207) | func PromStringTag(text string, labelsSnakeCase bool) (bool, string) {
  function sanitize (line 218) | func sanitize(text string) string {

FILE: pkg/promutil/prometheus_test.go
  function TestSanitize (line 26) | func TestSanitize(t *testing.T) {
  function TestPromStringTag (line 50) | func TestPromStringTag(t *testing.T) {
  function TestNewPrometheusCollector_CanReportMetricsAndErrors (line 119) | func TestNewPrometheusCollector_CanReportMetricsAndErrors(t *testing.T) {
  function TestNewPrometheusCollector_CanReportMetrics (line 150) | func TestNewPrometheusCollector_CanReportMetrics(t *testing.T) {
Condensed preview — 202 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (948K chars).
[
  {
    "path": ".dockerignore",
    "chars": 156,
    "preview": "data/\n.build/\n.tarballs/\n\n!.build/linux-amd64/\n!.build/linux-arm64/\n!.build/linux-armv7/\n!.build/linux-ppc64le/\n!.build/"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 69,
    "preview": "# These are supported funding model platforms\n\n\npatreon: thomaspeitz\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.yml",
    "chars": 1571,
    "preview": "name: 🐞 Bug\ndescription: File a bug report\ntitle: \"[BUG] <title>\"\nlabels: [bug]\nbody:\n- type: checkboxes\n  attributes:\n "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature.yml",
    "chars": 1307,
    "preview": "name: 🆕 Feature\ndescription: Request a new feature\ntitle: \"[FEATURE] <title>\"\nlabels: [enhancement]\nbody:\n- type: checkb"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 355,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: gomod\n    directory: /\n    schedule:\n      interval: monthly\n    open-pull-re"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 3938,
    "preview": "name: CI\n\non:\n  push:\n    tags:\n      - 'v*'\n    branches:\n      - master\n  pull_request:\n  workflow_call:\n\njobs:\n  test"
  },
  {
    "path": ".github/workflows/container_description.yml",
    "chars": 2461,
    "preview": "---\nname: Push README to Docker Hub\non:\n  push:\n    paths:\n      - \"README.md\"\n      - \"README-containers.md\"\n      - \"."
  },
  {
    "path": ".github/workflows/golangci-lint.yml",
    "chars": 1562,
    "preview": "---\n# This action is synced from https://github.com/prometheus/prometheus\nname: golangci-lint\non:\n  push:\n    branches: "
  },
  {
    "path": ".gitignore",
    "chars": 106,
    "preview": ".build\nyet-another-cloudwatch-exporter\n!charts/yet-another-cloudwatch-exporter\nvendor\ndist\n/yace\n*.tar.gz\n"
  },
  {
    "path": ".golangci.yml",
    "chars": 893,
    "preview": "version: \"2\"\noutput:\n  formats:\n    text:\n      path: stderr\n      colors: false\nlinters:\n  default: none\n  enable:\n    "
  },
  {
    "path": ".promu.yml",
    "chars": 659,
    "preview": "go:\n    # This must match .circle/config.yml.\n    version: 1.26\nrepository:\n    path: github.com/prometheus-community/ye"
  },
  {
    "path": ".yamllint",
    "chars": 507,
    "preview": "---\nextends: default\nignore: |\n  **/node_modules\n  web/api/v1/testdata/openapi_*_golden.yaml\n\nrules:\n  braces:\n    max-s"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 62472,
    "preview": "## main / (unreleased)\n\n## 0.64.0 / 2026-03-27\n\n**Important news and breaking changes**\n\n- BREAKING CHANGE: AWS SDK v1 s"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 152,
    "preview": "# Prometheus Community Code of Conduct\n\nPrometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation"
  },
  {
    "path": "CONTRIBUTE.md",
    "chars": 617,
    "preview": "# CONTRIBUTE\n\n## Steps to Contribute\n\n* We use [golangci-lint](https://github.com/golangci/golangci-lint) for linting th"
  },
  {
    "path": "Dockerfile",
    "chars": 400,
    "preview": "ARG ARCH=\"amd64\"\nARG OS=\"linux\"\nFROM quay.io/prometheus/busybox-${OS}-${ARCH}:latest\nLABEL maintainer=\"The Prometheus Au"
  },
  {
    "path": "LICENSE",
    "chars": 11352,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "MAINTAINERS.md",
    "chars": 257,
    "preview": "# Maintainers\n\n- Thomas Peitz (info@thomas-peitz.de / @thomaspeitz)\n- Cristian Greco (cristian.greco@grafana.com / @cris"
  },
  {
    "path": "Makefile",
    "chars": 832,
    "preview": "# Copyright 2024 The Prometheus Authors\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not "
  },
  {
    "path": "Makefile.common",
    "chars": 20101,
    "preview": "# Copyright The Prometheus Authors\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use t"
  },
  {
    "path": "NOTICE",
    "chars": 101,
    "preview": "Copyright 2018-2021 Invision AG\nCopyright 2021-2024 NERDSWORDS\nCopyright 2024 The Prometheus Authors\n"
  },
  {
    "path": "README.md",
    "chars": 16563,
    "preview": "# YACE - yet another cloudwatch exporter\n\n[![Container on Quay](https://quay.io/repository/prometheuscommunity/yet-anoth"
  },
  {
    "path": "SECURITY.md",
    "chars": 220,
    "preview": "# Reporting a security issue\n\nThe Prometheus security policy, including how to report vulnerabilities, can be\nfound here"
  },
  {
    "path": "VERSION",
    "chars": 7,
    "preview": "0.64.0\n"
  },
  {
    "path": "cmd/yace/main.go",
    "chars": 11263,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "cmd/yace/main_test.go",
    "chars": 1343,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "cmd/yace/scraper.go",
    "chars": 4006,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "docker-compose/README.md",
    "chars": 965,
    "preview": "## Setting up a local docker-compose environment\n\nThis folder contains a [docker-compose](./docker-compose.yaml) configu"
  },
  {
    "path": "docker-compose/docker-compose.yaml",
    "chars": 1464,
    "preview": "version: '3.8'\n\nnetworks:\n  monitoring:\n    driver: bridge\n\nvolumes:\n  prometheus_data: {}\n\nservices:\n  grafana:\n    ima"
  },
  {
    "path": "docker-compose/grafana/datasource.yaml",
    "chars": 193,
    "preview": "apiVersion: 1\n\ndatasources:\n  - name: Prometheus\n    type: prometheus\n    access: proxy\n    orgId: 1\n    url: http://pro"
  },
  {
    "path": "docker-compose/prometheus.yaml",
    "chars": 237,
    "preview": "global:\n  scrape_interval: 1m\nscrape_configs:\n  - job_name: prometheus\n    scrape_interval: 1m\n    static_configs:\n     "
  },
  {
    "path": "docker-compose/yace-config.yaml",
    "chars": 643,
    "preview": "apiVersion: v1alpha1\nsts-region: us-east-1\ndiscovery:\n  jobs:\n    - type: AWS/ECS\n      regions: [us-east-1]\n      perio"
  },
  {
    "path": "docs/configuration.md",
    "chars": 16153,
    "preview": "# Configuration\n\nYACE has two configuration mechanisms:\n\n- [command-line flags](#command-line-flags)\n- [yaml configurati"
  },
  {
    "path": "docs/embedding.md",
    "chars": 533,
    "preview": "# Embedding YACE in your application\n\nIt is possible to embed YACE into an external Go application. This mode might be u"
  },
  {
    "path": "docs/feature_flags.md",
    "chars": 677,
    "preview": "# Feature flags\n\nList of features or changes that are disabled by default since they are breaking changes or are conside"
  },
  {
    "path": "docs/installation.md",
    "chars": 2058,
    "preview": "# Installing and running YACE\n\nThere are various way to run YACE.\n\n## Binaries\n\nSee the [Releases](https://github.com/pr"
  },
  {
    "path": "examples/alb.yml",
    "chars": 1744,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/ApplicationELB\n      regions:\n        - us-east-1\n      period: "
  },
  {
    "path": "examples/apigw.yml",
    "chars": 387,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/ApiGateway\n      regions:\n        - us-east-1\n      period: 300\n"
  },
  {
    "path": "examples/apprunner.yaml",
    "chars": 787,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - regions:\n        - us-east-1\n      period: 300\n      length: 300\n      typ"
  },
  {
    "path": "examples/appstream.yml",
    "chars": 677,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/AppStream\n      regions:\n        - us-east-1\n      period: 300\n "
  },
  {
    "path": "examples/backup.yml",
    "chars": 744,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/Backup\n      regions:\n        - us-east-1\n      period: 300\n    "
  },
  {
    "path": "examples/cwagent.yml",
    "chars": 277,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: CWAgent\n      regions:\n        - us-east-1\n      period: 300\n      l"
  },
  {
    "path": "examples/ds.yml",
    "chars": 497,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/DirectoryService\n      regions:\n        - us-east-1\n      period"
  },
  {
    "path": "examples/dx.yml",
    "chars": 590,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/DX\n      regions:\n        - us-east-1\n      period: 300\n      le"
  },
  {
    "path": "examples/ebs.yml",
    "chars": 869,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/EBS\n      regions:\n        - us-east-1\n      period: 300\n      l"
  },
  {
    "path": "examples/ec.yml",
    "chars": 659,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/ElastiCache\n      regions:\n        - us-east-1\n      period: 300"
  },
  {
    "path": "examples/ec2.yml",
    "chars": 891,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/EC2\n      regions:\n        - us-east-1\n      period: 300\n      l"
  },
  {
    "path": "examples/ecs.yml",
    "chars": 440,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/ECS\n      regions:\n        - us-east-1\n      period: 300\n      l"
  },
  {
    "path": "examples/elb.yml",
    "chars": 983,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/ELB\n      regions:\n        - us-east-1\n      period: 300\n      l"
  },
  {
    "path": "examples/es.yml",
    "chars": 1103,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/ES\n      regions:\n        - us-east-1\n      period: 300\n      le"
  },
  {
    "path": "examples/historic-data.yml",
    "chars": 862,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/SQS\n      regions:\n        - us-east-1\n      period: 60\n      le"
  },
  {
    "path": "examples/kafka.yml",
    "chars": 1139,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/Kafka\n      regions:\n        - us-east-1\n      period: 300\n     "
  },
  {
    "path": "examples/kinesis.yml",
    "chars": 1330,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/Kinesis\n      regions:\n        - us-east-1\n      period: 300\n   "
  },
  {
    "path": "examples/kms.yml",
    "chars": 219,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/KMS\n      regions:\n        - us-east-1\n      period: 300\n      m"
  },
  {
    "path": "examples/lambda.yml",
    "chars": 390,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/Lambda\n      regions:\n        - us-east-1\n      period: 300\n    "
  },
  {
    "path": "examples/lambda_edge.yml",
    "chars": 633,
    "preview": "  # We can't configure discovery job for edge lambda function but static works.,he region is always us-east-1.\n  # Other"
  },
  {
    "path": "examples/logs.yml",
    "chars": 451,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/Logs\n      regions:\n        - us-east-1\n      period: 60\n      l"
  },
  {
    "path": "examples/mq.yml",
    "chars": 857,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/AmazonMQ\n      regions:\n        - us-east-1\n      period: 300\n  "
  },
  {
    "path": "examples/networkmanager.yml",
    "chars": 797,
    "preview": "# https://docs.aws.amazon.com/network-manager/latest/cloudwan/cloudwan-metrics.html\napiVersion: v1alpha1\ndiscovery:\n  jo"
  },
  {
    "path": "examples/ngw.yml",
    "chars": 1441,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/NATGateway\n      regions:\n        - us-east-1\n      period: 300\n"
  },
  {
    "path": "examples/nlb.yml",
    "chars": 650,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/NetworkELB\n      regions:\n        - us-east-1\n      period: 300\n"
  },
  {
    "path": "examples/private-link-endpoints.yaml",
    "chars": 424,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/PrivateLinkEndpoints\n      regions:\n        - us-east-1\n      pe"
  },
  {
    "path": "examples/private-link-services.yaml",
    "chars": 423,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/PrivateLinkServices\n      regions:\n        - us-east-1\n      per"
  },
  {
    "path": "examples/qldb.yml",
    "chars": 871,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  exportedTagsOnMetrics:\n    AWS/QLDB:\n      - Name\n  jobs:\n    - type: AWS/QLDB\n      r"
  },
  {
    "path": "examples/quicksight.yml",
    "chars": 352,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/QuickSight\n      regions:\n        - eu-west-2\n      period: 3000"
  },
  {
    "path": "examples/rds.yml",
    "chars": 764,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/RDS\n      regions:\n        - us-east-1\n      period: 300\n      l"
  },
  {
    "path": "examples/redshift-serverless.yml",
    "chars": 551,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/Redshift-Serverless\n      regions:\n        - us-east-1\n      per"
  },
  {
    "path": "examples/s3.yml",
    "chars": 277,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/S3\n      regions:\n        - us-east-1\n      period: 86400\n      "
  },
  {
    "path": "examples/ses.yaml",
    "chars": 434,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/SES\n      regions:\n        - us-east-1\n      period: 300\n      l"
  },
  {
    "path": "examples/sns.yml",
    "chars": 500,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/SNS\n      regions:\n        - us-east-1\n      period: 300\n      l"
  },
  {
    "path": "examples/sqs.yml",
    "chars": 794,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/SQS\n      regions:\n        - us-east-1\n      period: 60\n      le"
  },
  {
    "path": "examples/usage.yml",
    "chars": 260,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/Usage\n      regions:\n        - us-east-1\n      period: 300\n     "
  },
  {
    "path": "examples/vpn.yml",
    "chars": 321,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/VPN\n      regions:\n        - us-east-1\n      period: 300\n      l"
  },
  {
    "path": "go.mod",
    "chars": 3410,
    "preview": "module github.com/prometheus-community/yet-another-cloudwatch-exporter\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/aws/aws-sdk-go-"
  },
  {
    "path": "go.sum",
    "chars": 14283,
    "preview": "github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=\ngithub.com/alecthomas/kingpin/v2"
  },
  {
    "path": "mixin/README.md",
    "chars": 612,
    "preview": "# CloudWatch Mixin\n\nThis is a Prometheus [Monitoring Mixin](https://monitoring.mixins.dev/) that comes with pre-defined "
  },
  {
    "path": "mixin/config.libsonnet",
    "chars": 85,
    "preview": "{\n  // use to override the default configuration of base mixin\n  _config+:: {\n  },\n}\n"
  },
  {
    "path": "mixin/dashboards/all.libsonnet",
    "chars": 198,
    "preview": "{\n  'ebs.json': import 'ebs.libsonnet',\n  'ec2.json': import 'ec2.libsonnet',\n  'lambda.json': import 'lambda.libsonnet'"
  },
  {
    "path": "mixin/dashboards/common.libsonnet",
    "chars": 595,
    "preview": "{\n  // Tooltip type\n  // 0 = 'default': no shared crosshair or tooltip\n  // 1 = 'shared_crosshair': shared tooltip\n  // "
  },
  {
    "path": "mixin/dashboards/ebs.libsonnet",
    "chars": 6613,
    "preview": "local common = import 'common.libsonnet';\nlocal grafana = import 'grafonnet-7.0/grafana.libsonnet';\n\nlocal allLabels = '"
  },
  {
    "path": "mixin/dashboards/ec2.libsonnet",
    "chars": 8645,
    "preview": "local common = import 'common.libsonnet';\nlocal grafana = import 'grafonnet-7.0/grafana.libsonnet';\n\nlocal allLabels = '"
  },
  {
    "path": "mixin/dashboards/lambda.libsonnet",
    "chars": 5326,
    "preview": "local common = import 'common.libsonnet';\nlocal grafana = import 'grafonnet-7.0/grafana.libsonnet';\n\nlocal allLabels = '"
  },
  {
    "path": "mixin/dashboards/rds.libsonnet",
    "chars": 6881,
    "preview": "local common = import 'common.libsonnet';\nlocal grafana = import 'grafonnet-7.0/grafana.libsonnet';\n\nlocal allLabels = '"
  },
  {
    "path": "mixin/dashboards/s3.libsonnet",
    "chars": 5368,
    "preview": "local common = import 'common.libsonnet';\nlocal grafana = import 'grafonnet-7.0/grafana.libsonnet';\n\nlocal allLabels = '"
  },
  {
    "path": "mixin/jsonnetfile.json",
    "chars": 265,
    "preview": "{\n  \"version\": 1,\n  \"dependencies\": [\n    {\n      \"source\": {\n        \"git\": {\n          \"remote\": \"https://github.com/g"
  },
  {
    "path": "mixin/jsonnetfile.lock.json",
    "chars": 361,
    "preview": "{\n  \"version\": 1,\n  \"dependencies\": [\n    {\n      \"source\": {\n        \"git\": {\n          \"remote\": \"https://github.com/g"
  },
  {
    "path": "mixin/mixin.libsonnet",
    "chars": 557,
    "preview": "{\n  local config = import './config.libsonnet',\n  local util = import './util.libsonnet',\n  local mixin = (import './das"
  },
  {
    "path": "mixin/util.libsonnet",
    "chars": 566,
    "preview": "{\n  decorate_dashboard(dashboard, tags, refresh='30s', timeFrom='now-30m')::\n    dashboard {\n      editable: false,\n    "
  },
  {
    "path": "pkg/clients/README.md",
    "chars": 1094,
    "preview": "# Purpose of the clients package\nThe goal of this package is to abstract away as much of the AWS SDK implementation deta"
  },
  {
    "path": "pkg/clients/account/client.go",
    "chars": 2255,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/clients/cloudwatch/client.go",
    "chars": 8676,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/clients/cloudwatch/client_test.go",
    "chars": 3987,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/clients/cloudwatch/concurrency_client.go",
    "chars": 6157,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/clients/cloudwatch/input.go",
    "chars": 3184,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/clients/factory.go",
    "chars": 18550,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/clients/factory_test.go",
    "chars": 16902,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/clients/tagging/client.go",
    "chars": 6629,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/clients/tagging/concurrency_client.go",
    "chars": 1211,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/clients/tagging/filters.go",
    "chars": 15469,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/clients/tagging/filters_test.go",
    "chars": 11162,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/config/config.go",
    "chars": 19442,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/config/config_test.go",
    "chars": 5397,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/config/feature_flags.go",
    "chars": 1829,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/config/feature_flags_test.go",
    "chars": 1277,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/config/services.go",
    "chars": 28405,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/config/services_test.go",
    "chars": 1403,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/config/testdata/config_test.yml",
    "chars": 3828,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  exportedTagsOnMetrics:\n    AWS/EBS:\n      - VolumeId\n    AWS/Kafka:\n      - Name\n  job"
  },
  {
    "path": "pkg/config/testdata/custom_namespace.ok.yml",
    "chars": 421,
    "preview": "apiVersion: v1alpha1\nsts-region: eu-west-1\ncustomNamespace:\n  - name: customMetrics\n    namespace: CustomEC2Metrics\n    "
  },
  {
    "path": "pkg/config/testdata/custom_namespace_without_name.bad.yml",
    "chars": 397,
    "preview": "apiVersion: v1alpha1\nsts-region: eu-west-1\ncustomNamespace:\n  - namespace: CustomEC2Metrics\n    regions:\n      - us-east"
  },
  {
    "path": "pkg/config/testdata/custom_namespace_without_namespace.bad.yml",
    "chars": 389,
    "preview": "apiVersion: v1alpha1\nsts-region: eu-west-1\ncustomNamespace:\n  - name: customMetrics\n    regions:\n      - us-east-1\n    m"
  },
  {
    "path": "pkg/config/testdata/custom_namespace_without_region.bad.yml",
    "chars": 387,
    "preview": "apiVersion: v1alpha1\nsts-region: eu-west-1\ncustomNamespace:\n  - name: customMetrics\n    namespace: customMetrics\n    met"
  },
  {
    "path": "pkg/config/testdata/discovery_job_exported_tags_alias.bad.yml",
    "chars": 411,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  exportedTagsOnMetrics:\n    s3:\n      - BucketName\n  jobs:\n    - type: AWS/S3\n      reg"
  },
  {
    "path": "pkg/config/testdata/discovery_job_exported_tags_mismatch.bad.yml",
    "chars": 417,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  exportedTagsOnMetrics:\n    AWS/RDS:\n      - ClusterName\n  jobs:\n    - type: AWS/S3\n   "
  },
  {
    "path": "pkg/config/testdata/discovery_job_type_alias.bad.yml",
    "chars": 355,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: s3\n      regions:\n        - eu-west-1\n      metrics:\n        - name:"
  },
  {
    "path": "pkg/config/testdata/discovery_job_type_unknown.bad.yml",
    "chars": 195,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/FancyNewNamespace\n      regions:\n        - eu-west-1\n      metri"
  },
  {
    "path": "pkg/config/testdata/empty_rolearn.ok.yml",
    "chars": 391,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/S3\n      regions:\n        - eu-west-1\n      roles:\n        - rol"
  },
  {
    "path": "pkg/config/testdata/externalid_with_empty_rolearn.bad.yml",
    "chars": 423,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/S3\n      regions:\n        - eu-west-1\n      roles:\n        - ext"
  },
  {
    "path": "pkg/config/testdata/externalid_without_rolearn.bad.yml",
    "chars": 404,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/S3\n      regions:\n        - eu-west-1\n      roles:\n        - ext"
  },
  {
    "path": "pkg/config/testdata/multiple_roles.ok.yml",
    "chars": 462,
    "preview": "apiVersion: v1alpha1\ndiscovery:\n  jobs:\n    - type: AWS/S3\n      regions:\n        - eu-west-1\n      roles:\n        - rol"
  },
  {
    "path": "pkg/config/testdata/sts_region.ok.yml",
    "chars": 330,
    "preview": "apiVersion: v1alpha1\nsts-region: eu-west-1\ndiscovery:\n  jobs:\n    - type: AWS/S3\n      regions:\n        - eu-west-1\n    "
  },
  {
    "path": "pkg/config/testdata/unknown_version.bad.yml",
    "chars": 3501,
    "preview": "apiVersion: invalidVersion\ndiscovery:\n  exportedTagsOnMetrics:\n    AWS/EBS:\n      - VolumeId\n    AWS/Kafka:\n      - Name"
  },
  {
    "path": "pkg/exporter.go",
    "chars": 7294,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/exporter_enhancedmetrics_test.go",
    "chars": 17365,
    "preview": "package exporter\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/aws/aws-sdk-go-v2/aws\"\n\tdynamodbTy"
  },
  {
    "path": "pkg/exporter_test.go",
    "chars": 7759,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/config/provider.go",
    "chars": 1226,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/registry.go",
    "chars": 3112,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/registry_test.go",
    "chars": 8956,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/dynamodb/client.go",
    "chars": 2430,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/dynamodb/client_test.go",
    "chars": 3365,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/dynamodb/service.go",
    "chars": 7932,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/dynamodb/service_test.go",
    "chars": 8233,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/elasticache/client.go",
    "chars": 2669,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/elasticache/client_test.go",
    "chars": 4072,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/elasticache/service.go",
    "chars": 6818,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/elasticache/service_test.go",
    "chars": 7310,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/lambda/client.go",
    "chars": 2403,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/lambda/client_test.go",
    "chars": 3755,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/lambda/service.go",
    "chars": 6440,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/lambda/service_test.go",
    "chars": 6003,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/rds/client.go",
    "chars": 2540,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/rds/client_test.go",
    "chars": 4382,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/rds/service.go",
    "chars": 7307,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/rds/service_test.go",
    "chars": 8064,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service/services.go",
    "chars": 1633,
    "preview": "// Copyright 2026 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service.go",
    "chars": 3477,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/internal/enhancedmetrics/service_test.go",
    "chars": 5577,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/job/cloudwatchrunner/customnamespace.go",
    "chars": 1473,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/cloudwatchrunner/discovery.go",
    "chars": 1478,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/cloudwatchrunner/runner.go",
    "chars": 1167,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/custom.go",
    "chars": 3618,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/discovery.go",
    "chars": 7637,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/discovery_test.go",
    "chars": 13865,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/getmetricdata/compact.go",
    "chars": 1163,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/getmetricdata/compact_test.go",
    "chars": 2521,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/getmetricdata/iterator.go",
    "chars": 7288,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/getmetricdata/iterator_test.go",
    "chars": 10060,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/getmetricdata/processor.go",
    "chars": 5383,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/getmetricdata/processor_test.go",
    "chars": 13076,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/getmetricdata/windowcalculator.go",
    "chars": 1766,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/getmetricdata/windowcalculator_test.go",
    "chars": 3604,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/listmetrics/processor.go",
    "chars": 881,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator.go",
    "chars": 10531,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_api_gateway_test.go",
    "chars": 4859,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_client_vpn_test.go",
    "chars": 2280,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_ddosprotection_test.go",
    "chars": 2531,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_directoryservice_test.go",
    "chars": 2364,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_dx_test.go",
    "chars": 2278,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_ec2_test.go",
    "chars": 3834,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_ec_test.go",
    "chars": 3981,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_ecs_test.go",
    "chars": 3641,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_event_roles_test.go",
    "chars": 2496,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_globalaccelerator_test.go",
    "chars": 4171,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_gwlb_test.go",
    "chars": 3981,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_ipam_test.go",
    "chars": 2736,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_kms_test.go",
    "chars": 2238,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_lambda_test.go",
    "chars": 3711,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_logging_test.go",
    "chars": 1843,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_logs_test.go",
    "chars": 3417,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_mediaconvert_test.go",
    "chars": 3676,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_memorydb_test.go",
    "chars": 3943,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_mq_test.go",
    "chars": 3978,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_qldb_test.go",
    "chars": 2726,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_redshift_serverless_test.go",
    "chars": 2544,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_sagemaker_endpoint_test.go",
    "chars": 3258,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_sagemaker_inf_component_test.go",
    "chars": 2512,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_sagemaker_inf_rec_test.go",
    "chars": 2475,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_sagemaker_pipeline_test.go",
    "chars": 3830,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_sagemaker_processing_test.go",
    "chars": 2427,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_sagemaker_test.go",
    "chars": 6267,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_sagemaker_training_test.go",
    "chars": 2391,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/maxdimassociator/associator_sagemaker_transform_test.go",
    "chars": 2416,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/resourcemetadata/resource.go",
    "chars": 1339,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/scrape.go",
    "chars": 7615,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/job/scraper.go",
    "chars": 8617,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/job/scraper_test.go",
    "chars": 21751,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  },
  {
    "path": "pkg/job/static.go",
    "chars": 2331,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/model/model.go",
    "chars": 7789,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/model/model_test.go",
    "chars": 4706,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/promutil/migrate.go",
    "chars": 12738,
    "preview": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may n"
  },
  {
    "path": "pkg/promutil/migrate_test.go",
    "chars": 46613,
    "preview": "// Copyright The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not us"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the ivx/yet-another-cloudwatch-exporter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 202 files (836.9 KB), approximately 234.6k tokens, and a symbol index with 584 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!