├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
└── levitate
├── change-events
├── python
│ ├── README.md
│ ├── change_event.py
│ └── requirements.txt
├── ruby
│ └── change-event.rb
└── rust
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ └── src
│ └── main.rs
├── exporter
├── kube-state-metrics
│ └── README.md
└── statping
│ └── README.md
├── grafana-dashboards
└── cloudswatch-metric-stream
│ ├── ec2
│ ├── README.md
│ └── dashboard.json
│ └── rds
│ ├── README.md
│ └── dashboard.json
└── remote-write
├── jmxtrans
├── .gitignore
├── README.md
├── docker-compose.yaml
├── jmxtrans-config
│ └── graphite.json
├── jvmapp
│ ├── Dockerfile
│ └── SampleApp.java
├── relabel.yaml
└── vmagent.yaml
├── opentelemetry-collector
├── opencensus-receiver
│ └── docker
│ │ └── README.md
└── prometheus-receiver
│ ├── README.md
│ ├── app
│ ├── Dockerfile
│ ├── go.mod
│ ├── go.sum
│ └── main.go
│ ├── docker-compose.yaml
│ └── otel-collector-config.yaml
├── prometheus-agent
└── k8s
│ └── README.md
├── python
├── README.md
└── app.py
├── statsd
├── relay
│ ├── .gitignore
│ ├── README.md
│ ├── docker-compose.yaml
│ ├── statsd
│ │ ├── Dockerfile
│ │ └── config.js
│ ├── test
│ │ ├── requirements.txt
│ │ └── statsd-test.py
│ └── vmagent.yaml
├── repeater
│ ├── .gitignore
│ ├── README.md
│ ├── docker-compose.yaml
│ ├── statsd
│ │ ├── Dockerfile
│ │ └── config.js
│ ├── test
│ │ ├── requirements.txt
│ │ └── statsd-test.py
│ └── vmagent.yaml
└── vmagent-graphite
│ ├── .gitignore
│ ├── README.md
│ ├── docker-compose.yaml
│ ├── statsd
│ ├── Dockerfile
│ └── config.js
│ ├── test
│ ├── requirements.txt
│ └── statsd-test.py
│ └── vmagent.yaml
├── telegraf
├── http-prometheusremotewrite
│ ├── .gitignore
│ ├── README.md
│ ├── docker-compose.yaml
│ ├── telegraf
│ │ └── etc
│ │ │ └── telegraf.conf
│ └── test
│ │ └── statsd-test.py
├── influxdb-to-vmagent
│ ├── .gitignore
│ ├── README.md
│ ├── docker-compose.yaml
│ ├── telegraf
│ │ └── etc
│ │ │ └── telegraf.conf
│ ├── test
│ │ └── statsd-test.py
│ └── vmagent.yaml
└── prometheus-client
│ ├── .gitignore
│ ├── README.md
│ ├── docker-compose.yaml
│ ├── telegraf
│ └── etc
│ │ └── telegraf.conf
│ ├── test
│ └── statsd-test.py
│ └── vmagent.yaml
└── vmagent
├── docker
└── README.md
├── ecs
└── README.md
└── k8s
└── README.md
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | .
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 last9
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # last9-integrations
4 |
5 | Integrations and reference code used for Last9 products.
6 |
7 | ## Levitate Integrations
8 |
9 | [Levitate](https://last9.io/levitate-tsdb) is Last9’s managed time series data warehouse.
10 |
11 | We built Levitate to give engineering teams a cost-effective tool to monitor large, complex systems. Now, engineering hours are not spent monitoring your monitor i.e. managing TSDB availability, scaling, replication, and multiple instances.
12 |
13 | #### Solves High Cardinality
14 |
15 | Levitate is built to handle the massive scales of data and can handle queries at any cardinality. Above all, it gives you real-time insights into what metrics are unused.
16 |
17 | #### Pay for what you use, reduce costs
18 |
19 | Levitate reduces storage costs by up to 50% compared to similar TSDBs. This is over and above the engineering time, and overheads spent maintaining internal infrastructure.
20 | With Levitate's data retention policies & tiered storage, you pay for the metrics you use. Scale without having to tune the configuration & having to run a whole setup for data scaling.
21 |
22 | #### Increase engineering productivity
23 |
24 | Levitate is fully managed. No need to worry about adding more machines, managing replication, or multiple Prometheus instances. Just change the remote-write endpoint of your one or many TSDBs. A simple UI manages it all.
25 |
26 | With Levitate, you can resolve incidents faster with decreased querying times, and allow engineering to focus on building the product.
27 |
28 | Levitate is easy to integrate with any source that can send metrics to Prometheus.
29 |
30 | ----
31 |
32 | Find sample applications of supported integrations and some useful exporter demo setups below.
33 |
34 | ### remote-write
35 |
36 | Sample setups of common remote write integrations.
37 |
38 | - [opentelemetry collector via prometheus receiver](./levitate/remote-write/opentelemetry-collector/prometheus-receiver)
39 | - [statsd](./levitate/remote-write/statsd)
40 | - [telegraf](./levitate/remote-write/telegraf)
41 | - [jmxtrans](./levitate/remote-write/jmxtrans)
42 | - [vmagent](./levitate/remote-write/vmagent) - WIP 🏗️
43 |
44 | ### exporters
45 |
46 | Sample setups of common Prometheus exporters.
47 |
48 | - [kube-state-metrics](./levitate/exporter/kube-state-metrics) - WIP 🏗️
49 | - [statping](./levitate/exporter/statping) - WIP 🏗️
50 |
--------------------------------------------------------------------------------
/levitate/change-events/python/README.md:
--------------------------------------------------------------------------------
1 | ## Levitate Change Event Registration
2 |
3 | This Python script is used to register a change event with the Levitate API.
4 |
5 | ### Requirements
6 |
7 | - Python
8 | - requests library
9 |
10 | ### Setup
11 |
12 | Set up a virtual environment and activate it:
13 |
14 | ``` shell
15 | python3 -m venv venv
16 | source venv/bin/activate
17 | ```
18 |
19 | Install the required Python libraries:
20 |
21 | ``` shell
22 | pip install -r requirements.txt
23 | ```
24 |
25 | Set the required environment variables:
26 |
27 | ``` shell
28 | export LEVITATE_REFRESH_TOKEN=
29 | export LEVITATE_ORG=
30 | ```
31 |
32 | Follow the instructions [here](https://docs.last9.io/docs/change-events) to obtain the values of the environment variables.
33 |
34 | ### Usage
35 |
36 | Run the script:
37 |
38 | ``` shell
39 | python change_event.py
40 | ```
41 |
42 | If the change event is registered successfully, the script will print "Change event registered successfully". If there is an error, an exception will be raised with a message indicating the cause of the error.
43 |
--------------------------------------------------------------------------------
/levitate/change-events/python/change_event.py:
--------------------------------------------------------------------------------
1 | import os
2 | import requests
3 | import json
4 |
5 | LEVITATE_REFRESH_TOKEN = os.getenv("LEVITATE_REFRESH_TOKEN")
6 | LEVITATE_ACCESS_TOKEN_API = "https://app.last9.io/api/v4/oauth/access_token"
7 | LEVITATE_ORG = os.getenv("LEVITATE_ORG")
8 |
9 | def api_token():
10 | headers = {'Content-Type': 'application/json'}
11 | data = {"refresh_token": LEVITATE_REFRESH_TOKEN}
12 | response = requests.post(LEVITATE_ACCESS_TOKEN_API, headers=headers, data=json.dumps(data))
13 |
14 | if response.status_code != 200:
15 | raise Exception("Access Token can't be retrieved, {}".format(response.text))
16 |
17 | body = response.json()
18 | return body["access_token"]
19 |
20 | if not LEVITATE_REFRESH_TOKEN:
21 | raise Exception("LEVITATE_REFRESH_TOKEN is not set")
22 |
23 | if not LEVITATE_ORG:
24 | raise Exception("LEVITATE_ORG is not set")
25 |
26 | url = "https://app.last9.io/api/v4/organizations/{}/change_events".format(LEVITATE_ORG)
27 | headers = {
28 | 'Content-Type': 'application/json',
29 | 'X-LAST9-API-TOKEN': 'Bearer {}'.format(api_token())
30 | }
31 | data = {
32 | "event_name": "deployment",
33 | "event_state": "start",
34 | "attributes": {
35 | "revision": "",
36 | "user": "john.smith",
37 | "environment": "production"
38 | }
39 | }
40 | response = requests.put(url, headers=headers, data=json.dumps(data))
41 |
42 | if response.status_code == 200:
43 | print("Change event registered successfully")
44 | else:
45 | raise Exception("Change Event -> Levitate failed. {}".format(response.text))
46 |
--------------------------------------------------------------------------------
/levitate/change-events/python/requirements.txt:
--------------------------------------------------------------------------------
1 | requests==2.31.0
2 |
--------------------------------------------------------------------------------
/levitate/change-events/ruby/change-event.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "net/http"
4 | require "uri"
5 | require "json"
6 |
7 | # Follow the guide on
8 | LEVITATE_REFRESH_TOKEN = ENV["LEVITATE_REFRESH_TOKEN"]
9 | LEVITATE_ACCESS_TOKEN_API = "https://app.last9.io/api/v4/oauth/access_token"
10 | LEVITATE_ORG = ENV["LEVITATE_ORG"]
11 |
12 | class Levitate
13 | def api_token
14 | uri = URI.parse(LEVITATE_ACCESS_TOKEN_API)
15 | request = Net::HTTP::Post.new(uri)
16 | request.content_type = "application/json"
17 | request.body = JSON.dump({
18 | "refresh_token": LEVITATE_REFRESH_TOKEN
19 | })
20 | req_options = {
21 | use_ssl: uri.scheme == "https",
22 | }
23 |
24 | response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
25 | http.request(request)
26 | end
27 |
28 |
29 | body = JSON.parse(response.body)
30 | if body["access_token"] == nil
31 | raise "Access Token can't be rertieved, #{body}"
32 | end
33 |
34 | body["access_token"]
35 | end
36 | end
37 |
38 |
39 | raise "LEVITATE_REFRESH_TOKEN is not set" unless LEVITATE_REFRESH_TOKEN
40 | raise "LEVITATE_ORG is not set" unless LEVITATE_ORG
41 |
42 | uri = URI.parse("https://app.last9.io/api/v4/organizations/#{LEVITATE_ORG}/change_events")
43 | request = Net::HTTP::Put.new(uri)
44 | request.content_type = "application/json"
45 | request["X-LAST9-API-TOKEN"] = "Bearer #{Levitate.new.api_token}"
46 | request.body = JSON.dump({
47 | "event_name" => "deployment",
48 | "event_state" => "start",
49 | "attributes" => {
50 | # Add more metadata about which service is getting deployed
51 | "revision" => "",
52 | "user" => "john.smith",
53 | "environment" => "production"
54 | }
55 | })
56 | req_options = {
57 | use_ssl: uri.scheme == "https",
58 | }
59 |
60 | response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
61 | http.request(request)
62 | end
63 |
64 | if response.code == '200'
65 | puts "Change event registered succesfully"
66 | else
67 | raise "Change Event -> Levitate failed. #{response.body}"
68 | end
69 |
--------------------------------------------------------------------------------
/levitate/change-events/rust/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/levitate/change-events/rust/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "addr2line"
7 | version = "0.21.0"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
10 | dependencies = [
11 | "gimli",
12 | ]
13 |
14 | [[package]]
15 | name = "adler"
16 | version = "1.0.2"
17 | source = "registry+https://github.com/rust-lang/crates.io-index"
18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
19 |
20 | [[package]]
21 | name = "autocfg"
22 | version = "1.2.0"
23 | source = "registry+https://github.com/rust-lang/crates.io-index"
24 | checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
25 |
26 | [[package]]
27 | name = "backtrace"
28 | version = "0.3.71"
29 | source = "registry+https://github.com/rust-lang/crates.io-index"
30 | checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
31 | dependencies = [
32 | "addr2line",
33 | "cc",
34 | "cfg-if",
35 | "libc",
36 | "miniz_oxide",
37 | "object",
38 | "rustc-demangle",
39 | ]
40 |
41 | [[package]]
42 | name = "base64"
43 | version = "0.21.7"
44 | source = "registry+https://github.com/rust-lang/crates.io-index"
45 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
46 |
47 | [[package]]
48 | name = "bitflags"
49 | version = "1.3.2"
50 | source = "registry+https://github.com/rust-lang/crates.io-index"
51 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
52 |
53 | [[package]]
54 | name = "bitflags"
55 | version = "2.5.0"
56 | source = "registry+https://github.com/rust-lang/crates.io-index"
57 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
58 |
59 | [[package]]
60 | name = "bumpalo"
61 | version = "3.16.0"
62 | source = "registry+https://github.com/rust-lang/crates.io-index"
63 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
64 |
65 | [[package]]
66 | name = "bytes"
67 | version = "1.6.0"
68 | source = "registry+https://github.com/rust-lang/crates.io-index"
69 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
70 |
71 | [[package]]
72 | name = "cc"
73 | version = "1.0.95"
74 | source = "registry+https://github.com/rust-lang/crates.io-index"
75 | checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b"
76 |
77 | [[package]]
78 | name = "cfg-if"
79 | version = "1.0.0"
80 | source = "registry+https://github.com/rust-lang/crates.io-index"
81 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
82 |
83 | [[package]]
84 | name = "core-foundation"
85 | version = "0.9.4"
86 | source = "registry+https://github.com/rust-lang/crates.io-index"
87 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
88 | dependencies = [
89 | "core-foundation-sys",
90 | "libc",
91 | ]
92 |
93 | [[package]]
94 | name = "core-foundation-sys"
95 | version = "0.8.6"
96 | source = "registry+https://github.com/rust-lang/crates.io-index"
97 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
98 |
99 | [[package]]
100 | name = "encoding_rs"
101 | version = "0.8.34"
102 | source = "registry+https://github.com/rust-lang/crates.io-index"
103 | checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
104 | dependencies = [
105 | "cfg-if",
106 | ]
107 |
108 | [[package]]
109 | name = "equivalent"
110 | version = "1.0.1"
111 | source = "registry+https://github.com/rust-lang/crates.io-index"
112 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
113 |
114 | [[package]]
115 | name = "errno"
116 | version = "0.3.8"
117 | source = "registry+https://github.com/rust-lang/crates.io-index"
118 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
119 | dependencies = [
120 | "libc",
121 | "windows-sys 0.52.0",
122 | ]
123 |
124 | [[package]]
125 | name = "fastrand"
126 | version = "2.0.2"
127 | source = "registry+https://github.com/rust-lang/crates.io-index"
128 | checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
129 |
130 | [[package]]
131 | name = "fnv"
132 | version = "1.0.7"
133 | source = "registry+https://github.com/rust-lang/crates.io-index"
134 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
135 |
136 | [[package]]
137 | name = "foreign-types"
138 | version = "0.3.2"
139 | source = "registry+https://github.com/rust-lang/crates.io-index"
140 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
141 | dependencies = [
142 | "foreign-types-shared",
143 | ]
144 |
145 | [[package]]
146 | name = "foreign-types-shared"
147 | version = "0.1.1"
148 | source = "registry+https://github.com/rust-lang/crates.io-index"
149 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
150 |
151 | [[package]]
152 | name = "form_urlencoded"
153 | version = "1.2.1"
154 | source = "registry+https://github.com/rust-lang/crates.io-index"
155 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
156 | dependencies = [
157 | "percent-encoding",
158 | ]
159 |
160 | [[package]]
161 | name = "futures-channel"
162 | version = "0.3.30"
163 | source = "registry+https://github.com/rust-lang/crates.io-index"
164 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
165 | dependencies = [
166 | "futures-core",
167 | ]
168 |
169 | [[package]]
170 | name = "futures-core"
171 | version = "0.3.30"
172 | source = "registry+https://github.com/rust-lang/crates.io-index"
173 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
174 |
175 | [[package]]
176 | name = "futures-io"
177 | version = "0.3.30"
178 | source = "registry+https://github.com/rust-lang/crates.io-index"
179 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
180 |
181 | [[package]]
182 | name = "futures-sink"
183 | version = "0.3.30"
184 | source = "registry+https://github.com/rust-lang/crates.io-index"
185 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
186 |
187 | [[package]]
188 | name = "futures-task"
189 | version = "0.3.30"
190 | source = "registry+https://github.com/rust-lang/crates.io-index"
191 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
192 |
193 | [[package]]
194 | name = "futures-util"
195 | version = "0.3.30"
196 | source = "registry+https://github.com/rust-lang/crates.io-index"
197 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
198 | dependencies = [
199 | "futures-core",
200 | "futures-io",
201 | "futures-task",
202 | "memchr",
203 | "pin-project-lite",
204 | "pin-utils",
205 | "slab",
206 | ]
207 |
208 | [[package]]
209 | name = "gimli"
210 | version = "0.28.1"
211 | source = "registry+https://github.com/rust-lang/crates.io-index"
212 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
213 |
214 | [[package]]
215 | name = "h2"
216 | version = "0.3.26"
217 | source = "registry+https://github.com/rust-lang/crates.io-index"
218 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
219 | dependencies = [
220 | "bytes",
221 | "fnv",
222 | "futures-core",
223 | "futures-sink",
224 | "futures-util",
225 | "http",
226 | "indexmap",
227 | "slab",
228 | "tokio",
229 | "tokio-util",
230 | "tracing",
231 | ]
232 |
233 | [[package]]
234 | name = "hashbrown"
235 | version = "0.14.3"
236 | source = "registry+https://github.com/rust-lang/crates.io-index"
237 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
238 |
239 | [[package]]
240 | name = "http"
241 | version = "0.2.12"
242 | source = "registry+https://github.com/rust-lang/crates.io-index"
243 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
244 | dependencies = [
245 | "bytes",
246 | "fnv",
247 | "itoa",
248 | ]
249 |
250 | [[package]]
251 | name = "http-body"
252 | version = "0.4.6"
253 | source = "registry+https://github.com/rust-lang/crates.io-index"
254 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
255 | dependencies = [
256 | "bytes",
257 | "http",
258 | "pin-project-lite",
259 | ]
260 |
261 | [[package]]
262 | name = "httparse"
263 | version = "1.8.0"
264 | source = "registry+https://github.com/rust-lang/crates.io-index"
265 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
266 |
267 | [[package]]
268 | name = "httpdate"
269 | version = "1.0.3"
270 | source = "registry+https://github.com/rust-lang/crates.io-index"
271 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
272 |
273 | [[package]]
274 | name = "hyper"
275 | version = "0.14.28"
276 | source = "registry+https://github.com/rust-lang/crates.io-index"
277 | checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
278 | dependencies = [
279 | "bytes",
280 | "futures-channel",
281 | "futures-core",
282 | "futures-util",
283 | "h2",
284 | "http",
285 | "http-body",
286 | "httparse",
287 | "httpdate",
288 | "itoa",
289 | "pin-project-lite",
290 | "socket2",
291 | "tokio",
292 | "tower-service",
293 | "tracing",
294 | "want",
295 | ]
296 |
297 | [[package]]
298 | name = "hyper-tls"
299 | version = "0.5.0"
300 | source = "registry+https://github.com/rust-lang/crates.io-index"
301 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
302 | dependencies = [
303 | "bytes",
304 | "hyper",
305 | "native-tls",
306 | "tokio",
307 | "tokio-native-tls",
308 | ]
309 |
310 | [[package]]
311 | name = "idna"
312 | version = "0.5.0"
313 | source = "registry+https://github.com/rust-lang/crates.io-index"
314 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
315 | dependencies = [
316 | "unicode-bidi",
317 | "unicode-normalization",
318 | ]
319 |
320 | [[package]]
321 | name = "indexmap"
322 | version = "2.2.6"
323 | source = "registry+https://github.com/rust-lang/crates.io-index"
324 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
325 | dependencies = [
326 | "equivalent",
327 | "hashbrown",
328 | ]
329 |
330 | [[package]]
331 | name = "ipnet"
332 | version = "2.9.0"
333 | source = "registry+https://github.com/rust-lang/crates.io-index"
334 | checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
335 |
336 | [[package]]
337 | name = "itoa"
338 | version = "1.0.11"
339 | source = "registry+https://github.com/rust-lang/crates.io-index"
340 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
341 |
342 | [[package]]
343 | name = "js-sys"
344 | version = "0.3.69"
345 | source = "registry+https://github.com/rust-lang/crates.io-index"
346 | checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
347 | dependencies = [
348 | "wasm-bindgen",
349 | ]
350 |
351 | [[package]]
352 | name = "lazy_static"
353 | version = "1.4.0"
354 | source = "registry+https://github.com/rust-lang/crates.io-index"
355 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
356 |
357 | [[package]]
358 | name = "libc"
359 | version = "0.2.153"
360 | source = "registry+https://github.com/rust-lang/crates.io-index"
361 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
362 |
363 | [[package]]
364 | name = "linux-raw-sys"
365 | version = "0.4.13"
366 | source = "registry+https://github.com/rust-lang/crates.io-index"
367 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
368 |
369 | [[package]]
370 | name = "log"
371 | version = "0.4.21"
372 | source = "registry+https://github.com/rust-lang/crates.io-index"
373 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
374 |
375 | [[package]]
376 | name = "memchr"
377 | version = "2.7.2"
378 | source = "registry+https://github.com/rust-lang/crates.io-index"
379 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
380 |
381 | [[package]]
382 | name = "mime"
383 | version = "0.3.17"
384 | source = "registry+https://github.com/rust-lang/crates.io-index"
385 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
386 |
387 | [[package]]
388 | name = "miniz_oxide"
389 | version = "0.7.2"
390 | source = "registry+https://github.com/rust-lang/crates.io-index"
391 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
392 | dependencies = [
393 | "adler",
394 | ]
395 |
396 | [[package]]
397 | name = "mio"
398 | version = "0.8.11"
399 | source = "registry+https://github.com/rust-lang/crates.io-index"
400 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
401 | dependencies = [
402 | "libc",
403 | "wasi",
404 | "windows-sys 0.48.0",
405 | ]
406 |
407 | [[package]]
408 | name = "native-tls"
409 | version = "0.2.11"
410 | source = "registry+https://github.com/rust-lang/crates.io-index"
411 | checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
412 | dependencies = [
413 | "lazy_static",
414 | "libc",
415 | "log",
416 | "openssl",
417 | "openssl-probe",
418 | "openssl-sys",
419 | "schannel",
420 | "security-framework",
421 | "security-framework-sys",
422 | "tempfile",
423 | ]
424 |
425 | [[package]]
426 | name = "object"
427 | version = "0.32.2"
428 | source = "registry+https://github.com/rust-lang/crates.io-index"
429 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
430 | dependencies = [
431 | "memchr",
432 | ]
433 |
434 | [[package]]
435 | name = "once_cell"
436 | version = "1.19.0"
437 | source = "registry+https://github.com/rust-lang/crates.io-index"
438 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
439 |
440 | [[package]]
441 | name = "openssl"
442 | version = "0.10.64"
443 | source = "registry+https://github.com/rust-lang/crates.io-index"
444 | checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
445 | dependencies = [
446 | "bitflags 2.5.0",
447 | "cfg-if",
448 | "foreign-types",
449 | "libc",
450 | "once_cell",
451 | "openssl-macros",
452 | "openssl-sys",
453 | ]
454 |
455 | [[package]]
456 | name = "openssl-macros"
457 | version = "0.1.1"
458 | source = "registry+https://github.com/rust-lang/crates.io-index"
459 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
460 | dependencies = [
461 | "proc-macro2",
462 | "quote",
463 | "syn",
464 | ]
465 |
466 | [[package]]
467 | name = "openssl-probe"
468 | version = "0.1.5"
469 | source = "registry+https://github.com/rust-lang/crates.io-index"
470 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
471 |
472 | [[package]]
473 | name = "openssl-sys"
474 | version = "0.9.102"
475 | source = "registry+https://github.com/rust-lang/crates.io-index"
476 | checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2"
477 | dependencies = [
478 | "cc",
479 | "libc",
480 | "pkg-config",
481 | "vcpkg",
482 | ]
483 |
484 | [[package]]
485 | name = "percent-encoding"
486 | version = "2.3.1"
487 | source = "registry+https://github.com/rust-lang/crates.io-index"
488 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
489 |
490 | [[package]]
491 | name = "pin-project-lite"
492 | version = "0.2.14"
493 | source = "registry+https://github.com/rust-lang/crates.io-index"
494 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
495 |
496 | [[package]]
497 | name = "pin-utils"
498 | version = "0.1.0"
499 | source = "registry+https://github.com/rust-lang/crates.io-index"
500 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
501 |
502 | [[package]]
503 | name = "pkg-config"
504 | version = "0.3.30"
505 | source = "registry+https://github.com/rust-lang/crates.io-index"
506 | checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
507 |
508 | [[package]]
509 | name = "proc-macro2"
510 | version = "1.0.81"
511 | source = "registry+https://github.com/rust-lang/crates.io-index"
512 | checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
513 | dependencies = [
514 | "unicode-ident",
515 | ]
516 |
517 | [[package]]
518 | name = "quote"
519 | version = "1.0.36"
520 | source = "registry+https://github.com/rust-lang/crates.io-index"
521 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
522 | dependencies = [
523 | "proc-macro2",
524 | ]
525 |
526 | [[package]]
527 | name = "reqwest"
528 | version = "0.11.27"
529 | source = "registry+https://github.com/rust-lang/crates.io-index"
530 | checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
531 | dependencies = [
532 | "base64",
533 | "bytes",
534 | "encoding_rs",
535 | "futures-core",
536 | "futures-util",
537 | "h2",
538 | "http",
539 | "http-body",
540 | "hyper",
541 | "hyper-tls",
542 | "ipnet",
543 | "js-sys",
544 | "log",
545 | "mime",
546 | "native-tls",
547 | "once_cell",
548 | "percent-encoding",
549 | "pin-project-lite",
550 | "rustls-pemfile",
551 | "serde",
552 | "serde_json",
553 | "serde_urlencoded",
554 | "sync_wrapper",
555 | "system-configuration",
556 | "tokio",
557 | "tokio-native-tls",
558 | "tower-service",
559 | "url",
560 | "wasm-bindgen",
561 | "wasm-bindgen-futures",
562 | "web-sys",
563 | "winreg",
564 | ]
565 |
566 | [[package]]
567 | name = "rust"
568 | version = "0.1.0"
569 | dependencies = [
570 | "reqwest",
571 | "serde",
572 | "serde_json",
573 | ]
574 |
575 | [[package]]
576 | name = "rustc-demangle"
577 | version = "0.1.23"
578 | source = "registry+https://github.com/rust-lang/crates.io-index"
579 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
580 |
581 | [[package]]
582 | name = "rustix"
583 | version = "0.38.34"
584 | source = "registry+https://github.com/rust-lang/crates.io-index"
585 | checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
586 | dependencies = [
587 | "bitflags 2.5.0",
588 | "errno",
589 | "libc",
590 | "linux-raw-sys",
591 | "windows-sys 0.52.0",
592 | ]
593 |
594 | [[package]]
595 | name = "rustls-pemfile"
596 | version = "1.0.4"
597 | source = "registry+https://github.com/rust-lang/crates.io-index"
598 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
599 | dependencies = [
600 | "base64",
601 | ]
602 |
603 | [[package]]
604 | name = "ryu"
605 | version = "1.0.17"
606 | source = "registry+https://github.com/rust-lang/crates.io-index"
607 | checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
608 |
609 | [[package]]
610 | name = "schannel"
611 | version = "0.1.23"
612 | source = "registry+https://github.com/rust-lang/crates.io-index"
613 | checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
614 | dependencies = [
615 | "windows-sys 0.52.0",
616 | ]
617 |
618 | [[package]]
619 | name = "security-framework"
620 | version = "2.10.0"
621 | source = "registry+https://github.com/rust-lang/crates.io-index"
622 | checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
623 | dependencies = [
624 | "bitflags 1.3.2",
625 | "core-foundation",
626 | "core-foundation-sys",
627 | "libc",
628 | "security-framework-sys",
629 | ]
630 |
631 | [[package]]
632 | name = "security-framework-sys"
633 | version = "2.10.0"
634 | source = "registry+https://github.com/rust-lang/crates.io-index"
635 | checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef"
636 | dependencies = [
637 | "core-foundation-sys",
638 | "libc",
639 | ]
640 |
641 | [[package]]
642 | name = "serde"
643 | version = "1.0.198"
644 | source = "registry+https://github.com/rust-lang/crates.io-index"
645 | checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
646 | dependencies = [
647 | "serde_derive",
648 | ]
649 |
650 | [[package]]
651 | name = "serde_derive"
652 | version = "1.0.198"
653 | source = "registry+https://github.com/rust-lang/crates.io-index"
654 | checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
655 | dependencies = [
656 | "proc-macro2",
657 | "quote",
658 | "syn",
659 | ]
660 |
661 | [[package]]
662 | name = "serde_json"
663 | version = "1.0.116"
664 | source = "registry+https://github.com/rust-lang/crates.io-index"
665 | checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
666 | dependencies = [
667 | "itoa",
668 | "ryu",
669 | "serde",
670 | ]
671 |
672 | [[package]]
673 | name = "serde_urlencoded"
674 | version = "0.7.1"
675 | source = "registry+https://github.com/rust-lang/crates.io-index"
676 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
677 | dependencies = [
678 | "form_urlencoded",
679 | "itoa",
680 | "ryu",
681 | "serde",
682 | ]
683 |
684 | [[package]]
685 | name = "slab"
686 | version = "0.4.9"
687 | source = "registry+https://github.com/rust-lang/crates.io-index"
688 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
689 | dependencies = [
690 | "autocfg",
691 | ]
692 |
693 | [[package]]
694 | name = "socket2"
695 | version = "0.5.6"
696 | source = "registry+https://github.com/rust-lang/crates.io-index"
697 | checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
698 | dependencies = [
699 | "libc",
700 | "windows-sys 0.52.0",
701 | ]
702 |
703 | [[package]]
704 | name = "syn"
705 | version = "2.0.60"
706 | source = "registry+https://github.com/rust-lang/crates.io-index"
707 | checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
708 | dependencies = [
709 | "proc-macro2",
710 | "quote",
711 | "unicode-ident",
712 | ]
713 |
714 | [[package]]
715 | name = "sync_wrapper"
716 | version = "0.1.2"
717 | source = "registry+https://github.com/rust-lang/crates.io-index"
718 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
719 |
720 | [[package]]
721 | name = "system-configuration"
722 | version = "0.5.1"
723 | source = "registry+https://github.com/rust-lang/crates.io-index"
724 | checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
725 | dependencies = [
726 | "bitflags 1.3.2",
727 | "core-foundation",
728 | "system-configuration-sys",
729 | ]
730 |
731 | [[package]]
732 | name = "system-configuration-sys"
733 | version = "0.5.0"
734 | source = "registry+https://github.com/rust-lang/crates.io-index"
735 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
736 | dependencies = [
737 | "core-foundation-sys",
738 | "libc",
739 | ]
740 |
741 | [[package]]
742 | name = "tempfile"
743 | version = "3.10.1"
744 | source = "registry+https://github.com/rust-lang/crates.io-index"
745 | checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
746 | dependencies = [
747 | "cfg-if",
748 | "fastrand",
749 | "rustix",
750 | "windows-sys 0.52.0",
751 | ]
752 |
753 | [[package]]
754 | name = "tinyvec"
755 | version = "1.6.0"
756 | source = "registry+https://github.com/rust-lang/crates.io-index"
757 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
758 | dependencies = [
759 | "tinyvec_macros",
760 | ]
761 |
762 | [[package]]
763 | name = "tinyvec_macros"
764 | version = "0.1.1"
765 | source = "registry+https://github.com/rust-lang/crates.io-index"
766 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
767 |
768 | [[package]]
769 | name = "tokio"
770 | version = "1.37.0"
771 | source = "registry+https://github.com/rust-lang/crates.io-index"
772 | checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
773 | dependencies = [
774 | "backtrace",
775 | "bytes",
776 | "libc",
777 | "mio",
778 | "pin-project-lite",
779 | "socket2",
780 | "windows-sys 0.48.0",
781 | ]
782 |
783 | [[package]]
784 | name = "tokio-native-tls"
785 | version = "0.3.1"
786 | source = "registry+https://github.com/rust-lang/crates.io-index"
787 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
788 | dependencies = [
789 | "native-tls",
790 | "tokio",
791 | ]
792 |
793 | [[package]]
794 | name = "tokio-util"
795 | version = "0.7.10"
796 | source = "registry+https://github.com/rust-lang/crates.io-index"
797 | checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
798 | dependencies = [
799 | "bytes",
800 | "futures-core",
801 | "futures-sink",
802 | "pin-project-lite",
803 | "tokio",
804 | "tracing",
805 | ]
806 |
807 | [[package]]
808 | name = "tower-service"
809 | version = "0.3.2"
810 | source = "registry+https://github.com/rust-lang/crates.io-index"
811 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
812 |
813 | [[package]]
814 | name = "tracing"
815 | version = "0.1.40"
816 | source = "registry+https://github.com/rust-lang/crates.io-index"
817 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
818 | dependencies = [
819 | "pin-project-lite",
820 | "tracing-core",
821 | ]
822 |
823 | [[package]]
824 | name = "tracing-core"
825 | version = "0.1.32"
826 | source = "registry+https://github.com/rust-lang/crates.io-index"
827 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
828 | dependencies = [
829 | "once_cell",
830 | ]
831 |
832 | [[package]]
833 | name = "try-lock"
834 | version = "0.2.5"
835 | source = "registry+https://github.com/rust-lang/crates.io-index"
836 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
837 |
838 | [[package]]
839 | name = "unicode-bidi"
840 | version = "0.3.15"
841 | source = "registry+https://github.com/rust-lang/crates.io-index"
842 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
843 |
844 | [[package]]
845 | name = "unicode-ident"
846 | version = "1.0.12"
847 | source = "registry+https://github.com/rust-lang/crates.io-index"
848 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
849 |
850 | [[package]]
851 | name = "unicode-normalization"
852 | version = "0.1.23"
853 | source = "registry+https://github.com/rust-lang/crates.io-index"
854 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
855 | dependencies = [
856 | "tinyvec",
857 | ]
858 |
859 | [[package]]
860 | name = "url"
861 | version = "2.5.0"
862 | source = "registry+https://github.com/rust-lang/crates.io-index"
863 | checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
864 | dependencies = [
865 | "form_urlencoded",
866 | "idna",
867 | "percent-encoding",
868 | ]
869 |
870 | [[package]]
871 | name = "vcpkg"
872 | version = "0.2.15"
873 | source = "registry+https://github.com/rust-lang/crates.io-index"
874 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
875 |
876 | [[package]]
877 | name = "want"
878 | version = "0.3.1"
879 | source = "registry+https://github.com/rust-lang/crates.io-index"
880 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
881 | dependencies = [
882 | "try-lock",
883 | ]
884 |
885 | [[package]]
886 | name = "wasi"
887 | version = "0.11.0+wasi-snapshot-preview1"
888 | source = "registry+https://github.com/rust-lang/crates.io-index"
889 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
890 |
891 | [[package]]
892 | name = "wasm-bindgen"
893 | version = "0.2.92"
894 | source = "registry+https://github.com/rust-lang/crates.io-index"
895 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
896 | dependencies = [
897 | "cfg-if",
898 | "wasm-bindgen-macro",
899 | ]
900 |
901 | [[package]]
902 | name = "wasm-bindgen-backend"
903 | version = "0.2.92"
904 | source = "registry+https://github.com/rust-lang/crates.io-index"
905 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
906 | dependencies = [
907 | "bumpalo",
908 | "log",
909 | "once_cell",
910 | "proc-macro2",
911 | "quote",
912 | "syn",
913 | "wasm-bindgen-shared",
914 | ]
915 |
916 | [[package]]
917 | name = "wasm-bindgen-futures"
918 | version = "0.4.42"
919 | source = "registry+https://github.com/rust-lang/crates.io-index"
920 | checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
921 | dependencies = [
922 | "cfg-if",
923 | "js-sys",
924 | "wasm-bindgen",
925 | "web-sys",
926 | ]
927 |
928 | [[package]]
929 | name = "wasm-bindgen-macro"
930 | version = "0.2.92"
931 | source = "registry+https://github.com/rust-lang/crates.io-index"
932 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
933 | dependencies = [
934 | "quote",
935 | "wasm-bindgen-macro-support",
936 | ]
937 |
938 | [[package]]
939 | name = "wasm-bindgen-macro-support"
940 | version = "0.2.92"
941 | source = "registry+https://github.com/rust-lang/crates.io-index"
942 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
943 | dependencies = [
944 | "proc-macro2",
945 | "quote",
946 | "syn",
947 | "wasm-bindgen-backend",
948 | "wasm-bindgen-shared",
949 | ]
950 |
951 | [[package]]
952 | name = "wasm-bindgen-shared"
953 | version = "0.2.92"
954 | source = "registry+https://github.com/rust-lang/crates.io-index"
955 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
956 |
957 | [[package]]
958 | name = "web-sys"
959 | version = "0.3.69"
960 | source = "registry+https://github.com/rust-lang/crates.io-index"
961 | checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
962 | dependencies = [
963 | "js-sys",
964 | "wasm-bindgen",
965 | ]
966 |
967 | [[package]]
968 | name = "windows-sys"
969 | version = "0.48.0"
970 | source = "registry+https://github.com/rust-lang/crates.io-index"
971 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
972 | dependencies = [
973 | "windows-targets 0.48.5",
974 | ]
975 |
976 | [[package]]
977 | name = "windows-sys"
978 | version = "0.52.0"
979 | source = "registry+https://github.com/rust-lang/crates.io-index"
980 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
981 | dependencies = [
982 | "windows-targets 0.52.5",
983 | ]
984 |
985 | [[package]]
986 | name = "windows-targets"
987 | version = "0.48.5"
988 | source = "registry+https://github.com/rust-lang/crates.io-index"
989 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
990 | dependencies = [
991 | "windows_aarch64_gnullvm 0.48.5",
992 | "windows_aarch64_msvc 0.48.5",
993 | "windows_i686_gnu 0.48.5",
994 | "windows_i686_msvc 0.48.5",
995 | "windows_x86_64_gnu 0.48.5",
996 | "windows_x86_64_gnullvm 0.48.5",
997 | "windows_x86_64_msvc 0.48.5",
998 | ]
999 |
1000 | [[package]]
1001 | name = "windows-targets"
1002 | version = "0.52.5"
1003 | source = "registry+https://github.com/rust-lang/crates.io-index"
1004 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
1005 | dependencies = [
1006 | "windows_aarch64_gnullvm 0.52.5",
1007 | "windows_aarch64_msvc 0.52.5",
1008 | "windows_i686_gnu 0.52.5",
1009 | "windows_i686_gnullvm",
1010 | "windows_i686_msvc 0.52.5",
1011 | "windows_x86_64_gnu 0.52.5",
1012 | "windows_x86_64_gnullvm 0.52.5",
1013 | "windows_x86_64_msvc 0.52.5",
1014 | ]
1015 |
1016 | [[package]]
1017 | name = "windows_aarch64_gnullvm"
1018 | version = "0.48.5"
1019 | source = "registry+https://github.com/rust-lang/crates.io-index"
1020 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
1021 |
1022 | [[package]]
1023 | name = "windows_aarch64_gnullvm"
1024 | version = "0.52.5"
1025 | source = "registry+https://github.com/rust-lang/crates.io-index"
1026 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
1027 |
1028 | [[package]]
1029 | name = "windows_aarch64_msvc"
1030 | version = "0.48.5"
1031 | source = "registry+https://github.com/rust-lang/crates.io-index"
1032 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
1033 |
1034 | [[package]]
1035 | name = "windows_aarch64_msvc"
1036 | version = "0.52.5"
1037 | source = "registry+https://github.com/rust-lang/crates.io-index"
1038 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
1039 |
1040 | [[package]]
1041 | name = "windows_i686_gnu"
1042 | version = "0.48.5"
1043 | source = "registry+https://github.com/rust-lang/crates.io-index"
1044 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
1045 |
1046 | [[package]]
1047 | name = "windows_i686_gnu"
1048 | version = "0.52.5"
1049 | source = "registry+https://github.com/rust-lang/crates.io-index"
1050 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
1051 |
1052 | [[package]]
1053 | name = "windows_i686_gnullvm"
1054 | version = "0.52.5"
1055 | source = "registry+https://github.com/rust-lang/crates.io-index"
1056 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
1057 |
1058 | [[package]]
1059 | name = "windows_i686_msvc"
1060 | version = "0.48.5"
1061 | source = "registry+https://github.com/rust-lang/crates.io-index"
1062 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
1063 |
1064 | [[package]]
1065 | name = "windows_i686_msvc"
1066 | version = "0.52.5"
1067 | source = "registry+https://github.com/rust-lang/crates.io-index"
1068 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
1069 |
1070 | [[package]]
1071 | name = "windows_x86_64_gnu"
1072 | version = "0.48.5"
1073 | source = "registry+https://github.com/rust-lang/crates.io-index"
1074 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
1075 |
1076 | [[package]]
1077 | name = "windows_x86_64_gnu"
1078 | version = "0.52.5"
1079 | source = "registry+https://github.com/rust-lang/crates.io-index"
1080 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
1081 |
1082 | [[package]]
1083 | name = "windows_x86_64_gnullvm"
1084 | version = "0.48.5"
1085 | source = "registry+https://github.com/rust-lang/crates.io-index"
1086 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
1087 |
1088 | [[package]]
1089 | name = "windows_x86_64_gnullvm"
1090 | version = "0.52.5"
1091 | source = "registry+https://github.com/rust-lang/crates.io-index"
1092 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
1093 |
1094 | [[package]]
1095 | name = "windows_x86_64_msvc"
1096 | version = "0.48.5"
1097 | source = "registry+https://github.com/rust-lang/crates.io-index"
1098 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
1099 |
1100 | [[package]]
1101 | name = "windows_x86_64_msvc"
1102 | version = "0.52.5"
1103 | source = "registry+https://github.com/rust-lang/crates.io-index"
1104 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
1105 |
1106 | [[package]]
1107 | name = "winreg"
1108 | version = "0.50.0"
1109 | source = "registry+https://github.com/rust-lang/crates.io-index"
1110 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
1111 | dependencies = [
1112 | "cfg-if",
1113 | "windows-sys 0.48.0",
1114 | ]
1115 |
--------------------------------------------------------------------------------
/levitate/change-events/rust/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | reqwest = { version = "0.11", features = ["blocking", "json"] }
10 | serde = { version = "1.0", features = ["derive"] }
11 | serde_json = "1.0"
12 |
--------------------------------------------------------------------------------
/levitate/change-events/rust/README.md:
--------------------------------------------------------------------------------
1 | ## Levitate Change Event Registration
2 |
3 | This Rust script is used to register a change event with the Levitate API.
4 |
5 | ### Requirements
6 |
7 | - rustc
8 | - cargo
9 |
10 | ### Setup
11 |
12 | ``` shell
13 | cargo build
14 | ```
15 |
16 | Set the required environment variables:
17 |
18 | ``` shell
19 | export LEVITATE_REFRESH_TOKEN=
20 | export LEVITATE_ORG=
21 | ```
22 |
23 | Follow the instructions [here](https://docs.last9.io/docs/change-events) to obtain the values of the environment variables.
24 |
25 | ### Usage
26 |
27 | Run the script:
28 |
29 | ``` shell
30 | cargo run
31 | ```
32 |
33 | If the change event is registered successfully, the script will print "Change event registered successfully". If there is an error, an exception will be raised with a message indicating the cause of the error.
34 |
--------------------------------------------------------------------------------
/levitate/change-events/rust/src/main.rs:
--------------------------------------------------------------------------------
1 | extern crate reqwest;
2 | extern crate serde;
3 | extern crate serde_json;
4 |
5 | use std::env;
6 | use serde::{Serialize, Deserialize};
7 |
8 | #[derive(Serialize, Deserialize)]
9 | struct AccessToken {
10 | access_token: String,
11 | }
12 |
13 | #[derive(Serialize, Deserialize)]
14 | struct RefreshToken {
15 | refresh_token: String,
16 | }
17 |
18 | #[derive(Serialize, Deserialize)]
19 | struct Attributes {
20 | revision: String,
21 | user: String,
22 | environment: String,
23 | }
24 |
25 | #[derive(Serialize, Deserialize)]
26 | struct Event {
27 | event_name: String,
28 | event_state: String,
29 | attributes: Attributes,
30 | }
31 |
32 | fn main() -> Result<(), Box> {
33 | let levitate_refresh_token = env::var("LEVITATE_REFRESH_TOKEN").expect("LEVITATE_REFRESH_TOKEN is not set");
34 | let levitate_org = env::var("LEVITATE_ORG").expect("LEVITATE_ORG is not set");
35 |
36 | let client = reqwest::blocking::Client::new();
37 |
38 | let refresh_token = RefreshToken {
39 | refresh_token: levitate_refresh_token,
40 | };
41 |
42 | let res: AccessToken = client.post("https://app.last9.io/api/v4/oauth/access_token")
43 | .json(&refresh_token)
44 | .send()?
45 | .json()?;
46 |
47 | println!("Access Token: {}", res.access_token);
48 |
49 | let event = Event {
50 | event_name: String::from("deployment"),
51 | event_state: String::from("start"),
52 | attributes: Attributes {
53 | revision: String::from(""),
54 | user: String::from("john.smith"),
55 | environment: String::from("production"),
56 | },
57 | };
58 |
59 | let res = client.put(&format!("https://app.last9.io/api/v4/organizations/{}/change_events", levitate_org))
60 | .header("X-LAST9-API-TOKEN", format!("Bearer {}", res.access_token))
61 | .json(&event)
62 | .send()?;
63 |
64 | if res.status().is_success() {
65 | println!("Change event registered successfully");
66 | } else {
67 | eprintln!("Change Event -> Levitate failed. {}", res.text()?);
68 | }
69 |
70 | Ok(())
71 | }
72 |
--------------------------------------------------------------------------------
/levitate/exporter/kube-state-metrics/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/last9/last9-integrations/8c9a66d98f253ff5e7afc0f9824c551b3f61f478/levitate/exporter/kube-state-metrics/README.md
--------------------------------------------------------------------------------
/levitate/exporter/statping/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/last9/last9-integrations/8c9a66d98f253ff5e7afc0f9824c551b3f61f478/levitate/exporter/statping/README.md
--------------------------------------------------------------------------------
/levitate/grafana-dashboards/cloudswatch-metric-stream/ec2/README.md:
--------------------------------------------------------------------------------
1 | ## How to use?
2 |
3 | This directory contains a sample Grafana dashboard's JSON file based on metrics from AWS Cloudwatch metric stream.
4 |
5 | You can import this into any Grafana, select a data source and start using it.
6 |
7 | ## Dashboard structure
8 |
9 | The dashboard contains following metrics and variables.
10 |
11 | ### Metrics
12 |
13 | 1. The percentage of CPU Utilization `amazonaws_com_AWS_EC2_CPUUtilization`
14 | 2. CPU Credit Balance `amazonaws_com_AWS_EC2_CPUCreditBalance`
15 | 3. Network In `amazonaws_com_AWS_EC2_NetworkIn_sum`
16 | 4. Network Out `amazonaws_com_AWS_EC2_NetworkOut_sum`
17 | 5. Status Check Failed `amazonaws_com_AWS_EC2_StatusCheckFailed_sum`
18 | 6. EBS IO Balance `amazonaws_com_AWS_EC2_EBSIOBalance_`
19 | 7. EBS Byte Balance `amazonaws_com_AWS_EC2_EBSByteBalance_`
20 | 8. CPU Surplus credits charged `amazonaws_com_AWS_EC2_CPUSurplusCreditsCharged_sum`
21 |
22 | ### Variables
23 |
24 | 1. EC2 Instance Identifier
25 |
26 | ## Integrate with AWS Cloudwatch Metric Stream for sending data to Levitate
27 |
28 | Follow our integration guide for [AWS Cloudwatch Metric Stream](https://docs.last9.io/docs/how-to-send-cloudwatch-metrics-to-levitate-via-aws-cloudstream).
29 |
30 | > Note that this step is optional, you can use the dashboard as it is with any other source apart from Levitate if you are already set up with AWS Cloudwatch Metric Stream.
31 |
--------------------------------------------------------------------------------
/levitate/grafana-dashboards/cloudswatch-metric-stream/ec2/dashboard.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": {
3 | "list": [
4 | {
5 | "builtIn": 1,
6 | "datasource": {
7 | "type": "datasource",
8 | "uid": "grafana"
9 | },
10 | "enable": true,
11 | "hide": true,
12 | "iconColor": "rgba(0, 211, 255, 1)",
13 | "name": "Annotations & Alerts",
14 | "target": {
15 | "limit": 100,
16 | "matchAny": false,
17 | "tags": [],
18 | "type": "dashboard"
19 | },
20 | "type": "dashboard"
21 | }
22 | ]
23 | },
24 | "description": "Dashboard for EC2 Instances based on metrics from AWS CloudWatch metrics stream",
25 | "editable": true,
26 | "fiscalYearStartMonth": 0,
27 | "graphTooltip": 0,
28 | "id": 63,
29 | "links": [],
30 | "liveNow": false,
31 | "panels": [
32 | {
33 | "datasource": {
34 | "type": "prometheus",
35 | "uid": "3BK8XQaVk"
36 | },
37 | "description": "The percentage of CPU Utilization.",
38 | "fieldConfig": {
39 | "defaults": {
40 | "color": {
41 | "mode": "palette-classic"
42 | },
43 | "custom": {
44 | "axisCenteredZero": false,
45 | "axisColorMode": "text",
46 | "axisLabel": "",
47 | "axisPlacement": "auto",
48 | "barAlignment": 0,
49 | "drawStyle": "line",
50 | "fillOpacity": 0,
51 | "gradientMode": "none",
52 | "hideFrom": {
53 | "legend": false,
54 | "tooltip": false,
55 | "viz": false
56 | },
57 | "lineInterpolation": "linear",
58 | "lineWidth": 1,
59 | "pointSize": 5,
60 | "scaleDistribution": {
61 | "type": "linear"
62 | },
63 | "showPoints": "auto",
64 | "spanNulls": false,
65 | "stacking": {
66 | "group": "A",
67 | "mode": "none"
68 | },
69 | "thresholdsStyle": {
70 | "mode": "off"
71 | }
72 | },
73 | "mappings": [],
74 | "thresholds": {
75 | "mode": "absolute",
76 | "steps": [
77 | {
78 | "color": "green",
79 | "value": null
80 | },
81 | {
82 | "color": "red",
83 | "value": 80
84 | }
85 | ]
86 | },
87 | "unit": "percent"
88 | },
89 | "overrides": []
90 | },
91 | "gridPos": {
92 | "h": 8,
93 | "w": 8,
94 | "x": 0,
95 | "y": 0
96 | },
97 | "id": 2,
98 | "options": {
99 | "legend": {
100 | "calcs": [],
101 | "displayMode": "list",
102 | "placement": "bottom",
103 | "showLegend": true
104 | },
105 | "tooltip": {
106 | "mode": "single",
107 | "sort": "none"
108 | }
109 | },
110 | "targets": [
111 | {
112 | "datasource": {
113 | "type": "datasource",
114 | "uid": "3BK8XQaVk"
115 | },
116 | "exemplar": true,
117 | "expr": "sum by (InstanceId) (amazonaws_com_AWS_EC2_CPUUtilization_sum{InstanceId=~'$EC2_Instance_Identifier'}) / sum by (InstanceId) (amazonaws_com_AWS_EC2_CPUUtilization_count{InstanceId=~'$EC2_Instance_Identifier'})",
118 | "interval": "5m",
119 | "legendFormat": "",
120 | "refId": "A"
121 | }
122 | ],
123 | "title": "CPU Utilization",
124 | "type": "timeseries"
125 | },
126 | {
127 | "datasource": {
128 | "type": "prometheus",
129 | "uid": "3BK8XQaVk"
130 | },
131 | "description": "Status Check Failed",
132 | "fieldConfig": {
133 | "defaults": {
134 | "color": {
135 | "mode": "palette-classic"
136 | },
137 | "custom": {
138 | "axisCenteredZero": false,
139 | "axisColorMode": "text",
140 | "axisLabel": "",
141 | "axisPlacement": "auto",
142 | "barAlignment": 0,
143 | "drawStyle": "line",
144 | "fillOpacity": 0,
145 | "gradientMode": "none",
146 | "hideFrom": {
147 | "legend": false,
148 | "tooltip": false,
149 | "viz": false
150 | },
151 | "lineInterpolation": "linear",
152 | "lineWidth": 1,
153 | "pointSize": 5,
154 | "scaleDistribution": {
155 | "type": "linear"
156 | },
157 | "showPoints": "auto",
158 | "spanNulls": false,
159 | "stacking": {
160 | "group": "A",
161 | "mode": "none"
162 | },
163 | "thresholdsStyle": {
164 | "mode": "off"
165 | }
166 | },
167 | "mappings": [],
168 | "thresholds": {
169 | "mode": "absolute",
170 | "steps": [
171 | {
172 | "color": "green",
173 | "value": null
174 | },
175 | {
176 | "color": "red",
177 | "value": 80
178 | }
179 | ]
180 | },
181 | "unit": "none"
182 | },
183 | "overrides": []
184 | },
185 | "gridPos": {
186 | "h": 9,
187 | "w": 8,
188 | "x": 8,
189 | "y": 0
190 | },
191 | "id": 4,
192 | "options": {
193 | "legend": {
194 | "calcs": [],
195 | "displayMode": "list",
196 | "placement": "bottom",
197 | "showLegend": true
198 | },
199 | "tooltip": {
200 | "mode": "single",
201 | "sort": "none"
202 | }
203 | },
204 | "targets": [
205 | {
206 | "datasource": {
207 | "type": "datasource",
208 | "uid": "3BK8XQaVk"
209 | },
210 | "exemplar": true,
211 | "expr": "sum by (InstanceId) (amazonaws_com_AWS_EC2_StatusCheckFailed_sum{InstanceId=~'$EC2_Instance_Identifier'})",
212 | "interval": "5m",
213 | "legendFormat": "",
214 | "refId": "A"
215 | }
216 | ],
217 | "title": "Status Check Failed",
218 | "type": "timeseries"
219 | },
220 | {
221 | "datasource": {
222 | "type": "prometheus",
223 | "uid": "3BK8XQaVk"
224 | },
225 | "description": "CPU Credit Balance",
226 | "fieldConfig": {
227 | "defaults": {
228 | "color": {
229 | "mode": "palette-classic"
230 | },
231 | "custom": {
232 | "axisCenteredZero": false,
233 | "axisColorMode": "text",
234 | "axisLabel": "",
235 | "axisPlacement": "auto",
236 | "barAlignment": 0,
237 | "drawStyle": "line",
238 | "fillOpacity": 0,
239 | "gradientMode": "none",
240 | "hideFrom": {
241 | "legend": false,
242 | "tooltip": false,
243 | "viz": false
244 | },
245 | "lineInterpolation": "linear",
246 | "lineWidth": 1,
247 | "pointSize": 5,
248 | "scaleDistribution": {
249 | "type": "linear"
250 | },
251 | "showPoints": "auto",
252 | "spanNulls": false,
253 | "stacking": {
254 | "group": "A",
255 | "mode": "none"
256 | },
257 | "thresholdsStyle": {
258 | "mode": "off"
259 | }
260 | },
261 | "mappings": [],
262 | "thresholds": {
263 | "mode": "absolute",
264 | "steps": [
265 | {
266 | "color": "green",
267 | "value": null
268 | },
269 | {
270 | "color": "red",
271 | "value": 80
272 | }
273 | ]
274 | },
275 | "unit": "none"
276 | },
277 | "overrides": []
278 | },
279 | "gridPos": {
280 | "h": 8,
281 | "w": 8,
282 | "x": 16,
283 | "y": 0
284 | },
285 | "id": 3,
286 | "options": {
287 | "legend": {
288 | "calcs": [],
289 | "displayMode": "list",
290 | "placement": "bottom",
291 | "showLegend": true
292 | },
293 | "tooltip": {
294 | "mode": "single",
295 | "sort": "none"
296 | }
297 | },
298 | "targets": [
299 | {
300 | "datasource": {
301 | "type": "datasource",
302 | "uid": "3BK8XQaVk"
303 | },
304 | "exemplar": true,
305 | "expr": "sum by (InstanceId) (amazonaws_com_AWS_EC2_CPUCreditBalance{InstanceId=~'$EC2_Instance_Identifier', quantile='0'})",
306 | "interval": "5m",
307 | "legendFormat": "",
308 | "refId": "A"
309 | }
310 | ],
311 | "title": "CPU Credit Balance",
312 | "type": "timeseries"
313 | },
314 | {
315 | "datasource": {
316 | "type": "prometheus",
317 | "uid": "3BK8XQaVk"
318 | },
319 | "description": "Network out bytes",
320 | "fieldConfig": {
321 | "defaults": {
322 | "color": {
323 | "mode": "palette-classic"
324 | },
325 | "custom": {
326 | "axisCenteredZero": false,
327 | "axisColorMode": "text",
328 | "axisLabel": "",
329 | "axisPlacement": "auto",
330 | "barAlignment": 0,
331 | "drawStyle": "line",
332 | "fillOpacity": 0,
333 | "gradientMode": "none",
334 | "hideFrom": {
335 | "legend": false,
336 | "tooltip": false,
337 | "viz": false
338 | },
339 | "lineInterpolation": "linear",
340 | "lineWidth": 1,
341 | "pointSize": 5,
342 | "scaleDistribution": {
343 | "type": "linear"
344 | },
345 | "showPoints": "auto",
346 | "spanNulls": false,
347 | "stacking": {
348 | "group": "A",
349 | "mode": "none"
350 | },
351 | "thresholdsStyle": {
352 | "mode": "off"
353 | }
354 | },
355 | "mappings": [],
356 | "thresholds": {
357 | "mode": "absolute",
358 | "steps": [
359 | {
360 | "color": "green",
361 | "value": null
362 | },
363 | {
364 | "color": "red",
365 | "value": 80
366 | }
367 | ]
368 | },
369 | "unit": "none"
370 | },
371 | "overrides": []
372 | },
373 | "gridPos": {
374 | "h": 8,
375 | "w": 8,
376 | "x": 0,
377 | "y": 8
378 | },
379 | "id": 5,
380 | "options": {
381 | "legend": {
382 | "calcs": [],
383 | "displayMode": "list",
384 | "placement": "bottom",
385 | "showLegend": true
386 | },
387 | "tooltip": {
388 | "mode": "single",
389 | "sort": "none"
390 | }
391 | },
392 | "targets": [
393 | {
394 | "datasource": {
395 | "type": "datasource",
396 | "uid": "3BK8XQaVk"
397 | },
398 | "exemplar": true,
399 | "expr": "sum by (InstanceId) (amazonaws_com_AWS_EC2_NetworkIn_sum{InstanceId=~'$EC2_Instance_Identifier'})",
400 | "interval": "5m",
401 | "legendFormat": "",
402 | "refId": "A"
403 | }
404 | ],
405 | "title": "Network In",
406 | "type": "timeseries"
407 | },
408 | {
409 | "datasource": {
410 | "type": "prometheus",
411 | "uid": "3BK8XQaVk"
412 | },
413 | "description": "CPU surplus credits charged",
414 | "fieldConfig": {
415 | "defaults": {
416 | "color": {
417 | "mode": "palette-classic"
418 | },
419 | "custom": {
420 | "axisCenteredZero": false,
421 | "axisColorMode": "text",
422 | "axisLabel": "",
423 | "axisPlacement": "auto",
424 | "barAlignment": 0,
425 | "drawStyle": "line",
426 | "fillOpacity": 0,
427 | "gradientMode": "none",
428 | "hideFrom": {
429 | "legend": false,
430 | "tooltip": false,
431 | "viz": false
432 | },
433 | "lineInterpolation": "linear",
434 | "lineWidth": 1,
435 | "pointSize": 5,
436 | "scaleDistribution": {
437 | "type": "linear"
438 | },
439 | "showPoints": "auto",
440 | "spanNulls": false,
441 | "stacking": {
442 | "group": "A",
443 | "mode": "none"
444 | },
445 | "thresholdsStyle": {
446 | "mode": "off"
447 | }
448 | },
449 | "mappings": [],
450 | "thresholds": {
451 | "mode": "absolute",
452 | "steps": [
453 | {
454 | "color": "green",
455 | "value": null
456 | },
457 | {
458 | "color": "red",
459 | "value": 80
460 | }
461 | ]
462 | },
463 | "unit": "none"
464 | },
465 | "overrides": []
466 | },
467 | "gridPos": {
468 | "h": 9,
469 | "w": 8,
470 | "x": 16,
471 | "y": 8
472 | },
473 | "id": 4,
474 | "options": {
475 | "legend": {
476 | "calcs": [],
477 | "displayMode": "list",
478 | "placement": "bottom",
479 | "showLegend": true
480 | },
481 | "tooltip": {
482 | "mode": "single",
483 | "sort": "none"
484 | }
485 | },
486 | "targets": [
487 | {
488 | "datasource": {
489 | "type": "datasource",
490 | "uid": "3BK8XQaVk"
491 | },
492 | "exemplar": true,
493 | "expr": "sum by (InstanceId) (amazonaws_com_AWS_EC2_CPUSurplusCreditsCharged_sum{InstanceId=~'$EC2_Instance_Identifier'})",
494 | "interval": "5m",
495 | "legendFormat": "",
496 | "refId": "A"
497 | }
498 | ],
499 | "title": "CPU surplus credits charged",
500 | "type": "timeseries"
501 | },
502 | {
503 | "datasource": {
504 | "type": "prometheus",
505 | "uid": "3BK8XQaVk"
506 | },
507 | "description": "Network out bytes",
508 | "fieldConfig": {
509 | "defaults": {
510 | "color": {
511 | "mode": "palette-classic"
512 | },
513 | "custom": {
514 | "axisCenteredZero": false,
515 | "axisColorMode": "text",
516 | "axisLabel": "",
517 | "axisPlacement": "auto",
518 | "barAlignment": 0,
519 | "drawStyle": "line",
520 | "fillOpacity": 0,
521 | "gradientMode": "none",
522 | "hideFrom": {
523 | "legend": false,
524 | "tooltip": false,
525 | "viz": false
526 | },
527 | "lineInterpolation": "linear",
528 | "lineWidth": 1,
529 | "pointSize": 5,
530 | "scaleDistribution": {
531 | "type": "linear"
532 | },
533 | "showPoints": "auto",
534 | "spanNulls": false,
535 | "stacking": {
536 | "group": "A",
537 | "mode": "none"
538 | },
539 | "thresholdsStyle": {
540 | "mode": "off"
541 | }
542 | },
543 | "mappings": [],
544 | "thresholds": {
545 | "mode": "absolute",
546 | "steps": [
547 | {
548 | "color": "green",
549 | "value": null
550 | },
551 | {
552 | "color": "red",
553 | "value": 80
554 | }
555 | ]
556 | },
557 | "unit": "none"
558 | },
559 | "overrides": []
560 | },
561 | "gridPos": {
562 | "h": 8,
563 | "w": 8,
564 | "x": 8,
565 | "y": 9
566 | },
567 | "id": 5,
568 | "options": {
569 | "legend": {
570 | "calcs": [],
571 | "displayMode": "list",
572 | "placement": "bottom",
573 | "showLegend": true
574 | },
575 | "tooltip": {
576 | "mode": "single",
577 | "sort": "none"
578 | }
579 | },
580 | "targets": [
581 | {
582 | "datasource": {
583 | "type": "datasource",
584 | "uid": "3BK8XQaVk"
585 | },
586 | "exemplar": true,
587 | "expr": "sum by (InstanceId) (amazonaws_com_AWS_EC2_NetworkOut_sum{InstanceId=~'$EC2_Instance_Identifier'})",
588 | "interval": "5m",
589 | "legendFormat": "",
590 | "refId": "A"
591 | }
592 | ],
593 | "title": "Network Out",
594 | "type": "timeseries"
595 | },
596 | {
597 | "datasource": {
598 | "type": "prometheus",
599 | "uid": "3BK8XQaVk"
600 | },
601 | "description": "EBS IO Balance",
602 | "fieldConfig": {
603 | "defaults": {
604 | "color": {
605 | "mode": "palette-classic"
606 | },
607 | "custom": {
608 | "axisCenteredZero": false,
609 | "axisColorMode": "text",
610 | "axisLabel": "",
611 | "axisPlacement": "auto",
612 | "barAlignment": 0,
613 | "drawStyle": "line",
614 | "fillOpacity": 0,
615 | "gradientMode": "none",
616 | "hideFrom": {
617 | "legend": false,
618 | "tooltip": false,
619 | "viz": false
620 | },
621 | "lineInterpolation": "linear",
622 | "lineWidth": 1,
623 | "pointSize": 5,
624 | "scaleDistribution": {
625 | "type": "linear"
626 | },
627 | "showPoints": "auto",
628 | "spanNulls": false,
629 | "stacking": {
630 | "group": "A",
631 | "mode": "none"
632 | },
633 | "thresholdsStyle": {
634 | "mode": "off"
635 | }
636 | },
637 | "mappings": [],
638 | "thresholds": {
639 | "mode": "absolute",
640 | "steps": [
641 | {
642 | "color": "green",
643 | "value": null
644 | },
645 | {
646 | "color": "red",
647 | "value": 80
648 | }
649 | ]
650 | },
651 | "unit": "none"
652 | },
653 | "overrides": []
654 | },
655 | "gridPos": {
656 | "h": 9,
657 | "w": 8,
658 | "x": 0,
659 | "y": 16
660 | },
661 | "id": 4,
662 | "options": {
663 | "legend": {
664 | "calcs": [],
665 | "displayMode": "list",
666 | "placement": "bottom",
667 | "showLegend": true
668 | },
669 | "tooltip": {
670 | "mode": "single",
671 | "sort": "none"
672 | }
673 | },
674 | "targets": [
675 | {
676 | "datasource": {
677 | "type": "datasource",
678 | "uid": "3BK8XQaVk"
679 | },
680 | "exemplar": true,
681 | "expr": "sum by (InstanceId) (amazonaws_com_AWS_EC2_EBSIOBalance_{InstanceId=~'$EC2_Instance_Identifier', quantile='0'})",
682 | "interval": "5m",
683 | "legendFormat": "",
684 | "refId": "A"
685 | }
686 | ],
687 | "title": "EBS IO Balance",
688 | "type": "timeseries"
689 | },
690 | {
691 | "datasource": {
692 | "type": "prometheus",
693 | "uid": "3BK8XQaVk"
694 | },
695 | "description": "EBS Byte Balance",
696 | "fieldConfig": {
697 | "defaults": {
698 | "color": {
699 | "mode": "palette-classic"
700 | },
701 | "custom": {
702 | "axisCenteredZero": false,
703 | "axisColorMode": "text",
704 | "axisLabel": "",
705 | "axisPlacement": "auto",
706 | "barAlignment": 0,
707 | "drawStyle": "line",
708 | "fillOpacity": 0,
709 | "gradientMode": "none",
710 | "hideFrom": {
711 | "legend": false,
712 | "tooltip": false,
713 | "viz": false
714 | },
715 | "lineInterpolation": "linear",
716 | "lineWidth": 1,
717 | "pointSize": 5,
718 | "scaleDistribution": {
719 | "type": "linear"
720 | },
721 | "showPoints": "auto",
722 | "spanNulls": false,
723 | "stacking": {
724 | "group": "A",
725 | "mode": "none"
726 | },
727 | "thresholdsStyle": {
728 | "mode": "off"
729 | }
730 | },
731 | "mappings": [],
732 | "thresholds": {
733 | "mode": "absolute",
734 | "steps": [
735 | {
736 | "color": "green",
737 | "value": null
738 | },
739 | {
740 | "color": "red",
741 | "value": 80
742 | }
743 | ]
744 | },
745 | "unit": "none"
746 | },
747 | "overrides": []
748 | },
749 | "gridPos": {
750 | "h": 9,
751 | "w": 8,
752 | "x": 8,
753 | "y": 17
754 | },
755 | "id": 4,
756 | "options": {
757 | "legend": {
758 | "calcs": [],
759 | "displayMode": "list",
760 | "placement": "bottom",
761 | "showLegend": true
762 | },
763 | "tooltip": {
764 | "mode": "single",
765 | "sort": "none"
766 | }
767 | },
768 | "targets": [
769 | {
770 | "datasource": {
771 | "type": "datasource",
772 | "uid": "3BK8XQaVk"
773 | },
774 | "exemplar": true,
775 | "expr": "sum by (InstanceId) (amazonaws_com_AWS_EC2_EBSByteBalance_{InstanceId=~'$EC2_Instance_Identifier', quantile='0'})",
776 | "interval": "5m",
777 | "legendFormat": "",
778 | "refId": "A"
779 | }
780 | ],
781 | "title": "EBS Byte Balance",
782 | "type": "timeseries"
783 | }
784 | ],
785 | "schemaVersion": 37,
786 | "style": "dark",
787 | "tags": [],
788 | "templating": {
789 | "list": [
790 | {
791 | "allValue": "",
792 | "current": {
793 | "selected": false,
794 | "text": "All",
795 | "value": "$__all"
796 | },
797 | "datasource": {
798 | "type": "prometheus",
799 | "uid": "3BK8XQaVk"
800 | },
801 | "definition": "label_values(amazonaws_com_AWS_EC2_CPUUtilization{}, InstanceId)",
802 | "hide": 0,
803 | "includeAll": true,
804 | "label": "EC2 Instance Identifier",
805 | "multi": true,
806 | "name": "EC2_Instance_Identifier",
807 | "options": [],
808 | "query": {
809 | "query": "label_values(amazonaws_com_AWS_EC2_CPUUtilization{}, InstanceId)",
810 | "refId": "StandardVariableQuery"
811 | },
812 | "refresh": 1,
813 | "regex": "",
814 | "skipUrlSync": false,
815 | "sort": 1,
816 | "type": "query"
817 | }
818 | ]
819 | },
820 | "time": {
821 | "from": "now-30m",
822 | "to": "now"
823 | },
824 | "timepicker": {},
825 | "timezone": "browser",
826 | "title": "EC2",
827 | "uid": "pSD2rzfff",
828 | "version": 1,
829 | "weekStart": "monday"
830 | }
831 |
--------------------------------------------------------------------------------
/levitate/grafana-dashboards/cloudswatch-metric-stream/rds/README.md:
--------------------------------------------------------------------------------
1 | ## How to use?
2 |
3 | This directory contains a sample Grafana dashboard's JSON file based on metrics from AWS Cloudwatch metric stream.
4 |
5 | You can import this into any Grafana, select a data source and start using it.
6 |
7 | ## Dashboard structure
8 |
9 | The dashboard contains following metrics and variables.
10 |
11 | ### Metrics
12 |
13 | 1. The percentage of CPU Utilization `amazonaws_com_AWS_RDS_CPUUtilization`
14 | 2. Number of DB Connections `amazonaws_com_AWS_RDS_DatabaseConnections`
15 | 3. EBS Byte Balance `amazonaws_com_AWS_RDS_EBSByteBalance_`
16 | 4. EBS I/O Balance `amazonaws_com_AWS_RDS_EBSIOBalance_`
17 |
18 | ### Variables
19 |
20 | 1. DB Instance Identifier
21 | 2. Cloud Region
22 |
23 | ## Integrate with AWS Cloudwatch Metric Stream for sending data to Levitate
24 |
25 | Follow our integration guide for [AWS Cloudwatch Metric Stream](https://docs.last9.io/docs/how-to-send-cloudwatch-metrics-to-levitate-via-aws-cloudstream).
26 |
27 | > Note that this step is optional, you can use the dashboard as it is with any other source apart from Levitate if you are already set up with AWS Cloudwatch Metric Stream.
28 |
--------------------------------------------------------------------------------
/levitate/grafana-dashboards/cloudswatch-metric-stream/rds/dashboard.json:
--------------------------------------------------------------------------------
1 | {
2 | "__inputs": [
3 | {
4 | "name": "DATASOURCE",
5 | "label": "Datasource",
6 | "description": "",
7 | "type": "datasource",
8 | "pluginId": "prometheus",
9 | "pluginName": "Prometheus"
10 | }
11 | ],
12 | "__elements": [],
13 | "__requires": [
14 | {
15 | "type": "grafana",
16 | "id": "grafana",
17 | "name": "Grafana",
18 | "version": "8.4.0"
19 | },
20 | {
21 | "type": "datasource",
22 | "id": "prometheus",
23 | "name": "Prometheus",
24 | "version": "1.0.0"
25 | },
26 | {
27 | "type": "panel",
28 | "id": "timeseries",
29 | "name": "Time series",
30 | "version": ""
31 | }
32 | ],
33 | "annotations": {
34 | "list": [
35 | {
36 | "builtIn": 1,
37 | "datasource": "-- Grafana --",
38 | "enable": true,
39 | "hide": true,
40 | "iconColor": "rgba(0, 211, 255, 1)",
41 | "name": "Annotations & Alerts",
42 | "target": {
43 | "limit": 100,
44 | "matchAny": false,
45 | "tags": [],
46 | "type": "dashboard"
47 | },
48 | "type": "dashboard"
49 | }
50 | ]
51 | },
52 | "description": "Dashboard for RDS based on metrics from AWS CloudWatch metrics stream",
53 | "editable": true,
54 | "fiscalYearStartMonth": 0,
55 | "graphTooltip": 0,
56 | "id": null,
57 | "iteration": 1679303184200,
58 | "links": [],
59 | "liveNow": false,
60 | "panels": [
61 | {
62 | "datasource": {
63 | "type": "prometheus",
64 | "uid": "${DATASOURCE}"
65 | },
66 | "description": "The percentage of CPU Utilization.",
67 | "fieldConfig": {
68 | "defaults": {
69 | "color": {
70 | "mode": "palette-classic"
71 | },
72 | "custom": {
73 | "axisLabel": "",
74 | "axisPlacement": "auto",
75 | "barAlignment": 0,
76 | "drawStyle": "line",
77 | "fillOpacity": 0,
78 | "gradientMode": "none",
79 | "hideFrom": {
80 | "legend": false,
81 | "tooltip": false,
82 | "viz": false
83 | },
84 | "lineInterpolation": "linear",
85 | "lineWidth": 1,
86 | "pointSize": 5,
87 | "scaleDistribution": {
88 | "type": "linear"
89 | },
90 | "showPoints": "auto",
91 | "spanNulls": false,
92 | "stacking": {
93 | "group": "A",
94 | "mode": "none"
95 | },
96 | "thresholdsStyle": {
97 | "mode": "off"
98 | }
99 | },
100 | "mappings": [],
101 | "thresholds": {
102 | "mode": "absolute",
103 | "steps": [
104 | {
105 | "color": "green",
106 | "value": null
107 | },
108 | {
109 | "color": "red",
110 | "value": 80
111 | }
112 | ]
113 | },
114 | "unit": "percent"
115 | },
116 | "overrides": []
117 | },
118 | "gridPos": {
119 | "h": 8,
120 | "w": 8,
121 | "x": 0,
122 | "y": 0
123 | },
124 | "id": 2,
125 | "options": {
126 | "legend": {
127 | "calcs": [],
128 | "displayMode": "list",
129 | "placement": "bottom"
130 | },
131 | "tooltip": {
132 | "mode": "single"
133 | }
134 | },
135 | "targets": [
136 | {
137 | "datasource": {
138 | "type": "datasource",
139 | "uid": "${DATASOURCE}"
140 | },
141 | "exemplar": true,
142 | "expr": "sum by (DBInstanceIdentifier, cloud_region) (amazonaws_com_AWS_RDS_CPUUtilization{DBInstanceIdentifier=~\"$DB_Instance_Identifier\", cloud_region=~\"$Cloud_Region\"})",
143 | "interval": "1m",
144 | "legendFormat": "",
145 | "refId": "A"
146 | }
147 | ],
148 | "title": "CPU Utilization",
149 | "type": "timeseries"
150 | },
151 | {
152 | "datasource": {
153 | "type": "prometheus",
154 | "uid": "${DATASOURCE}"
155 | },
156 | "description": "Number of DB Connections",
157 | "fieldConfig": {
158 | "defaults": {
159 | "color": {
160 | "mode": "palette-classic"
161 | },
162 | "custom": {
163 | "axisLabel": "",
164 | "axisPlacement": "auto",
165 | "barAlignment": 0,
166 | "drawStyle": "line",
167 | "fillOpacity": 0,
168 | "gradientMode": "none",
169 | "hideFrom": {
170 | "legend": false,
171 | "tooltip": false,
172 | "viz": false
173 | },
174 | "lineInterpolation": "linear",
175 | "lineWidth": 1,
176 | "pointSize": 5,
177 | "scaleDistribution": {
178 | "type": "linear"
179 | },
180 | "showPoints": "auto",
181 | "spanNulls": false,
182 | "stacking": {
183 | "group": "A",
184 | "mode": "none"
185 | },
186 | "thresholdsStyle": {
187 | "mode": "off"
188 | }
189 | },
190 | "mappings": [],
191 | "thresholds": {
192 | "mode": "absolute",
193 | "steps": [
194 | {
195 | "color": "green",
196 | "value": null
197 | },
198 | {
199 | "color": "red",
200 | "value": 80
201 | }
202 | ]
203 | },
204 | "unit": "none"
205 | },
206 | "overrides": []
207 | },
208 | "gridPos": {
209 | "h": 8,
210 | "w": 8,
211 | "x": 8,
212 | "y": 0
213 | },
214 | "id": 3,
215 | "options": {
216 | "legend": {
217 | "calcs": [],
218 | "displayMode": "list",
219 | "placement": "bottom"
220 | },
221 | "tooltip": {
222 | "mode": "single"
223 | }
224 | },
225 | "targets": [
226 | {
227 | "datasource": {
228 | "type": "datasource",
229 | "uid": "${DATASOURCE}"
230 | },
231 | "exemplar": true,
232 | "expr": "sum by (DBInstanceIdentifier, cloud_region) (amazonaws_com_AWS_RDS_DatabaseConnections{DBInstanceIdentifier=~\"$DB_Instance_Identifier\", cloud_region=~\"$Cloud_Region\"})",
233 | "interval": "1m",
234 | "legendFormat": "",
235 | "refId": "A"
236 | }
237 | ],
238 | "title": "Connections",
239 | "type": "timeseries"
240 | },
241 | {
242 | "datasource": {
243 | "type": "prometheus",
244 | "uid": "${DATASOURCE}"
245 | },
246 | "description": "The percentage of throughput credits remaining in the burst bucket of your RDS database. This metric is available for basic monitoring only.",
247 | "fieldConfig": {
248 | "defaults": {
249 | "color": {
250 | "mode": "palette-classic"
251 | },
252 | "custom": {
253 | "axisLabel": "",
254 | "axisPlacement": "auto",
255 | "barAlignment": 0,
256 | "drawStyle": "line",
257 | "fillOpacity": 0,
258 | "gradientMode": "none",
259 | "hideFrom": {
260 | "legend": false,
261 | "tooltip": false,
262 | "viz": false
263 | },
264 | "lineInterpolation": "linear",
265 | "lineWidth": 1,
266 | "pointSize": 5,
267 | "scaleDistribution": {
268 | "type": "linear"
269 | },
270 | "showPoints": "auto",
271 | "spanNulls": false,
272 | "stacking": {
273 | "group": "A",
274 | "mode": "none"
275 | },
276 | "thresholdsStyle": {
277 | "mode": "off"
278 | }
279 | },
280 | "mappings": [],
281 | "thresholds": {
282 | "mode": "absolute",
283 | "steps": [
284 | {
285 | "color": "green",
286 | "value": null
287 | },
288 | {
289 | "color": "red",
290 | "value": 80
291 | }
292 | ]
293 | },
294 | "unit": "none"
295 | },
296 | "overrides": []
297 | },
298 | "gridPos": {
299 | "h": 8,
300 | "w": 8,
301 | "x": 16,
302 | "y": 0
303 | },
304 | "id": 5,
305 | "options": {
306 | "legend": {
307 | "calcs": [],
308 | "displayMode": "list",
309 | "placement": "bottom"
310 | },
311 | "tooltip": {
312 | "mode": "single"
313 | }
314 | },
315 | "targets": [
316 | {
317 | "datasource": {
318 | "type": "datasource",
319 | "uid": "${DATASOURCE}"
320 | },
321 | "exemplar": true,
322 | "expr": "sum by (DBInstanceIdentifier, cloud_region) (amazonaws_com_AWS_RDS_EBSByteBalance_{DBInstanceIdentifier=~\"$DB_Instance_Identifier\", cloud_region=~\"$Cloud_Region\"})",
323 | "interval": "1m",
324 | "legendFormat": "",
325 | "refId": "A"
326 | }
327 | ],
328 | "title": "EBS Byte Balance",
329 | "type": "timeseries"
330 | },
331 | {
332 | "datasource": {
333 | "type": "prometheus",
334 | "uid": "${DATASOURCE}"
335 | },
336 | "description": "The percentage of I/O credits remaining in the burst bucket of your RDS database. This metric is available for basic monitoring only.",
337 | "fieldConfig": {
338 | "defaults": {
339 | "color": {
340 | "mode": "palette-classic"
341 | },
342 | "custom": {
343 | "axisLabel": "",
344 | "axisPlacement": "auto",
345 | "barAlignment": 0,
346 | "drawStyle": "line",
347 | "fillOpacity": 0,
348 | "gradientMode": "none",
349 | "hideFrom": {
350 | "legend": false,
351 | "tooltip": false,
352 | "viz": false
353 | },
354 | "lineInterpolation": "linear",
355 | "lineWidth": 1,
356 | "pointSize": 5,
357 | "scaleDistribution": {
358 | "type": "linear"
359 | },
360 | "showPoints": "auto",
361 | "spanNulls": false,
362 | "stacking": {
363 | "group": "A",
364 | "mode": "none"
365 | },
366 | "thresholdsStyle": {
367 | "mode": "off"
368 | }
369 | },
370 | "mappings": [],
371 | "thresholds": {
372 | "mode": "absolute",
373 | "steps": [
374 | {
375 | "color": "green",
376 | "value": null
377 | },
378 | {
379 | "color": "red",
380 | "value": 80
381 | }
382 | ]
383 | },
384 | "unit": "none"
385 | },
386 | "overrides": []
387 | },
388 | "gridPos": {
389 | "h": 9,
390 | "w": 8,
391 | "x": 0,
392 | "y": 8
393 | },
394 | "id": 4,
395 | "options": {
396 | "legend": {
397 | "calcs": [],
398 | "displayMode": "list",
399 | "placement": "bottom"
400 | },
401 | "tooltip": {
402 | "mode": "single"
403 | }
404 | },
405 | "targets": [
406 | {
407 | "datasource": {
408 | "type": "datasource",
409 | "uid": "${DATASOURCE}"
410 | },
411 | "exemplar": true,
412 | "expr": "sum by (DBInstanceIdentifier, cloud_region) (amazonaws_com_AWS_RDS_EBSIOBalance_{DBInstanceIdentifier=~\"$DB_Instance_Identifier\", cloud_region=~\"$Cloud_Region\"})",
413 | "interval": "1m",
414 | "legendFormat": "",
415 | "refId": "A"
416 | }
417 | ],
418 | "title": "EBS I/O Balance",
419 | "type": "timeseries"
420 | }
421 | ],
422 | "schemaVersion": 34,
423 | "style": "dark",
424 | "tags": [],
425 | "templating": {
426 | "list": [
427 | {
428 | "allValue": "",
429 | "current": {},
430 | "datasource": {
431 | "type": "prometheus",
432 | "uid": "${DATASOURCE}"
433 | },
434 | "definition": "label_values(amazonaws_com_AWS_RDS_CPUUtilization{}, DBInstanceIdentifier)",
435 | "hide": 0,
436 | "includeAll": true,
437 | "label": "DB Instance Identifier",
438 | "multi": true,
439 | "name": "DB_Instance_Identifier",
440 | "options": [],
441 | "query": {
442 | "query": "label_values(amazonaws_com_AWS_RDS_CPUUtilization{}, DBInstanceIdentifier)",
443 | "refId": "StandardVariableQuery"
444 | },
445 | "refresh": 1,
446 | "regex": "",
447 | "skipUrlSync": false,
448 | "sort": 1,
449 | "type": "query"
450 | },
451 | {
452 | "allValue": "",
453 | "current": {},
454 | "datasource": {
455 | "type": "prometheus",
456 | "uid": "${DATASOURCE}"
457 | },
458 | "definition": "label_values(amazonaws_com_AWS_RDS_CPUUtilization{}, cloud_region)",
459 | "hide": 0,
460 | "includeAll": true,
461 | "label": "Cloud Region",
462 | "multi": true,
463 | "name": "Cloud_Region",
464 | "options": [],
465 | "query": {
466 | "query": "label_values(amazonaws_com_AWS_RDS_CPUUtilization{}, cloud_region)",
467 | "refId": "StandardVariableQuery"
468 | },
469 | "refresh": 1,
470 | "regex": "",
471 | "skipUrlSync": false,
472 | "sort": 1,
473 | "type": "query"
474 | }
475 | ]
476 | },
477 | "time": {
478 | "from": "now-30m",
479 | "to": "now"
480 | },
481 | "timepicker": {},
482 | "timezone": "browser",
483 | "title": "RDS",
484 | "uid": "pSD2rzf4k",
485 | "version": 12,
486 | "weekStart": "monday"
487 | }
488 |
--------------------------------------------------------------------------------
/levitate/remote-write/jmxtrans/.gitignore:
--------------------------------------------------------------------------------
1 | *.env
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/jmxtrans/README.md:
--------------------------------------------------------------------------------
1 | This directory contains demo code for jmxtrans to Levitate remote write integration
2 | using jmxtrans Graphite output plugin pointing to vmagent.
3 |
4 | [jmxtrans/jmxtrans](https://hub.docker.com/r/jmxtrans/jmxtrans) image does not work on MacOS M1 chipset. To test this docker-compose
5 | setup, please use a Linux variant.
6 |
7 | ### Steps
8 |
9 | 1. Update the following variables in [docker-compose.yaml](./docker-compose.yaml) or update export them as environment variables
10 | - $LEVITATE_REMOTE_WRITE_URL
11 | - $LEVITATE_REMOTE_WRITE_USERNAME
12 | - $LEVITATE_REMOTE_WRITE_PASSWORD
13 | 2. Run `docker-compose up --build --force-recreate --remove-orphans`
14 |
15 | ### Validate
16 |
17 | 1. The above run should publish the [sample app](./jvmapp/SampleApp.java) metrics to Levitate.
18 | 2. By default, graphite metrics are dumped in `a.b.c.d` format. This can lead to increase in metric names and remove the flexibility of labels i.e. instead of having `requests{host='a'}`, without any
19 | transformation, the metric would show up as `requests.host.a`
20 | 3. To address this, we leverage vmagent [graphite relabeling](https://docs.victoriametrics.com/vmagent.html#graphite-relabeling). A sample setup is added in [vmagent.yaml](vmagent.yaml), which converts a flattened metric like
21 |
22 | ```
23 | "metric": {
24 | "__name__": "sample.service.jvmapp_4000.sun_management_MemoryImpl.HeapMemoryUsage_committed",
25 | },
26 | ```
27 |
28 | to
29 |
30 | ```
31 | "metric": {
32 | "__name__": "HeapMemoryUsage_committed",
33 | "service": "sample_service",
34 | "instance": "jvmapp_4000",
35 | }
36 | ```
37 | 4. This sample [vmagent.yaml](vmagent.yaml) can be modified for any other relabeling as required.
38 |
--------------------------------------------------------------------------------
/levitate/remote-write/jmxtrans/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | # Java app and JVM config sourced from http://mintbeans.com/jvm-monitoring-docker/
2 | version: '3.6'
3 | services:
4 | jvmapp:
5 | build: jvmapp
6 | container_name: jvmapp
7 | ports:
8 | - "4000:4000"
9 |
10 | jmxtrans:
11 | image: jmxtrans/jmxtrans
12 | container_name: jmxtrans
13 | environment:
14 | CONTINUE_ON_ERROR: "false"
15 | SECONDS_BETWEEN_RUNS: 5
16 | GRAPHITE_HOST: vmagent_levitate
17 | GRAPHITE_PORT: 2003
18 | volumes:
19 | - ./jmxtrans-config:/var/lib/jmxtrans
20 | depends_on:
21 | - jvmapp
22 |
23 | vmagent_levitate:
24 | image: victoriametrics/vmagent:v1.85.3
25 | ports:
26 | - 8430:8429
27 | - 2003:2003/tcp
28 | - 2003:2003/udp
29 | volumes:
30 | - vmagentdata:/vmagentdata
31 | - ./relabel.yaml:/etc/relabel.yaml
32 | - ./vmagent.yaml:/etc/vmagent.yaml
33 | command:
34 | - "--graphiteListenAddr=:2003"
35 | - "--remoteWrite.url=${LEVITATE_REMOTE_WRITE_URL}"
36 | - "--remoteWrite.basicAuth.username=${LEVITATE_REMOTE_WRITE_USERNAME}"
37 | - "--remoteWrite.basicAuth.password=${LEVITATE_REMOTE_WRITE_PASSWORD}"
38 | - "--remoteWrite.relabelConfig=/etc/relabel.yaml"
39 | - "--promscrape.config=/etc/vmagent.yaml"
40 | restart: always
41 |
42 | volumes:
43 | vmagentdata: {}
44 |
--------------------------------------------------------------------------------
/levitate/remote-write/jmxtrans/jmxtrans-config/graphite.json:
--------------------------------------------------------------------------------
1 | {
2 | "servers": [
3 | {
4 | "host": "jvmapp",
5 | "port": "4000",
6 | "queries": [
7 | {
8 | "obj": "java.lang:type=Memory",
9 | "attr": [
10 | "HeapMemoryUsage",
11 | "NonHeapMemoryUsage"
12 | ],
13 | "outputWriters": [
14 | {
15 | "@class": "com.googlecode.jmxtrans.model.output.StdOutWriter"
16 | },
17 | {
18 | "@class": "com.googlecode.jmxtrans.model.output.GraphiteWriterFactory",
19 | "host": "vmagent_levitate",
20 | "port": "2003",
21 | "rootPrefix": "sample.service"
22 | }
23 | ]
24 | }
25 | ]
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/levitate/remote-write/jmxtrans/jvmapp/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:8
2 |
3 | COPY SampleApp.java /SampleApp.java
4 | RUN javac SampleApp.java
5 |
6 | CMD java \
7 | -Djava.rmi.server.hostname=jvmapp \
8 | -Dcom.sun.management.jmxremote \
9 | -Dcom.sun.management.jmxremote.port=4000 \
10 | -Dcom.sun.management.jmxremote.rmi.port=4000 \
11 | -Dcom.sun.management.jmxremote.local.only=false \
12 | -Dcom.sun.management.jmxremote.authenticate=false \
13 | -Dcom.sun.management.jmxremote.ssl=false \
14 | SampleApp
15 |
--------------------------------------------------------------------------------
/levitate/remote-write/jmxtrans/jvmapp/SampleApp.java:
--------------------------------------------------------------------------------
1 | public final class SampleApp {
2 | public static void main(String []args) throws Exception {
3 | final java.util.Random generator = new java.util.Random();
4 | while (true) {
5 | System.out.println("test");
6 | generator.ints(1000000, 0, 100).sorted();
7 | Thread.sleep(5000L);
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/levitate/remote-write/jmxtrans/relabel.yaml:
--------------------------------------------------------------------------------
1 | - action: graphite
2 | match: "*.*.*.*.*"
3 | labels:
4 | __name__: "${5}"
5 | service: "${1}_${2}"
6 | instance: "${3}"
7 |
--------------------------------------------------------------------------------
/levitate/remote-write/jmxtrans/vmagent.yaml:
--------------------------------------------------------------------------------
1 | global:
2 | scrape_interval: 1m
3 | scrape_configs:
4 | - job_name: "scrape_vmagent_self"
5 | static_configs:
6 | - targets: [ "localhost:8429" ]
7 |
--------------------------------------------------------------------------------
/levitate/remote-write/opentelemetry-collector/opencensus-receiver/docker/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/last9/last9-integrations/8c9a66d98f253ff5e7afc0f9824c551b3f61f478/levitate/remote-write/opentelemetry-collector/opencensus-receiver/docker/README.md
--------------------------------------------------------------------------------
/levitate/remote-write/opentelemetry-collector/prometheus-receiver/README.md:
--------------------------------------------------------------------------------
1 | ## Introduction
2 |
3 | This directory contains an example of a Prometheus receiver setup with OpenTelemetry collector which sends
4 | data to [Levitate](https://last9.io/products/levitate)
5 |
6 | Follow through the tutorial [here](https://docs.last9.io/docs/integration-opentelemetry) for a walk-through of the setup and the information flow, side by side.
7 |
8 | ### Running
9 |
10 | Replace the following variables in `otel-collector-config.yaml` with the actual values from your Levitate cluster.
11 |
12 | ```sh
13 | $levitate_username -> Cluster ID
14 | $levitate_password -> Write Token
15 | $levitate_write_endpoint -> Levitate Remote Write endpoint
16 | ```
17 |
18 | Make sure that you have docker running and then perform:
19 |
20 | ```sh
21 | docker-compose up -d
22 | ```
23 |
24 | After that, the Golang application will start on port 9000, and the Open Telemetry collector will start on port `4317`.
25 | Send a few HTTP requests on `http://localhost:9000/hello`.
26 | It will emit metrics relayed to Levitate via Open Telemetry collector.
27 |
28 |
29 | ### Verification
30 |
31 | Create a Read token for Levitate cluster and connect to [Grafana](https://docs.last9.io/docs/levitate-grafana-config) for verification.
32 |
33 | If all goes well, you should see the metrics as follows:
34 |
35 | ```json
36 | {
37 | "status": "success",
38 | "isPartial": false,
39 | "data": {
40 | "resultType": "matrix",
41 | "result": [
42 | {
43 | "metric": {
44 | "__name__": "levitate_request_counts_total",
45 | "__l9cluster__": "ebce9978-80f0-4976-9103-d435a7a4adf6",
46 | "__l9lake__": "prometheus",
47 | "__tenant__": "omecs",
48 | "env": "production",
49 | "instance": "app:8000",
50 | "job": "otel-collector-01",
51 | "otel_scope_name": "levitate-otel-demo",
52 | "program": "levitate",
53 | "via_cluster": "cs-test-levitate-01"
54 | },
55 | "values": [
56 | [
57 | 1672307336,
58 | "3"
59 | ],
60 | [
61 | 1672307396,
62 | "5"
63 | ]
64 | ]
65 | }
66 | ]
67 | }
68 | }
69 | ```
70 |
71 | ## Related Articles
72 |
73 | [What is OpenTelemetry](https://last9.io/blog/what-is-opentelemetry/)
74 |
75 | [What is OpenTelemetry Collector](https://last9.io/blog/what-is-opentelemetry-collector/)
76 |
77 | [Instrumenting Java applications using OpenTelemetry](https://last9.io/blog/how-to-instrument-java-applications-using-opentelemetry-tutorial-best-practices/)
78 |
79 | Read more about the difference between [Prometheus vs. Otel](https://last9.io/blog/opentelemetry-vs-prometheus/#metrics-in-opentelemetry-vs-prometheus).
80 |
81 | Here is a post on [How to filter metrics by labels using OpenTelemetry Collector](https://last9.io/blog/filtering-metrics-by-labels-in-opentelemetry-collector/).
82 |
--------------------------------------------------------------------------------
/levitate/remote-write/opentelemetry-collector/prometheus-receiver/app/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.18 as build
2 | WORKDIR /app/
3 | COPY . .
4 | RUN CGO_ENABLED=0 go build -o main main.go
5 | FROM alpine:3.15
6 | COPY --from=build /app/main /app/main
7 | CMD ["/app/main"]
8 |
--------------------------------------------------------------------------------
/levitate/remote-write/opentelemetry-collector/prometheus-receiver/app/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/last9-integrations/levitate/remote-write/opentelemetry-collector/prometheus-receiver/app
2 |
3 | go 1.19
4 |
5 | require (
6 | github.com/prometheus/client_golang v1.14.0
7 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0
8 | go.opentelemetry.io/otel v1.11.2
9 | go.opentelemetry.io/otel/exporters/prometheus v0.34.0
10 | go.opentelemetry.io/otel/metric v0.34.0
11 | go.opentelemetry.io/otel/sdk/metric v0.34.0
12 | )
13 |
14 | require (
15 | github.com/beorn7/perks v1.0.1 // indirect
16 | github.com/cespare/xxhash/v2 v2.1.2 // indirect
17 | github.com/felixge/httpsnoop v1.0.3 // indirect
18 | github.com/go-logr/logr v1.2.3 // indirect
19 | github.com/go-logr/stdr v1.2.2 // indirect
20 | github.com/golang/protobuf v1.5.2 // indirect
21 | github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
22 | github.com/prometheus/client_model v0.3.0 // indirect
23 | github.com/prometheus/common v0.37.0 // indirect
24 | github.com/prometheus/procfs v0.8.0 // indirect
25 | go.opentelemetry.io/otel/sdk v1.11.2 // indirect
26 | go.opentelemetry.io/otel/trace v1.11.2 // indirect
27 | golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 // indirect
28 | google.golang.org/protobuf v1.33.0 // indirect
29 | )
30 |
--------------------------------------------------------------------------------
/levitate/remote-write/opentelemetry-collector/prometheus-receiver/app/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
16 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
17 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
18 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
19 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
20 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
21 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
22 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
23 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
24 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
25 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
26 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
27 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
28 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
29 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
30 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
31 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
32 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
33 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
34 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
35 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
36 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
37 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
38 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
39 | github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
40 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
41 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
42 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
43 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
44 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
45 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
46 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
47 | github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
48 | github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
49 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
50 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
51 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
52 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
53 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
54 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
55 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
56 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
57 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
58 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
59 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
60 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
61 | github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
62 | github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
63 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
64 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
65 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
66 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
67 | github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
68 | github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
69 | github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
70 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
71 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
72 | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
73 | github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
74 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
75 | github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
76 | github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
77 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
78 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
79 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
80 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
81 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
82 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
83 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
84 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
85 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
86 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
87 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
88 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
89 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
90 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
91 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
92 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
93 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
94 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
95 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
96 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
97 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
98 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
99 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
100 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
101 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
102 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
103 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
104 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
105 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
106 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
107 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
108 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
109 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
110 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
111 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
112 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
113 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
114 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
115 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
116 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
117 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
118 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
119 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
120 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
121 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
122 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
123 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
124 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
125 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
126 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
127 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
128 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
129 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
130 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
131 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
132 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
133 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
134 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
135 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
136 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
137 | github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
138 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
139 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
140 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
141 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
142 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
143 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
144 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
145 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
146 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
147 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
148 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
149 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
150 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
151 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
152 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
153 | github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
154 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
155 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
156 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
157 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
158 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
159 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
160 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
161 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
162 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
163 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
164 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
165 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
166 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
167 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
168 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
169 | github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
170 | github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
171 | github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
172 | github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
173 | github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
174 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
175 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
176 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
177 | github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
178 | github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
179 | github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
180 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
181 | github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
182 | github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
183 | github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
184 | github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
185 | github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
186 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
187 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
188 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
189 | github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
190 | github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
191 | github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
192 | github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
193 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
194 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
195 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
196 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
197 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
198 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
199 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
200 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
201 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
202 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
203 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
204 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
205 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
206 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
207 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
208 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
209 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
210 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
211 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0 h1:yt2NKzK7Vyo6h0+X8BA4FpreZQTlVEIarnsBP/H5mzs=
212 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0/go.mod h1:+ARmXlUlc51J7sZeCBkBJNdHGySrdOzgzxp6VWRWM1U=
213 | go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0=
214 | go.opentelemetry.io/otel v1.11.2/go.mod h1:7p4EUV+AqgdlNV9gL97IgUZiVR3yrFXYo53f9BM3tRI=
215 | go.opentelemetry.io/otel/exporters/prometheus v0.34.0 h1:L5D+HxdaC/ORB47ribbTBbkXRZs9JzPjq0EoIOMWncM=
216 | go.opentelemetry.io/otel/exporters/prometheus v0.34.0/go.mod h1:6gUoJyfhoWqF0tOLaY0ZmKgkQRcvEQx6p5rVlKHp3s4=
217 | go.opentelemetry.io/otel/metric v0.34.0 h1:MCPoQxcg/26EuuJwpYN1mZTeCYAUGx8ABxfW07YkjP8=
218 | go.opentelemetry.io/otel/metric v0.34.0/go.mod h1:ZFuI4yQGNCupurTXCwkeD/zHBt+C2bR7bw5JqUm/AP8=
219 | go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNXUiU=
220 | go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU=
221 | go.opentelemetry.io/otel/sdk/metric v0.34.0 h1:7ElxfQpXCFZlRTvVRTkcUvK8Gt5DC8QzmzsLsO2gdzo=
222 | go.opentelemetry.io/otel/sdk/metric v0.34.0/go.mod h1:l4r16BIqiqPy5rd14kkxllPy/fOI4tWo1jkpD9Z3ffQ=
223 | go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0=
224 | go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA=
225 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
226 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
227 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
228 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
229 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
230 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
231 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
232 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
233 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
234 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
235 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
236 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
237 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
238 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
239 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
240 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
241 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
242 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
243 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
244 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
245 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
246 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
247 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
248 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
249 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
250 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
251 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
252 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
253 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
254 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
255 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
256 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
257 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
258 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
259 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
260 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
261 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
262 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
263 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
264 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
265 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
266 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
267 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
268 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
269 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
270 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
271 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
272 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
273 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
274 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
275 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
276 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
277 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
278 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
279 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
280 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
281 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
282 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
283 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
284 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
285 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
286 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
287 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
288 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
289 | golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
290 | golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
291 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
292 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
293 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
294 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
295 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
296 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
297 | golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
298 | golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
299 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
300 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
301 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
302 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
303 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
304 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
305 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
306 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
307 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
308 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
309 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
310 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
311 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
312 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
313 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
314 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
315 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
316 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
317 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
318 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
319 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
320 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
321 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
322 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
323 | golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
324 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
325 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
326 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
327 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
328 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
329 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
330 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
331 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
332 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
333 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
334 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
335 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
336 | golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
337 | golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
338 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
339 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
340 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
341 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
342 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
343 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
344 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
345 | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
346 | golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc=
347 | golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
348 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
349 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
350 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
351 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
352 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
353 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
354 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
355 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
356 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
357 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
358 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
359 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
360 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
361 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
362 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
363 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
364 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
365 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
366 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
367 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
368 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
369 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
370 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
371 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
372 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
373 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
374 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
375 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
376 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
377 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
378 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
379 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
380 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
381 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
382 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
383 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
384 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
385 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
386 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
387 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
388 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
389 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
390 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
391 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
392 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
393 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
394 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
395 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
396 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
397 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
398 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
399 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
400 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
401 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
402 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
403 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
404 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
405 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
406 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
407 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
408 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
409 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
410 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
411 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
412 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
413 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
414 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
415 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
416 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
417 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
418 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
419 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
420 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
421 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
422 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
423 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
424 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
425 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
426 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
427 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
428 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
429 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
430 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
431 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
432 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
433 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
434 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
435 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
436 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
437 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
438 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
439 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
440 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
441 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
442 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
443 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
444 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
445 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
446 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
447 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
448 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
449 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
450 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
451 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
452 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
453 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
454 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
455 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
456 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
457 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
458 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
459 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
460 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
461 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
462 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
463 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
464 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
465 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
466 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
467 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
468 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
469 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
470 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
471 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
472 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
473 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
474 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
475 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
476 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
477 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
478 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
479 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
480 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
481 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
482 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
483 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
484 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
485 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
486 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
487 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
488 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
489 | gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
490 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
491 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
492 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
493 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
494 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
495 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
496 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
497 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
498 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
499 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
500 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
501 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
502 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
503 |
--------------------------------------------------------------------------------
/levitate/remote-write/opentelemetry-collector/prometheus-receiver/app/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 |
7 | "github.com/prometheus/client_golang/prometheus/promhttp"
8 | "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
9 | "go.opentelemetry.io/otel/attribute"
10 | "go.opentelemetry.io/otel/exporters/prometheus"
11 | "go.opentelemetry.io/otel/metric/instrument"
12 | "go.opentelemetry.io/otel/sdk/metric"
13 | )
14 |
15 | func main() {
16 | exporter, err := prometheus.New()
17 | if err != nil {
18 | log.Fatal(err)
19 | }
20 | provider := metric.NewMeterProvider(metric.WithReader(exporter))
21 | meter := provider.Meter("levitate-otel-demo")
22 | requestCount, _ := meter.SyncInt64().Counter(
23 | "levitate/request_counts",
24 | instrument.WithDescription("The number of requests received"),
25 | )
26 |
27 | programLabel := attribute.String("program", "levitate")
28 | envLabel := attribute.String("env", "production")
29 | labels := []attribute.KeyValue{programLabel, envLabel}
30 |
31 | // Start the prometheus HTTP server and pass the exporter Collector to it
32 | go serveMetrics()
33 |
34 | handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
35 | ctx := req.Context()
36 | requestCount.Add(ctx, 1, labels...)
37 |
38 | if _, err := w.Write([]byte("Hello World")); err != nil {
39 | http.Error(w, "write operation failed.", http.StatusInternalServerError)
40 | return
41 | }
42 |
43 | })
44 |
45 | mux := http.NewServeMux()
46 | mux.Handle("/hello", otelhttp.NewHandler(handler, "/hello"))
47 | server := &http.Server{
48 | Addr: ":9000",
49 | Handler: mux,
50 | }
51 | if err := server.ListenAndServe(); err != http.ErrServerClosed {
52 | log.Fatalf("%v", err)
53 | }
54 | }
55 |
56 | func serveMetrics() {
57 | log.Printf("serving metrics")
58 | mux := http.NewServeMux()
59 | mux.Handle("/metrics", promhttp.Handler())
60 | server := &http.Server{
61 | Addr: ":8000",
62 | Handler: mux,
63 | }
64 | if err := server.ListenAndServe(); err != http.ErrServerClosed {
65 | log.Fatalf("%v", err)
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/levitate/remote-write/opentelemetry-collector/prometheus-receiver/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: "3.5"
2 | services:
3 | otel-collector:
4 | container_name: otel-collector-contrib
5 | image: otel/opentelemetry-collector-contrib:0.64.0
6 | restart: always
7 | command: ["--config=/etc/otel-collector-config.yaml"]
8 | volumes:
9 | - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
10 | ports:
11 | - "8888:8888" # Prometheus metrics exposed by the collector
12 | - "4317:4317" # OTLP gRPC receiver
13 | - "4318:4318" # OTLP http receiver
14 |
15 | app:
16 | container_name: app
17 | build:
18 | dockerfile: Dockerfile
19 | context: ./app
20 | restart: always
21 | ports:
22 | - "8000:8000" # metrics
23 | - "9000:9000" # app
24 | depends_on:
25 | - otel-collector
26 |
--------------------------------------------------------------------------------
/levitate/remote-write/opentelemetry-collector/prometheus-receiver/otel-collector-config.yaml:
--------------------------------------------------------------------------------
1 | extensions:
2 | basicauth/prw:
3 | client_auth:
4 | # Replace these variables by their actual values
5 | username: $levitate_username
6 | password: $levitate_password
7 |
8 | receivers:
9 | prometheus:
10 | config:
11 | scrape_configs:
12 | - job_name: 'otel-collector-01'
13 | scrape_interval: 60s
14 | static_configs:
15 | - targets: ['otel-collector:8888', 'app:8000']
16 |
17 | exporters:
18 | prometheusremotewrite:
19 | auth:
20 | authenticator: basicauth/prw
21 | endpoint: "$levitate_write_endpoint" # Replace this variable by its actual value
22 |
23 | service:
24 | extensions: [basicauth/prw]
25 | pipelines:
26 | metrics:
27 | receivers: [prometheus]
28 | exporters: [prometheusremotewrite]
29 |
--------------------------------------------------------------------------------
/levitate/remote-write/prometheus-agent/k8s/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/last9/last9-integrations/8c9a66d98f253ff5e7afc0f9824c551b3f61f478/levitate/remote-write/prometheus-agent/k8s/README.md
--------------------------------------------------------------------------------
/levitate/remote-write/python/README.md:
--------------------------------------------------------------------------------
1 | ## Getting started
2 |
3 | Make sure that you have snappy installed as per instructions [here](https://github.com/andrix/python-snappy).
4 |
5 | ```sh
6 | pip install python-snappy
7 | pip install opentelemetry-exporter-prometheus-remote-write
8 | ```
9 |
10 | This will install required dependencies. After that, pass the username and password of Prometheus backend. (It can be Levitate cluster).
11 |
12 | ```sh
13 | python app.py LEVITATE_REMOTE_WRITE_URL LEVITATE_CLUSTER_USERNAME LEVITATE_CLUSTER_PASSWORD 'my_metric' '{"environment": "staging", "label": "9999"}'
14 | ```
15 |
16 | After this you can explore the metric in Grafana to make sure it is accessible.
17 |
18 | You can refer to complete tutorial [here](https://docs.last9.io/docs/using-open-telemetry-exporter-for-prometheus-remote-write).
19 |
--------------------------------------------------------------------------------
/levitate/remote-write/python/app.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import logging
4 | import random
5 | import sys
6 | import time
7 | import json
8 | from logging import INFO
9 |
10 | from opentelemetry import metrics
11 | from opentelemetry.exporter.prometheus_remote_write import (
12 | PrometheusRemoteWriteMetricsExporter,
13 | )
14 | from opentelemetry.metrics import Observation
15 | from opentelemetry.sdk.metrics import MeterProvider
16 | from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
17 |
18 | logging.basicConfig(stream=sys.stdout, level=logging.INFO)
19 | logger = logging.getLogger(__name__)
20 |
21 |
22 | exporter = PrometheusRemoteWriteMetricsExporter(
23 | endpoint=sys.argv[1],
24 | basic_auth={
25 | "username": sys.argv[2],
26 | "password": sys.argv[3],
27 | },
28 | headers={},
29 | )
30 | reader = PeriodicExportingMetricReader(exporter, 1000)
31 | provider = MeterProvider(metric_readers=[reader])
32 | metrics.set_meter_provider(provider)
33 | meter = metrics.get_meter(__name__)
34 |
35 | requests_counter = meter.create_counter(
36 | name=sys.argv[4],
37 | description="number of requests",
38 | )
39 |
40 | testing_labels = json.loads(sys.argv[5])
41 |
42 | num = random.randint(0, 1000)
43 | requests_counter.add(num % 131 + 200, testing_labels)
44 | logger.log(level=INFO, msg="completed metrics collection cycle")
45 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/relay/.gitignore:
--------------------------------------------------------------------------------
1 | *.env
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/relay/README.md:
--------------------------------------------------------------------------------
1 | This folder contains demo code for statsd to Levitate remote write integration
2 | using stasd_exporter relay method.
3 |
4 | Read more about the flow [here](https://docs.last9.io/docs/levitate-integrations-statsd#relay-method)
5 |
6 | ### Steps
7 |
8 | 1. Update the following variables in [docker-compose.yaml](./docker-compose.yaml) or update export them as environment variables
9 | - $LEVITATE_REMOTE_WRITE_URL
10 | - $LEVITATE_REMOTE_WRITE_USERNAME
11 | - $LEVITATE_REMOTE_WRITE_PASSWORD
12 | 2. Run `docker-compose up --build --force-recreate --remove-orphans`
13 |
14 | ### Validate
15 |
16 | 1. Run a test app that sends metrics to statsd.
17 | ```
18 | pip install -r requirements.txt
19 | python ./test/statsd-test.py
20 | ```
21 | 2. After 5 minutes, query for a sample metric `performance_request_successful_count_value`.
22 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/relay/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 | services:
3 |
4 | statsd:
5 | build: statsd
6 | ports:
7 | - 8125:8125/udp
8 | - 8126:8126/udp
9 | restart: always
10 |
11 | statsd_exporter:
12 | image: prom/statsd-exporter
13 | ports:
14 | - 9125:9125/udp
15 | - 9102:9102/tcp
16 | command:
17 | - "--statsd.relay.address=statsd:8125"
18 | - "--web.listen-address=:9102"
19 | restart: always
20 |
21 | vmagent_levitate:
22 | image: victoriametrics/vmagent:v1.85.3
23 | ports:
24 | - 8429:8429
25 | volumes:
26 | - vmagentdata:/vmagentdata
27 | - ./vmagent.yaml:/etc/prometheus/prometheus.yaml
28 | command:
29 | - "--promscrape.config=/etc/prometheus/prometheus.yaml"
30 | - "--remoteWrite.url=${LEVITATE_REMOTE_WRITE_URL}"
31 | - "--remoteWrite.basicAuth.username=${LEVITATE_REMOTE_WRITE_USERNAME}"
32 | - "--remoteWrite.basicAuth.password=${LEVITATE_REMOTE_WRITE_PASSWORD}"
33 | restart: always
34 |
35 | volumes:
36 | vmagentdata: {}
37 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/relay/statsd/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:latest
2 |
3 | RUN apt-get update && apt-get install -y --force-yes git
4 | RUN git clone https://github.com/etsy/statsd.git
5 | RUN cd /statsd
6 |
7 | ADD config.js /statsd/config.js
8 |
9 | EXPOSE 8125/udp
10 | EXPOSE 8126/udp
11 | EXPOSE 8125/tcp
12 | EXPOSE 8126/tcp
13 |
14 | CMD /usr/local/bin/node /statsd/stats.js /statsd/config.js
15 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/relay/statsd/config.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | return {
3 | port: 8125,
4 | debug: false,
5 | backends: ['./backends/console'],
6 | server: "./servers/udp",
7 | includeStatsdMetrics: false,
8 | includeInfluxdbMetrics: false,
9 | keyNameSanitize: false
10 | };
11 |
12 | })();
13 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/relay/test/requirements.txt:
--------------------------------------------------------------------------------
1 | statsd
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/relay/test/statsd-test.py:
--------------------------------------------------------------------------------
1 | import statsd
2 | from time import sleep
3 | from random import randint, choice
4 |
5 | c = statsd.StatsClient('localhost', 9125, prefix='performance')
6 |
7 | while True:
8 | incr = randint(1, 5)
9 | metric_type = choice(['A', 'B', 'C'])
10 | print(f"\radding metric: type: {metric_type}, incr: {incr}", end="")
11 | c.incr(f'request.successful.count,type={metric_type}', incr)
12 | sleep(1)
13 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/relay/vmagent.yaml:
--------------------------------------------------------------------------------
1 | global:
2 | scrape_interval: 30s
3 | scrape_configs:
4 | - job_name: "scrape_statsd_exporter_relay_1"
5 | static_configs:
6 | - targets: [ "statsd_exporter:9102" ]
7 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/repeater/.gitignore:
--------------------------------------------------------------------------------
1 | *.env
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/repeater/README.md:
--------------------------------------------------------------------------------
1 | This directory contains demo code for statsd to Levitate remote write integration
2 | using stasd_exporter repeater method.
3 |
4 | Read more about the flow [here](https://docs.last9.io/docs/levitate-integrations-statsd#repeater-method)
5 |
6 | ### Steps
7 |
8 | 1. Update the following variables in [docker-compose.yaml](./docker-compose.yaml) or update export them as environment variables
9 | - $LEVITATE_REMOTE_WRITE_URL
10 | - $LEVITATE_REMOTE_WRITE_USERNAME
11 | - $LEVITATE_REMOTE_WRITE_PASSWORD
12 | 2. Run `docker-compose up --build --force-recreate --remove-orphans`
13 |
14 | ### Validate
15 |
16 | 1. Run a test app that sends metrics to statsd.
17 | ```
18 | pip install -r requirements.txt
19 | python ./test/statsd-test.py
20 | ```
21 | 2. After 5 minutes, query for a sample metric `performance_request_successful_count_value`.
22 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/repeater/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 | services:
3 |
4 | statsd:
5 | build: statsd
6 | ports:
7 | - 8125:8125/udp
8 | - 8126:8126/udp
9 | restart: always
10 |
11 | statsd_exporter:
12 | image: prom/statsd-exporter
13 | ports:
14 | - 9102:9102/tcp
15 | command:
16 | - "--statsd.listen-udp=:9125"
17 | - "--web.listen-address=:9102"
18 | restart: always
19 |
20 | vmagent_levitate:
21 | image: victoriametrics/vmagent:v1.85.3
22 | ports:
23 | - 8429:8429
24 | volumes:
25 | - vmagentdata:/vmagentdata
26 | - ./vmagent.yaml:/etc/prometheus/prometheus.yaml
27 | command:
28 | - "--promscrape.config=/etc/prometheus/prometheus.yaml"
29 | - "--remoteWrite.url=${LEVITATE_REMOTE_WRITE_URL}"
30 | - "--remoteWrite.basicAuth.username=${LEVITATE_REMOTE_WRITE_USERNAME}"
31 | - "--remoteWrite.basicAuth.password=${LEVITATE_REMOTE_WRITE_PASSWORD}"
32 | restart: always
33 |
34 | volumes:
35 | vmagentdata: {}
36 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/repeater/statsd/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:latest
2 |
3 | RUN apt-get update && apt-get install -y --force-yes git
4 | RUN git clone https://github.com/etsy/statsd.git
5 | # Install generic-pool module as it is required by repeater backend
6 | RUN cd /statsd && npm install generic-pool@2.2.0
7 |
8 | ADD config.js /statsd/config.js
9 |
10 | EXPOSE 8125/udp
11 | EXPOSE 8126/udp
12 | EXPOSE 8125/tcp
13 | EXPOSE 8126/tcp
14 |
15 | CMD /usr/local/bin/node /statsd/stats.js /statsd/config.js
16 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/repeater/statsd/config.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | return {
3 | port: parseInt(process.env.STATSD_PORT) || 8125,
4 | debug: process.env.STATSD_DEBUG || false,
5 | backends: ['./backends/console', './backends/repeater'],
6 | repeater: [ { host: 'statsd_exporter', port: 9125 }],
7 | server: "./servers/udp",
8 | includeStatsdMetrics: false,
9 | includeInfluxdbMetrics: false,
10 | keyNameSanitize: false
11 | };
12 |
13 | })();
14 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/repeater/test/requirements.txt:
--------------------------------------------------------------------------------
1 | statsd
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/repeater/test/statsd-test.py:
--------------------------------------------------------------------------------
1 | import statsd
2 | from time import sleep
3 | from random import randint, choice
4 |
5 | c = statsd.StatsClient('localhost', 8125, prefix='performance')
6 |
7 | while True:
8 | incr = randint(1, 5)
9 | metric_type = choice(['A', 'B', 'C'])
10 | print(f"\radding metric: type: {metric_type}, incr: {incr}", end="")
11 | c.incr(f'request.successful.count,type={metric_type}', incr)
12 | sleep(1)
13 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/repeater/vmagent.yaml:
--------------------------------------------------------------------------------
1 | global:
2 | scrape_interval: 30s
3 | scrape_configs:
4 | - job_name: "scrape_statsd_exporter_repeater_1"
5 | static_configs:
6 | - targets: [ "statsd_exporter:9102" ]
7 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/vmagent-graphite/.gitignore:
--------------------------------------------------------------------------------
1 | *.env
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/vmagent-graphite/README.md:
--------------------------------------------------------------------------------
1 | This folder contains demo code for statsd to Levitate remote write integration
2 | using vmagent.
3 |
4 | Read more about the flow [here]()
5 |
6 | ### Steps
7 |
8 | 1. Update the following variables in [docker-compose.yaml](./docker-compose.yaml) or update export them as environment variables
9 | - $LEVITATE_REMOTE_WRITE_URL
10 | - $LEVITATE_REMOTE_WRITE_USERNAME
11 | - $LEVITATE_REMOTE_WRITE_PASSWORD
12 | 2. Run `docker-compose up --build --force-recreate --remove-orphans`
13 |
14 | ### Validate
15 |
16 | 1. Run a test app that sends metrics to statsd.
17 | ```
18 | pip install -r requirements.txt
19 | python ./test/statsd-test.py
20 | ```
21 | 2. After 5 minutes, query for a sample metric `performance_request_successful_count_value`.
22 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/vmagent-graphite/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 | services:
3 | statsd:
4 | build: statsd
5 | depends_on:
6 | - vmagent_levitate
7 | ports:
8 | - 8125:8125/udp
9 | - 8126:8126/udp
10 | restart: always
11 |
12 | vmagent_levitate:
13 | image: victoriametrics/vmagent:v1.85.3
14 | ports:
15 | - 8429:8429
16 | - 2003:2003/tcp
17 | - 2003:2003/udp
18 | volumes:
19 | - vmagentdata:/vmagentdata
20 | - ./vmagent.yaml:/etc/prometheus/prometheus.yaml
21 | command:
22 | - "--graphiteListenAddr=:2003"
23 | - "--promscrape.config=/etc/prometheus/prometheus.yaml"
24 | - "--remoteWrite.url=${LEVITATE_REMOTE_WRITE_URL}"
25 | - "--remoteWrite.basicAuth.username=${LEVITATE_REMOTE_WRITE_USERNAME}"
26 | - "--remoteWrite.basicAuth.password=${LEVITATE_REMOTE_WRITE_PASSWORD}"
27 | restart: always
28 |
29 | volumes:
30 | vmagentdata: {}
31 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/vmagent-graphite/statsd/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:latest
2 |
3 | RUN apt-get update && apt-get install -y --force-yes git
4 | RUN git clone https://github.com/etsy/statsd.git
5 | RUN cd /statsd
6 |
7 | ADD config.js /statsd/config.js
8 |
9 | EXPOSE 8125/udp
10 | EXPOSE 8126/udp
11 | EXPOSE 8125/tcp
12 | EXPOSE 8126/tcp
13 |
14 | CMD /usr/local/bin/node /statsd/stats.js /statsd/config.js
15 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/vmagent-graphite/statsd/config.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | return {
3 | port: 8125,
4 | debug: true,
5 | backends: ["./backends/console", "./backends/graphite"],
6 | graphiteHost: "vmagent_levitate",
7 | graphitePort: 2003,
8 | server: "./servers/udp",
9 | includeStatsdMetrics: false,
10 | includeInfluxdbMetrics: false,
11 | keyNameSanitize: false
12 | };
13 | })();
14 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/vmagent-graphite/test/requirements.txt:
--------------------------------------------------------------------------------
1 | statsd
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/vmagent-graphite/test/statsd-test.py:
--------------------------------------------------------------------------------
1 | import statsd
2 | from time import sleep
3 | from random import randint, choice
4 |
5 | c = statsd.StatsClient('localhost', 8125, prefix='performance2')
6 |
7 | while True:
8 | incr = randint(1, 5)
9 | metric_type = choice(['A', 'B', 'C'])
10 | print(f"\radding metric: type: {metric_type}, incr: {incr}", end="")
11 | c.incr(f'request.successful.count,type={metric_type}', incr)
12 | sleep(1)
13 |
--------------------------------------------------------------------------------
/levitate/remote-write/statsd/vmagent-graphite/vmagent.yaml:
--------------------------------------------------------------------------------
1 | global:
2 | # Sane default of 1 minute. Anything less than this is too frequent.
3 | scrape_interval: 1m
4 | scrape_configs:
5 | - job_name: "scrape_vmagent_self"
6 | static_configs:
7 | - targets: [ "localhost:8429" ]
8 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/http-prometheusremotewrite/.gitignore:
--------------------------------------------------------------------------------
1 | *.env
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/http-prometheusremotewrite/README.md:
--------------------------------------------------------------------------------
1 | This folder contains demo code for Telegraf to Levitate remote write integration
2 | using InfluxDB http output plugin with data_format as prometheusremotewrite.
3 |
4 | ### Steps
5 |
6 | 1. Update the following variables in [docker-compose.yaml](./docker-compose.yaml) or update export them as environment variables
7 | - $LEVITATE_REMOTE_WRITE_URL
8 | - $LEVITATE_REMOTE_WRITE_USERNAME
9 | - $LEVITATE_REMOTE_WRITE_PASSWORD
10 | 2. Run `docker-compose up --build --force-recreate --remove-orphans`
11 |
12 | ### Validate
13 |
14 | 1. Run a test app that sends metrics to Telegraf.
15 | ```
16 | pip install -r requirements.txt
17 | python ./test/statsd-test.py
18 | ```
19 | 2. After 5 minutes, query for a sample metric `performance_request_successful_count_value`.
20 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/http-prometheusremotewrite/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 | services:
3 | telegraf:
4 | image: telegraf:1.24
5 | volumes:
6 | - ./telegraf/etc/telegraf.conf:/etc/telegraf/telegraf.conf:ro
7 | environment:
8 | - LEVITATE_REMOTE_WRITE_URL=${LEVITATE_REMOTE_WRITE_URL}
9 | - LEVITATE_REMOTE_WRITE_USERNAME=${LEVITATE_REMOTE_WRITE_USERNAME}
10 | - LEVITATE_REMOTE_WRITE_PASSWORD=${LEVITATE_REMOTE_WRITE_PASSWORD}
11 | ports:
12 | - '8125:8125/udp'
13 | restart: always
14 |
15 | volumes:
16 | vmagentdata: {}
17 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/http-prometheusremotewrite/telegraf/etc/telegraf.conf:
--------------------------------------------------------------------------------
1 | # Telegraf configuration
2 |
3 | # Telegraf is entirely plugin driven. All metrics are gathered from the
4 | # declared inputs, and sent to the declared outputs.
5 |
6 | # Plugins must be declared in here to be active.
7 | # To deactivate a plugin, comment out the name and any variables.
8 |
9 | # Use 'telegraf -config telegraf.conf -test' to see what metrics a config
10 | # file would generate.
11 |
12 | # Global tags can be specified here in key="value" format.
13 | [global_tags]
14 | # dc = "us-east-1" # will tag all metrics with dc=us-east-1
15 | # rack = "1a"
16 |
17 | # Configuration for telegraf agent
18 | [agent]
19 | ## Default data collection interval for all inputs
20 | interval = "5s"
21 | ## Rounds collection interval to 'interval'
22 | ## ie, if interval="10s" then always collect on :00, :10, :20, etc.
23 | round_interval = true
24 |
25 | ## Telegraf will cache metric_buffer_limit metrics for each output, and will
26 | ## flush this buffer on a successful write.
27 | metric_buffer_limit = 10000
28 | ## Flush the buffer whenever full, regardless of flush_interval.
29 | flush_buffer_when_full = true
30 |
31 | ## Collection jitter is used to jitter the collection by a random amount.
32 | ## Each plugin will sleep for a random time within jitter before collecting.
33 | ## This can be used to avoid many plugins querying things like sysfs at the
34 | ## same time, which can have a measurable effect on the system.
35 | collection_jitter = "0s"
36 |
37 | ## Default flushing interval for all outputs. You shouldn't set this below
38 | ## interval. Maximum flush_interval will be flush_interval + flush_jitter
39 | flush_interval = "1s"
40 | ## Jitter the flush interval by a random amount. This is primarily to avoid
41 | ## large write spikes for users running a large number of telegraf instances.
42 | ## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s
43 | flush_jitter = "0s"
44 |
45 | ## Run telegraf in debug mode
46 | debug = false
47 | ## Run telegraf in quiet mode
48 | quiet = false
49 | ## Override default hostname, if empty use os.Hostname()
50 | hostname = ""
51 |
52 |
53 | ###############################################################################
54 | # OUTPUTS #
55 | ###############################################################################
56 |
57 |
58 | ######## read ##########
59 | # Warning: When generating histogram and summary types, output may not be correct if the metric spans multiple batches.
60 | # This issue can be somewhat, but not fully, mitigated by using outputs that support writing in "batch format".
61 | # When using histogram and summary types, it is recommended to use only the prometheus_client output.
62 | ######## read ##########
63 | # A plugin that can transmit metrics over HTTP
64 | [[outputs.http]]
65 | ## URL is the address to send metrics to
66 | url = "${LEVITATE_REMOTE_WRITE_URL}"
67 |
68 | ## HTTP Basic Auth credentials
69 | username = "${LEVITATE_REMOTE_WRITE_USERNAME}"
70 | password = "${LEVITATE_REMOTE_WRITE_PASSWORD}"
71 |
72 | ## Data format to output.
73 | data_format = "prometheusremotewrite"
74 |
75 | ## Additional HTTP headers
76 | [outputs.http.headers]
77 | Content-Type = "application/x-protobuf"
78 | Content-Encoding = "snappy"
79 | X-Prometheus-Remote-Write-Version = "0.1.0"
80 |
81 | #
82 | ###############################################################################
83 | # INPUTS #
84 | ###############################################################################
85 | # Statsd Server
86 | [[inputs.statsd]]
87 | ## Protocol, must be "tcp", "udp4", "udp6" or "udp" (default=udp)
88 | protocol = "udp"
89 |
90 | ## MaxTCPConnection - applicable when protocol is set to tcp (default=250)
91 | max_tcp_connections = 250
92 |
93 | ## Enable TCP keep alive probes (default=false)
94 | tcp_keep_alive = false
95 |
96 | ## Specifies the keep-alive period for an active network connection.
97 | ## Only applies to TCP sockets and will be ignored if tcp_keep_alive is false.
98 | ## Defaults to the OS configuration.
99 | # tcp_keep_alive_period = "2h"
100 |
101 | ## Address and port to host UDP listener on
102 | service_address = ":8125"
103 |
104 | ## The following configuration options control when telegraf clears it's cache
105 | ## of previous values. If set to false, then telegraf will only clear it's
106 | ## cache when the daemon is restarted.
107 | ## Reset gauges every interval (default=true)
108 | delete_gauges = true
109 | ## Reset counters every interval (default=true)
110 | delete_counters = true
111 | ## Reset sets every interval (default=true)
112 | delete_sets = true
113 | ## Reset timings & histograms every interval (default=true)
114 | delete_timings = true
115 |
116 | ## Percentiles to calculate for timing & histogram stats
117 | percentiles = [90]
118 |
119 | ## separator to use between elements of a statsd metric
120 | metric_separator = "_"
121 |
122 | ## Parses tags in the datadog statsd format
123 | ## http://docs.datadoghq.com/guides/dogstatsd/
124 | parse_data_dog_tags = false
125 |
126 | ## Statsd data translation templates, more info can be read here:
127 | ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md#graphite
128 | # templates = [
129 | # "cpu.* measurement*"
130 | # ]
131 |
132 | ## Number of UDP messages allowed to queue up, once filled,
133 | ## the statsd server will start dropping packets
134 | allowed_pending_messages = 10000
135 |
136 | ## Number of timing/histogram values to track per-measurement in the
137 | ## calculation of percentiles. Raising this limit increases the accuracy
138 | ## of percentiles but also increases the memory usage and cpu time.
139 | percentile_limit = 1000
140 |
141 | ## Maximum socket buffer size in bytes, once the buffer fills up, metrics
142 | ## will start dropping. Defaults to the OS default.
143 | # read_buffer_size = 65535
144 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/http-prometheusremotewrite/test/statsd-test.py:
--------------------------------------------------------------------------------
1 | import statsd
2 | from time import sleep
3 | from random import randint, choice
4 |
5 | c = statsd.StatsClient('localhost', 8125, prefix='performance')
6 |
7 | while True:
8 | incr = randint(1, 5)
9 | metric_type = choice(['A', 'B', 'C'])
10 | print(f"\radding metric: type: {metric_type}, incr: {incr}", end="")
11 | c.incr(f'request.successful.count,type={metric_type}', incr)
12 | sleep(1)
13 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/influxdb-to-vmagent/.gitignore:
--------------------------------------------------------------------------------
1 | *.env
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/influxdb-to-vmagent/README.md:
--------------------------------------------------------------------------------
1 | ### Overview
2 |
3 | This directory contains demo code for Telegraf to Levitate remote write integration
4 | using InfluxDB output plugin pointing to vmagent.
5 |
6 | Read more about the flow [here](https://docs.last9.io/docs/levitate-integrations-telegraf).
7 |
8 |
9 | ### Steps
10 |
11 | 1. Update the following variables in [docker-compose.yaml](./docker-compose.yaml) or update export them as environment variables
12 | - $LEVITATE_REMOTE_WRITE_URL
13 | - $LEVITATE_REMOTE_WRITE_USERNAME
14 | - $LEVITATE_REMOTE_WRITE_PASSWORD
15 | 2. Run `docker-compose up --build --force-recreate --remove-orphans`
16 |
17 | ### Validate
18 |
19 | 1. Run a test app that sends metrics to Telegraf.
20 | ```
21 | pip install -r requirements.txt
22 | python ./test/statsd-test.py
23 | ```
24 | 2. After few minutes, query for a sample metric `performance_request_successful_count_value` using Levitate read endpoint.
25 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/influxdb-to-vmagent/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 | services:
3 | telegraf:
4 | image: telegraf:1.24
5 | volumes:
6 | - ./telegraf/etc/telegraf.conf:/etc/telegraf/telegraf.conf:ro
7 | ports:
8 | - '8125:8125/udp'
9 | restart: always
10 |
11 | vmagent_levitate:
12 | image: victoriametrics/vmagent:v1.85.3
13 | ports:
14 | - 8429:8429
15 | volumes:
16 | - vmagentdata:/vmagentdata
17 | - ./vmagent.yaml:/etc/prometheus/prometheus.yaml
18 | command:
19 | - "--promscrape.config=/etc/prometheus/prometheus.yaml"
20 | - "--remoteWrite.url=${LEVITATE_REMOTE_WRITE_URL}"
21 | - "--remoteWrite.basicAuth.username=${LEVITATE_REMOTE_WRITE_USERNAME}"
22 | - "--remoteWrite.basicAuth.password=${LEVITATE_REMOTE_WRITE_PASSWORD}"
23 | restart: always
24 |
25 | volumes:
26 | vmdata: {}
27 | vmagentdata: {}
28 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/influxdb-to-vmagent/telegraf/etc/telegraf.conf:
--------------------------------------------------------------------------------
1 | # Telegraf configuration
2 |
3 | # Telegraf is entirely plugin driven. All metrics are gathered from the
4 | # declared inputs, and sent to the declared outputs.
5 |
6 | # Plugins must be declared in here to be active.
7 | # To deactivate a plugin, comment out the name and any variables.
8 |
9 | # Use 'telegraf -config telegraf.conf -test' to see what metrics a config
10 | # file would generate.
11 |
12 | # Global tags can be specified here in key="value" format.
13 | [global_tags]
14 | # dc = "us-east-1" # will tag all metrics with dc=us-east-1
15 | # rack = "1a"
16 |
17 | # Configuration for telegraf agent
18 | [agent]
19 | ## Default data collection interval for all inputs
20 | interval = "5s"
21 | ## Rounds collection interval to 'interval'
22 | ## ie, if interval="10s" then always collect on :00, :10, :20, etc.
23 | round_interval = true
24 |
25 | ## Telegraf will cache metric_buffer_limit metrics for each output, and will
26 | ## flush this buffer on a successful write.
27 | metric_buffer_limit = 10000
28 | ## Flush the buffer whenever full, regardless of flush_interval.
29 | flush_buffer_when_full = true
30 |
31 | ## Collection jitter is used to jitter the collection by a random amount.
32 | ## Each plugin will sleep for a random time within jitter before collecting.
33 | ## This can be used to avoid many plugins querying things like sysfs at the
34 | ## same time, which can have a measurable effect on the system.
35 | collection_jitter = "0s"
36 |
37 | ## Default flushing interval for all outputs. You shouldn't set this below
38 | ## interval. Maximum flush_interval will be flush_interval + flush_jitter
39 | flush_interval = "1s"
40 | ## Jitter the flush interval by a random amount. This is primarily to avoid
41 | ## large write spikes for users running a large number of telegraf instances.
42 | ## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s
43 | flush_jitter = "0s"
44 |
45 | ## Run telegraf in debug mode
46 | debug = false
47 | ## Run telegraf in quiet mode
48 | quiet = false
49 | ## Override default hostname, if empty use os.Hostname()
50 | hostname = ""
51 |
52 |
53 | ###############################################################################
54 | # OUTPUTS #
55 | ###############################################################################
56 | [[outputs.influxdb]]
57 | urls = ["http://vmagent_levitate:8429"]
58 |
59 | #
60 | ###############################################################################
61 | # INPUTS #
62 | ###############################################################################
63 | # Statsd Server
64 | [[inputs.statsd]]
65 | ## Protocol, must be "tcp", "udp4", "udp6" or "udp" (default=udp)
66 | protocol = "udp"
67 |
68 | ## MaxTCPConnection - applicable when protocol is set to tcp (default=250)
69 | max_tcp_connections = 250
70 |
71 | ## Enable TCP keep alive probes (default=false)
72 | tcp_keep_alive = false
73 |
74 | ## Specifies the keep-alive period for an active network connection.
75 | ## Only applies to TCP sockets and will be ignored if tcp_keep_alive is false.
76 | ## Defaults to the OS configuration.
77 | # tcp_keep_alive_period = "2h"
78 |
79 | ## Address and port to host UDP listener on
80 | service_address = ":8125"
81 |
82 | ## The following configuration options control when telegraf clears it's cache
83 | ## of previous values. If set to false, then telegraf will only clear it's
84 | ## cache when the daemon is restarted.
85 | ## Reset gauges every interval (default=true)
86 | delete_gauges = true
87 | ## Reset counters every interval (default=true)
88 | delete_counters = true
89 | ## Reset sets every interval (default=true)
90 | delete_sets = true
91 | ## Reset timings & histograms every interval (default=true)
92 | delete_timings = true
93 |
94 | ## Percentiles to calculate for timing & histogram stats
95 | percentiles = [90]
96 |
97 | ## separator to use between elements of a statsd metric
98 | metric_separator = "_"
99 |
100 | ## Parses tags in the datadog statsd format
101 | ## http://docs.datadoghq.com/guides/dogstatsd/
102 | parse_data_dog_tags = false
103 |
104 | ## Statsd data translation templates, more info can be read here:
105 | ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md#graphite
106 | # templates = [
107 | # "cpu.* measurement*"
108 | # ]
109 |
110 | ## Number of UDP messages allowed to queue up, once filled,
111 | ## the statsd server will start dropping packets
112 | allowed_pending_messages = 10000
113 |
114 | ## Number of timing/histogram values to track per-measurement in the
115 | ## calculation of percentiles. Raising this limit increases the accuracy
116 | ## of percentiles but also increases the memory usage and cpu time.
117 | percentile_limit = 1000
118 |
119 | ## Maximum socket buffer size in bytes, once the buffer fills up, metrics
120 | ## will start dropping. Defaults to the OS default.
121 | # read_buffer_size = 65535
122 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/influxdb-to-vmagent/test/statsd-test.py:
--------------------------------------------------------------------------------
1 | import statsd
2 | from time import sleep
3 | from random import randint, choice
4 |
5 | c = statsd.StatsClient('localhost', 8125, prefix='performance')
6 |
7 | while True:
8 | incr = randint(1, 5)
9 | metric_type = choice(['A', 'B', 'C'])
10 | print(f"\radding metric: type: {metric_type}, incr: {incr}", end="")
11 | c.incr(f'request.successful.count,type={metric_type}', incr)
12 | sleep(1)
13 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/influxdb-to-vmagent/vmagent.yaml:
--------------------------------------------------------------------------------
1 | global:
2 | scrape_interval: 1m
3 | scrape_configs:
4 | - job_name: "scrape_vmagent_self"
5 | static_configs:
6 | - targets: [ "localhost:8429" ]
7 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/prometheus-client/.gitignore:
--------------------------------------------------------------------------------
1 | *.env
2 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/prometheus-client/README.md:
--------------------------------------------------------------------------------
1 | This folder contains demo code for Telegraf to Levitate remote write integration
2 | using InfluxDB prometheus_client output plugin.
3 |
4 | ### Steps
5 |
6 | 1. Update the following variables in [docker-compose.yaml](./docker-compose.yaml) or update export them as environment variables
7 | - $LEVITATE_REMOTE_WRITE_URL
8 | - $LEVITATE_REMOTE_WRITE_USERNAME
9 | - $LEVITATE_REMOTE_WRITE_PASSWORD
10 | 2. Run `docker-compose up --build --force-recreate --remove-orphans`
11 |
12 | ### Validate
13 |
14 | 1. Run a test app that sends metrics to Telegraf.
15 | ```
16 | pip install -r requirements.txt
17 | python ./test/statsd-test.py
18 | ```
19 | 2. After 5 minutes, query for a sample metric `performance_request_successful_count_value`.
20 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/prometheus-client/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 | services:
3 | telegraf:
4 | image: telegraf:1.24
5 | volumes:
6 | - ./telegraf/etc/telegraf.conf:/etc/telegraf/telegraf.conf:ro
7 | ports:
8 | - '8125:8125/udp'
9 | - '9273:9273'
10 | restart: always
11 |
12 | vmagent_levitate:
13 | image: victoriametrics/vmagent:v1.85.3
14 | ports:
15 | - 8429:8429
16 | volumes:
17 | - vmagentdata:/vmagentdata
18 | - ./vmagent.yaml:/etc/prometheus/prometheus.yaml
19 | command:
20 | - "--promscrape.config=/etc/prometheus/prometheus.yaml"
21 | - "--remoteWrite.url=${LEVITATE_REMOTE_WRITE_URL}"
22 | - "--remoteWrite.basicAuth.username=${LEVITATE_REMOTE_WRITE_USERNAME}"
23 | - "--remoteWrite.basicAuth.password=${LEVITATE_REMOTE_WRITE_PASSWORD}"
24 | restart: always
25 |
26 | volumes:
27 | vmagentdata: {}
28 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/prometheus-client/telegraf/etc/telegraf.conf:
--------------------------------------------------------------------------------
1 | # Telegraf configuration
2 |
3 | # Telegraf is entirely plugin driven. All metrics are gathered from the
4 | # declared inputs, and sent to the declared outputs.
5 |
6 | # Plugins must be declared in here to be active.
7 | # To deactivate a plugin, comment out the name and any variables.
8 |
9 | # Use 'telegraf -config telegraf.conf -test' to see what metrics a config
10 | # file would generate.
11 |
12 | # Global tags can be specified here in key="value" format.
13 | [global_tags]
14 | # dc = "us-east-1" # will tag all metrics with dc=us-east-1
15 | # rack = "1a"
16 |
17 | # Configuration for telegraf agent
18 | [agent]
19 | ## Default data collection interval for all inputs
20 | interval = "5s"
21 | ## Rounds collection interval to 'interval'
22 | ## ie, if interval="10s" then always collect on :00, :10, :20, etc.
23 | round_interval = true
24 |
25 | ## Telegraf will cache metric_buffer_limit metrics for each output, and will
26 | ## flush this buffer on a successful write.
27 | metric_buffer_limit = 10000
28 | ## Flush the buffer whenever full, regardless of flush_interval.
29 | flush_buffer_when_full = true
30 |
31 | ## Collection jitter is used to jitter the collection by a random amount.
32 | ## Each plugin will sleep for a random time within jitter before collecting.
33 | ## This can be used to avoid many plugins querying things like sysfs at the
34 | ## same time, which can have a measurable effect on the system.
35 | collection_jitter = "0s"
36 |
37 | ## Default flushing interval for all outputs. You shouldn't set this below
38 | ## interval. Maximum flush_interval will be flush_interval + flush_jitter
39 | flush_interval = "1s"
40 | ## Jitter the flush interval by a random amount. This is primarily to avoid
41 | ## large write spikes for users running a large number of telegraf instances.
42 | ## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s
43 | flush_jitter = "0s"
44 |
45 | ## Run telegraf in debug mode
46 | debug = false
47 | ## Run telegraf in quiet mode
48 | quiet = false
49 | ## Override default hostname, if empty use os.Hostname()
50 | hostname = ""
51 |
52 |
53 | ###############################################################################
54 | # OUTPUTS #
55 | ###############################################################################
56 |
57 | # Configuration for the Prometheus client to spawn
58 | [[outputs.prometheus_client]]
59 | ## Address to listen on.
60 | listen = ":9273"
61 |
62 | ## Metric version controls the mapping from Prometheus metrics into Telegraf metrics.
63 | ## See "Metric Format Configuration" in plugins/inputs/prometheus/README.md for details.
64 | ## Valid options: 1, 2
65 | # metric_version = 1
66 |
67 | ## Use HTTP Basic Authentication.
68 | # basic_username = "Foo"
69 | # basic_password = "Bar"
70 |
71 | ## If set, the IP Ranges which are allowed to access metrics.
72 | ## ex: ip_range = ["192.168.0.0/24", "192.168.1.0/30"]
73 | # ip_range = []
74 |
75 | ## Path to publish the metrics on.
76 | # path = "/metrics"
77 |
78 | ## Expiration interval for each metric. 0 == no expiration
79 | # expiration_interval = "60s"
80 |
81 | ## Collectors to enable, valid entries are "gocollector" and "process".
82 | ## If unset, both are enabled.
83 | # collectors_exclude = ["gocollector", "process"]
84 |
85 | ## Send string metrics as Prometheus labels.
86 | ## Unless set to false all string metrics will be sent as labels.
87 | # string_as_label = true
88 |
89 | ## If set, enable TLS with the given certificate.
90 | # tls_cert = "/etc/ssl/telegraf.crt"
91 | # tls_key = "/etc/ssl/telegraf.key"
92 |
93 | ## Set one or more allowed client CA certificate file names to
94 | ## enable mutually authenticated TLS connections
95 | # tls_allowed_cacerts = ["/etc/telegraf/clientca.pem"]
96 |
97 | ## Export metric collection time.
98 | # export_timestamp = false
99 |
100 | #
101 | ###############################################################################
102 | # INPUTS #
103 | ###############################################################################
104 | # Statsd Server
105 | [[inputs.statsd]]
106 | ## Protocol, must be "tcp", "udp4", "udp6" or "udp" (default=udp)
107 | protocol = "udp"
108 |
109 | ## MaxTCPConnection - applicable when protocol is set to tcp (default=250)
110 | max_tcp_connections = 250
111 |
112 | ## Enable TCP keep alive probes (default=false)
113 | tcp_keep_alive = false
114 |
115 | ## Specifies the keep-alive period for an active network connection.
116 | ## Only applies to TCP sockets and will be ignored if tcp_keep_alive is false.
117 | ## Defaults to the OS configuration.
118 | # tcp_keep_alive_period = "2h"
119 |
120 | ## Address and port to host UDP listener on
121 | service_address = ":8125"
122 |
123 | ## The following configuration options control when telegraf clears it's cache
124 | ## of previous values. If set to false, then telegraf will only clear it's
125 | ## cache when the daemon is restarted.
126 | ## Reset gauges every interval (default=true)
127 | delete_gauges = true
128 | ## Reset counters every interval (default=true)
129 | delete_counters = true
130 | ## Reset sets every interval (default=true)
131 | delete_sets = true
132 | ## Reset timings & histograms every interval (default=true)
133 | delete_timings = true
134 |
135 | ## Percentiles to calculate for timing & histogram stats
136 | percentiles = [90]
137 |
138 | ## separator to use between elements of a statsd metric
139 | metric_separator = "_"
140 |
141 | ## Parses tags in the datadog statsd format
142 | ## http://docs.datadoghq.com/guides/dogstatsd/
143 | parse_data_dog_tags = false
144 |
145 | ## Statsd data translation templates, more info can be read here:
146 | ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md#graphite
147 | # templates = [
148 | # "cpu.* measurement*"
149 | # ]
150 |
151 | ## Number of UDP messages allowed to queue up, once filled,
152 | ## the statsd server will start dropping packets
153 | allowed_pending_messages = 10000
154 |
155 | ## Number of timing/histogram values to track per-measurement in the
156 | ## calculation of percentiles. Raising this limit increases the accuracy
157 | ## of percentiles but also increases the memory usage and cpu time.
158 | percentile_limit = 1000
159 |
160 | ## Maximum socket buffer size in bytes, once the buffer fills up, metrics
161 | ## will start dropping. Defaults to the OS default.
162 | # read_buffer_size = 65535
163 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/prometheus-client/test/statsd-test.py:
--------------------------------------------------------------------------------
1 | import statsd
2 | from time import sleep
3 | from random import randint, choice
4 |
5 | c = statsd.StatsClient('localhost', 8125, prefix='performance')
6 |
7 | while True:
8 | incr = randint(1, 5)
9 | metric_type = choice(['A', 'B', 'C'])
10 | print(f"\radding metric: type: {metric_type}, incr: {incr}", end="")
11 | c.incr(f'request.successful.count,type={metric_type}', incr)
12 | sleep(1)
13 |
--------------------------------------------------------------------------------
/levitate/remote-write/telegraf/prometheus-client/vmagent.yaml:
--------------------------------------------------------------------------------
1 | global:
2 | scrape_interval: 1m
3 | scrape_configs:
4 | - job_name: "scrape_telegraf_prometheus_client"
5 | static_configs:
6 | - targets: [ "telegraf:9273" ]
7 |
--------------------------------------------------------------------------------
/levitate/remote-write/vmagent/docker/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/last9/last9-integrations/8c9a66d98f253ff5e7afc0f9824c551b3f61f478/levitate/remote-write/vmagent/docker/README.md
--------------------------------------------------------------------------------
/levitate/remote-write/vmagent/ecs/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/last9/last9-integrations/8c9a66d98f253ff5e7afc0f9824c551b3f61f478/levitate/remote-write/vmagent/ecs/README.md
--------------------------------------------------------------------------------
/levitate/remote-write/vmagent/k8s/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/last9/last9-integrations/8c9a66d98f253ff5e7afc0f9824c551b3f61f478/levitate/remote-write/vmagent/k8s/README.md
--------------------------------------------------------------------------------