├── server
├── src
│ ├── log.json
│ ├── data
│ │ └── sample_data.json
│ ├── Dockerfile
│ ├── conf.json
│ ├── logger
│ │ └── logger.go
│ ├── util
│ │ ├── ds.go
│ │ ├── context.go
│ │ └── sanitizer.go
│ ├── app
│ │ ├── cors.go
│ │ ├── middleware.go
│ │ └── handler.go
│ ├── ds
│ │ ├── trie
│ │ │ ├── algo.go
│ │ │ └── trie.go
│ │ ├── ds.go
│ │ └── hashmap
│ │ │ └── hashmap.go
│ ├── Makefile
│ ├── go.mod
│ ├── conf
│ │ └── conf.go
│ ├── docker-compose.yml
│ ├── server.go
│ └── go.sum
├── monitoring
│ ├── grafana_config.ini
│ ├── grafana_datasources.yml
│ ├── grafana_dashboard.yml
│ ├── prometheus.yml
│ ├── docker-compose.yml
│ └── custom_dashboard.json
├── tests
│ ├── curl_latency
│ ├── test.sh
│ ├── tests.js
│ ├── test-battle.js
│ └── test_data.json
├── infra
│ ├── ingress.yml
│ └── deployment.yaml
└── notes
│ └── server-latency
├── client
└── typeahead-search-app
│ ├── public
│ ├── robots.txt
│ ├── favicon.ico
│ ├── manifest.json
│ └── index.html
│ ├── src
│ ├── config
│ │ └── constants.js
│ ├── setupTests.js
│ ├── index.css
│ ├── components
│ │ ├── About.js
│ │ ├── Navbar.js
│ │ └── MainContent.js
│ ├── reportWebVitals.js
│ ├── services
│ │ └── httpService.js
│ └── index.js
│ ├── .gitignore
│ ├── Dockerfile
│ ├── package.json
│ └── README.md
├── runningStats.txt
├── curl-format.txt
├── azure-pipelines.yml
└── README.md
/server/src/log.json:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/server/monitoring/grafana_config.ini:
--------------------------------------------------------------------------------
1 | [paths]
2 | provisioning = /etc/grafana/provisioning
3 |
4 | [server]
5 | enable_gzip = true
--------------------------------------------------------------------------------
/client/typeahead-search-app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Shubham8287/flash/HEAD/client/typeahead-search-app/public/favicon.ico
--------------------------------------------------------------------------------
/server/src/data/sample_data.json:
--------------------------------------------------------------------------------
1 | [
2 | "a",
3 | "aa",
4 | "aaa",
5 | "aah",
6 | "aaa",
7 | "aahed",
8 | "aahs",
9 | "aal",
10 | "aalii",
11 | "aaliis"
12 | ]
--------------------------------------------------------------------------------
/server/src/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.19-alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY go.mod ./
6 | RUN go mod download
7 |
8 | COPY ./ ./
9 |
10 | EXPOSE 8080
11 | RUN echo $
12 |
13 | CMD go run server.go
--------------------------------------------------------------------------------
/server/src/conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "//algo": "map",
3 | "algo": "trie",
4 | "//data_path": "./data/sample_data.json",
5 | "data_path": "./data/words_dictionary.json",
6 | "logging": true,
7 | "//logging": false
8 | }
--------------------------------------------------------------------------------
/client/typeahead-search-app/src/config/constants.js:
--------------------------------------------------------------------------------
1 | const constant = {
2 | "serverUrl" : "http://localhost",
3 | "serverPort" : "4000",
4 | "findApi" : "/find",
5 | "insertApi" : "/insert"
6 | };
7 |
8 | export default constant;
--------------------------------------------------------------------------------
/server/src/logger/logger.go:
--------------------------------------------------------------------------------
1 | package logger
2 |
3 | import (
4 | "github.com/sirupsen/logrus"
5 | )
6 |
7 | var Log *logrus.Logger
8 |
9 | func init() {
10 | Log = logrus.New()
11 | Log.SetFormatter(&logrus.JSONFormatter{})
12 | }
13 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/runningStats.txt:
--------------------------------------------------------------------------------
1 |
2 | Latency test with below command
3 |
4 | `ab -n 100 -c 1 -k https://flashy.azurewebsites.net/find?prefix=pop`
5 |
6 | 50% 102
7 | 66% 103
8 | 75% 103
9 | 80% 103
10 | 90% 103
11 | 95% 109
12 | 98% 205
13 | 99% 222
14 | 100% 222
--------------------------------------------------------------------------------
/server/monitoring/grafana_datasources.yml:
--------------------------------------------------------------------------------
1 | apiVersion: 1
2 |
3 | datasources:
4 | - name: 'prometheus'
5 | type: 'prometheus'
6 | access: 'proxy'
7 | url: 'http://prometheus:9090'
8 | - name: 'perfstat'
9 | type: 'prometheus'
10 | access: 'proxy'
11 | url: 'http://perfstat:8880/metrics'
--------------------------------------------------------------------------------
/server/src/util/ds.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | type Response struct {
4 | Prefix string `json:"prefix"`
5 | Matches []string `json:"matches"`
6 | }
7 |
8 | // TODO: sort by frequency
9 | func FilterMatchingStrings(wordList []string) []string {
10 | if len(wordList) < 20 {
11 | return wordList
12 | }
13 | return wordList[0:20]
14 | }
15 |
--------------------------------------------------------------------------------
/curl-format.txt:
--------------------------------------------------------------------------------
1 | time_namelookup: %{time_namelookup}s\n
2 | time_connect: %{time_connect}s\n
3 | time_appconnect: %{time_appconnect}s\n
4 | time_pretransfer: %{time_pretransfer}s\n
5 | time_redirect: %{time_redirect}s\n
6 | time_starttransfer: %{time_starttransfer}s\n
7 | ----------\n
8 | time_total: %{time_total}s\n
9 |
--------------------------------------------------------------------------------
/server/tests/curl_latency:
--------------------------------------------------------------------------------
1 | time_namelookup: %{time_namelookup}s\n
2 | time_connect: %{time_connect}s\n
3 | time_appconnect: %{time_appconnect}s\n
4 | time_pretransfer: %{time_pretransfer}s\n
5 | time_redirect: %{time_redirect}s\n
6 | time_starttransfer: %{time_starttransfer}s\n
7 | ----------\n
8 | time_total: %{time_total}s\n
9 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/src/components/About.js:
--------------------------------------------------------------------------------
1 | function About() {
2 | return (
3 | <>
4 |
5 |
6 |
About Project
7 |
FLASH is experiment around type ahead seach :-)
8 |
9 |
10 | >
11 | )
12 | }
13 |
14 | export default About;
--------------------------------------------------------------------------------
/client/typeahead-search-app/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/server/monitoring/grafana_dashboard.yml:
--------------------------------------------------------------------------------
1 | apiVersion: 1
2 |
3 | providers:
4 | - name: Default # A uniquely identifiable name for the provider
5 | folder: Services # The folder where to place the dashboards
6 | type: file
7 | options:
8 | path:
9 | # Default path for Windows: C:/Program Files/GrafanaLabs/grafana/public/dashboards
10 | # Default path for Linux is: /var/lib/grafana/dashboards
--------------------------------------------------------------------------------
/client/typeahead-search-app/src/services/httpService.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import constant from '../config/constants';
3 |
4 | function fetchSuggestions(data) {
5 | const findApi = constant.serverUrl + ":" + constant.serverPort + constant.findApi;
6 | const retData = axios
7 | .get(findApi, { params: { prefix: data }})
8 | .catch((error) => {
9 | console.error(error);
10 | });
11 | return retData;
12 | }
13 | export default fetchSuggestions;
--------------------------------------------------------------------------------
/client/typeahead-search-app/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16
2 |
3 | # Create app directory
4 | WORKDIR /usr/src/app
5 |
6 | # Install app dependencies
7 | # A wildcard is used to ensure both package.json AND package-lock.json are copied
8 | # where available (npm@5+)
9 | COPY package*.json ./
10 |
11 | RUN npm install
12 | # If you are building your code for production
13 | # RUN npm ci --only=production
14 |
15 | # Bundle app source
16 | COPY . .
17 |
18 | EXPOSE 3000
19 | CMD [ "npm", "start" ]
20 |
--------------------------------------------------------------------------------
/server/tests/test.sh:
--------------------------------------------------------------------------------
1 | DATA_PATH='../src/data/words_dictionary.json'
2 | TEST_DATA_PATH='./test_data.json'
3 | echo "[" > $TEST_DATA_PATH
4 | totalLines=$(wc -l < $DATA_PATH)
5 |
6 | for i in `eval echo {2.."$1"}`
7 | do
8 | pickedLine=$(sed -n "$((($RANDOM*$RANDOM)%$totalLines))"p $DATA_PATH)
9 | echo $pickedLine >> $TEST_DATA_PATH
10 | done
11 |
12 | pickedLine=$(sed -n "$((($RANDOM*$RANDOM)%$totalLines))"p $DATA_PATH)
13 | echo $pickedLine | sed -e 's/\",/"/g' >> $TEST_DATA_PATH
14 |
15 | echo "]" >> $TEST_DATA_PATH
--------------------------------------------------------------------------------
/server/src/app/cors.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import "net/http"
4 |
5 | func enableCors(w *http.ResponseWriter) {
6 | (*w).Header().Set("Access-Control-Allow-Origin", "*")
7 | }
8 |
9 | func setupResponse(w *http.ResponseWriter) {
10 | (*w).Header().Set("Access-Control-Allow-Origin", "*")
11 | (*w).Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
12 | (*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
13 | (*w).Header().Set("Content-Type", "application/json")
14 | }
15 |
--------------------------------------------------------------------------------
/server/infra/ingress.yml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.k8s.io/v1
2 | kind: Ingress
3 | metadata:
4 | name: flash-ingress
5 | namespace: ingress-basic
6 | annotations:
7 | kubernetes.io/ingress.class: nginx
8 | nginx.ingress.kubernetes.io/ssl-redirect: "false"
9 | nginx.ingress.kubernetes.io/use-regex: "true"
10 | nginx.ingress.kubernetes.io/rewrite-target: /$1
11 | spec:
12 | rules:
13 | - http:
14 | paths:
15 | - path: /?(.*)
16 | pathType: Prefix
17 | backend:
18 | service:
19 | name: flash
20 | port:
21 | number: 80
22 |
--------------------------------------------------------------------------------
/server/src/app/middleware.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "context"
5 | "flash/util"
6 | "net/http"
7 | "time"
8 |
9 | "github.com/google/uuid"
10 | )
11 |
12 | func Middleware(next http.HandlerFunc) http.HandlerFunc {
13 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
14 | ctx := r.Context()
15 | reqID := uuid.New()
16 | ctx = context.WithValue(ctx, util.REQUEST_ID, reqID.String())
17 | ctx = context.WithValue(ctx, util.LAST_LOG_TIME, time.Now())
18 | r = r.WithContext(ctx)
19 | // Log.WithField("request_id", reqID).Info("request_id_generated")
20 | next.ServeHTTP(w, r)
21 | })
22 | }
23 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/server/infra/deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: flash
5 | labels:
6 | app: flash
7 | spec:
8 | replicas: 2
9 | selector:
10 | matchLabels:
11 | app: flash
12 | template:
13 | metadata:
14 | labels:
15 | app: flash
16 | spec:
17 | containers:
18 | - name: flash
19 | image: flashy.azurecr.io/flashy:latest
20 | ports:
21 | - containerPort: 8080
22 | ---
23 | apiVersion: v1
24 | kind: Service
25 | metadata:
26 | name: flash
27 | spec:
28 | selector:
29 | app: flash
30 | ports:
31 | - port: 80
32 | targetPort: 8080
33 |
--------------------------------------------------------------------------------
/server/src/ds/trie/algo.go:
--------------------------------------------------------------------------------
1 | package trie
2 |
3 | func (t *trie) generateAllWordsWithPrefix(currentNode *trieNode, currentString string) []string {
4 | matchingStrings := []string{}
5 | usingDFS(currentNode, &matchingStrings, currentString)
6 | return matchingStrings
7 | }
8 |
9 | func usingDFS(currentNode *trieNode, matchingStrings *[]string, currentString string) {
10 | if currentNode.isWordEnd {
11 | *matchingStrings = append(*matchingStrings, (currentString))
12 | }
13 | for i := 0; i < 26; i++ {
14 | if currentNode.childrens[i] != nil {
15 | usingDFS(currentNode.childrens[i], matchingStrings, currentString+(string(i+int('a'))))
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/server/src/util/context.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "context"
5 | "time"
6 | )
7 |
8 | const REQUEST_ID = "requestID"
9 | const LAST_LOG_TIME = "lastUpdateTimestamp"
10 |
11 | func SetElapsedTimeStamp(ctx context.Context) time.Duration {
12 |
13 | last_time := ctx.Value(LAST_LOG_TIME)
14 | cur_time := time.Now()
15 | elapsed_time := cur_time.Sub(last_time.(time.Time))
16 | ctx = context.WithValue(ctx, REQUEST_ID, last_time)
17 |
18 | return elapsed_time
19 | }
20 |
21 | func GetRequestID(ctx context.Context) string {
22 |
23 | reqID := ctx.Value(REQUEST_ID)
24 |
25 | if ret, ok := reqID.(string); ok {
26 | return ret
27 | }
28 |
29 | return ""
30 | }
31 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/src/components/Navbar.js:
--------------------------------------------------------------------------------
1 | import { Navbar, Nav, Container, NavDropdown } from 'react-bootstrap';
2 |
3 | function NavbarTop() {
4 | return (
5 |
6 |
7 | FLASH
8 |
9 |
10 |
13 |
16 |
17 |
18 |
19 | )
20 | }
21 |
22 |
23 | export default NavbarTop;
24 |
--------------------------------------------------------------------------------
/server/src/Makefile:
--------------------------------------------------------------------------------
1 |
2 | dep:
3 | sudo apt-get -y update
4 | sudo apt-get -y install \
5 | ca-certificates \
6 | curl \
7 | gnupg \
8 | lsb-release
9 | sudo mkdir -p /etc/apt/keyrings
10 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
11 | echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
12 | sudo apt-get -y update
13 | sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-compose
14 | sudo service docker start
15 |
16 |
17 | mon:
18 | cd ../monitoring; sudo docker-compose up;
19 |
20 | run:
21 | sudo docker-compose up
22 |
--------------------------------------------------------------------------------
/server/src/util/sanitizer.go:
--------------------------------------------------------------------------------
1 | package util
2 | import (
3 | "strings"
4 | "regexp"
5 | )
6 |
7 | // Sanitized the input prefix recieved.
8 | func SanitizeString(prefix string) string {
9 | // regex expression
10 | nonSpecialCharacterRegex := regexp.MustCompile(`[^a-zA-Z/-]+`)
11 |
12 | var sanitizedPrefix string = "";
13 |
14 | // trim the string
15 | sanitizedPrefix = strings.TrimSpace(prefix)
16 |
17 | // add "-" for in -between spaces
18 | sanitizedPrefix = strings.ReplaceAll(sanitizedPrefix, " ", "-")
19 |
20 | // remove special characters
21 | sanitizedPrefix = nonSpecialCharacterRegex.ReplaceAllString(sanitizedPrefix, "")
22 |
23 | // lowercase all the upercase letters
24 | sanitizedPrefix = strings.ToLower(sanitizedPrefix)
25 |
26 | // return the sanitized string
27 | return sanitizedPrefix
28 | }
29 |
--------------------------------------------------------------------------------
/server/src/go.mod:
--------------------------------------------------------------------------------
1 | module flash
2 |
3 | go 1.19
4 |
5 | replace flash/app => ./app
6 |
7 | require (
8 | github.com/sirupsen/logrus v1.8.1 // indirect
9 | golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 // indirect
10 | )
11 |
12 | require (
13 | github.com/beorn7/perks v1.0.1 // indirect
14 | github.com/cespare/xxhash/v2 v2.1.2 // indirect
15 | github.com/golang/protobuf v1.5.2 // indirect
16 | github.com/google/uuid v1.3.0 // indirect
17 | github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
18 | github.com/prometheus/client_golang v1.13.0 // indirect
19 | github.com/prometheus/client_model v0.2.0 // indirect
20 | github.com/prometheus/common v0.37.0 // indirect
21 | github.com/prometheus/procfs v0.8.0 // indirect
22 | github.com/slok/go-http-metrics v0.10.0 // indirect
23 | google.golang.org/protobuf v1.28.1 // indirect
24 | )
25 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import { BrowserRouter,Routes,Route } from "react-router-dom";
5 | import reportWebVitals from './reportWebVitals';
6 | import NavbarTop from './components/Navbar';
7 | import MainContent from './components/MainContent';
8 | import About from './components/About';
9 |
10 | ReactDOM.render(
11 |
12 |
13 |
14 |
15 | } />
16 | } />
17 |
18 |
19 | ,
20 | document.getElementById('root')
21 | );
22 |
23 | // If you want to start measuring performance in your app, pass a function
24 | // to log results (for example: reportWebVitals(console.log))
25 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
26 | reportWebVitals();
27 |
--------------------------------------------------------------------------------
/server/src/conf/conf.go:
--------------------------------------------------------------------------------
1 | package conf
2 |
3 | import (
4 | "encoding/json"
5 | . "flash/logger"
6 | "fmt"
7 | "io/ioutil"
8 | "os"
9 |
10 | "github.com/sirupsen/logrus"
11 | )
12 |
13 | const CONFIGPATH = "./conf.json"
14 |
15 | type Config struct {
16 | Algo string `json:"algo"`
17 | DataPath string `json:"data_path"`
18 | LoggingEnabled bool `json:"logging"`
19 | }
20 |
21 | var configInstance Config
22 |
23 | func readConfig() Config {
24 | Log.Info("config_reading_start")
25 | jsonFile, err := os.Open(CONFIGPATH)
26 | if err != nil {
27 | fmt.Println("error:", err)
28 | }
29 | byteValue, _ := ioutil.ReadAll(jsonFile)
30 | defer jsonFile.Close()
31 |
32 | config := Config{}
33 | json.Unmarshal(byteValue, &config)
34 | Log.WithFields(logrus.Fields{
35 | "algorithm": config.Algo,
36 | "data_path": config.DataPath,
37 | "logging_enabled": config.LoggingEnabled,
38 | }).Info("config_reading_done")
39 |
40 | return config
41 | }
42 |
43 | func Get() Config {
44 | if configInstance == (Config{}) {
45 | configInstance = readConfig()
46 | }
47 | return configInstance
48 | }
49 |
--------------------------------------------------------------------------------
/server/src/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | # perfstat:
5 | # container_name: perfstat
6 | # image: flaviostutz/perfstat
7 | # privileged: true
8 | # volumes:
9 | # - /etc/hostname:/etc/hostname
10 | # ports:
11 | # - 8880:8880
12 | # deploy:
13 | # mode: global
14 | # networks:
15 | # - app
16 |
17 | node-exporter:
18 | image: prom/node-exporter:latest
19 | container_name: node-exporter
20 | restart: unless-stopped
21 | volumes:
22 | - /proc:/host/proc:ro
23 | - /sys:/host/sys:ro
24 | - /:/rootfs:ro
25 | command:
26 | - '--path.procfs=/host/proc'
27 | - '--path.rootfs=/rootfs'
28 | - '--path.sysfs=/host/sys'
29 | - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
30 | ports:
31 | - 9100:9100
32 | # networks:
33 | # - app
34 |
35 |
36 | flash:
37 | container_name: flash
38 | build: .
39 | ports:
40 | - 8080:8080
41 | - 8081:8081
42 | # networks:
43 | # - app
44 |
45 | # networks:
46 | # app:
47 | # driver: bridge
--------------------------------------------------------------------------------
/server/monitoring/prometheus.yml:
--------------------------------------------------------------------------------
1 | ## prometheus.yml ##
2 |
3 | # global settings
4 | global:
5 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
6 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
7 | # scrape_timeout is set to the global default (10s).
8 |
9 |
10 |
11 | # A scrape configuration containing exactly one endpoint to scrape:
12 | # Here it's Prometheus itself.
13 | scrape_configs:
14 | # The job name is added as a label `job=` to any timeseries scraped from this config.
15 | - job_name: 'flash'
16 | metrics_path: '/'
17 | scrape_interval: 5s
18 | static_configs:
19 | - targets: ['10.1.0.4:8081']
20 |
21 | - job_name: 'nodejs'
22 | metrics_path: '/metrics'
23 | scrape_interval: 5s
24 | static_configs:
25 | - targets: ['10.1.0.4:8080']
26 |
27 | - job_name: "node"
28 | scrape_interval: 5s
29 | static_configs:
30 | - targets: ["10.1.0.4:9100"]
31 |
32 | # - job_name: 'perfstat'
33 | # metrics_path: '/metrics'
34 | # scrape_interval: 5s
35 | # static_configs:
36 | # - targets: ['perfstat:8880']
--------------------------------------------------------------------------------
/client/typeahead-search-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "typeahead-search-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.2",
7 | "@testing-library/react": "^12.1.3",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^0.26.0",
10 | "bootstrap": "^5.1.3",
11 | "react": "^17.0.2",
12 | "react-autosuggest": "^10.1.0",
13 | "react-bootstrap": "^2.1.2",
14 | "react-dom": "^17.0.2",
15 | "react-router-dom": "^6.2.1",
16 | "react-scripts": "5.0.0",
17 | "web-vitals": "^2.1.4"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/server/monitoring/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | volumes:
4 | prometheus_data: {}
5 | grafana_data: {}
6 |
7 | services:
8 |
9 | prometheus:
10 | container_name: prometheus
11 | hostname: prometheus
12 | image: prom/prometheus
13 | volumes:
14 | - ./prometheus.yml:/etc/prometheus/prometheus.yml
15 | - prometheus_data:/prometheus
16 | command:
17 | - '--config.file=/etc/prometheus/prometheus.yml'
18 | - '--storage.tsdb.path=/prometheus'
19 | - '--web.console.libraries=/etc/prometheus/console_libraries'
20 | - '--web.console.templates=/etc/prometheus/consoles'
21 | - '--web.enable-lifecycle'
22 | ports:
23 | - 9090:9090
24 | # networks:
25 | # - src_app
26 |
27 | grafana:
28 | container_name: grafana
29 | hostname: grafana
30 | image: grafana/grafana
31 | volumes:
32 | - ./grafana_datasources.yml:/etc/grafana/provisioning/datasources/all.yaml
33 | # - ./grafana_config.ini:/etc/grafana/config.ini
34 | - grafana_data:/var/lib/grafana
35 | # networks:
36 | # - src_app
37 | ports:
38 | - 3000:3000
39 | # networks:
40 | # src_app:
41 | # external: true
42 |
--------------------------------------------------------------------------------
/server/tests/tests.js:
--------------------------------------------------------------------------------
1 | import http from 'k6/http';
2 | import { SharedArray } from 'k6/data';
3 | import { sleep, check, randomSeed } from 'k6';
4 |
5 | const BASE_URL = "http://192.168.1.69:8080"
6 |
7 | export const options = {
8 | stages: [
9 | { duration: '1s', target: 20000 },
10 | { duration: '120s', target: 20000 }
11 | ],
12 | };
13 |
14 | const testQueries = new SharedArray('users', function () {
15 | const f = JSON.parse(open('./test_data.json'));
16 | return f;
17 | });
18 |
19 | export default function () {
20 | const rndIndex = Math.floor((Math.random()*10000000)%testQueries.length)
21 | const res = http.get(BASE_URL+'/find?prefix='+ testQueries[rndIndex]);
22 | //const res = http.get(BASE_URL+'/isAlive');
23 | check(res, { 'status was 200': (r) => isFine(JSON.parse(r.body), testQueries[rndIndex]) });
24 | // check(res, { 'status was 200': (r) => true });
25 | sleep(1);
26 | }
27 |
28 | function isFine(body, prefix) {
29 | if(body.prefix != prefix) {
30 | return false;
31 | }
32 | let allMatches = true
33 | body.matches.map(m => {
34 | allMatches &= m.startsWith(prefix);
35 | })
36 | return allMatches;
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/server/src/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flash/app"
5 | . "flash/logger"
6 | "log"
7 | "net/http"
8 |
9 | "github.com/prometheus/client_golang/prometheus/promhttp"
10 | metrics "github.com/slok/go-http-metrics/metrics/prometheus"
11 | "github.com/slok/go-http-metrics/middleware"
12 | "github.com/slok/go-http-metrics/middleware/std"
13 | )
14 |
15 | const (
16 | PORT = ":8080"
17 | metricsAddr = ":8081"
18 | )
19 |
20 | func handleRequests() {
21 | mdlw := middleware.New(middleware.Config{
22 | Recorder: metrics.NewRecorder(metrics.Config{}),
23 | })
24 | mux := http.NewServeMux()
25 | mux.HandleFunc("/", app.HomeReq)
26 | mux.HandleFunc("/isAlive", app.Middleware(app.PingReq))
27 | mux.HandleFunc("/find", app.FindReq)
28 | mux.HandleFunc("/insert", app.InsertReq)
29 |
30 | serv := std.Handler("", mdlw, mux)
31 | // http.Handle("/metrics", promhttp.Handler())
32 | // Serve our metrics.
33 | go func() {
34 | log.Printf("metrics listening at %s", metricsAddr)
35 | if err := http.ListenAndServe(metricsAddr, promhttp.Handler()); err != nil {
36 | log.Panicf("error while serving metrics: %s", err)
37 | }
38 | }()
39 | Log.Fatal(http.ListenAndServe(PORT, serv))
40 | }
41 |
42 | func main() {
43 | handleRequests()
44 | }
--------------------------------------------------------------------------------
/server/tests/test-battle.js:
--------------------------------------------------------------------------------
1 | import http from 'k6/http';
2 | import { SharedArray } from 'k6/data';
3 | import { sleep, check, randomSeed } from 'k6';
4 |
5 | const BASE_URL = "http://10.1.0.4:8080"
6 |
7 | export const options = {
8 | stages: [
9 | { duration: '1s', target: 10000 },
10 | { duration: '60s', target: 10000 }
11 | ],
12 | };
13 |
14 | const testQueries = new SharedArray('users', function () {
15 | const f = JSON.parse(open('./test_data.json'));
16 | return f;
17 | });
18 |
19 | export default function () {
20 | const rndIndex = Math.floor((Math.random()*10000000)%testQueries.length)
21 | const res = http.get(BASE_URL+'/insert?key='+ testQueries[rndIndex]+'&value='+ testQueries[rndIndex]);
22 | //const res = http.get(BASE_URL+'/isAlive');
23 | // check(res, { 'status was 200': (r) => isFine(JSON.parse(r.body), testQueries[rndIndex]) });
24 | //console.log(res.body,testQueries[rndIndex])
25 | check(res, { 'status was 200': (r) => r.body==testQueries[rndIndex] });
26 | sleep(1);
27 | }
28 |
29 | function isFine(body, prefix) {
30 | if(body.prefix != prefix) {
31 | return false;
32 | }
33 | let allMatches = true
34 | body.matches.map(m => {
35 | allMatches &= m.startsWith(prefix);
36 | })
37 | return allMatches;
38 |
39 | }
--------------------------------------------------------------------------------
/server/src/ds/ds.go:
--------------------------------------------------------------------------------
1 | package ds
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "flash/conf"
7 | "flash/ds/hashmap"
8 | "flash/ds/trie"
9 | . "flash/logger"
10 | "fmt"
11 | "io/ioutil"
12 | "time"
13 | )
14 |
15 | type DataStructure interface {
16 | Find(string) []string
17 | Insert(string)
18 | }
19 |
20 | var bucketData DataStructure = nil
21 | var configuration conf.Config = conf.Get()
22 |
23 | func init() {
24 | if configuration.Algo == "map" {
25 | bucketData = hashmap.Get()
26 | } else {
27 | bucketData = trie.Get()
28 | }
29 | fillData(bucketData)
30 | }
31 |
32 | func fillData(bucketData DataStructure) {
33 | Log.Info("file_reading_started")
34 | fileData, err := ioutil.ReadFile(configuration.DataPath)
35 | if err != nil {
36 | fmt.Print(err)
37 | }
38 |
39 | var intialWordSet = []string{}
40 | err = json.Unmarshal(fileData, &intialWordSet)
41 | if err != nil {
42 | fmt.Println("error:", err)
43 | }
44 | Log.Info("file_reading_done")
45 | start := time.Now()
46 | for i := 0; i < len(intialWordSet); i++ {
47 | bucketData.Insert(intialWordSet[i])
48 | }
49 | t := time.Now()
50 | Log.WithField("time_elapsed", t.Sub(start)).Info("Initialiazing_data_in_ds_done")
51 | }
52 |
53 | func GetDs(ctx context.Context) DataStructure {
54 | if bucketData != nil {
55 | return bucketData
56 | }
57 | return bucketData
58 | }
59 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | # Docker
2 | # Build and push an image to Azure Container Registry
3 | # https://docs.microsoft.com/azure/devops/pipelines/languages/docker
4 |
5 | trigger:
6 | - main
7 |
8 | resources:
9 | - repo: self
10 |
11 | variables:
12 | # Container registry service connection established during pipeline creation
13 | dockerRegistryServiceConnection: '8a2c981b-7611-490d-82fd-6894b63187ce'
14 | imageRepository: 'flashy'
15 | containerRegistry: 'flashy.azurecr.io'
16 | dockerfilePath: '$(Build.SourcesDirectory)/server/src/Dockerfile'
17 | tag: '$(Build.BuildId)'
18 | dockerContext: $(Build.SourcesDirectory)/server/src/
19 | # Agent VM image name
20 | vmImageName: 'ubuntu-latest'
21 |
22 | stages:
23 | - stage: Build
24 |
25 | displayName: Build and push stage
26 | jobs:
27 | - job: Build
28 | displayName: Build
29 | pool:
30 | vmImage: $(vmImageName)
31 | steps:
32 | - task: Docker@2
33 | displayName: Build and push an image to container registry
34 | inputs:
35 | command: buildAndPush
36 | repository: $(imageRepository)
37 | dockerfile: $(dockerfilePath)
38 | buildContext: $(dockerContext)
39 | containerRegistry: $(dockerRegistryServiceConnection)
40 | tags: |
41 | $(tag)
42 | - task: PublishPipelineArtifact@1
43 | inputs:
44 | artifactName: 'repo'
45 | path: $(Build.Repository.LocalPath)
46 |
--------------------------------------------------------------------------------
/server/src/ds/trie/trie.go:
--------------------------------------------------------------------------------
1 | package trie
2 |
3 | import (
4 | "flash/util"
5 | )
6 |
7 | const (
8 | //ALBHABET_SIZE total characters in english alphabet
9 | ALBHABET_SIZE = 26
10 | )
11 |
12 | type trieNode struct {
13 | childrens [ALBHABET_SIZE]*trieNode
14 | isWordEnd bool
15 | }
16 |
17 | type trie struct {
18 | root *trieNode
19 | }
20 |
21 | var trieInstance *trie = nil
22 |
23 | func Get() *trie {
24 | if trieInstance == nil {
25 | trieInstance = &trie{
26 | root: &trieNode{},
27 | }
28 | }
29 | return trieInstance
30 | }
31 |
32 | func (t *trie) Insert(word string) {
33 | // sanitize the input string
34 | word = util.SanitizeString(word)
35 |
36 | wordLength := len(word)
37 | currentNode := t.root
38 | for i := 0; i < wordLength; i++ {
39 | index := word[i] - 'a'
40 | if currentNode.childrens[index] == nil {
41 | currentNode.childrens[index] = &trieNode{}
42 | }
43 | currentNode = currentNode.childrens[index]
44 | }
45 | currentNode.isWordEnd = true
46 | }
47 |
48 | func (t *trie) Find(word string) []string {
49 | wordLength := len(word)
50 | currentNode := t.root
51 | for i := 0; i < wordLength; i++ {
52 | index := word[i] - 'a'
53 | if currentNode.childrens[index] == nil {
54 | //t.Insert(word)
55 | return []string{}
56 | }
57 | currentNode = currentNode.childrens[index]
58 | }
59 |
60 | matchingStrings := t.generateAllWordsWithPrefix(currentNode, word)
61 | response := util.FilterMatchingStrings(matchingStrings)
62 |
63 | return response
64 | }
65 |
--------------------------------------------------------------------------------
/server/src/app/handler.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "encoding/json"
5 | "flash/conf"
6 | "flash/ds"
7 | "flash/logger"
8 | "flash/util"
9 | "fmt"
10 | "html"
11 | "net/http"
12 |
13 | "github.com/sirupsen/logrus"
14 | )
15 |
16 | var config conf.Config = conf.Get()
17 |
18 | func HomeReq(w http.ResponseWriter, r *http.Request) {
19 | fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
20 | }
21 |
22 | func PingReq(w http.ResponseWriter, r *http.Request) {
23 | fmt.Fprintf(w, "Boss is always fine")
24 | }
25 |
26 | func FindReq(w http.ResponseWriter, r *http.Request) {
27 | ctx := r.Context()
28 | searchBucket := ds.GetDs(ctx)
29 | setupResponse(&w)
30 | prefix := r.FormValue("prefix")
31 |
32 | // sanitize the incoming "prefix" query param
33 | sanitizedPrefix := util.SanitizeString(prefix)
34 |
35 | matches := searchBucket.Find(sanitizedPrefix)
36 |
37 | if config.LoggingEnabled == true {
38 | logger.Log.WithFields(logrus.Fields{
39 | "request_id": util.GetRequestID(ctx),
40 | // "time_elapsed": util.SetElapsedTimeStamp(ctx),
41 | }).Info("find_matches_received")
42 |
43 | }
44 | response := util.Response{
45 | Prefix: sanitizedPrefix,
46 | Matches: matches,
47 | }
48 | json.NewEncoder(w).Encode(response)
49 | }
50 |
51 | func InsertReq(w http.ResponseWriter, r *http.Request) {
52 | ctx := r.Context()
53 | searchBucket := ds.GetDs(ctx)
54 | setupResponse(&w)
55 | prefix := r.FormValue("prefix")
56 |
57 | // sanitize the incoming "prefix" query param.
58 | sanitizedPrefix := util.SanitizeString(prefix)
59 |
60 | searchBucket.Insert(sanitizedPrefix)
61 |
62 | response := util.Response{
63 | Prefix: sanitizedPrefix,
64 | }
65 | json.NewEncoder(w).Encode(response)
66 | }
67 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/src/components/MainContent.js:
--------------------------------------------------------------------------------
1 |
2 | import {Container} from 'react-bootstrap';
3 | import { useState } from 'react';
4 | import fetchSuggestions from '../services/httpService';
5 | import Autosuggest from 'react-autosuggest';
6 |
7 | function MainContent () {
8 | const [value, setValue] = useState('');
9 | const [suggestedValue, setSuggestedValue] = useState('');
10 |
11 | const onChange = (event, { newValue }) => {
12 | setValue(newValue);
13 | };
14 |
15 | // You already implemented this logic above, so just use it.
16 | const onSuggestionsFetchRequested = async ({ value }) => {
17 | let returnData = await fetchSuggestions(value);
18 | setSuggestedValue(returnData.data.matches);
19 | };
20 |
21 | // Autosuggest will call this function every time you need to clear suggestions.
22 | const onSuggestionsClearRequested = () =>
23 | {
24 | setSuggestedValue('');
25 | };
26 |
27 | const getSuggestionValue = suggestion => suggestion;
28 |
29 | // Use your imagination to render suggestions.
30 | const renderSuggestion = function (suggestion) {
31 | return (
32 |
33 | {suggestion}
34 |
35 | );
36 | }
37 |
38 |
39 | // Autosuggest will pass through all these props to the input.
40 | const inputProps = {
41 | placeholder: 'Type your query',
42 | value,
43 | onChange: onChange
44 | };
45 |
46 | return (
47 | <>
48 |
49 |
57 |
58 | >
59 | )
60 | }
61 |
62 | export default MainContent;
--------------------------------------------------------------------------------
/client/typeahead-search-app/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
19 |
25 |
26 |
35 | React App
36 |
37 |
38 |
39 |
40 |
50 |
51 |
52 |
53 |
54 |
57 |
58 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/server/src/ds/hashmap/hashmap.go:
--------------------------------------------------------------------------------
1 | package hashmap
2 |
3 | import (
4 | "flash/util"
5 | )
6 |
7 | type bucketType map[string][]Item
8 |
9 | var bucket bucketType = nil
10 |
11 | // sample bucket
12 | // [a:[{2 aaa} {2 aa} {1 a} {1 aah} {1 aahed} {1 aahs} {1 aal} {1 aalii} {1 aaliis}]
13 | // aa:[[{2 aaa} {2 aa} {1 aah} {1 aahed} {1 aahs} {1 aal} {1 aalii} {1 aaliis}]
14 | // aaa:[{2 aaa}] aah:[{1 aah} {1 aahed} {1 aahs}] aahe:[{1 aahed}]
15 | // aahed:[{1 aahed}] aahs:[{1 aahs}] aal:[{1 aal} {1 aalii} {1 aaliis}]
16 | // aali:[{1 aalii} {1 aaliis}] aalii:[{1 aalii} {1 aaliis}]
17 | // aaliis:[{1 aaliis}]
18 | // w:[{4 waskodimagama} {3 wask}]
19 | // wa:[{4 waskodimagama} {3 wask}]
20 | // was:[{4 waskodimagama} {3 wask}]
21 | // wask:[{4 waskodimagama} {3 wask}]
22 | // wasko:[{4 waskodimagama}]
23 | // waskod:[{4 waskodimagama}]
24 | // waskodi:[{4 waskodimagama}]
25 | // waskodim:[{4 waskodimagama}]
26 | // waskodima:[{4 waskodimagama}]
27 | // waskodimag:[{4 waskodimagama}]
28 | // waskodimaga:[{4 waskodimagama}]
29 | // waskodimagam:[{4 waskodimagama}]
30 | // waskodimagama:[{4 waskodimagama}]
31 | // ]
32 | type Item struct {
33 | freq int
34 | word string
35 | }
36 |
37 | func Get() *bucketType {
38 | if bucket == nil {
39 | bucket = make(bucketType)
40 | }
41 | return &bucket
42 | }
43 |
44 | func (b *bucketType) Find(prefix string) []string {
45 | return filterMatchingWordItem(bucket[prefix])
46 | }
47 |
48 | func (b *bucketType) Insert(word string) {
49 | // sanitize the input string
50 | word = util.SanitizeString(word)
51 |
52 | var prefixWord string
53 | for i := 0; i < len(word); i++ {
54 | prefixWord += string(word[i])
55 | _, ok := bucket[prefixWord]
56 | if ok {
57 | idx, ok := findWord(bucket[prefixWord], word)
58 | if ok {
59 | newWordItem := bucket[prefixWord][idx]
60 | bucket[prefixWord] = removeWordItem(bucket[prefixWord], idx)
61 | newWordItem.freq++
62 | bucket[prefixWord] = insertWordItem(bucket[prefixWord], newWordItem)
63 | } else {
64 | freq := 1
65 | if len(bucket[prefixWord]) != 0 {
66 | freq = bucket[prefixWord][len(bucket[prefixWord])-1].freq
67 | }
68 | newWordItem := Item{
69 | word: word,
70 | freq: freq,
71 | }
72 | bucket[prefixWord] = insertWordItem(bucket[prefixWord], newWordItem)
73 | }
74 | } else {
75 | bucket[prefixWord] = append(bucket[prefixWord], Item{
76 | word: word,
77 | freq: 1,
78 | })
79 | }
80 | }
81 | }
82 |
83 | func filterMatchingWordItem(wordList []Item) []string {
84 | var matchingStrings []string
85 | for i := 0; i < len(wordList) && i < 20; i++ {
86 | matchingStrings = append(matchingStrings, wordList[i].word)
87 | }
88 | return matchingStrings
89 | }
90 |
91 | func findWord(wordList []Item, word string) (int, bool) {
92 | for i := 0; i < len(wordList); i++ {
93 | if wordList[i].word == word {
94 | return i, true
95 | }
96 | }
97 | return -1, false
98 | }
99 |
100 | func removeWordItem(wordList []Item, idx int) []Item {
101 | return append(wordList[:idx], wordList[idx+1:]...)
102 | }
103 |
104 | func insertWordItem(wordList []Item, newWord Item) []Item {
105 | if len(wordList) == 100 {
106 | wordList = wordList[:99]
107 | }
108 | pos := len(wordList)
109 | for i := len(wordList) - 1; i >= 0; i-- {
110 | if wordList[i].freq >= newWord.freq {
111 | break
112 | }
113 | pos--
114 | }
115 | wordList = append(wordList, newWord)
116 | copy(wordList[pos+1:], wordList[pos:])
117 | wordList[pos] = newWord
118 | return wordList
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/client/typeahead-search-app/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flash
2 | Flash is highly optimised typeahead(search recommendation) server. We are building it with an aim to learn and teach various tradeoffs/practices.
3 | While building it, we will use different data structures/storage devices/protocols/deployment strategies and compare them from different aspects.
4 |
5 | ## Design perspective
6 | 1. ### Expection with the server?
7 | keeping in mind the fact that we are designing for Humans. Average time at which humans respond is 200ms( interval b/w consecutive key stokes), So we need to keep this in mind and keep our latency < 200ms always and..... Amazon search recommendation api calls responds in around ~100ms.
8 |
9 | 2. ### Where are we storing our dataset (strings which server will recommend)?
10 |
11 | Lookup time for Memory, SSD, and HDD is 100ns, 150us, 10 ms respective.
12 | It makes sense for us to keep all data in memory itself for low latency. We can do sharding on range bases, if data grows more than the size of 1 node. further we can use disk to take backup by taking periodic snapshot of data, for fault tolerance on poweroff. Later, we can also try to use SSD for storage and see how trade off b/w cost vs latency works.
13 |
14 |
15 | 2. ### Which Data structure to choose for hold strings in memory?
16 |
17 | Our usecase is to fetch popular strings with same prefix. Trie looks intuitive here, but I feel we could perform better with hashmap as with hashmap it will be easy for us to shard, Maps are native for memory, and for every prefix as key, we can use a priority queue as value which contains all popular strings with same prefix as key. Doing this with trie will be little harder. But it's going to be interesting to compare both DS. Making an algorithm to scale them.
18 |
19 |
20 | 3. ### Are we taking care of protocol too?
21 | yes, Idea is to make api call to server with every key stroke in search box and return all strings with same prefix as response, means server will be in heavy read load.
22 | We can use websockets to faster resonse from server and not setting up TCP connection for every keystroke but I feel using ws is going to be overkill as we don't need duplex connection. We can start with HTTP and do some optimisations like adding "Connection: keep-alive" header to tell server to not close connection for subsequent connections.
23 |
24 | 4. ### Deployment Strategies.
25 | As latency is most important factor, We can try to deploy in various regions and using a load balancer to route to closes geolocation server. We need low latency, with high avaibility and less or eventual consistency that means it's fine if users in different region see different suggestions for their prefix. I feel deployment is dominant part in keeping latency low, We can do benchmarking after adding every new component(load balancer, sharding) to understand their affects.
26 |
27 | 5. ### Why Go?
28 | Keeping perfomance in mind, I chose GO over any iterperative language. Rust might be even better choice, but as I don't have enough knowledge with Rust rigth now so may be We an migrate it later.
29 |
30 | 6. ### Lot to add.
31 |
32 |
33 | ### To build server:
34 | ```
35 | git clone https://github.com/Shubham8287/flash
36 | cd flash/server/src
37 | make run # start flash and node expoerter server
38 | make mon # to setup monitoring
39 | ```
40 |
41 | ### Check if server is up:
42 | `curl localhost:8080/isAlive`
43 | You should get response - `Boss is always fine`
44 |
45 | To run actual Api hit - `localhost:8080/find?prefix=yo`
46 | you will get a response of top matching string starting with prefix "yo"
47 | ```
48 | {"prefix":"yo","matches":["yo","yob","yobbo","yobboes","yobbos","yobi","yobs","yocco","yochel","yock","yocked","yockel","yockernut","yocking","yocks","yod","yode","yodel","yodeled","yodeler"]}
49 | ```
50 |
51 | ### To profile:
52 | - import `_ "net/http/pprof"`
53 | - run `go tool pprof -http : http://localhost:8080/debug/pprof/{allocs/goroutine/heap/profile/etc}
54 | > for healthcheck route in localhost, I am getting response ~1-2ms.
55 |
56 | ## Handy commands
57 | - `go run ./...` - to run server
58 | - `lsof -i:[PORT]` - to know PID of proccess running on PORT.
59 | - `curl -w "@curl-format.txt" -s [URL]` - to know response time of your request with curl
60 | - `sudo pmap [PID]` - check total memory used by PID
61 | - `ab -n 100 -c 1 -k URL` - use apache bench to make n request with c concurrency. -k is to keep tcp connection open.
62 |
63 |
--------------------------------------------------------------------------------
/server/notes/server-latency:
--------------------------------------------------------------------------------
1 | ## p95 with log and log in docker
2 | checks.........................: 100.00% ✓ 120993 ✗ 0
3 | data_received..................: 46 MB 736 kB/s
4 | data_sent......................: 12 MB 196 kB/s
5 | http_req_blocked...............: avg=496.3µs min=1.2µs med=2.8µs max=125.02ms p(90)=4.59µs p(95)=8.2µs
6 | http_req_connecting............: avg=400.74µs min=0s med=0s max=104.55ms p(90)=0s p(95)=0s
7 | http_req_duration..............: avg=6.23ms min=191.7µs med=1.04ms max=250.82ms p(90)=12.13ms p(95)=31.09ms
8 | { expected_response:true }...: avg=6.23ms min=191.7µs med=1.04ms max=250.82ms p(90)=12.13ms p(95)=31.09ms
9 | http_req_failed................: 0.00% ✓ 0 ✗ 120993
10 | http_req_receiving.............: avg=248.05µs min=10.8µs med=30.7µs max=126.15ms p(90)=131.3µs p(95)=226.6µs
11 | http_req_sending...............: avg=550.29µs min=4.4µs med=11.6µs max=104.49ms p(90)=272.7µs p(95)=815.42µs
12 | http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
13 | http_req_waiting...............: avg=5.43ms min=158.9µs med=892.31µs max=174.26ms p(90)=11.16ms p(95)=27.55ms
14 | http_reqs......................: 120993 1951.310417/s
15 | iteration_duration.............: avg=1s min=1s med=1s max=1.25s p(90)=1.01s p(95)=1.03s
16 | iterations.....................: 120993 1951.310417/s
17 | vus............................: 744 min=0 max=2000
18 | vus_max........................: 2000 min=1627 max=2000
19 | ## p95 with log as shell process
20 | checks.........................: 100.00% ✓ 81149 ✗ 0
21 | data_received..................: 31 MB 494 kB/s
22 | data_sent......................: 8.1 MB 131 kB/s
23 | http_req_blocked...............: avg=3.46ms min=1.2µs med=2.7µs max=550.29ms p(90)=4.4µs p(95)=11.3µs
24 | http_req_connecting............: avg=3.27ms min=0s med=0s max=372.12ms p(90)=0s p(95)=0s
25 | http_req_duration..............: avg=498.11ms min=172.8µs med=235.54ms max=4.95s p(90)=1.27s p(95)=2.1s
26 | { expected_response:true }...: avg=498.11ms min=172.8µs med=235.54ms max=4.95s p(90)=1.27s p(95)=2.1s
27 | http_req_failed................: 0.00% ✓ 0 ✗ 81149
28 | http_req_receiving.............: avg=1.02ms min=10.5µs med=24.2µs max=441.05ms p(90)=75.82µs p(95)=5.91ms
29 | http_req_sending...............: avg=2.2ms min=4.59µs med=11.1µs max=357.63ms p(90)=5.14ms p(95)=12.43ms
30 | http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
31 | http_req_waiting...............: avg=494.87ms min=146.7µs med=233.27ms max=4.94s p(90)=1.26s p(95)=2.1s
32 | http_reqs......................: 81149 1308.515824/s
33 | iteration_duration.............: avg=1.5s min=1s med=1.24s max=6.13s p(90)=2.27s p(95)=3.2s
34 | iterations.....................: 81149 1308.515824/s
35 | vus............................: 1090 min=0 max=2000
36 | vus_max........................: 2000 min=1350 max=2000
37 |
38 |
39 | ##ping on localhost
40 | ~0.05ms
41 |
42 | ## empty localhost server
43 | curl -w "@curl_latency" "http://localhost:8080/" -o /dev/null
44 | % Total % Received % Xferd Average Speed Time Time Time Current
45 | Dload Upload Total Spent Left Speed
46 | 100 10 100 10 0 0 22371 0 --:--:-- --:--:-- --:--:-- 10000
47 | time_namelookup: 0.000014s
48 | time_connect: 0.000218s
49 | time_appconnect: 0.000000s
50 | time_pretransfer: 0.000241s
51 | time_redirect: 0.000000s
52 | time_starttransfer: 0.000420s
53 | ----------
54 | time_total: 0.000447s = ~0.5ms
55 |
56 |
57 |
58 | ## 400 req on healthcheck
59 | http_req_blocked...............: avg=27.45µs min=3.35µs med=7.67µs max=512.75µs p(90)=10.51µs p(95)=32.51µs
60 | http_req_connecting............: avg=13.33µs min=0s med=0s max=341.69µs p(90)=0s p(95)=0s
61 | http_req_duration..............: avg=504.75µs min=176.81µs med=506.77µs max=695.92µs p(90)=587.81µs p(95)=606.93µs
62 | { expected_response:true }...: avg=504.75µs min=176.81µs med=506.77µs max=695.92µs p(90)=587.81µs p(95)=606.93µs
63 | http_req_failed................: 0.00% ✓ 0 ✗ 419
64 | http_req_receiving.............: avg=87.42µs min=29.86µs med=85.93µs max=159.86µs p(90)=105.28µs p(95)=119.06µs
65 | http_req_sending...............: avg=39.28µs min=13.14µs med=34.53µs max=185.85µs p(90)=46.76µs p(95)=71.25µs
66 | http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
67 | http_req_waiting...............: avg=378.04µs min=118.38µs med=379.77µs max=503.55µs p(90)=447.63µs p(95)=466.73µs
68 | http_reqs......................: 419 19.062438/s
69 | iteration_duration.............: avg=1s min=1s med=1s max=1s p(90)=1s p(95)=1s
70 | iterations.....................: 419 19.062438/s
71 | = ~0.5ms
72 |
73 | ## 400k on healthcheck
74 | running (22.0s), 0000/2000 VUs, 41957 complete and 0 interrupted iterations
75 | default ✓ [======================================] 0000/2000 VUs 21s
76 |
77 | ✓ status was 200
78 |
79 | checks.........................: 100.00% ✓ 41957 ✗ 0
80 | data_received..................: 5.7 MB 259 kB/s
81 | data_sent......................: 3.7 MB 166 kB/s
82 | http_req_blocked...............: avg=34.45µs min=824ns med=4.54µs max=35.2ms p(90)=9.04µs p(95)=62.65µs
83 | http_req_connecting............: avg=23.12µs min=0s med=0s max=35.12ms p(90)=0s p(95)=0s
84 | http_req_duration..............: avg=435.42µs min=42.14µs med=301.79µs max=17.78ms p(90)=892.83µs p(95)=1.34ms
85 | { expected_response:true }...: avg=435.42µs min=42.14µs med=301.79µs max=17.78ms p(90)=892.83µs p(95)=1.34ms
86 | http_req_failed................: 0.00% ✓ 0 ✗ 41957
87 | http_req_receiving.............: avg=61.54µs min=5.73µs med=43.47µs max=4.45ms p(90)=77.57µs p(95)=108.81µs
88 | http_req_sending...............: avg=60.8µs min=3.77µs med=19.38µs max=4.21ms p(90)=59.33µs p(95)=227.02µs
89 | http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
90 | http_req_waiting...............: avg=313.06µs min=21.36µs med=220.16µs max=16.58ms p(90)=606.44µs p(95)=915.34µs
91 | http_reqs......................: 41957 1906.721746/s
92 | iteration_duration.............: avg=1s min=1s med=1s max=1.04s p(90)=1s p(95)=1s
93 | iterations.....................: 41957 1906.721746/s
94 | vus............................: 1402 min=655 max=2000
95 | vus_max........................: 2000 min=2000 max=2000
96 | =~1ms
97 |
98 | ## 400 req on /find
99 | checks.........................: 100.00% ✓ 419 ✗ 0
100 | data_received..................: 158 kB 7.2 kB/s
101 | data_sent......................: 43 kB 1.9 kB/s
102 | http_req_blocked...............: avg=26.56µs min=2.82µs med=7.48µs max=476.79µs p(90)=9.44µs p(95)=37.49µs
103 | http_req_connecting............: avg=12.94µs min=0s med=0s max=336.05µs p(90)=0s p(95)=0s
104 | http_req_duration..............: avg=647.24µs min=251.94µs med=636.5µs max=4.87ms p(90)=738.52µs p(95)=763.65µs
105 | { expected_response:true }...: avg=647.24µs min=251.94µs med=636.5µs max=4.87ms p(90)=738.52µs p(95)=763.65µs
106 | http_req_failed................: 0.00% ✓ 0 ✗ 419
107 | http_req_receiving.............: avg=103.85µs min=30.13µs med=101.21µs max=228.98µs p(90)=134.74µs p(95)=147.76µs
108 | http_req_sending...............: avg=42.72µs min=11.4µs med=38.57µs max=176.05µs p(90)=52.38µs p(95)=75.83µs
109 | http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
110 | http_req_waiting...............: avg=500.66µs min=210.4µs med=491.08µs max=4.67ms p(90)=580.4µs p(95)=596.82µs
111 | http_reqs......................: 419 19.057783/s
112 | iteration_duration.............: avg=1s min=1s med=1s max=1s p(90)=1s p(95)=1s
113 |
114 | = ~0.7ms
115 |
116 |
117 | ## 40k req on /find with no log or log to file
118 | checks.........................: 100.00% ✓ 41965 ✗ 0
119 | data_received..................: 16 MB 719 kB/s
120 | data_sent......................: 4.3 MB 193 kB/s
121 | http_req_blocked...............: avg=53.37µs min=884ns med=4.68µs max=41.27ms p(90)=9.12µs p(95)=85.36µs
122 | http_req_connecting............: avg=33µs min=0s med=0s max=41.2ms p(90)=0s p(95)=0s
123 | http_req_duration..............: avg=878.96µs min=49.81µs med=355.43µs max=47.86ms p(90)=1.52ms p(95)=2.49ms
124 | { expected_response:true }...: avg=878.96µs min=49.81µs med=355.43µs max=47.86ms p(90)=1.52ms p(95)=2.49ms
125 | http_req_failed................: 0.00% ✓ 0 ✗ 41965
126 | http_req_receiving.............: avg=93.99µs min=7.59µs med=47.66µs max=22.69ms p(90)=101.29µs p(95)=268.23µs
127 | http_req_sending...............: avg=130.65µs min=4.11µs med=20.52µs max=27.92ms p(90)=132.52µs p(95)=419.53µs
128 | http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
129 | http_req_waiting...............: avg=654.31µs min=32.52µs med=255.54µs max=41.91ms p(90)=1.03ms p(95)=1.75ms
130 | http_reqs......................: 41965 1907.081841/s
131 | iteration_duration.............: avg=1s min=1s med=1s max=1.06s p(90)=1s p(95)=1s
132 | iterations.....................: 41965 1907.081841/s
133 | vus............................: 1720 min=360 max=2000
134 | vus_max........................: 2000 min=2000 max=2000
135 | ~=20ms
136 |
137 | ## 40k with one log
138 |
139 | checks.........................: 100.00% ✓ 39073 ✗ 0
140 | data_received..................: 15 MB 672 kB/s
141 | data_sent......................: 4.0 MB 181 kB/s
142 | http_req_blocked...............: avg=137.9µs min=853ns med=4.76µs max=59.25ms p(90)=8.28µs p(95)=95.24µs
143 | http_req_connecting............: avg=69.23µs min=0s med=0s max=43.92ms p(90)=0s p(95)=47.52µs
144 | http_req_duration..............: avg=77.33ms min=74.23µs med=823.24µs max=2.45s p(90)=80.97ms p(95)=496.05ms
145 | { expected_response:true }...: avg=77.33ms min=74.23µs med=823.24µs max=2.45s p(90)=80.97ms p(95)=496.05ms
146 | http_req_failed................: 0.00% ✓ 0 ✗ 39073
147 | http_req_receiving.............: avg=178.46µs min=8.65µs med=47.89µs max=41.88ms p(90)=117.14µs p(95)=372.95µs
148 | http_req_sending...............: avg=470.57µs min=4.01µs med=21.35µs max=42.19ms p(90)=301.42µs p(95)=1.55ms
149 | http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
150 | http_req_waiting...............: avg=76.68ms min=53.56µs med=599.58µs max=2.45s p(90)=80.9ms p(95)=495.99ms
151 | http_reqs......................: 39073 1781.48041/s
152 | iteration_duration.............: avg=1.07s min=1s med=1s max=3.48s p(90)=1.08s p(95)=1.49s
153 | iterations.....................: 39073 1781.48041/s
154 | vus............................: 1266 min=850 max=2000
155 | vus_max........................: 2000 min=2000 max=2000
156 |
157 | ## 20k concurrent user making 92k requests with log
158 | running (25.8s), 00000/20000 VUs, 92370 complete and 0 interrupted iterations
159 | default ✓ [======================================] 00000/20000 VUs 21s
160 |
161 | ✓ status was 200
162 |
163 | checks.........................: 100.00% ✓ 92370 ✗ 0
164 | data_received..................: 35 MB 1.4 MB/s
165 | data_sent......................: 9.4 MB 364 kB/s
166 | http_req_blocked...............: avg=41.92ms min=862ns med=4.57µs max=864.37ms p(90)=150.95ms p(95)=275.75ms
167 | http_req_connecting............: avg=41.47ms min=0s med=0s max=837.2ms p(90)=150.41ms p(95)=263.59ms
168 | http_req_duration..............: avg=3.76s min=101.27µs med=3.97s max=11.95s p(90)=5.62s p(95)=6.51s
169 | { expected_response:true }...: avg=3.76s min=101.27µs med=3.97s max=11.95s p(90)=5.62s p(95)=6.51s
170 | http_req_failed................: 0.00% ✓ 0 ✗ 92370
171 | http_req_receiving.............: avg=417.99µs min=9.77µs med=44.74µs max=346.94ms p(90)=69.5µs p(95)=136.42µs
172 | http_req_sending...............: avg=3.64ms min=4.32µs med=22.07µs max=381.16ms p(90)=8.99ms p(95)=17.01ms
173 | http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
174 | http_req_waiting...............: avg=3.75s min=74.57µs med=3.97s max=11.95s p(90)=5.62s p(95)=6.51s
175 | http_reqs......................: 92370 3586.930593/s
176 | iteration_duration.............: avg=4.82s min=1s med=5.04s max=12.95s p(90)=6.64s p(95)=7.52s
177 | iterations.....................: 92370 3586.930593/s
178 | vus............................: 818 min=0 max=20000
179 | vus_max........................: 20000 min=1967 max=20000
180 |
181 | ## 20k concurrent user making 267k requests without log or log with file
182 | running (22.0s), 00000/20000 VUs, 267924 complete and 0 interrupted iterations
183 | default ✓ [======================================] 00000/20000 VUs 21s
184 |
185 | ✓ status was 200
186 |
187 | checks.........................: 100.00% ✓ 267924 ✗ 0
188 | data_received..................: 101 MB 4.6 MB/s
189 | data_sent......................: 27 MB 1.2 MB/s
190 | http_req_blocked...............: avg=31.6ms min=880ns med=2.56µs max=1.45s p(90)=9.05µs p(95)=196.52ms
191 | http_req_connecting............: avg=30.83ms min=0s med=0s max=1.29s p(90)=0s p(95)=196.32ms
192 | http_req_duration..............: avg=208.22ms min=59.11µs med=134.03ms max=2.04s p(90)=553.1ms p(95)=711.66ms
193 | { expected_response:true }...: avg=208.22ms min=59.11µs med=134.03ms max=2.04s p(90)=553.1ms p(95)=711.66ms
194 | http_req_failed................: 0.00% ✓ 0 ✗ 267924
195 | http_req_receiving.............: avg=947.42µs min=7.9µs med=20.98µs max=699.6ms p(90)=124.45µs p(95)=1ms
196 | http_req_sending...............: avg=8.67ms min=4.53µs med=15.93µs max=2.04s p(90)=20.23ms p(95)=33.49ms
197 | http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
198 | http_req_waiting...............: avg=198.61ms min=40.07µs med=128.94ms max=1.27s p(90)=531.53ms p(95)=683.33ms
199 | http_reqs......................: 267924 12156.143024/s
200 | iteration_duration.............: avg=1.4s min=1s med=1.17s max=6.12s p(90)=2.14s p(95)=2.64s
201 | iterations.....................: 267924 12156.143024/s
202 | vus............................: 14593 min=0 max=20000
203 | vus_max........................: 20000 min=1666 max=20000
--------------------------------------------------------------------------------
/server/tests/test_data.json:
--------------------------------------------------------------------------------
1 | [
2 | "appreciative",
3 | "unstainable",
4 | "semiflexion",
5 | "parrakeet",
6 | "empidonax",
7 | "bushfire",
8 | "moksha",
9 | "disillusioning",
10 | "set",
11 | "steppeland",
12 | "mimsy",
13 | "adeleidae",
14 | "nonjudgmental",
15 | "bulldogism",
16 | "ovipara",
17 | "turbidness",
18 | "dissectible",
19 | "athenaeums",
20 | "vertebriform",
21 | "erythroclasis",
22 | "ceroma",
23 | "disozonize",
24 | "nonstudiousness",
25 | "stomatode",
26 | "unpriority",
27 | "rhizautoicous",
28 | "muscicapine",
29 | "pollucite",
30 | "coclea",
31 | "portuguese",
32 | "inaneness",
33 | "perturbant",
34 | "sphenopsid",
35 | "strombite",
36 | "pearl",
37 | "anticonscriptive",
38 | "tantalum",
39 | "tritopine",
40 | "beneficience",
41 | "trafficks",
42 | "bumbledom",
43 | "antibubonic",
44 | "rhamninose",
45 | "catholicos",
46 | "fissipeds",
47 | "immensity",
48 | "chromosomic",
49 | "overmelodiously",
50 | "limuloidea",
51 | "intradermically",
52 | "rober",
53 | "bastide",
54 | "metoposcopy",
55 | "pointedly",
56 | "graphed",
57 | "beggaries",
58 | "symbolistic",
59 | "isomyarian",
60 | "camister",
61 | "heteronomic",
62 | "reiterance",
63 | "witching",
64 | "rencounter",
65 | "microns",
66 | "photuria",
67 | "expressage",
68 | "inkhorn",
69 | "nasosinusitis",
70 | "adib",
71 | "gild",
72 | "noncircumspectly",
73 | "bilobular",
74 | "fallage",
75 | "torpid",
76 | "tracks",
77 | "averting",
78 | "londonese",
79 | "thanatopsis",
80 | "intown",
81 | "medication",
82 | "unconfidentialness",
83 | "spuriousness",
84 | "liberaliser",
85 | "pigman",
86 | "amnesties",
87 | "handjar",
88 | "pejorism",
89 | "reavoid",
90 | "latiseptate",
91 | "syncretizing",
92 | "leptynite",
93 | "unpervaded",
94 | "hagiocracies",
95 | "holist",
96 | "carbaryl",
97 | "nonsuppositional",
98 | "joculator",
99 | "indra",
100 | "unspherical",
101 | "pretire",
102 | "vanadosilicate",
103 | "birchbark",
104 | "phycoerythrin",
105 | "nonrealism",
106 | "ergatomorphic",
107 | "wachna",
108 | "clergymen",
109 | "brahms",
110 | "gonophorous",
111 | "enneahedrons",
112 | "dogfighting",
113 | "unsulliedness",
114 | "wheedles",
115 | "psyches",
116 | "overembellishing",
117 | "podesta",
118 | "terpsichorean",
119 | "sequaces",
120 | "adelphous",
121 | "horselaugher",
122 | "waterblink",
123 | "visionarily",
124 | "unsupernatural",
125 | "unnecessary",
126 | "fault",
127 | "algerita",
128 | "squarehead",
129 | "activated",
130 | "dharnas",
131 | "craniacromial",
132 | "amidating",
133 | "untuckered",
134 | "trip",
135 | "splinterproof",
136 | "numbing",
137 | "conocephalus",
138 | "pyohemothorax",
139 | "antthrush",
140 | "meconidium",
141 | "seventieths",
142 | "stratagem",
143 | "bowings",
144 | "doubtful",
145 | "motacilla",
146 | "cerebrotomy",
147 | "allargando",
148 | "obsoletely",
149 | "ostler",
150 | "unprofuse",
151 | "kacha",
152 | "prealphabetically",
153 | "baysmelt",
154 | "schizogony",
155 | "vorticellae",
156 | "somnambulator",
157 | "tapping",
158 | "combinement",
159 | "androcracy",
160 | "prespecializing",
161 | "remediably",
162 | "cardiomyomalacia",
163 | "congrid",
164 | "nonsedimentable",
165 | "bolty",
166 | "arnotta",
167 | "autarkist",
168 | "andalusian",
169 | "densitometry",
170 | "gestic",
171 | "phenomenalist",
172 | "psychometric",
173 | "celeusma",
174 | "tashlik",
175 | "epithem",
176 | "ciliately",
177 | "supernationalist",
178 | "microcytic",
179 | "overgreedily",
180 | "theriomorph",
181 | "cranesbill",
182 | "trolled",
183 | "nonbookish",
184 | "transversality",
185 | "isopoda",
186 | "tankah",
187 | "ungainfulness",
188 | "doc",
189 | "instreaming",
190 | "jimjams",
191 | "mutedness",
192 | "alcedininae",
193 | "evirato",
194 | "ottawa",
195 | "crackly",
196 | "unbanded",
197 | "overmodifies",
198 | "sulphoselenide",
199 | "mighted",
200 | "meddlesomely",
201 | "helled",
202 | "glycolic",
203 | "gamesmanship",
204 | "hummocks",
205 | "warehousing",
206 | "pechys",
207 | "rhinobyon",
208 | "flaith",
209 | "nemeses",
210 | "overinstructiveness",
211 | "quadrinucleate",
212 | "ritornellos",
213 | "noncrystallizable",
214 | "chylifactory",
215 | "grab",
216 | "spasmophile",
217 | "inthrall",
218 | "garaging",
219 | "jalousies",
220 | "koninckite",
221 | "thoraces",
222 | "miscites",
223 | "groot",
224 | "lavages",
225 | "foretopman",
226 | "hypnesthetic",
227 | "betook",
228 | "tablefellowship",
229 | "wooded",
230 | "untraitorously",
231 | "luminificent",
232 | "chromatically",
233 | "overdisciplined",
234 | "toponymies",
235 | "mastoiditis",
236 | "drachmae",
237 | "abutilons",
238 | "ungruesome",
239 | "startups",
240 | "windplayer",
241 | "sarcophagic",
242 | "cader",
243 | "grouthead",
244 | "glaserite",
245 | "musicological",
246 | "infantas",
247 | "etiolates",
248 | "sizably",
249 | "incarnational",
250 | "gardenlike",
251 | "unbudgingly",
252 | "conventioner",
253 | "rickettsial",
254 | "tampions",
255 | "gynecomorphous",
256 | "almacigo",
257 | "nontropically",
258 | "lignosity",
259 | "intortillage",
260 | "hasidic",
261 | "bivouacked",
262 | "monogenically",
263 | "similary",
264 | "confessant",
265 | "pentalpha",
266 | "sweeteners",
267 | "ventriculite",
268 | "congreve",
269 | "antefurca",
270 | "externation",
271 | "tasbih",
272 | "colorimetrically",
273 | "redacted",
274 | "incur",
275 | "accidie",
276 | "gardenlike",
277 | "prithee",
278 | "bedazzles",
279 | "gyres",
280 | "domiciles",
281 | "veining",
282 | "sulphotelluride",
283 | "azine",
284 | "goldurn",
285 | "liss",
286 | "casketed",
287 | "phlegma",
288 | "roseous",
289 | "cheerers",
290 | "siphonapterous",
291 | "paragraphia",
292 | "boltage",
293 | "gad",
294 | "lax",
295 | "saccharobutyric",
296 | "strychninism",
297 | "veneris",
298 | "bellbirds",
299 | "japishly",
300 | "sontag",
301 | "vesica",
302 | "mutinied",
303 | "revocableness",
304 | "avarish",
305 | "pyrotechnician",
306 | "biacuminate",
307 | "satrapical",
308 | "drizzlier",
309 | "semiclerically",
310 | "abrachia",
311 | "pursuits",
312 | "directively",
313 | "unlethal",
314 | "peridiastole",
315 | "akee",
316 | "correctory",
317 | "diamondwise",
318 | "bribers",
319 | "akra",
320 | "reforward",
321 | "jinrikiman",
322 | "lightninged",
323 | "skeleton",
324 | "silicons",
325 | "chorded",
326 | "principling",
327 | "reaccredit",
328 | "communiqu",
329 | "fastigiated",
330 | "destining",
331 | "cabaan",
332 | "mosul",
333 | "dotards",
334 | "authenticalness",
335 | "phalangologist",
336 | "cruelhearted",
337 | "proved",
338 | "semitrailer",
339 | "trapeziums",
340 | "insessores",
341 | "consocies",
342 | "ashfall",
343 | "hent",
344 | "unarithmetical",
345 | "mormyrus",
346 | "hirsles",
347 | "teetering",
348 | "coconqueror",
349 | "expressage",
350 | "condivision",
351 | "guyots",
352 | "inequitate",
353 | "irreformable",
354 | "prowess",
355 | "catapult",
356 | "besnowed",
357 | "montanans",
358 | "necessariness",
359 | "fault",
360 | "sickish",
361 | "loup",
362 | "excise",
363 | "incorruptibly",
364 | "tharf",
365 | "septarium",
366 | "stringybark",
367 | "categorem",
368 | "octapody",
369 | "perpetuities",
370 | "tembeitera",
371 | "legibilities",
372 | "astonishedly",
373 | "nonbotanic",
374 | "akebia",
375 | "forages",
376 | "committent",
377 | "noachical",
378 | "plurennial",
379 | "semicrome",
380 | "araneid",
381 | "waired",
382 | "nd",
383 | "busway",
384 | "perh",
385 | "respreads",
386 | "mails",
387 | "bancus",
388 | "pillaging",
389 | "labyrinthitis",
390 | "tushy",
391 | "unbeheld",
392 | "succinctness",
393 | "cupromanganese",
394 | "unproscribable",
395 | "dijudicate",
396 | "phytographic",
397 | "unwatered",
398 | "marmor",
399 | "obvoluted",
400 | "beastbane",
401 | "recreates",
402 | "loopholed",
403 | "cystotomies",
404 | "quenches",
405 | "superimpersonally",
406 | "strutted",
407 | "dactylous",
408 | "suggestibleness",
409 | "siliquous",
410 | "pavois",
411 | "monopolylogue",
412 | "joinered",
413 | "wretchlessly",
414 | "toilets",
415 | "verrucoseness",
416 | "ophthalmometer",
417 | "sanskritist",
418 | "dice",
419 | "fundraising",
420 | "betag",
421 | "mixtilineal",
422 | "puyallup",
423 | "postings",
424 | "drowningly",
425 | "entailer",
426 | "flutiest",
427 | "tradesman",
428 | "buccinal",
429 | "rectification",
430 | "opposite",
431 | "jehovic",
432 | "faventine",
433 | "faculae",
434 | "astonished",
435 | "dolour",
436 | "pipers",
437 | "embracer",
438 | "dhan",
439 | "unceremoniousness",
440 | "nonsubmergible",
441 | "tidesurveyor",
442 | "agios",
443 | "unloaded",
444 | "malabarese",
445 | "adtevac",
446 | "hooven",
447 | "hastefully",
448 | "browned",
449 | "unepauleted",
450 | "encrusted",
451 | "hoc",
452 | "unjaded",
453 | "ditheism",
454 | "vamoosing",
455 | "holmic",
456 | "scension",
457 | "equidivision",
458 | "intercourse",
459 | "hance",
460 | "fabricant",
461 | "powwowism",
462 | "siamoise",
463 | "washaki",
464 | "tarhood",
465 | "dioceses",
466 | "verisimilitudinous",
467 | "havioured",
468 | "pilotings",
469 | "fugate",
470 | "misparsing",
471 | "sinistrality",
472 | "plashingly",
473 | "glumal",
474 | "fellowlike",
475 | "noctiluscence",
476 | "nonpainter",
477 | "behavers",
478 | "roomier",
479 | "entrained",
480 | "legatory",
481 | "scooch",
482 | "isobutene",
483 | "remnantal",
484 | "stickybeak",
485 | "yis",
486 | "satrapy",
487 | "ligustrin",
488 | "ripplier",
489 | "geopolitics",
490 | "jiggled",
491 | "plebicolar",
492 | "roguish",
493 | "pantherish",
494 | "keffel",
495 | "ultrastellar",
496 | "enzymology",
497 | "blastoporphyritic",
498 | "secretional",
499 | "caodaism",
500 | "cranker",
501 | "dictyosiphon",
502 | "azotometer",
503 | "antiaggressionist",
504 | "phlebectomy",
505 | "reyoked",
506 | "reavowed",
507 | "ppd",
508 | "knappish",
509 | "taciturnity",
510 | "gonadal",
511 | "unprocessed",
512 | "aphorist",
513 | "escharine",
514 | "objectify",
515 | "petallike",
516 | "pimenton",
517 | "planetesimal",
518 | "satura",
519 | "praedial",
520 | "unpremeditate",
521 | "unprayable",
522 | "denitrificator",
523 | "scares",
524 | "whimming",
525 | "lycanthropist",
526 | "roistered",
527 | "euspongia",
528 | "minahassa",
529 | "concubitus",
530 | "bleymes",
531 | "agatelike",
532 | "sadistic",
533 | "chemicoluminescent",
534 | "fabricators",
535 | "misfielding",
536 | "hedgewood",
537 | "somepart",
538 | "xerotripsis",
539 | "aristate",
540 | "psychostatically",
541 | "measled",
542 | "oilheating",
543 | "norleucine",
544 | "laddock",
545 | "gynaecomasty",
546 | "harnesslike",
547 | "vanfoss",
548 | "grades",
549 | "alcoholate",
550 | "abstrict",
551 | "schoolgirlishness",
552 | "douane",
553 | "overluxuriant",
554 | "unanguished",
555 | "deforcer",
556 | "fuddles",
557 | "otiant",
558 | "oogeny",
559 | "ternary",
560 | "reductant",
561 | "wakeup",
562 | "fucker",
563 | "lianoid",
564 | "cormus",
565 | "seraing",
566 | "euboic",
567 | "unexpressible",
568 | "unmeltable",
569 | "poalike",
570 | "checkbit",
571 | "snitchy",
572 | "ramosely",
573 | "bizarrely",
574 | "immunogenetics",
575 | "perniciousness",
576 | "tagetol",
577 | "murmurlessly",
578 | "fantods",
579 | "pentremites",
580 | "underrating",
581 | "levis",
582 | "brasier",
583 | "botchier",
584 | "wavefront",
585 | "gelsemic",
586 | "seismograms",
587 | "wans",
588 | "unpuffing",
589 | "evacue",
590 | "cavies",
591 | "funnies",
592 | "imaginativeness",
593 | "unbrown",
594 | "palustrine",
595 | "springtrap",
596 | "reshooting",
597 | "thecae",
598 | "unwired",
599 | "stercoraries",
600 | "waterleaf",
601 | "bacbakiri",
602 | "suprapubian",
603 | "juicing",
604 | "succulency",
605 | "preinspector",
606 | "dudler",
607 | "liveableness",
608 | "padcloth",
609 | "outbeaming",
610 | "zoonoses",
611 | "overshowered",
612 | "pyrotechnician",
613 | "potholders",
614 | "valleywise",
615 | "organographist",
616 | "hairbell",
617 | "semirattlesnake",
618 | "sulphobismuthite",
619 | "cathartically",
620 | "eruditely",
621 | "psoriases",
622 | "girthline",
623 | "embrica",
624 | "reservedly",
625 | "debited",
626 | "cryptopyic",
627 | "underprincipal",
628 | "reclaimers",
629 | "unforgiving",
630 | "outshifts",
631 | "fido",
632 | "cattlebush",
633 | "autoimmunize",
634 | "onymancy",
635 | "nondurable",
636 | "bromopnea",
637 | "rallentando",
638 | "discontinuity",
639 | "kapas",
640 | "duressor",
641 | "screams",
642 | "siderographist",
643 | "unritually",
644 | "commandeering",
645 | "passableness",
646 | "spurdog",
647 | "colyone",
648 | "hematogenous",
649 | "sternness",
650 | "untempested",
651 | "pudical",
652 | "toxiinfection",
653 | "cocoanut",
654 | "rebate",
655 | "frass",
656 | "swanpans",
657 | "darling",
658 | "romanos",
659 | "shema",
660 | "disquietedness",
661 | "lichenian",
662 | "detubation",
663 | "hemase",
664 | "degas",
665 | "deary",
666 | "pyramidion",
667 | "begaze",
668 | "subcrureus",
669 | "shrubless",
670 | "souse",
671 | "penorcon",
672 | "diakinetic",
673 | "elvanite",
674 | "quadruplicate",
675 | "unchoke",
676 | "cherubic",
677 | "operabilities",
678 | "ondagram",
679 | "amusive",
680 | "carrow",
681 | "counterindoctrination",
682 | "unbehoving",
683 | "plantarium",
684 | "reprosecute",
685 | "evetide",
686 | "podagras",
687 | "frayne",
688 | "emoluments",
689 | "bertha",
690 | "dysgenesic",
691 | "pycnic",
692 | "arefact",
693 | "sinistrorsal",
694 | "dependence",
695 | "pharmaceutics",
696 | "laughterful",
697 | "sympathetectomies",
698 | "parameterize",
699 | "beclog",
700 | "noniodized",
701 | "reclaim",
702 | "overmans",
703 | "repropitiation",
704 | "mentalistic",
705 | "episcopising",
706 | "fibrotuberculosis",
707 | "delichon",
708 | "vesicularly",
709 | "apostemate",
710 | "syzygium",
711 | "emersonian",
712 | "celioparacentesis",
713 | "schismatize",
714 | "ptychosperma",
715 | "featherbone",
716 | "thelphusidae",
717 | "outfled",
718 | "jolts",
719 | "forestries",
720 | "unrequisitioned",
721 | "currs",
722 | "castellatus",
723 | "proseminary",
724 | "livering",
725 | "diapasm",
726 | "chondriomere",
727 | "gell",
728 | "demulsion",
729 | "hellicate",
730 | "roughens",
731 | "argentine",
732 | "unavengingly",
733 | "condemns",
734 | "untrainable",
735 | "galavanting",
736 | "locators",
737 | "conations",
738 | "tunnellike",
739 | "shammas",
740 | "seedtime",
741 | "polarizable",
742 | "urophi",
743 | "reckonings",
744 | "orientated",
745 | "harkening",
746 | "mimeo",
747 | "unpropitiatedness",
748 | "unshanked",
749 | "virally",
750 | "ciphertexts",
751 | "philomelian",
752 | "septette",
753 | "miszealous",
754 | "octangular",
755 | "semihistoric",
756 | "passerby",
757 | "copaiva",
758 | "procontinuation",
759 | "mouflons",
760 | "viz",
761 | "treague",
762 | "monopitch",
763 | "stiffed",
764 | "hussydom",
765 | "unclify",
766 | "turcopole",
767 | "prospectuses",
768 | "soosoo",
769 | "mascagnite",
770 | "obstinacious",
771 | "confederatism",
772 | "quinquenerved",
773 | "recking",
774 | "trimorphism",
775 | "affirmly",
776 | "steersman",
777 | "hypodiploid",
778 | "alphabetizing",
779 | "undecillionth",
780 | "shogun",
781 | "realter",
782 | "quattie",
783 | "heinousness",
784 | "precompiling",
785 | "flossflower",
786 | "thecasporal",
787 | "infringer",
788 | "headier",
789 | "microseismicity",
790 | "comate",
791 | "cetologist",
792 | "enrober",
793 | "elastases",
794 | "reefing",
795 | "outprayed",
796 | "contortionistic",
797 | "kampongs",
798 | "intemerate",
799 | "peulvan",
800 | "rheo",
801 | "sailflying",
802 | "signa",
803 | "legumins",
804 | "relumines",
805 | "birls",
806 | "misween",
807 | "omnifying",
808 | "crotalo",
809 | "cheesecake",
810 | "hydragogy",
811 | "alkalemia",
812 | "metepisternal",
813 | "badon",
814 | "untoured",
815 | "skedaddled",
816 | "catechetic",
817 | "cased",
818 | "mesepimeral",
819 | "underdogs",
820 | "kaddish",
821 | "colourize",
822 | "machar",
823 | "striffen",
824 | "slurried",
825 | "lindo",
826 | "lurdanism",
827 | "sabbathize",
828 | "dehydrogenized",
829 | "martes",
830 | "cunctatious",
831 | "nabcheat",
832 | "hackles",
833 | "poetized",
834 | "overquarter",
835 | "redeny",
836 | "playwright",
837 | "diesel",
838 | "chartroom",
839 | "uncavernous",
840 | "formicoidea",
841 | "noneloquently",
842 | "supersevere",
843 | "raver",
844 | "shines",
845 | "nailhead",
846 | "allicient",
847 | "unbleeding",
848 | "hick",
849 | "hemadromograph",
850 | "delatinization",
851 | "manuscript",
852 | "symphily",
853 | "unlikeable",
854 | "stringendos",
855 | "myograph",
856 | "deltation",
857 | "caranga",
858 | "phaseal",
859 | "maracas",
860 | "txt",
861 | "epididymodeferentectomy",
862 | "polydental",
863 | "defibrillation",
864 | "nonfeudal",
865 | "inalacrity",
866 | "metabolised",
867 | "woodcraft",
868 | "monticuline",
869 | "pteraspidae",
870 | "palfrey",
871 | "subderivative",
872 | "nonservileness",
873 | "kjeldahlization",
874 | "witter",
875 | "autometry",
876 | "cai",
877 | "interlunar",
878 | "diplegia",
879 | "methodise",
880 | "nonmystic",
881 | "osmophore",
882 | "kilopound",
883 | "graft",
884 | "ejusdem",
885 | "prosubstantive",
886 | "androgyny",
887 | "cogeneric",
888 | "smee",
889 | "counterclockwise",
890 | "scantle",
891 | "moror",
892 | "slitlike",
893 | "gimel",
894 | "nitrosulphonic",
895 | "evolutionarily",
896 | "superdifficult",
897 | "precorruption",
898 | "tourneur",
899 | "repeg",
900 | "hortonolite",
901 | "reclinate",
902 | "unpredicableness",
903 | "merenchymatous",
904 | "bicameral",
905 | "unvirtue",
906 | "superquoted",
907 | "mercurially",
908 | "simblot",
909 | "revolvingly",
910 | "rearward",
911 | "faradaic",
912 | "interspinous",
913 | "sluggish",
914 | "haemothorax",
915 | "exegetically",
916 | "imidazole",
917 | "roughers",
918 | "solidifies",
919 | "monad",
920 | "coordinative",
921 | "disapprobation",
922 | "unperceptibly",
923 | "untroublable",
924 | "faraon",
925 | "rupture",
926 | "perpetuation",
927 | "basified",
928 | "juris",
929 | "juniors",
930 | "venipuncture",
931 | "overnervously",
932 | "whipstock",
933 | "shouldn",
934 | "dramaturgy",
935 | "abattis",
936 | "powderization",
937 | "mistide",
938 | "ricardianism",
939 | "tinwork",
940 | "stations",
941 | "chacona",
942 | "nidamental",
943 | "trancoidal",
944 | "aspidocephali",
945 | "thunderstricken",
946 | "thysanopterous",
947 | "pteroclidae",
948 | "pandiabolism",
949 | "noncaffeinic",
950 | "suffixer",
951 | "yohimbe",
952 | "tetracoralline",
953 | "stainably",
954 | "insufflator",
955 | "slouchiness",
956 | "squandered",
957 | "hypodermatically",
958 | "canthal",
959 | "counterpoising",
960 | "westernizing",
961 | "ighly",
962 | "poetastress",
963 | "enveigle",
964 | "hoarders",
965 | "merchantableness",
966 | "cystignathine",
967 | "tobogganeer",
968 | "collect",
969 | "hereness",
970 | "lacustrian",
971 | "imperializing",
972 | "cisandine",
973 | "relentlessness",
974 | "nonpedagogic",
975 | "marvin",
976 | "appense",
977 | "fibromyoma",
978 | "formulisation",
979 | "enthrallments",
980 | "inopportuneness",
981 | "boulimy",
982 | "headcloths",
983 | "surprisedly",
984 | "counterproof",
985 | "nonregressive",
986 | "vocative",
987 | "procurative",
988 | "nonpropitiable",
989 | "algiomuscular",
990 | "spilling",
991 | "domn",
992 | "ecorche",
993 | "scoreboards",
994 | "supersocial",
995 | "prisable",
996 | "agnathostomata",
997 | "ruttish",
998 | "hepatorrhea",
999 | "dewinesses",
1000 | "deposed",
1001 | "kiwanis"
1002 | ]
1003 |
--------------------------------------------------------------------------------
/server/src/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
56 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
57 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
58 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
59 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
60 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
61 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
62 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
63 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
64 | github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
65 | github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
66 | github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
67 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
68 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
69 | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
70 | github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
71 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
72 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
73 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
74 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
75 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
76 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
77 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
78 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
79 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
80 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
81 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
82 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
83 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
84 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
85 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
86 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
87 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
88 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
89 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
90 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
91 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
92 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
93 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
94 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
95 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
96 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
97 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
98 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
99 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
100 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
101 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
102 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
103 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
104 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
105 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
106 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
107 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
108 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
109 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
110 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
111 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
112 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
113 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
114 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
115 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
116 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
117 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
118 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
119 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
120 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
121 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
122 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
123 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
124 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
125 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
126 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
127 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
128 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
129 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
130 | github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
131 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
132 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
133 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
134 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
135 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
136 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
137 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
138 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
139 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
140 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
141 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
142 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
143 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
144 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
145 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
146 | github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
147 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
148 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
149 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
150 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
151 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
152 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
153 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
154 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
155 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
156 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
157 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
158 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
159 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
160 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
161 | github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
162 | github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
163 | github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
164 | github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
165 | github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
166 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
167 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
168 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
169 | github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
170 | github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
171 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
172 | github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
173 | github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
174 | github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
175 | github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
176 | github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
177 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
178 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
179 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
180 | github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
181 | github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
182 | github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
183 | github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
184 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
185 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
186 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
187 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
188 | github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
189 | github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
190 | github.com/slok/go-http-metrics v0.10.0 h1:rh0LaYEKza5eaYRGDXujKrOln57nHBi4TtVhmNEpbgM=
191 | github.com/slok/go-http-metrics v0.10.0/go.mod h1:lFqdaS4kWMfUKCSukjC47PdCeTk+hXDUVm8kLHRqJ38=
192 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
193 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
194 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
195 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
196 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
197 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
198 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
199 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
200 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
201 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
202 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
203 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
204 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
205 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
206 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
207 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
208 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
209 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
210 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
211 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
212 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
213 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
214 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
215 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
216 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
217 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
218 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
219 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
220 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
221 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
222 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
223 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
224 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
225 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
226 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
227 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
228 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
229 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
230 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
231 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
232 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
233 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
234 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
235 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
236 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
237 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
238 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
239 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
240 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
241 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
242 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
243 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
244 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
245 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
246 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
247 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
248 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
249 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
250 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
251 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
252 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
253 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
254 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
255 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
256 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
257 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
258 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
259 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
260 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
261 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
262 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
263 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
264 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
265 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
266 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
267 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
268 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
269 | golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
270 | golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
271 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
272 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
273 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
274 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
275 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
276 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
277 | golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
278 | golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
279 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
280 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
281 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
282 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
283 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
284 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
285 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
286 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
287 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
288 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
289 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
290 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
291 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
292 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
293 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
294 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
295 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
296 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
297 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
298 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
299 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
300 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
301 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
302 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
303 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
304 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
305 | golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
306 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
307 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
308 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
309 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
310 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
311 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
312 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
313 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
314 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
315 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
316 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
317 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
318 | golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
319 | golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
320 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
321 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
322 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
323 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
324 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
325 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
326 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
327 | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
328 | golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 h1:cy1ko5847T/lJ45eyg/7uLprIE/amW5IXxGtEnQdYMI=
329 | golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
330 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
331 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
332 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
333 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
334 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
335 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
336 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
337 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
338 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
339 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
340 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
341 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
342 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
343 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
344 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
345 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
346 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
347 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
348 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
349 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
350 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
351 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
352 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
353 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
354 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
355 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
356 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
357 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
358 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
359 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
360 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
361 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
362 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
363 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
364 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
365 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
366 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
367 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
368 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
369 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
370 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
371 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
372 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
373 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
374 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
375 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
376 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
377 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
378 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
379 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
380 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
381 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
382 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
383 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
384 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
385 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
386 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
387 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
388 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
389 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
390 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
391 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
392 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
393 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
394 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
395 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
396 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
397 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
398 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
399 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
400 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
401 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
402 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
403 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
404 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
405 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
406 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
407 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
408 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
409 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
410 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
411 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
412 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
413 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
414 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
415 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
416 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
417 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
418 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
419 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
420 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
421 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
422 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
423 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
424 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
425 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
426 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
427 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
428 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
429 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
430 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
431 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
432 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
433 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
434 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
435 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
436 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
437 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
438 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
439 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
440 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
441 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
442 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
443 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
444 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
445 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
446 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
447 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
448 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
449 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
450 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
451 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
452 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
453 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
454 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
455 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
456 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
457 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
458 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
459 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
460 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
461 | google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
462 | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
463 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
464 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
465 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
466 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
467 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
468 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
469 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
470 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
471 | gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
472 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
473 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
474 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
475 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
476 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
477 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
478 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
479 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
480 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
481 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
482 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
483 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
484 |
--------------------------------------------------------------------------------
/server/monitoring/custom_dashboard.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": {
3 | "list": [
4 | {
5 | "builtIn": 1,
6 | "datasource": {
7 | "type": "grafana",
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 | "editable": true,
25 | "fiscalYearStartMonth": 0,
26 | "graphTooltip": 0,
27 | "id": 1,
28 | "links": [],
29 | "liveNow": false,
30 | "panels": [
31 | {
32 | "collapsed": false,
33 | "gridPos": {
34 | "h": 1,
35 | "w": 24,
36 | "x": 0,
37 | "y": 0
38 | },
39 | "id": 28,
40 | "panels": [],
41 | "title": "App",
42 | "type": "row"
43 | },
44 | {
45 | "datasource": {
46 | "type": "prometheus",
47 | "uid": "P1809F7CD0C75ACF3"
48 | },
49 | "fieldConfig": {
50 | "defaults": {
51 | "color": {
52 | "mode": "palette-classic"
53 | },
54 | "custom": {
55 | "axisCenteredZero": false,
56 | "axisColorMode": "text",
57 | "axisLabel": "",
58 | "axisPlacement": "auto",
59 | "barAlignment": 0,
60 | "drawStyle": "line",
61 | "fillOpacity": 0,
62 | "gradientMode": "none",
63 | "hideFrom": {
64 | "legend": false,
65 | "tooltip": false,
66 | "viz": false
67 | },
68 | "lineInterpolation": "linear",
69 | "lineWidth": 1,
70 | "pointSize": 5,
71 | "scaleDistribution": {
72 | "type": "linear"
73 | },
74 | "showPoints": "auto",
75 | "spanNulls": false,
76 | "stacking": {
77 | "group": "A",
78 | "mode": "none"
79 | },
80 | "thresholdsStyle": {
81 | "mode": "off"
82 | }
83 | },
84 | "mappings": [],
85 | "thresholds": {
86 | "mode": "absolute",
87 | "steps": [
88 | {
89 | "color": "green",
90 | "value": null
91 | },
92 | {
93 | "color": "red",
94 | "value": 80
95 | }
96 | ]
97 | }
98 | },
99 | "overrides": []
100 | },
101 | "gridPos": {
102 | "h": 11,
103 | "w": 12,
104 | "x": 0,
105 | "y": 1
106 | },
107 | "id": 4,
108 | "options": {
109 | "legend": {
110 | "calcs": [],
111 | "displayMode": "list",
112 | "placement": "bottom",
113 | "showLegend": true
114 | },
115 | "tooltip": {
116 | "mode": "single",
117 | "sort": "none"
118 | }
119 | },
120 | "targets": [
121 | {
122 | "datasource": {
123 | "type": "prometheus",
124 | "uid": "P1809F7CD0C75ACF3"
125 | },
126 | "editorMode": "builder",
127 | "exemplar": false,
128 | "expr": "histogram_quantile(0.95, sum by(le) (rate(http_request_duration_seconds_bucket{handler=\"/find\"}[15s])))",
129 | "format": "time_series",
130 | "interval": "",
131 | "legendFormat": "95%",
132 | "range": true,
133 | "refId": "A"
134 | },
135 | {
136 | "datasource": {
137 | "type": "prometheus",
138 | "uid": "P1809F7CD0C75ACF3"
139 | },
140 | "editorMode": "builder",
141 | "expr": "histogram_quantile(0.5, sum by(le) (rate(http_request_duration_seconds_bucket{handler=\"/find\"}[15s])))",
142 | "format": "time_series",
143 | "hide": false,
144 | "interval": "",
145 | "legendFormat": "50%",
146 | "range": true,
147 | "refId": "B"
148 | }
149 | ],
150 | "title": "Percentiles",
151 | "type": "timeseries"
152 | },
153 | {
154 | "datasource": {
155 | "type": "prometheus",
156 | "uid": "P1809F7CD0C75ACF3"
157 | },
158 | "fieldConfig": {
159 | "defaults": {
160 | "color": {
161 | "mode": "palette-classic"
162 | },
163 | "custom": {
164 | "axisCenteredZero": false,
165 | "axisColorMode": "text",
166 | "axisLabel": "",
167 | "axisPlacement": "auto",
168 | "barAlignment": 0,
169 | "drawStyle": "line",
170 | "fillOpacity": 0,
171 | "gradientMode": "none",
172 | "hideFrom": {
173 | "legend": false,
174 | "tooltip": false,
175 | "viz": false
176 | },
177 | "lineInterpolation": "linear",
178 | "lineWidth": 1,
179 | "pointSize": 5,
180 | "scaleDistribution": {
181 | "type": "linear"
182 | },
183 | "showPoints": "auto",
184 | "spanNulls": false,
185 | "stacking": {
186 | "group": "A",
187 | "mode": "none"
188 | },
189 | "thresholdsStyle": {
190 | "mode": "off"
191 | }
192 | },
193 | "mappings": [],
194 | "thresholds": {
195 | "mode": "absolute",
196 | "steps": [
197 | {
198 | "color": "green",
199 | "value": null
200 | },
201 | {
202 | "color": "red",
203 | "value": 80
204 | }
205 | ]
206 | }
207 | },
208 | "overrides": []
209 | },
210 | "gridPos": {
211 | "h": 11,
212 | "w": 12,
213 | "x": 12,
214 | "y": 1
215 | },
216 | "id": 2,
217 | "options": {
218 | "legend": {
219 | "calcs": [],
220 | "displayMode": "list",
221 | "placement": "bottom",
222 | "showLegend": true
223 | },
224 | "tooltip": {
225 | "mode": "single",
226 | "sort": "none"
227 | }
228 | },
229 | "targets": [
230 | {
231 | "datasource": {
232 | "type": "prometheus",
233 | "uid": "P1809F7CD0C75ACF3"
234 | },
235 | "editorMode": "builder",
236 | "expr": "rate(http_request_duration_seconds_count{code=\"200\", handler=\"/find\"}[15s])",
237 | "legendFormat": "__auto",
238 | "range": true,
239 | "refId": "A"
240 | }
241 | ],
242 | "title": "req/s (agg. on last 15 sec)",
243 | "type": "timeseries"
244 | },
245 | {
246 | "datasource": {
247 | "type": "prometheus",
248 | "uid": "P1809F7CD0C75ACF3"
249 | },
250 | "description": "",
251 | "fieldConfig": {
252 | "defaults": {
253 | "color": {
254 | "mode": "palette-classic"
255 | },
256 | "custom": {
257 | "axisCenteredZero": false,
258 | "axisColorMode": "text",
259 | "axisLabel": "percentage",
260 | "axisPlacement": "auto",
261 | "barAlignment": 0,
262 | "drawStyle": "line",
263 | "fillOpacity": 70,
264 | "gradientMode": "none",
265 | "hideFrom": {
266 | "legend": false,
267 | "tooltip": false,
268 | "viz": false
269 | },
270 | "lineInterpolation": "smooth",
271 | "lineWidth": 2,
272 | "pointSize": 5,
273 | "scaleDistribution": {
274 | "type": "linear"
275 | },
276 | "showPoints": "never",
277 | "spanNulls": false,
278 | "stacking": {
279 | "group": "A",
280 | "mode": "percent"
281 | },
282 | "thresholdsStyle": {
283 | "mode": "off"
284 | }
285 | },
286 | "links": [],
287 | "mappings": [],
288 | "min": 0,
289 | "thresholds": {
290 | "mode": "absolute",
291 | "steps": [
292 | {
293 | "color": "green",
294 | "value": null
295 | },
296 | {
297 | "color": "red",
298 | "value": 80
299 | }
300 | ]
301 | },
302 | "unit": "percentunit"
303 | },
304 | "overrides": [
305 | {
306 | "matcher": {
307 | "id": "byName",
308 | "options": "Idle - Waiting for something to happen"
309 | },
310 | "properties": [
311 | {
312 | "id": "color",
313 | "value": {
314 | "fixedColor": "#052B51",
315 | "mode": "fixed"
316 | }
317 | }
318 | ]
319 | },
320 | {
321 | "matcher": {
322 | "id": "byName",
323 | "options": "Iowait - Waiting for I/O to complete"
324 | },
325 | "properties": [
326 | {
327 | "id": "color",
328 | "value": {
329 | "fixedColor": "#EAB839",
330 | "mode": "fixed"
331 | }
332 | }
333 | ]
334 | },
335 | {
336 | "matcher": {
337 | "id": "byName",
338 | "options": "Irq - Servicing interrupts"
339 | },
340 | "properties": [
341 | {
342 | "id": "color",
343 | "value": {
344 | "fixedColor": "#BF1B00",
345 | "mode": "fixed"
346 | }
347 | }
348 | ]
349 | },
350 | {
351 | "matcher": {
352 | "id": "byName",
353 | "options": "Nice - Niced processes executing in user mode"
354 | },
355 | "properties": [
356 | {
357 | "id": "color",
358 | "value": {
359 | "fixedColor": "#C15C17",
360 | "mode": "fixed"
361 | }
362 | }
363 | ]
364 | },
365 | {
366 | "matcher": {
367 | "id": "byName",
368 | "options": "Softirq - Servicing softirqs"
369 | },
370 | "properties": [
371 | {
372 | "id": "color",
373 | "value": {
374 | "fixedColor": "#E24D42",
375 | "mode": "fixed"
376 | }
377 | }
378 | ]
379 | },
380 | {
381 | "matcher": {
382 | "id": "byName",
383 | "options": "Steal - Time spent in other operating systems when running in a virtualized environment"
384 | },
385 | "properties": [
386 | {
387 | "id": "color",
388 | "value": {
389 | "fixedColor": "#FCE2DE",
390 | "mode": "fixed"
391 | }
392 | }
393 | ]
394 | },
395 | {
396 | "matcher": {
397 | "id": "byName",
398 | "options": "System - Processes executing in kernel mode"
399 | },
400 | "properties": [
401 | {
402 | "id": "color",
403 | "value": {
404 | "fixedColor": "#508642",
405 | "mode": "fixed"
406 | }
407 | }
408 | ]
409 | },
410 | {
411 | "matcher": {
412 | "id": "byName",
413 | "options": "User - Normal processes executing in user mode"
414 | },
415 | "properties": [
416 | {
417 | "id": "color",
418 | "value": {
419 | "fixedColor": "#5195CE",
420 | "mode": "fixed"
421 | }
422 | }
423 | ]
424 | }
425 | ]
426 | },
427 | "gridPos": {
428 | "h": 12,
429 | "w": 12,
430 | "x": 0,
431 | "y": 12
432 | },
433 | "id": 30,
434 | "links": [],
435 | "options": {
436 | "legend": {
437 | "calcs": [
438 | "mean",
439 | "lastNotNull",
440 | "max",
441 | "min"
442 | ],
443 | "displayMode": "table",
444 | "placement": "bottom",
445 | "showLegend": true,
446 | "width": 250
447 | },
448 | "tooltip": {
449 | "mode": "multi",
450 | "sort": "desc"
451 | }
452 | },
453 | "pluginVersion": "9.2.0",
454 | "targets": [
455 | {
456 | "datasource": {
457 | "type": "prometheus",
458 | "uid": "P1809F7CD0C75ACF3"
459 | },
460 | "editorMode": "code",
461 | "expr": "sum by(instance) (irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\", mode=\"system\"}[$__rate_interval])) / on(instance) group_left sum by (instance)((irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])))",
462 | "format": "time_series",
463 | "interval": "",
464 | "intervalFactor": 1,
465 | "legendFormat": "System - Processes executing in kernel mode",
466 | "range": true,
467 | "refId": "A",
468 | "step": 240
469 | },
470 | {
471 | "datasource": {
472 | "type": "prometheus",
473 | "uid": "P1809F7CD0C75ACF3"
474 | },
475 | "editorMode": "code",
476 | "expr": "sum by(instance) (irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\", mode=\"user\"}[$__rate_interval])) / on(instance) group_left sum by (instance)((irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])))",
477 | "format": "time_series",
478 | "intervalFactor": 1,
479 | "legendFormat": "User - Normal processes executing in user mode",
480 | "range": true,
481 | "refId": "B",
482 | "step": 240
483 | },
484 | {
485 | "datasource": {
486 | "type": "prometheus",
487 | "uid": "P1809F7CD0C75ACF3"
488 | },
489 | "editorMode": "code",
490 | "expr": "sum by(instance) (irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\", mode=\"nice\"}[$__rate_interval])) / on(instance) group_left sum by (instance)((irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])))",
491 | "format": "time_series",
492 | "intervalFactor": 1,
493 | "legendFormat": "Nice - Niced processes executing in user mode",
494 | "range": true,
495 | "refId": "C",
496 | "step": 240
497 | },
498 | {
499 | "datasource": {
500 | "type": "prometheus",
501 | "uid": "P1809F7CD0C75ACF3"
502 | },
503 | "editorMode": "code",
504 | "expr": "sum by(instance) (irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\", mode=\"iowait\"}[$__rate_interval])) / on(instance) group_left sum by (instance)((irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])))",
505 | "format": "time_series",
506 | "intervalFactor": 1,
507 | "legendFormat": "Iowait - Waiting for I/O to complete",
508 | "range": true,
509 | "refId": "E",
510 | "step": 240
511 | },
512 | {
513 | "datasource": {
514 | "type": "prometheus",
515 | "uid": "P1809F7CD0C75ACF3"
516 | },
517 | "editorMode": "code",
518 | "expr": "sum by(instance) (irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\", mode=\"irq\"}[$__rate_interval])) / on(instance) group_left sum by (instance)((irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])))",
519 | "format": "time_series",
520 | "intervalFactor": 1,
521 | "legendFormat": "Irq - Servicing interrupts",
522 | "range": true,
523 | "refId": "F",
524 | "step": 240
525 | },
526 | {
527 | "datasource": {
528 | "type": "prometheus",
529 | "uid": "P1809F7CD0C75ACF3"
530 | },
531 | "editorMode": "code",
532 | "expr": "sum by(instance) (irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\", mode=\"softirq\"}[$__rate_interval])) / on(instance) group_left sum by (instance)((irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])))",
533 | "format": "time_series",
534 | "intervalFactor": 1,
535 | "legendFormat": "Softirq - Servicing softirqs",
536 | "range": true,
537 | "refId": "G",
538 | "step": 240
539 | },
540 | {
541 | "datasource": {
542 | "type": "prometheus",
543 | "uid": "P1809F7CD0C75ACF3"
544 | },
545 | "editorMode": "code",
546 | "expr": "sum by(instance) (irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\", mode=\"steal\"}[$__rate_interval])) / on(instance) group_left sum by (instance)((irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])))",
547 | "format": "time_series",
548 | "intervalFactor": 1,
549 | "legendFormat": "Steal - Time spent in other operating systems when running in a virtualized environment",
550 | "range": true,
551 | "refId": "H",
552 | "step": 240
553 | },
554 | {
555 | "datasource": {
556 | "type": "prometheus",
557 | "uid": "P1809F7CD0C75ACF3"
558 | },
559 | "editorMode": "code",
560 | "expr": "sum by(instance) (irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\", mode=\"idle\"}[$__rate_interval])) / on(instance) group_left sum by (instance)((irate(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])))",
561 | "format": "time_series",
562 | "hide": false,
563 | "intervalFactor": 1,
564 | "legendFormat": "Idle - Waiting for something to happen",
565 | "range": true,
566 | "refId": "J",
567 | "step": 240
568 | }
569 | ],
570 | "title": "CPU",
571 | "type": "timeseries"
572 | },
573 | {
574 | "datasource": {
575 | "type": "prometheus",
576 | "uid": "P1809F7CD0C75ACF3"
577 | },
578 | "fieldConfig": {
579 | "defaults": {
580 | "color": {
581 | "mode": "palette-classic"
582 | },
583 | "custom": {
584 | "axisCenteredZero": false,
585 | "axisColorMode": "text",
586 | "axisLabel": "MB",
587 | "axisPlacement": "auto",
588 | "barAlignment": 0,
589 | "drawStyle": "line",
590 | "fillOpacity": 0,
591 | "gradientMode": "none",
592 | "hideFrom": {
593 | "legend": false,
594 | "tooltip": false,
595 | "viz": false
596 | },
597 | "lineInterpolation": "linear",
598 | "lineWidth": 1,
599 | "pointSize": 5,
600 | "scaleDistribution": {
601 | "type": "linear"
602 | },
603 | "showPoints": "auto",
604 | "spanNulls": false,
605 | "stacking": {
606 | "group": "A",
607 | "mode": "none"
608 | },
609 | "thresholdsStyle": {
610 | "mode": "off"
611 | }
612 | },
613 | "mappings": [],
614 | "thresholds": {
615 | "mode": "absolute",
616 | "steps": [
617 | {
618 | "color": "green",
619 | "value": null
620 | },
621 | {
622 | "color": "red",
623 | "value": 80
624 | }
625 | ]
626 | }
627 | },
628 | "overrides": []
629 | },
630 | "gridPos": {
631 | "h": 10,
632 | "w": 12,
633 | "x": 12,
634 | "y": 12
635 | },
636 | "id": 8,
637 | "options": {
638 | "legend": {
639 | "calcs": [],
640 | "displayMode": "list",
641 | "placement": "bottom",
642 | "showLegend": true
643 | },
644 | "tooltip": {
645 | "mode": "single",
646 | "sort": "none"
647 | }
648 | },
649 | "targets": [
650 | {
651 | "datasource": {
652 | "type": "prometheus",
653 | "uid": "P1809F7CD0C75ACF3"
654 | },
655 | "editorMode": "builder",
656 | "exemplar": false,
657 | "expr": "go_memstats_alloc_bytes",
658 | "instant": false,
659 | "legendFormat": "__auto",
660 | "range": true,
661 | "refId": "A"
662 | }
663 | ],
664 | "title": "Memory",
665 | "transformations": [
666 | {
667 | "id": "calculateField",
668 | "options": {
669 | "binary": {
670 | "left": "{__name__=\"go_memstats_alloc_bytes\", instance=\"localhost:8081\", job=\"flash\"}",
671 | "operator": "/",
672 | "reducer": "sum",
673 | "right": "1048576"
674 | },
675 | "mode": "binary",
676 | "reduce": {
677 | "reducer": "sum"
678 | },
679 | "replaceFields": true
680 | }
681 | }
682 | ],
683 | "type": "timeseries"
684 | },
685 | {
686 | "datasource": {
687 | "type": "prometheus",
688 | "uid": "P1809F7CD0C75ACF3"
689 | },
690 | "fieldConfig": {
691 | "defaults": {
692 | "color": {
693 | "mode": "palette-classic"
694 | },
695 | "custom": {
696 | "axisCenteredZero": false,
697 | "axisColorMode": "text",
698 | "axisLabel": "",
699 | "axisPlacement": "auto",
700 | "barAlignment": 0,
701 | "drawStyle": "line",
702 | "fillOpacity": 0,
703 | "gradientMode": "none",
704 | "hideFrom": {
705 | "legend": false,
706 | "tooltip": false,
707 | "viz": false
708 | },
709 | "lineInterpolation": "linear",
710 | "lineWidth": 1,
711 | "pointSize": 5,
712 | "scaleDistribution": {
713 | "type": "linear"
714 | },
715 | "showPoints": "auto",
716 | "spanNulls": false,
717 | "stacking": {
718 | "group": "A",
719 | "mode": "none"
720 | },
721 | "thresholdsStyle": {
722 | "mode": "off"
723 | }
724 | },
725 | "mappings": [],
726 | "thresholds": {
727 | "mode": "absolute",
728 | "steps": [
729 | {
730 | "color": "green",
731 | "value": null
732 | },
733 | {
734 | "color": "red",
735 | "value": 80
736 | }
737 | ]
738 | }
739 | },
740 | "overrides": []
741 | },
742 | "gridPos": {
743 | "h": 10,
744 | "w": 12,
745 | "x": 12,
746 | "y": 22
747 | },
748 | "id": 12,
749 | "options": {
750 | "legend": {
751 | "calcs": [],
752 | "displayMode": "list",
753 | "placement": "bottom",
754 | "showLegend": true
755 | },
756 | "tooltip": {
757 | "mode": "single",
758 | "sort": "none"
759 | }
760 | },
761 | "targets": [
762 | {
763 | "datasource": {
764 | "type": "prometheus",
765 | "uid": "P1809F7CD0C75ACF3"
766 | },
767 | "editorMode": "builder",
768 | "expr": "rate(go_gc_duration_seconds_count[15s])",
769 | "legendFormat": "__auto",
770 | "range": true,
771 | "refId": "A"
772 | }
773 | ],
774 | "title": "GC",
775 | "type": "timeseries"
776 | },
777 | {
778 | "datasource": {
779 | "type": "prometheus",
780 | "uid": "P1809F7CD0C75ACF3"
781 | },
782 | "fieldConfig": {
783 | "defaults": {
784 | "color": {
785 | "mode": "palette-classic"
786 | },
787 | "custom": {
788 | "axisCenteredZero": false,
789 | "axisColorMode": "text",
790 | "axisLabel": "",
791 | "axisPlacement": "auto",
792 | "barAlignment": 0,
793 | "drawStyle": "line",
794 | "fillOpacity": 0,
795 | "gradientMode": "none",
796 | "hideFrom": {
797 | "legend": false,
798 | "tooltip": false,
799 | "viz": false
800 | },
801 | "lineInterpolation": "linear",
802 | "lineWidth": 1,
803 | "pointSize": 5,
804 | "scaleDistribution": {
805 | "type": "linear"
806 | },
807 | "showPoints": "auto",
808 | "spanNulls": false,
809 | "stacking": {
810 | "group": "A",
811 | "mode": "none"
812 | },
813 | "thresholdsStyle": {
814 | "mode": "off"
815 | }
816 | },
817 | "mappings": [],
818 | "thresholds": {
819 | "mode": "absolute",
820 | "steps": [
821 | {
822 | "color": "green",
823 | "value": null
824 | },
825 | {
826 | "color": "red",
827 | "value": 80
828 | }
829 | ]
830 | }
831 | },
832 | "overrides": []
833 | },
834 | "gridPos": {
835 | "h": 10,
836 | "w": 12,
837 | "x": 0,
838 | "y": 24
839 | },
840 | "id": 10,
841 | "options": {
842 | "legend": {
843 | "calcs": [],
844 | "displayMode": "list",
845 | "placement": "bottom",
846 | "showLegend": true
847 | },
848 | "tooltip": {
849 | "mode": "single",
850 | "sort": "none"
851 | }
852 | },
853 | "targets": [
854 | {
855 | "datasource": {
856 | "type": "prometheus",
857 | "uid": "P1809F7CD0C75ACF3"
858 | },
859 | "editorMode": "builder",
860 | "expr": "go_threads",
861 | "legendFormat": "__auto",
862 | "range": true,
863 | "refId": "A"
864 | }
865 | ],
866 | "title": "threads",
867 | "type": "timeseries"
868 | },
869 | {
870 | "datasource": {
871 | "type": "prometheus",
872 | "uid": "P1809F7CD0C75ACF3"
873 | },
874 | "fieldConfig": {
875 | "defaults": {
876 | "color": {
877 | "mode": "palette-classic"
878 | },
879 | "custom": {
880 | "axisCenteredZero": false,
881 | "axisColorMode": "text",
882 | "axisLabel": "",
883 | "axisPlacement": "auto",
884 | "barAlignment": 0,
885 | "drawStyle": "line",
886 | "fillOpacity": 0,
887 | "gradientMode": "none",
888 | "hideFrom": {
889 | "legend": false,
890 | "tooltip": false,
891 | "viz": false
892 | },
893 | "lineInterpolation": "linear",
894 | "lineWidth": 1,
895 | "pointSize": 5,
896 | "scaleDistribution": {
897 | "type": "linear"
898 | },
899 | "showPoints": "auto",
900 | "spanNulls": false,
901 | "stacking": {
902 | "group": "A",
903 | "mode": "none"
904 | },
905 | "thresholdsStyle": {
906 | "mode": "off"
907 | }
908 | },
909 | "mappings": [],
910 | "thresholds": {
911 | "mode": "absolute",
912 | "steps": [
913 | {
914 | "color": "green",
915 | "value": null
916 | },
917 | {
918 | "color": "red",
919 | "value": 80
920 | }
921 | ]
922 | }
923 | },
924 | "overrides": []
925 | },
926 | "gridPos": {
927 | "h": 10,
928 | "w": 12,
929 | "x": 0,
930 | "y": 34
931 | },
932 | "id": 6,
933 | "options": {
934 | "legend": {
935 | "calcs": [],
936 | "displayMode": "list",
937 | "placement": "bottom",
938 | "showLegend": true
939 | },
940 | "tooltip": {
941 | "mode": "single",
942 | "sort": "none"
943 | }
944 | },
945 | "targets": [
946 | {
947 | "datasource": {
948 | "type": "prometheus",
949 | "uid": "P1809F7CD0C75ACF3"
950 | },
951 | "editorMode": "builder",
952 | "expr": "go_goroutines",
953 | "legendFormat": "__auto",
954 | "range": true,
955 | "refId": "A"
956 | }
957 | ],
958 | "title": "go routines count",
959 | "type": "timeseries"
960 | },
961 | {
962 | "collapsed": false,
963 | "gridPos": {
964 | "h": 1,
965 | "w": 24,
966 | "x": 0,
967 | "y": 44
968 | },
969 | "id": 26,
970 | "panels": [],
971 | "title": "Node",
972 | "type": "row"
973 | },
974 | {
975 | "datasource": {
976 | "type": "prometheus",
977 | "uid": "P1809F7CD0C75ACF3"
978 | },
979 | "description": "",
980 | "fieldConfig": {
981 | "defaults": {
982 | "color": {
983 | "mode": "palette-classic"
984 | },
985 | "custom": {
986 | "axisCenteredZero": false,
987 | "axisColorMode": "text",
988 | "axisLabel": "IO read (-) / write (+)",
989 | "axisPlacement": "auto",
990 | "barAlignment": 0,
991 | "drawStyle": "line",
992 | "fillOpacity": 20,
993 | "gradientMode": "none",
994 | "hideFrom": {
995 | "legend": false,
996 | "tooltip": false,
997 | "viz": false
998 | },
999 | "lineInterpolation": "linear",
1000 | "lineWidth": 1,
1001 | "pointSize": 5,
1002 | "scaleDistribution": {
1003 | "type": "linear"
1004 | },
1005 | "showPoints": "never",
1006 | "spanNulls": false,
1007 | "stacking": {
1008 | "group": "A",
1009 | "mode": "none"
1010 | },
1011 | "thresholdsStyle": {
1012 | "mode": "off"
1013 | }
1014 | },
1015 | "links": [],
1016 | "mappings": [],
1017 | "thresholds": {
1018 | "mode": "absolute",
1019 | "steps": [
1020 | {
1021 | "color": "green",
1022 | "value": null
1023 | },
1024 | {
1025 | "color": "red",
1026 | "value": 80
1027 | }
1028 | ]
1029 | },
1030 | "unit": "iops"
1031 | },
1032 | "overrides": [
1033 | {
1034 | "matcher": {
1035 | "id": "byRegexp",
1036 | "options": "/.*Read.*/"
1037 | },
1038 | "properties": [
1039 | {
1040 | "id": "custom.transform",
1041 | "value": "negative-Y"
1042 | }
1043 | ]
1044 | },
1045 | {
1046 | "matcher": {
1047 | "id": "byRegexp",
1048 | "options": "/.*sda_.*/"
1049 | },
1050 | "properties": [
1051 | {
1052 | "id": "color",
1053 | "value": {
1054 | "fixedColor": "#7EB26D",
1055 | "mode": "fixed"
1056 | }
1057 | }
1058 | ]
1059 | },
1060 | {
1061 | "matcher": {
1062 | "id": "byRegexp",
1063 | "options": "/.*sdb_.*/"
1064 | },
1065 | "properties": [
1066 | {
1067 | "id": "color",
1068 | "value": {
1069 | "fixedColor": "#EAB839",
1070 | "mode": "fixed"
1071 | }
1072 | }
1073 | ]
1074 | },
1075 | {
1076 | "matcher": {
1077 | "id": "byRegexp",
1078 | "options": "/.*sdc_.*/"
1079 | },
1080 | "properties": [
1081 | {
1082 | "id": "color",
1083 | "value": {
1084 | "fixedColor": "#6ED0E0",
1085 | "mode": "fixed"
1086 | }
1087 | }
1088 | ]
1089 | },
1090 | {
1091 | "matcher": {
1092 | "id": "byRegexp",
1093 | "options": "/.*sdd_.*/"
1094 | },
1095 | "properties": [
1096 | {
1097 | "id": "color",
1098 | "value": {
1099 | "fixedColor": "#EF843C",
1100 | "mode": "fixed"
1101 | }
1102 | }
1103 | ]
1104 | },
1105 | {
1106 | "matcher": {
1107 | "id": "byRegexp",
1108 | "options": "/.*sde_.*/"
1109 | },
1110 | "properties": [
1111 | {
1112 | "id": "color",
1113 | "value": {
1114 | "fixedColor": "#E24D42",
1115 | "mode": "fixed"
1116 | }
1117 | }
1118 | ]
1119 | },
1120 | {
1121 | "matcher": {
1122 | "id": "byRegexp",
1123 | "options": "/.*sda1.*/"
1124 | },
1125 | "properties": [
1126 | {
1127 | "id": "color",
1128 | "value": {
1129 | "fixedColor": "#584477",
1130 | "mode": "fixed"
1131 | }
1132 | }
1133 | ]
1134 | },
1135 | {
1136 | "matcher": {
1137 | "id": "byRegexp",
1138 | "options": "/.*sda2_.*/"
1139 | },
1140 | "properties": [
1141 | {
1142 | "id": "color",
1143 | "value": {
1144 | "fixedColor": "#BA43A9",
1145 | "mode": "fixed"
1146 | }
1147 | }
1148 | ]
1149 | },
1150 | {
1151 | "matcher": {
1152 | "id": "byRegexp",
1153 | "options": "/.*sda3_.*/"
1154 | },
1155 | "properties": [
1156 | {
1157 | "id": "color",
1158 | "value": {
1159 | "fixedColor": "#F4D598",
1160 | "mode": "fixed"
1161 | }
1162 | }
1163 | ]
1164 | },
1165 | {
1166 | "matcher": {
1167 | "id": "byRegexp",
1168 | "options": "/.*sdb1.*/"
1169 | },
1170 | "properties": [
1171 | {
1172 | "id": "color",
1173 | "value": {
1174 | "fixedColor": "#0A50A1",
1175 | "mode": "fixed"
1176 | }
1177 | }
1178 | ]
1179 | },
1180 | {
1181 | "matcher": {
1182 | "id": "byRegexp",
1183 | "options": "/.*sdb2.*/"
1184 | },
1185 | "properties": [
1186 | {
1187 | "id": "color",
1188 | "value": {
1189 | "fixedColor": "#BF1B00",
1190 | "mode": "fixed"
1191 | }
1192 | }
1193 | ]
1194 | },
1195 | {
1196 | "matcher": {
1197 | "id": "byRegexp",
1198 | "options": "/.*sdb2.*/"
1199 | },
1200 | "properties": [
1201 | {
1202 | "id": "color",
1203 | "value": {
1204 | "fixedColor": "#BF1B00",
1205 | "mode": "fixed"
1206 | }
1207 | }
1208 | ]
1209 | },
1210 | {
1211 | "matcher": {
1212 | "id": "byRegexp",
1213 | "options": "/.*sdb3.*/"
1214 | },
1215 | "properties": [
1216 | {
1217 | "id": "color",
1218 | "value": {
1219 | "fixedColor": "#E0752D",
1220 | "mode": "fixed"
1221 | }
1222 | }
1223 | ]
1224 | },
1225 | {
1226 | "matcher": {
1227 | "id": "byRegexp",
1228 | "options": "/.*sdc1.*/"
1229 | },
1230 | "properties": [
1231 | {
1232 | "id": "color",
1233 | "value": {
1234 | "fixedColor": "#962D82",
1235 | "mode": "fixed"
1236 | }
1237 | }
1238 | ]
1239 | },
1240 | {
1241 | "matcher": {
1242 | "id": "byRegexp",
1243 | "options": "/.*sdc2.*/"
1244 | },
1245 | "properties": [
1246 | {
1247 | "id": "color",
1248 | "value": {
1249 | "fixedColor": "#614D93",
1250 | "mode": "fixed"
1251 | }
1252 | }
1253 | ]
1254 | },
1255 | {
1256 | "matcher": {
1257 | "id": "byRegexp",
1258 | "options": "/.*sdc3.*/"
1259 | },
1260 | "properties": [
1261 | {
1262 | "id": "color",
1263 | "value": {
1264 | "fixedColor": "#9AC48A",
1265 | "mode": "fixed"
1266 | }
1267 | }
1268 | ]
1269 | },
1270 | {
1271 | "matcher": {
1272 | "id": "byRegexp",
1273 | "options": "/.*sdd1.*/"
1274 | },
1275 | "properties": [
1276 | {
1277 | "id": "color",
1278 | "value": {
1279 | "fixedColor": "#65C5DB",
1280 | "mode": "fixed"
1281 | }
1282 | }
1283 | ]
1284 | },
1285 | {
1286 | "matcher": {
1287 | "id": "byRegexp",
1288 | "options": "/.*sdd2.*/"
1289 | },
1290 | "properties": [
1291 | {
1292 | "id": "color",
1293 | "value": {
1294 | "fixedColor": "#F9934E",
1295 | "mode": "fixed"
1296 | }
1297 | }
1298 | ]
1299 | },
1300 | {
1301 | "matcher": {
1302 | "id": "byRegexp",
1303 | "options": "/.*sdd3.*/"
1304 | },
1305 | "properties": [
1306 | {
1307 | "id": "color",
1308 | "value": {
1309 | "fixedColor": "#EA6460",
1310 | "mode": "fixed"
1311 | }
1312 | }
1313 | ]
1314 | },
1315 | {
1316 | "matcher": {
1317 | "id": "byRegexp",
1318 | "options": "/.*sde1.*/"
1319 | },
1320 | "properties": [
1321 | {
1322 | "id": "color",
1323 | "value": {
1324 | "fixedColor": "#E0F9D7",
1325 | "mode": "fixed"
1326 | }
1327 | }
1328 | ]
1329 | },
1330 | {
1331 | "matcher": {
1332 | "id": "byRegexp",
1333 | "options": "/.*sdd2.*/"
1334 | },
1335 | "properties": [
1336 | {
1337 | "id": "color",
1338 | "value": {
1339 | "fixedColor": "#FCEACA",
1340 | "mode": "fixed"
1341 | }
1342 | }
1343 | ]
1344 | },
1345 | {
1346 | "matcher": {
1347 | "id": "byRegexp",
1348 | "options": "/.*sde3.*/"
1349 | },
1350 | "properties": [
1351 | {
1352 | "id": "color",
1353 | "value": {
1354 | "fixedColor": "#F9E2D2",
1355 | "mode": "fixed"
1356 | }
1357 | }
1358 | ]
1359 | }
1360 | ]
1361 | },
1362 | "gridPos": {
1363 | "h": 12,
1364 | "w": 12,
1365 | "x": 0,
1366 | "y": 45
1367 | },
1368 | "id": 24,
1369 | "links": [],
1370 | "options": {
1371 | "legend": {
1372 | "calcs": [
1373 | "mean",
1374 | "lastNotNull",
1375 | "max",
1376 | "min"
1377 | ],
1378 | "displayMode": "table",
1379 | "placement": "bottom",
1380 | "showLegend": true
1381 | },
1382 | "tooltip": {
1383 | "mode": "single",
1384 | "sort": "none"
1385 | }
1386 | },
1387 | "pluginVersion": "9.2.0",
1388 | "targets": [
1389 | {
1390 | "datasource": {
1391 | "type": "prometheus",
1392 | "uid": "P1809F7CD0C75ACF3"
1393 | },
1394 | "expr": "rate(node_disk_reads_completed_total{instance=\"$node\",job=\"$job\",device=~\"$diskdevices\"}[$__rate_interval])",
1395 | "intervalFactor": 4,
1396 | "legendFormat": "{{device}} - Reads completed",
1397 | "refId": "A",
1398 | "step": 240
1399 | },
1400 | {
1401 | "datasource": {
1402 | "type": "prometheus",
1403 | "uid": "P1809F7CD0C75ACF3"
1404 | },
1405 | "expr": "rate(node_disk_writes_completed_total{instance=\"$node\",job=\"$job\",device=~\"$diskdevices\"}[$__rate_interval])",
1406 | "intervalFactor": 1,
1407 | "legendFormat": "{{device}} - Writes completed",
1408 | "refId": "B",
1409 | "step": 240
1410 | }
1411 | ],
1412 | "title": "Disk IOps",
1413 | "type": "timeseries"
1414 | },
1415 | {
1416 | "datasource": {
1417 | "type": "prometheus",
1418 | "uid": "P1809F7CD0C75ACF3"
1419 | },
1420 | "description": "",
1421 | "fieldConfig": {
1422 | "defaults": {
1423 | "color": {
1424 | "mode": "palette-classic"
1425 | },
1426 | "custom": {
1427 | "axisCenteredZero": false,
1428 | "axisColorMode": "text",
1429 | "axisLabel": "bytes",
1430 | "axisPlacement": "auto",
1431 | "barAlignment": 0,
1432 | "drawStyle": "line",
1433 | "fillOpacity": 40,
1434 | "gradientMode": "none",
1435 | "hideFrom": {
1436 | "legend": false,
1437 | "tooltip": false,
1438 | "viz": false
1439 | },
1440 | "lineInterpolation": "linear",
1441 | "lineWidth": 1,
1442 | "pointSize": 5,
1443 | "scaleDistribution": {
1444 | "type": "linear"
1445 | },
1446 | "showPoints": "never",
1447 | "spanNulls": false,
1448 | "stacking": {
1449 | "group": "A",
1450 | "mode": "normal"
1451 | },
1452 | "thresholdsStyle": {
1453 | "mode": "off"
1454 | }
1455 | },
1456 | "links": [],
1457 | "mappings": [],
1458 | "min": 0,
1459 | "thresholds": {
1460 | "mode": "absolute",
1461 | "steps": [
1462 | {
1463 | "color": "green",
1464 | "value": null
1465 | },
1466 | {
1467 | "color": "red",
1468 | "value": 80
1469 | }
1470 | ]
1471 | },
1472 | "unit": "bytes"
1473 | },
1474 | "overrides": [
1475 | {
1476 | "matcher": {
1477 | "id": "byName",
1478 | "options": "Apps"
1479 | },
1480 | "properties": [
1481 | {
1482 | "id": "color",
1483 | "value": {
1484 | "fixedColor": "#629E51",
1485 | "mode": "fixed"
1486 | }
1487 | }
1488 | ]
1489 | },
1490 | {
1491 | "matcher": {
1492 | "id": "byName",
1493 | "options": "Buffers"
1494 | },
1495 | "properties": [
1496 | {
1497 | "id": "color",
1498 | "value": {
1499 | "fixedColor": "#614D93",
1500 | "mode": "fixed"
1501 | }
1502 | }
1503 | ]
1504 | },
1505 | {
1506 | "matcher": {
1507 | "id": "byName",
1508 | "options": "Cache"
1509 | },
1510 | "properties": [
1511 | {
1512 | "id": "color",
1513 | "value": {
1514 | "fixedColor": "#6D1F62",
1515 | "mode": "fixed"
1516 | }
1517 | }
1518 | ]
1519 | },
1520 | {
1521 | "matcher": {
1522 | "id": "byName",
1523 | "options": "Cached"
1524 | },
1525 | "properties": [
1526 | {
1527 | "id": "color",
1528 | "value": {
1529 | "fixedColor": "#511749",
1530 | "mode": "fixed"
1531 | }
1532 | }
1533 | ]
1534 | },
1535 | {
1536 | "matcher": {
1537 | "id": "byName",
1538 | "options": "Committed"
1539 | },
1540 | "properties": [
1541 | {
1542 | "id": "color",
1543 | "value": {
1544 | "fixedColor": "#508642",
1545 | "mode": "fixed"
1546 | }
1547 | }
1548 | ]
1549 | },
1550 | {
1551 | "matcher": {
1552 | "id": "byName",
1553 | "options": "Free"
1554 | },
1555 | "properties": [
1556 | {
1557 | "id": "color",
1558 | "value": {
1559 | "fixedColor": "#0A437C",
1560 | "mode": "fixed"
1561 | }
1562 | }
1563 | ]
1564 | },
1565 | {
1566 | "matcher": {
1567 | "id": "byName",
1568 | "options": "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working"
1569 | },
1570 | "properties": [
1571 | {
1572 | "id": "color",
1573 | "value": {
1574 | "fixedColor": "#CFFAFF",
1575 | "mode": "fixed"
1576 | }
1577 | }
1578 | ]
1579 | },
1580 | {
1581 | "matcher": {
1582 | "id": "byName",
1583 | "options": "Inactive"
1584 | },
1585 | "properties": [
1586 | {
1587 | "id": "color",
1588 | "value": {
1589 | "fixedColor": "#584477",
1590 | "mode": "fixed"
1591 | }
1592 | }
1593 | ]
1594 | },
1595 | {
1596 | "matcher": {
1597 | "id": "byName",
1598 | "options": "PageTables"
1599 | },
1600 | "properties": [
1601 | {
1602 | "id": "color",
1603 | "value": {
1604 | "fixedColor": "#0A50A1",
1605 | "mode": "fixed"
1606 | }
1607 | }
1608 | ]
1609 | },
1610 | {
1611 | "matcher": {
1612 | "id": "byName",
1613 | "options": "Page_Tables"
1614 | },
1615 | "properties": [
1616 | {
1617 | "id": "color",
1618 | "value": {
1619 | "fixedColor": "#0A50A1",
1620 | "mode": "fixed"
1621 | }
1622 | }
1623 | ]
1624 | },
1625 | {
1626 | "matcher": {
1627 | "id": "byName",
1628 | "options": "RAM_Free"
1629 | },
1630 | "properties": [
1631 | {
1632 | "id": "color",
1633 | "value": {
1634 | "fixedColor": "#E0F9D7",
1635 | "mode": "fixed"
1636 | }
1637 | }
1638 | ]
1639 | },
1640 | {
1641 | "matcher": {
1642 | "id": "byName",
1643 | "options": "Slab"
1644 | },
1645 | "properties": [
1646 | {
1647 | "id": "color",
1648 | "value": {
1649 | "fixedColor": "#806EB7",
1650 | "mode": "fixed"
1651 | }
1652 | }
1653 | ]
1654 | },
1655 | {
1656 | "matcher": {
1657 | "id": "byName",
1658 | "options": "Slab_Cache"
1659 | },
1660 | "properties": [
1661 | {
1662 | "id": "color",
1663 | "value": {
1664 | "fixedColor": "#E0752D",
1665 | "mode": "fixed"
1666 | }
1667 | }
1668 | ]
1669 | },
1670 | {
1671 | "matcher": {
1672 | "id": "byName",
1673 | "options": "Swap"
1674 | },
1675 | "properties": [
1676 | {
1677 | "id": "color",
1678 | "value": {
1679 | "fixedColor": "#BF1B00",
1680 | "mode": "fixed"
1681 | }
1682 | }
1683 | ]
1684 | },
1685 | {
1686 | "matcher": {
1687 | "id": "byName",
1688 | "options": "Swap - Swap memory usage"
1689 | },
1690 | "properties": [
1691 | {
1692 | "id": "color",
1693 | "value": {
1694 | "fixedColor": "#BF1B00",
1695 | "mode": "fixed"
1696 | }
1697 | }
1698 | ]
1699 | },
1700 | {
1701 | "matcher": {
1702 | "id": "byName",
1703 | "options": "Swap_Cache"
1704 | },
1705 | "properties": [
1706 | {
1707 | "id": "color",
1708 | "value": {
1709 | "fixedColor": "#C15C17",
1710 | "mode": "fixed"
1711 | }
1712 | }
1713 | ]
1714 | },
1715 | {
1716 | "matcher": {
1717 | "id": "byName",
1718 | "options": "Swap_Free"
1719 | },
1720 | "properties": [
1721 | {
1722 | "id": "color",
1723 | "value": {
1724 | "fixedColor": "#2F575E",
1725 | "mode": "fixed"
1726 | }
1727 | }
1728 | ]
1729 | },
1730 | {
1731 | "matcher": {
1732 | "id": "byName",
1733 | "options": "Unused"
1734 | },
1735 | "properties": [
1736 | {
1737 | "id": "color",
1738 | "value": {
1739 | "fixedColor": "#EAB839",
1740 | "mode": "fixed"
1741 | }
1742 | }
1743 | ]
1744 | },
1745 | {
1746 | "matcher": {
1747 | "id": "byName",
1748 | "options": "Unused - Free memory unassigned"
1749 | },
1750 | "properties": [
1751 | {
1752 | "id": "color",
1753 | "value": {
1754 | "fixedColor": "#052B51",
1755 | "mode": "fixed"
1756 | }
1757 | }
1758 | ]
1759 | },
1760 | {
1761 | "matcher": {
1762 | "id": "byRegexp",
1763 | "options": "/.*Hardware Corrupted - *./"
1764 | },
1765 | "properties": [
1766 | {
1767 | "id": "custom.stacking",
1768 | "value": {
1769 | "group": false,
1770 | "mode": "normal"
1771 | }
1772 | }
1773 | ]
1774 | },
1775 | {
1776 | "__systemRef": "hideSeriesFrom",
1777 | "matcher": {
1778 | "id": "byNames",
1779 | "options": {
1780 | "mode": "exclude",
1781 | "names": [
1782 | "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working"
1783 | ],
1784 | "prefix": "All except:",
1785 | "readOnly": true
1786 | }
1787 | },
1788 | "properties": [
1789 | {
1790 | "id": "custom.hideFrom",
1791 | "value": {
1792 | "legend": false,
1793 | "tooltip": false,
1794 | "viz": true
1795 | }
1796 | }
1797 | ]
1798 | }
1799 | ]
1800 | },
1801 | "gridPos": {
1802 | "h": 14,
1803 | "w": 12,
1804 | "x": 12,
1805 | "y": 45
1806 | },
1807 | "id": 16,
1808 | "links": [],
1809 | "options": {
1810 | "legend": {
1811 | "calcs": [
1812 | "mean",
1813 | "lastNotNull",
1814 | "max",
1815 | "min"
1816 | ],
1817 | "displayMode": "table",
1818 | "placement": "bottom",
1819 | "showLegend": true,
1820 | "width": 350
1821 | },
1822 | "tooltip": {
1823 | "mode": "multi",
1824 | "sort": "none"
1825 | }
1826 | },
1827 | "pluginVersion": "9.2.0",
1828 | "targets": [
1829 | {
1830 | "datasource": {
1831 | "type": "prometheus",
1832 | "uid": "P1809F7CD0C75ACF3"
1833 | },
1834 | "expr": "node_memory_MemTotal_bytes{instance=\"$node\",job=\"$job\"} - node_memory_MemFree_bytes{instance=\"$node\",job=\"$job\"} - node_memory_Buffers_bytes{instance=\"$node\",job=\"$job\"} - node_memory_Cached_bytes{instance=\"$node\",job=\"$job\"} - node_memory_Slab_bytes{instance=\"$node\",job=\"$job\"} - node_memory_PageTables_bytes{instance=\"$node\",job=\"$job\"} - node_memory_SwapCached_bytes{instance=\"$node\",job=\"$job\"}",
1835 | "format": "time_series",
1836 | "hide": false,
1837 | "intervalFactor": 1,
1838 | "legendFormat": "Apps - Memory used by user-space applications",
1839 | "refId": "A",
1840 | "step": 240
1841 | },
1842 | {
1843 | "datasource": {
1844 | "type": "prometheus",
1845 | "uid": "P1809F7CD0C75ACF3"
1846 | },
1847 | "expr": "node_memory_PageTables_bytes{instance=\"$node\",job=\"$job\"}",
1848 | "format": "time_series",
1849 | "hide": false,
1850 | "intervalFactor": 1,
1851 | "legendFormat": "PageTables - Memory used to map between virtual and physical memory addresses",
1852 | "refId": "B",
1853 | "step": 240
1854 | },
1855 | {
1856 | "datasource": {
1857 | "type": "prometheus",
1858 | "uid": "P1809F7CD0C75ACF3"
1859 | },
1860 | "expr": "node_memory_SwapCached_bytes{instance=\"$node\",job=\"$job\"}",
1861 | "format": "time_series",
1862 | "intervalFactor": 1,
1863 | "legendFormat": "SwapCache - Memory that keeps track of pages that have been fetched from swap but not yet been modified",
1864 | "refId": "C",
1865 | "step": 240
1866 | },
1867 | {
1868 | "datasource": {
1869 | "type": "prometheus",
1870 | "uid": "P1809F7CD0C75ACF3"
1871 | },
1872 | "expr": "node_memory_Slab_bytes{instance=\"$node\",job=\"$job\"}",
1873 | "format": "time_series",
1874 | "hide": false,
1875 | "intervalFactor": 1,
1876 | "legendFormat": "Slab - Memory used by the kernel to cache data structures for its own use (caches like inode, dentry, etc)",
1877 | "refId": "D",
1878 | "step": 240
1879 | },
1880 | {
1881 | "datasource": {
1882 | "type": "prometheus",
1883 | "uid": "P1809F7CD0C75ACF3"
1884 | },
1885 | "expr": "node_memory_Cached_bytes{instance=\"$node\",job=\"$job\"}",
1886 | "format": "time_series",
1887 | "hide": false,
1888 | "intervalFactor": 1,
1889 | "legendFormat": "Cache - Parked file data (file content) cache",
1890 | "refId": "E",
1891 | "step": 240
1892 | },
1893 | {
1894 | "datasource": {
1895 | "type": "prometheus",
1896 | "uid": "P1809F7CD0C75ACF3"
1897 | },
1898 | "expr": "node_memory_Buffers_bytes{instance=\"$node\",job=\"$job\"}",
1899 | "format": "time_series",
1900 | "hide": false,
1901 | "intervalFactor": 1,
1902 | "legendFormat": "Buffers - Block device (e.g. harddisk) cache",
1903 | "refId": "F",
1904 | "step": 240
1905 | },
1906 | {
1907 | "datasource": {
1908 | "type": "prometheus",
1909 | "uid": "P1809F7CD0C75ACF3"
1910 | },
1911 | "expr": "node_memory_MemFree_bytes{instance=\"$node\",job=\"$job\"}",
1912 | "format": "time_series",
1913 | "hide": false,
1914 | "intervalFactor": 1,
1915 | "legendFormat": "Unused - Free memory unassigned",
1916 | "refId": "G",
1917 | "step": 240
1918 | },
1919 | {
1920 | "datasource": {
1921 | "type": "prometheus",
1922 | "uid": "P1809F7CD0C75ACF3"
1923 | },
1924 | "expr": "(node_memory_SwapTotal_bytes{instance=\"$node\",job=\"$job\"} - node_memory_SwapFree_bytes{instance=\"$node\",job=\"$job\"})",
1925 | "format": "time_series",
1926 | "hide": false,
1927 | "intervalFactor": 1,
1928 | "legendFormat": "Swap - Swap space used",
1929 | "refId": "H",
1930 | "step": 240
1931 | },
1932 | {
1933 | "datasource": {
1934 | "type": "prometheus",
1935 | "uid": "P1809F7CD0C75ACF3"
1936 | },
1937 | "expr": "node_memory_HardwareCorrupted_bytes{instance=\"$node\",job=\"$job\"}",
1938 | "format": "time_series",
1939 | "hide": false,
1940 | "intervalFactor": 1,
1941 | "legendFormat": "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working",
1942 | "refId": "I",
1943 | "step": 240
1944 | }
1945 | ],
1946 | "title": "Memory Stack",
1947 | "type": "timeseries"
1948 | },
1949 | {
1950 | "datasource": {
1951 | "type": "prometheus",
1952 | "uid": "P1809F7CD0C75ACF3"
1953 | },
1954 | "description": "",
1955 | "fieldConfig": {
1956 | "defaults": {
1957 | "color": {
1958 | "mode": "palette-classic"
1959 | },
1960 | "custom": {
1961 | "axisCenteredZero": false,
1962 | "axisColorMode": "text",
1963 | "axisLabel": "bytes",
1964 | "axisPlacement": "auto",
1965 | "barAlignment": 0,
1966 | "drawStyle": "line",
1967 | "fillOpacity": 40,
1968 | "gradientMode": "none",
1969 | "hideFrom": {
1970 | "legend": false,
1971 | "tooltip": false,
1972 | "viz": false
1973 | },
1974 | "lineInterpolation": "linear",
1975 | "lineWidth": 1,
1976 | "pointSize": 5,
1977 | "scaleDistribution": {
1978 | "type": "linear"
1979 | },
1980 | "showPoints": "never",
1981 | "spanNulls": false,
1982 | "stacking": {
1983 | "group": "A",
1984 | "mode": "none"
1985 | },
1986 | "thresholdsStyle": {
1987 | "mode": "off"
1988 | }
1989 | },
1990 | "links": [],
1991 | "mappings": [],
1992 | "min": 0,
1993 | "thresholds": {
1994 | "mode": "absolute",
1995 | "steps": [
1996 | {
1997 | "color": "green",
1998 | "value": null
1999 | },
2000 | {
2001 | "color": "red",
2002 | "value": 80
2003 | }
2004 | ]
2005 | },
2006 | "unit": "bytes"
2007 | },
2008 | "overrides": []
2009 | },
2010 | "gridPos": {
2011 | "h": 12,
2012 | "w": 12,
2013 | "x": 0,
2014 | "y": 57
2015 | },
2016 | "id": 20,
2017 | "links": [],
2018 | "options": {
2019 | "legend": {
2020 | "calcs": [
2021 | "mean",
2022 | "lastNotNull",
2023 | "max",
2024 | "min"
2025 | ],
2026 | "displayMode": "table",
2027 | "placement": "bottom",
2028 | "showLegend": true
2029 | },
2030 | "tooltip": {
2031 | "mode": "multi",
2032 | "sort": "none"
2033 | }
2034 | },
2035 | "pluginVersion": "9.2.0",
2036 | "targets": [
2037 | {
2038 | "datasource": {
2039 | "type": "prometheus",
2040 | "uid": "P1809F7CD0C75ACF3"
2041 | },
2042 | "expr": "node_filesystem_size_bytes{instance=\"$node\",job=\"$job\",device!~'rootfs'} - node_filesystem_avail_bytes{instance=\"$node\",job=\"$job\",device!~'rootfs'}",
2043 | "format": "time_series",
2044 | "intervalFactor": 1,
2045 | "legendFormat": "{{mountpoint}}",
2046 | "refId": "A",
2047 | "step": 240
2048 | }
2049 | ],
2050 | "title": "Disk Space Used",
2051 | "type": "timeseries"
2052 | },
2053 | {
2054 | "datasource": {
2055 | "type": "prometheus",
2056 | "uid": "P1809F7CD0C75ACF3"
2057 | },
2058 | "fieldConfig": {
2059 | "defaults": {
2060 | "color": {
2061 | "mode": "palette-classic"
2062 | },
2063 | "custom": {
2064 | "axisCenteredZero": false,
2065 | "axisColorMode": "text",
2066 | "axisLabel": "bits out (-) / in (+)",
2067 | "axisPlacement": "auto",
2068 | "barAlignment": 0,
2069 | "drawStyle": "line",
2070 | "fillOpacity": 40,
2071 | "gradientMode": "none",
2072 | "hideFrom": {
2073 | "legend": false,
2074 | "tooltip": false,
2075 | "viz": false
2076 | },
2077 | "lineInterpolation": "linear",
2078 | "lineWidth": 1,
2079 | "pointSize": 5,
2080 | "scaleDistribution": {
2081 | "type": "linear"
2082 | },
2083 | "showPoints": "never",
2084 | "spanNulls": false,
2085 | "stacking": {
2086 | "group": "A",
2087 | "mode": "none"
2088 | },
2089 | "thresholdsStyle": {
2090 | "mode": "off"
2091 | }
2092 | },
2093 | "links": [],
2094 | "mappings": [],
2095 | "thresholds": {
2096 | "mode": "absolute",
2097 | "steps": [
2098 | {
2099 | "color": "green",
2100 | "value": null
2101 | },
2102 | {
2103 | "color": "red",
2104 | "value": 80
2105 | }
2106 | ]
2107 | },
2108 | "unit": "bps"
2109 | },
2110 | "overrides": [
2111 | {
2112 | "matcher": {
2113 | "id": "byName",
2114 | "options": "receive_packets_eth0"
2115 | },
2116 | "properties": [
2117 | {
2118 | "id": "color",
2119 | "value": {
2120 | "fixedColor": "#7EB26D",
2121 | "mode": "fixed"
2122 | }
2123 | }
2124 | ]
2125 | },
2126 | {
2127 | "matcher": {
2128 | "id": "byName",
2129 | "options": "receive_packets_lo"
2130 | },
2131 | "properties": [
2132 | {
2133 | "id": "color",
2134 | "value": {
2135 | "fixedColor": "#E24D42",
2136 | "mode": "fixed"
2137 | }
2138 | }
2139 | ]
2140 | },
2141 | {
2142 | "matcher": {
2143 | "id": "byName",
2144 | "options": "transmit_packets_eth0"
2145 | },
2146 | "properties": [
2147 | {
2148 | "id": "color",
2149 | "value": {
2150 | "fixedColor": "#7EB26D",
2151 | "mode": "fixed"
2152 | }
2153 | }
2154 | ]
2155 | },
2156 | {
2157 | "matcher": {
2158 | "id": "byName",
2159 | "options": "transmit_packets_lo"
2160 | },
2161 | "properties": [
2162 | {
2163 | "id": "color",
2164 | "value": {
2165 | "fixedColor": "#E24D42",
2166 | "mode": "fixed"
2167 | }
2168 | }
2169 | ]
2170 | },
2171 | {
2172 | "matcher": {
2173 | "id": "byRegexp",
2174 | "options": "/.*Trans.*/"
2175 | },
2176 | "properties": [
2177 | {
2178 | "id": "custom.transform",
2179 | "value": "negative-Y"
2180 | }
2181 | ]
2182 | }
2183 | ]
2184 | },
2185 | "gridPos": {
2186 | "h": 12,
2187 | "w": 12,
2188 | "x": 12,
2189 | "y": 59
2190 | },
2191 | "id": 22,
2192 | "links": [],
2193 | "options": {
2194 | "legend": {
2195 | "calcs": [
2196 | "mean",
2197 | "lastNotNull",
2198 | "max",
2199 | "min"
2200 | ],
2201 | "displayMode": "table",
2202 | "placement": "bottom",
2203 | "showLegend": true
2204 | },
2205 | "tooltip": {
2206 | "mode": "multi",
2207 | "sort": "none"
2208 | }
2209 | },
2210 | "pluginVersion": "9.2.0",
2211 | "targets": [
2212 | {
2213 | "datasource": {
2214 | "type": "prometheus",
2215 | "uid": "P1809F7CD0C75ACF3"
2216 | },
2217 | "expr": "rate(node_network_receive_bytes_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])*8",
2218 | "format": "time_series",
2219 | "intervalFactor": 1,
2220 | "legendFormat": "{{device}} - Receive",
2221 | "refId": "A",
2222 | "step": 240
2223 | },
2224 | {
2225 | "datasource": {
2226 | "type": "prometheus",
2227 | "uid": "P1809F7CD0C75ACF3"
2228 | },
2229 | "expr": "rate(node_network_transmit_bytes_total{instance=\"$node\",job=\"$job\"}[$__rate_interval])*8",
2230 | "format": "time_series",
2231 | "intervalFactor": 1,
2232 | "legendFormat": "{{device}} - Transmit",
2233 | "refId": "B",
2234 | "step": 240
2235 | }
2236 | ],
2237 | "title": "Network Traffic",
2238 | "type": "timeseries"
2239 | },
2240 | {
2241 | "datasource": {
2242 | "type": "prometheus",
2243 | "uid": "P1809F7CD0C75ACF3"
2244 | },
2245 | "description": "",
2246 | "fieldConfig": {
2247 | "defaults": {
2248 | "color": {
2249 | "mode": "palette-classic"
2250 | },
2251 | "custom": {
2252 | "axisCenteredZero": false,
2253 | "axisColorMode": "text",
2254 | "axisLabel": "bytes read (-) / write (+)",
2255 | "axisPlacement": "auto",
2256 | "barAlignment": 0,
2257 | "drawStyle": "line",
2258 | "fillOpacity": 40,
2259 | "gradientMode": "none",
2260 | "hideFrom": {
2261 | "legend": false,
2262 | "tooltip": false,
2263 | "viz": false
2264 | },
2265 | "lineInterpolation": "linear",
2266 | "lineWidth": 1,
2267 | "pointSize": 5,
2268 | "scaleDistribution": {
2269 | "type": "linear"
2270 | },
2271 | "showPoints": "never",
2272 | "spanNulls": false,
2273 | "stacking": {
2274 | "group": "A",
2275 | "mode": "none"
2276 | },
2277 | "thresholdsStyle": {
2278 | "mode": "off"
2279 | }
2280 | },
2281 | "links": [],
2282 | "mappings": [],
2283 | "thresholds": {
2284 | "mode": "absolute",
2285 | "steps": [
2286 | {
2287 | "color": "green"
2288 | },
2289 | {
2290 | "color": "red",
2291 | "value": 80
2292 | }
2293 | ]
2294 | },
2295 | "unit": "Bps"
2296 | },
2297 | "overrides": [
2298 | {
2299 | "matcher": {
2300 | "id": "byName",
2301 | "options": "io time"
2302 | },
2303 | "properties": [
2304 | {
2305 | "id": "color",
2306 | "value": {
2307 | "fixedColor": "#890F02",
2308 | "mode": "fixed"
2309 | }
2310 | }
2311 | ]
2312 | },
2313 | {
2314 | "matcher": {
2315 | "id": "byRegexp",
2316 | "options": "/.*read*./"
2317 | },
2318 | "properties": [
2319 | {
2320 | "id": "custom.transform",
2321 | "value": "negative-Y"
2322 | }
2323 | ]
2324 | },
2325 | {
2326 | "matcher": {
2327 | "id": "byRegexp",
2328 | "options": "/.*sda.*/"
2329 | },
2330 | "properties": [
2331 | {
2332 | "id": "color",
2333 | "value": {
2334 | "fixedColor": "#7EB26D",
2335 | "mode": "fixed"
2336 | }
2337 | }
2338 | ]
2339 | },
2340 | {
2341 | "matcher": {
2342 | "id": "byRegexp",
2343 | "options": "/.*sdb.*/"
2344 | },
2345 | "properties": [
2346 | {
2347 | "id": "color",
2348 | "value": {
2349 | "fixedColor": "#EAB839",
2350 | "mode": "fixed"
2351 | }
2352 | }
2353 | ]
2354 | },
2355 | {
2356 | "matcher": {
2357 | "id": "byRegexp",
2358 | "options": "/.*sdc.*/"
2359 | },
2360 | "properties": [
2361 | {
2362 | "id": "color",
2363 | "value": {
2364 | "fixedColor": "#6ED0E0",
2365 | "mode": "fixed"
2366 | }
2367 | }
2368 | ]
2369 | },
2370 | {
2371 | "matcher": {
2372 | "id": "byRegexp",
2373 | "options": "/.*sdd.*/"
2374 | },
2375 | "properties": [
2376 | {
2377 | "id": "color",
2378 | "value": {
2379 | "fixedColor": "#EF843C",
2380 | "mode": "fixed"
2381 | }
2382 | }
2383 | ]
2384 | },
2385 | {
2386 | "matcher": {
2387 | "id": "byRegexp",
2388 | "options": "/.*sde.*/"
2389 | },
2390 | "properties": [
2391 | {
2392 | "id": "color",
2393 | "value": {
2394 | "fixedColor": "#E24D42",
2395 | "mode": "fixed"
2396 | }
2397 | }
2398 | ]
2399 | },
2400 | {
2401 | "matcher": {
2402 | "id": "byType",
2403 | "options": "time"
2404 | },
2405 | "properties": [
2406 | {
2407 | "id": "custom.axisPlacement",
2408 | "value": "hidden"
2409 | }
2410 | ]
2411 | }
2412 | ]
2413 | },
2414 | "gridPos": {
2415 | "h": 12,
2416 | "w": 12,
2417 | "x": 12,
2418 | "y": 71
2419 | },
2420 | "id": 18,
2421 | "links": [],
2422 | "options": {
2423 | "legend": {
2424 | "calcs": [
2425 | "mean",
2426 | "lastNotNull",
2427 | "max",
2428 | "min"
2429 | ],
2430 | "displayMode": "table",
2431 | "placement": "bottom",
2432 | "showLegend": true
2433 | },
2434 | "tooltip": {
2435 | "mode": "multi",
2436 | "sort": "none"
2437 | }
2438 | },
2439 | "pluginVersion": "9.2.0",
2440 | "targets": [
2441 | {
2442 | "datasource": {
2443 | "type": "prometheus",
2444 | "uid": "P1809F7CD0C75ACF3"
2445 | },
2446 | "expr": "rate(node_disk_read_bytes_total{instance=\"$node\",job=\"$job\",device=~\"$diskdevices\"}[$__rate_interval])",
2447 | "format": "time_series",
2448 | "hide": false,
2449 | "intervalFactor": 1,
2450 | "legendFormat": "{{device}} - Successfully read bytes",
2451 | "refId": "A",
2452 | "step": 240
2453 | },
2454 | {
2455 | "datasource": {
2456 | "type": "prometheus",
2457 | "uid": "P1809F7CD0C75ACF3"
2458 | },
2459 | "expr": "rate(node_disk_written_bytes_total{instance=\"$node\",job=\"$job\",device=~\"$diskdevices\"}[$__rate_interval])",
2460 | "format": "time_series",
2461 | "hide": false,
2462 | "intervalFactor": 1,
2463 | "legendFormat": "{{device}} - Successfully written bytes",
2464 | "refId": "B",
2465 | "step": 240
2466 | }
2467 | ],
2468 | "title": "I/O Usage Read / Write",
2469 | "type": "timeseries"
2470 | }
2471 | ],
2472 | "refresh": false,
2473 | "schemaVersion": 37,
2474 | "style": "dark",
2475 | "tags": [],
2476 | "templating": {
2477 | "list": [
2478 | {
2479 | "current": {
2480 | "selected": false,
2481 | "text": "node",
2482 | "value": "node"
2483 | },
2484 | "datasource": {
2485 | "type": "prometheus",
2486 | "uid": "P1809F7CD0C75ACF3"
2487 | },
2488 | "definition": "label_values(node_uname_info, job)",
2489 | "hide": 0,
2490 | "includeAll": false,
2491 | "label": "Job",
2492 | "multi": false,
2493 | "name": "job",
2494 | "options": [],
2495 | "query": {
2496 | "query": "label_values(node_uname_info, job)",
2497 | "refId": "StandardVariableQuery"
2498 | },
2499 | "refresh": 1,
2500 | "regex": "",
2501 | "skipUrlSync": false,
2502 | "sort": 1,
2503 | "type": "query"
2504 | },
2505 | {
2506 | "current": {
2507 | "selected": false,
2508 | "text": "prometheus",
2509 | "value": "prometheus"
2510 | },
2511 | "hide": 0,
2512 | "includeAll": false,
2513 | "label": "datasource",
2514 | "multi": false,
2515 | "name": "DS_PROMETHEUS",
2516 | "options": [],
2517 | "query": "prometheus",
2518 | "refresh": 1,
2519 | "regex": "",
2520 | "skipUrlSync": false,
2521 | "type": "datasource"
2522 | },
2523 | {
2524 | "current": {
2525 | "selected": false,
2526 | "text": "10.1.0.4:9100",
2527 | "value": "10.1.0.4:9100"
2528 | },
2529 | "datasource": {
2530 | "type": "prometheus",
2531 | "uid": "P1809F7CD0C75ACF3"
2532 | },
2533 | "definition": "label_values(node_uname_info{job=\"$job\"}, instance)",
2534 | "hide": 0,
2535 | "includeAll": false,
2536 | "label": "Host:",
2537 | "multi": false,
2538 | "name": "node",
2539 | "options": [],
2540 | "query": {
2541 | "query": "label_values(node_uname_info{job=\"$job\"}, instance)",
2542 | "refId": "StandardVariableQuery"
2543 | },
2544 | "refresh": 1,
2545 | "regex": "",
2546 | "skipUrlSync": false,
2547 | "sort": 1,
2548 | "type": "query"
2549 | },
2550 | {
2551 | "current": {
2552 | "selected": false,
2553 | "text": "[a-z]+|nvme[0-9]+n[0-9]+|mmcblk[0-9]+",
2554 | "value": "[a-z]+|nvme[0-9]+n[0-9]+|mmcblk[0-9]+"
2555 | },
2556 | "hide": 0,
2557 | "includeAll": false,
2558 | "multi": false,
2559 | "name": "diskdevices",
2560 | "options": [
2561 | {
2562 | "selected": true,
2563 | "text": "[a-z]+|nvme[0-9]+n[0-9]+|mmcblk[0-9]+",
2564 | "value": "[a-z]+|nvme[0-9]+n[0-9]+|mmcblk[0-9]+"
2565 | }
2566 | ],
2567 | "query": "[a-z]+|nvme[0-9]+n[0-9]+|mmcblk[0-9]+",
2568 | "skipUrlSync": false,
2569 | "type": "custom"
2570 | }
2571 | ]
2572 | },
2573 | "time": {
2574 | "from": "now-30m",
2575 | "to": "now"
2576 | },
2577 | "timepicker": {},
2578 | "timezone": "",
2579 | "title": "http dashboard",
2580 | "uid": "70gF87v4k",
2581 | "version": 1,
2582 | "weekStart": ""
2583 | }
--------------------------------------------------------------------------------