forked from vikunja/vikunja
Compare commits
20 Commits
renovate/g
...
master
Author | SHA1 | Date | |
---|---|---|---|
5b0628233d | |||
c6980a390f | |||
2859c71253 | |||
150c3f032c | |||
bfc4dd05ed | |||
cd812b4232 | |||
e4f150bbe3 | |||
db0126968a | |||
c12bac0c96 | |||
fba333866d | |||
d02d413c5e | |||
c51662c270 | |||
021e3e307b | |||
b4cdb75d15 | |||
ad6ef03c0c | |||
5930d5aabf | |||
3c5925c827 | |||
b7c8c1f533 | |||
bf41b2ed9f | |||
525a547500 |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -20,3 +20,4 @@ docs/resources/
|
||||||
pkg/static/templates_vfsdata.go
|
pkg/static/templates_vfsdata.go
|
||||||
files/
|
files/
|
||||||
!pkg/files/
|
!pkg/files/
|
||||||
|
vikunja-dump*
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -19,7 +19,7 @@ GOFMT ?= gofmt -s
|
||||||
GOFLAGS := -v -mod=vendor
|
GOFLAGS := -v -mod=vendor
|
||||||
EXTRA_GOFLAGS ?=
|
EXTRA_GOFLAGS ?=
|
||||||
|
|
||||||
LDFLAGS := -X "code.vikunja.io/api/pkg/version.Version=$(shell git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')" -X "main.Tags=$(TAGS)" -X "code.vikunja.io/api/pkg/version.BuildTime=$(shell date -R)"
|
LDFLAGS := -X "code.vikunja.io/api/pkg/version.Version=$(shell git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')" -X "main.Tags=$(TAGS)"
|
||||||
|
|
||||||
PACKAGES ?= $(filter-out code.vikunja.io/api/pkg/integrations,$(shell go list -mod=vendor ./... | grep -v /vendor/))
|
PACKAGES ?= $(filter-out code.vikunja.io/api/pkg/integrations,$(shell go list -mod=vendor ./... | grep -v /vendor/))
|
||||||
SOURCES ?= $(shell find . -name "*.go" -type f)
|
SOURCES ?= $(shell find . -name "*.go" -type f)
|
||||||
|
|
|
@ -32,6 +32,8 @@ service:
|
||||||
enabletaskcomments: true
|
enabletaskcomments: true
|
||||||
# Whether totp is enabled. In most cases you want to leave that enabled.
|
# Whether totp is enabled. In most cases you want to leave that enabled.
|
||||||
enabletotp: true
|
enabletotp: true
|
||||||
|
# If not empty, enables logging of crashes and unhandled errors in sentry.
|
||||||
|
sentrydsn: ''
|
||||||
|
|
||||||
database:
|
database:
|
||||||
# Database type to use. Supported types are mysql, postgres and sqlite.
|
# Database type to use. Supported types are mysql, postgres and sqlite.
|
||||||
|
|
|
@ -16,9 +16,9 @@ params:
|
||||||
description: The to-do app to organize your life
|
description: The to-do app to organize your life
|
||||||
author: The Vikunja Authors
|
author: The Vikunja Authors
|
||||||
website: https://vikunja.io
|
website: https://vikunja.io
|
||||||
fanthomEnabled: false
|
plausibleEnabled: true
|
||||||
fathomUrl: fathom.kolaente.de
|
plausibleDomain: vikunja.io
|
||||||
fathomSiteID: RYKSD
|
plausibleURL: https://analytics.kolaente.de
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
page:
|
page:
|
||||||
|
|
|
@ -75,6 +75,8 @@ service:
|
||||||
enabletaskcomments: true
|
enabletaskcomments: true
|
||||||
# Whether totp is enabled. In most cases you want to leave that enabled.
|
# Whether totp is enabled. In most cases you want to leave that enabled.
|
||||||
enabletotp: true
|
enabletotp: true
|
||||||
|
# If not empty, enables logging of crashes and unhandled errors in sentry.
|
||||||
|
sentrydsn: ''
|
||||||
|
|
||||||
database:
|
database:
|
||||||
# Database type to use. Supported types are mysql, postgres and sqlite.
|
# Database type to use. Supported types are mysql, postgres and sqlite.
|
||||||
|
|
|
@ -218,3 +218,57 @@ services:
|
||||||
- frontend
|
- frontend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
{{< /highlight >}}
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
## Example with Caddy v2 as proxy
|
||||||
|
|
||||||
|
You will need the following `Caddyfile` on your host (or elsewhere, but then you'd need to adjust the proxy mount at the bottom of the compose file):
|
||||||
|
|
||||||
|
{{< highlight conf >}}
|
||||||
|
vikunja.example.com {
|
||||||
|
reverse_proxy /api/* api:3456
|
||||||
|
reverse_proxy frontend:80
|
||||||
|
}
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
`docker-compose.yml` config:
|
||||||
|
|
||||||
|
{{< highlight yaml >}}
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: mariadb:10
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: supersecret
|
||||||
|
MYSQL_DATABASE: vikunja
|
||||||
|
volumes:
|
||||||
|
- ./db:/var/lib/mysql
|
||||||
|
restart: unless-stopped
|
||||||
|
api:
|
||||||
|
image: vikunja/api
|
||||||
|
environment:
|
||||||
|
VIKUNJA_DATABASE_HOST: db
|
||||||
|
VIKUNJA_DATABASE_PASSWORD: supersecret
|
||||||
|
VIKUNJA_DATABASE_TYPE: mysql
|
||||||
|
VIKUNJA_DATABASE_USER: root
|
||||||
|
VIKUNJA_DATABASE_DATABASE: vikunja
|
||||||
|
volumes:
|
||||||
|
- ./files:/app/vikunja/files
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
restart: unless-stopped
|
||||||
|
frontend:
|
||||||
|
image: vikunja/frontend
|
||||||
|
restart: unless-stopped
|
||||||
|
caddy:
|
||||||
|
image: caddy
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- frontend
|
||||||
|
volumes:
|
||||||
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
|
@ -81,4 +81,23 @@ Starts Vikunja's REST api server.
|
||||||
Usage:
|
Usage:
|
||||||
{{< highlight bash >}}
|
{{< highlight bash >}}
|
||||||
$ vikunja web
|
$ vikunja web
|
||||||
{{< /highlight >}}
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
### `dump`
|
||||||
|
|
||||||
|
Creates a zip file with all vikunja-related files.
|
||||||
|
This includes config, version, all files and the full database.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
{{< highlight bash >}}
|
||||||
|
$ vikunja dump
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
### `restore`
|
||||||
|
|
||||||
|
Restores a previously created dump from a zip file, see `dump`.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
{{< highlight bash >}}
|
||||||
|
$ vikunja restore <path to dump zip file>
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
2
docs/themes/vikunja
vendored
2
docs/themes/vikunja
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 7dce4df7b6068137d3e6127693706e806fc264b1
|
Subproject commit f50566db25df9fa03243ba06d17511e050d4be95
|
14
go.mod
14
go.mod
|
@ -19,7 +19,7 @@ module code.vikunja.io/api
|
||||||
require (
|
require (
|
||||||
4d63.com/embedfiles v1.0.0 // indirect
|
4d63.com/embedfiles v1.0.0 // indirect
|
||||||
4d63.com/tz v1.1.0
|
4d63.com/tz v1.1.0
|
||||||
code.vikunja.io/web v0.0.0-20200208214421-c90649369427
|
code.vikunja.io/web v0.0.0-20200618164749-a5f3d450d39a
|
||||||
gitea.com/xorm/xorm-redis-cache v0.2.0
|
gitea.com/xorm/xorm-redis-cache v0.2.0
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
|
||||||
|
@ -31,6 +31,7 @@ require (
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||||
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
|
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
|
||||||
|
github.com/getsentry/sentry-go v0.6.1
|
||||||
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
||||||
github.com/go-openapi/spec v0.19.4 // indirect
|
github.com/go-openapi/spec v0.19.4 // indirect
|
||||||
github.com/go-redis/redis/v7 v7.4.0
|
github.com/go-redis/redis/v7 v7.4.0
|
||||||
|
@ -54,11 +55,11 @@ require (
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/pelletier/go-toml v1.4.0 // indirect
|
github.com/pelletier/go-toml v1.4.0 // indirect
|
||||||
github.com/pquerna/otp v1.2.0
|
github.com/pquerna/otp v1.2.0
|
||||||
github.com/prometheus/client_golang v1.6.0
|
github.com/prometheus/client_golang v1.7.0
|
||||||
github.com/samedi/caldav-go v3.0.0+incompatible
|
github.com/samedi/caldav-go v3.0.0+incompatible
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
||||||
github.com/spf13/afero v1.2.2
|
github.com/spf13/afero v1.3.0
|
||||||
github.com/spf13/cobra v1.0.0
|
github.com/spf13/cobra v1.0.0
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/viper v1.7.0
|
github.com/spf13/viper v1.7.0
|
||||||
|
@ -68,7 +69,8 @@ require (
|
||||||
github.com/urfave/cli v1.22.2 // indirect
|
github.com/urfave/cli v1.22.2 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect
|
||||||
|
golang.org/x/text v0.3.3 // indirect
|
||||||
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef // indirect
|
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||||
|
@ -76,10 +78,10 @@ require (
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4
|
honnef.co/go/tools v0.0.1-2020.1.4
|
||||||
src.techknowlogick.com/xgo v0.0.0-20200602060627-a09175ea9056
|
src.techknowlogick.com/xgo v0.0.0-20200602060627-a09175ea9056
|
||||||
src.techknowlogick.com/xormigrate v1.2.1
|
src.techknowlogick.com/xormigrate v1.3.0
|
||||||
xorm.io/builder v0.3.7
|
xorm.io/builder v0.3.7
|
||||||
xorm.io/core v0.7.3
|
xorm.io/core v0.7.3
|
||||||
xorm.io/xorm v1.0.1
|
xorm.io/xorm v1.0.2
|
||||||
)
|
)
|
||||||
|
|
||||||
replace (
|
replace (
|
||||||
|
|
144
go.sum
144
go.sum
|
@ -19,8 +19,8 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7
|
||||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||||
code.vikunja.io/web v0.0.0-20200208214421-c90649369427 h1:6ps5r0OxZNRdmCavh1k/xMwftN27hHauo+EtdTGxLug=
|
code.vikunja.io/web v0.0.0-20200618164749-a5f3d450d39a h1:RiLIcnTTBP43QlL7nL0ko+PkzaBUCp7NmgogPeZBx5I=
|
||||||
code.vikunja.io/web v0.0.0-20200208214421-c90649369427/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
code.vikunja.io/web v0.0.0-20200618164749-a5f3d450d39a/go.mod h1:q3to9xazLf9XoqIRk1Y+YCjGr5TYgpQFNSVclCKrmEQ=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||||
|
@ -28,20 +28,28 @@ gitea.com/xorm/tests v0.7.0 h1:pFcaxTGGAWw3rDuVfhBdyr+mX1uzdTtncyAKxkCQ/IE=
|
||||||
gitea.com/xorm/tests v0.7.0/go.mod h1:ngmhQrSBgihBbOqw1hdReSQJAnTlbStYTn0vruUFwDc=
|
gitea.com/xorm/tests v0.7.0/go.mod h1:ngmhQrSBgihBbOqw1hdReSQJAnTlbStYTn0vruUFwDc=
|
||||||
gitea.com/xorm/xorm-redis-cache v0.2.0 h1:qglRHt6/7vJmDeld6j+n10M9PmruAh+Le2lgNraFu3g=
|
gitea.com/xorm/xorm-redis-cache v0.2.0 h1:qglRHt6/7vJmDeld6j+n10M9PmruAh+Le2lgNraFu3g=
|
||||||
gitea.com/xorm/xorm-redis-cache v0.2.0/go.mod h1:juYdjkmIKvLbPkdfBVKGVJ2daFQIJAgKsn4mL4ZK8Zk=
|
gitea.com/xorm/xorm-redis-cache v0.2.0/go.mod h1:juYdjkmIKvLbPkdfBVKGVJ2daFQIJAgKsn4mL4ZK8Zk=
|
||||||
|
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw=
|
||||||
|
github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
|
||||||
|
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
|
||||||
|
github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM=
|
||||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
|
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
||||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
|
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
|
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
@ -49,6 +57,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 h1:P5U+E4x5OkVEKQDklVPmzs71WM56RTTRqV4OrDC//Y4=
|
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 h1:P5U+E4x5OkVEKQDklVPmzs71WM56RTTRqV4OrDC//Y4=
|
||||||
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro=
|
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro=
|
||||||
|
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
@ -56,6 +65,7 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
|
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
||||||
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
|
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
|
||||||
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||||
|
@ -78,12 +88,16 @@ github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJ
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
|
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
|
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||||
|
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
@ -98,16 +112,22 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADGYw5LqMnHqSkyIELsHCGF6PkrmM31V8rF7o=
|
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADGYw5LqMnHqSkyIELsHCGF6PkrmM31V8rF7o=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e h1:LzwWXEScfcTu7vUZNlDDWDARoSGEtvlDKK2BYHowNeE=
|
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
|
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||||
|
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||||
|
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||||
|
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
|
@ -116,6 +136,9 @@ github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835 h1:roDmqJ4Qes7hrDOsW
|
||||||
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835/go.mod h1:BjL/N0+C+j9uNX+1xcNuM9vdSIcXCZrQZUYbXOFbgN8=
|
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835/go.mod h1:BjL/N0+C+j9uNX+1xcNuM9vdSIcXCZrQZUYbXOFbgN8=
|
||||||
github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc=
|
github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc=
|
||||||
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
|
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||||
|
github.com/getsentry/sentry-go v0.6.1 h1:K84dY1/57OtWhdyr5lbU78Q/+qgzkEyGc/ud+Sipi5k=
|
||||||
|
github.com/getsentry/sentry-go v0.6.1/go.mod h1:0yZBuzSvbZwBnvaF9VwZIMen3kXscY8/uasKtAX1qG8=
|
||||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
||||||
|
@ -125,11 +148,15 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm
|
||||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||||
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
|
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
||||||
|
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||||
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
|
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||||
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
||||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
|
@ -156,8 +183,6 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
|
||||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||||
github.com/go-redis/redis/v7 v7.2.0 h1:CrCexy/jYWZjW0AyVoHlcJUeZN19VWlbepTh1Vq6dJs=
|
github.com/go-redis/redis/v7 v7.2.0 h1:CrCexy/jYWZjW0AyVoHlcJUeZN19VWlbepTh1Vq6dJs=
|
||||||
github.com/go-redis/redis/v7 v7.2.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
|
github.com/go-redis/redis/v7 v7.2.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
|
||||||
github.com/go-redis/redis/v7 v7.3.0 h1:3oHqd0W7f/VLKBxeYTEpqdMUsmMectngjM9OtoRoIgg=
|
|
||||||
github.com/go-redis/redis/v7 v7.3.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
|
|
||||||
github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4=
|
github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4=
|
||||||
github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
|
github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
|
||||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||||
|
@ -167,6 +192,9 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-testfixtures/testfixtures/v3 v3.2.0 h1:FGAW3z5UzmrZGjR/dZp1u3Tbld0SDmirLO4RrR5++7Q=
|
github.com/go-testfixtures/testfixtures/v3 v3.2.0 h1:FGAW3z5UzmrZGjR/dZp1u3Tbld0SDmirLO4RrR5++7Q=
|
||||||
github.com/go-testfixtures/testfixtures/v3 v3.2.0/go.mod h1:RZctY24ixituGC73XlAV1gkCwYMVwiSwPm26MNlQIhE=
|
github.com/go-testfixtures/testfixtures/v3 v3.2.0/go.mod h1:RZctY24ixituGC73XlAV1gkCwYMVwiSwPm26MNlQIhE=
|
||||||
|
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||||
|
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||||
|
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
@ -191,10 +219,13 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
|
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||||
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||||
|
@ -203,6 +234,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
|
@ -237,6 +269,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
|
||||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
||||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
@ -250,8 +283,13 @@ github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 h1:VHgatEHNcBFE
|
||||||
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
|
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
|
||||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
|
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
|
||||||
|
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
|
||||||
|
github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI=
|
||||||
|
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
|
||||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
|
||||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||||
github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||||
|
@ -277,13 +315,23 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22
|
||||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
|
||||||
|
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
|
||||||
|
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
|
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
||||||
|
github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk=
|
||||||
|
github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U=
|
||||||
|
github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw=
|
||||||
|
github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
|
github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/compress v1.9.6/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
github.com/klauspost/compress v1.9.6/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible h1:PkEEpmbrFXlMul8cOplR8nkcIM/NDbx+H6fq2+vaKAA=
|
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible h1:PkEEpmbrFXlMul8cOplR8nkcIM/NDbx+H6fq2+vaKAA=
|
||||||
|
@ -291,6 +339,7 @@ github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible/
|
||||||
github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048 h1:j/BtLkVyqtAXvlb22nic/pSlWLuGx4gddouWVt65HDI=
|
github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048 h1:j/BtLkVyqtAXvlb22nic/pSlWLuGx4gddouWVt65HDI=
|
||||||
github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048/go.mod h1:dv6KyzAg9UuJWiE1pwkvvB2i0TvcQM6QhdsXLZ7K5KI=
|
github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048/go.mod h1:dv6KyzAg9UuJWiE1pwkvvB2i0TvcQM6QhdsXLZ7K5KI=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
@ -302,6 +351,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f h1:fNJtR+TNyxTdYCZU40fc8Or8RyBqMOKYNv+Zay5gjvk=
|
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f h1:fNJtR+TNyxTdYCZU40fc8Or8RyBqMOKYNv+Zay5gjvk=
|
||||||
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f/go.mod h1:kU/7PwzgNxZH4das4XNsSpBSOD09XIF5YEPzjpkGnGE=
|
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f/go.mod h1:kU/7PwzgNxZH4das4XNsSpBSOD09XIF5YEPzjpkGnGE=
|
||||||
|
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||||
github.com/labstack/echo/v4 v4.1.16 h1:8swiwjE5Jkai3RPfZoahp8kjVCRNq+y7Q0hPji2Kz0o=
|
github.com/labstack/echo/v4 v4.1.16 h1:8swiwjE5Jkai3RPfZoahp8kjVCRNq+y7Q0hPji2Kz0o=
|
||||||
github.com/labstack/echo/v4 v4.1.16/go.mod h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI=
|
github.com/labstack/echo/v4 v4.1.16/go.mod h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI=
|
||||||
github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
|
github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
|
||||||
|
@ -315,8 +365,6 @@ github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
|
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
|
||||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.5.2 h1:yTSXVswvWUOQ3k1sd7vJfDrbSl8lKuscqFJRqjC0ifw=
|
|
||||||
github.com/lib/pq v1.5.2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.6.0 h1:I5DPxhYJChW9KYc66se+oKFFQX6VuQrKiprsX6ivRZc=
|
github.com/lib/pq v1.6.0 h1:I5DPxhYJChW9KYc66se+oKFFQX6VuQrKiprsX6ivRZc=
|
||||||
github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g=
|
github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g=
|
||||||
github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY=
|
github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY=
|
||||||
|
@ -351,11 +399,16 @@ github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+tw
|
||||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||||
github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg=
|
||||||
|
github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ=
|
||||||
|
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
@ -370,7 +423,11 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
|
github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM=
|
||||||
|
github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4=
|
||||||
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
|
@ -380,6 +437,7 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
|
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
|
||||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||||
|
@ -398,12 +456,15 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
|
||||||
github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
|
github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
|
||||||
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
|
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||||
|
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
|
@ -414,8 +475,8 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+Ci
|
||||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
|
github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R9JX0FuA/U=
|
||||||
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
|
github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
|
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
|
||||||
|
@ -430,24 +491,28 @@ github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
|
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
|
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
|
||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
|
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
|
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
|
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||||
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
|
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shopspring/decimal v0.0.0-20191009025716-f1972eb1d1f5/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
github.com/shopspring/decimal v0.0.0-20191009025716-f1972eb1d1f5/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||||
|
@ -465,10 +530,11 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk=
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
|
||||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||||
|
@ -479,6 +545,7 @@ github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
|
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
|
||||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||||
|
@ -511,6 +578,7 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr
|
||||||
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
||||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
|
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
|
||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
github.com/ulule/limiter/v3 v3.5.0 h1:QRAebbswjlezHIfiSQgM8+jMxaz/zsrxGRuiUJ43MHo=
|
github.com/ulule/limiter/v3 v3.5.0 h1:QRAebbswjlezHIfiSQgM8+jMxaz/zsrxGRuiUJ43MHo=
|
||||||
|
@ -519,16 +587,25 @@ github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
|
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||||
github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||||
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
||||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||||
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
|
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
|
||||||
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
|
||||||
|
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||||
|
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||||
|
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||||
|
@ -542,6 +619,7 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -549,14 +627,12 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
|
||||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
|
|
||||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed h1:g4KENRiCMEx58Q7/ecwfT0N2o8z35Fnbsjig/Alf2T4=
|
|
||||||
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
|
||||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
@ -582,6 +658,7 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -595,6 +672,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
|
||||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
|
||||||
|
@ -609,10 +687,12 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
|
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||||
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||||
|
@ -632,6 +712,7 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -659,23 +740,27 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
||||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
@ -738,6 +823,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||||
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
|
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||||
|
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||||
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
|
@ -762,6 +849,7 @@ gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eR
|
||||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||||
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||||
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
@ -788,19 +876,17 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
src.techknowlogick.com/xgo v0.0.0-20200514233805-209a5cf70012 h1:k1/qGRpsaGka4IHT2UIUdPqM6+oo3O7+8S3ACN2kJZQ=
|
|
||||||
src.techknowlogick.com/xgo v0.0.0-20200514233805-209a5cf70012/go.mod h1:31CE1YKtDOrKTk9PSnjTpe6YbO6W/0LTYZ1VskL09oU=
|
|
||||||
src.techknowlogick.com/xgo v0.0.0-20200601230223-eeb7c0a673dd h1:6hliDQiQTI45t45ECQxdnLhdkd8y96dsBeeun0A/9jQ=
|
|
||||||
src.techknowlogick.com/xgo v0.0.0-20200601230223-eeb7c0a673dd/go.mod h1:31CE1YKtDOrKTk9PSnjTpe6YbO6W/0LTYZ1VskL09oU=
|
|
||||||
src.techknowlogick.com/xgo v0.0.0-20200602060627-a09175ea9056 h1:9XYMVs36yGHbSNs+m7kHg5lQnTOie2bMLM1c8LtAoXs=
|
src.techknowlogick.com/xgo v0.0.0-20200602060627-a09175ea9056 h1:9XYMVs36yGHbSNs+m7kHg5lQnTOie2bMLM1c8LtAoXs=
|
||||||
src.techknowlogick.com/xgo v0.0.0-20200602060627-a09175ea9056/go.mod h1:31CE1YKtDOrKTk9PSnjTpe6YbO6W/0LTYZ1VskL09oU=
|
src.techknowlogick.com/xgo v0.0.0-20200602060627-a09175ea9056/go.mod h1:31CE1YKtDOrKTk9PSnjTpe6YbO6W/0LTYZ1VskL09oU=
|
||||||
src.techknowlogick.com/xormigrate v1.2.0 h1:bq9JaI48bxB+OddMghicjmV7sGmBUogJq4HmTN0DOcw=
|
|
||||||
src.techknowlogick.com/xormigrate v1.2.0/go.mod h1:7so27LAfBRqAxbma5jKYeL4ykVG1Jhsv9ncSq1KBCs4=
|
|
||||||
src.techknowlogick.com/xormigrate v1.2.1 h1:HMtGqV5QN5zvYU244jzFCJ27rAljkMn/jsgp+H4S6WA=
|
src.techknowlogick.com/xormigrate v1.2.1 h1:HMtGqV5QN5zvYU244jzFCJ27rAljkMn/jsgp+H4S6WA=
|
||||||
src.techknowlogick.com/xormigrate v1.2.1/go.mod h1:PhU3iInlbFSev3M4ZnmAeWy9ZHUVDbz3U1X9Sg9S8xQ=
|
src.techknowlogick.com/xormigrate v1.2.1/go.mod h1:PhU3iInlbFSev3M4ZnmAeWy9ZHUVDbz3U1X9Sg9S8xQ=
|
||||||
|
src.techknowlogick.com/xormigrate v1.3.0 h1:cCOEk8CjhRqxMtE8X8aV0qd6b2njwU1c3++ZuyaTsA0=
|
||||||
|
src.techknowlogick.com/xormigrate v1.3.0/go.mod h1:lmB01Zzm8lkvGE+qvlZoaIl39c8iEvHtYMtSFiHg250=
|
||||||
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
|
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
|
||||||
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||||
xorm.io/core v0.7.3 h1:W8ws1PlrnkS1CZU1YWaYLMQcQilwAmQXU0BJDJon+H0=
|
xorm.io/core v0.7.3 h1:W8ws1PlrnkS1CZU1YWaYLMQcQilwAmQXU0BJDJon+H0=
|
||||||
xorm.io/core v0.7.3/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
xorm.io/core v0.7.3/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
||||||
xorm.io/xorm v1.0.1 h1:/lITxpJtkZauNpdzj+L9CN/3OQxZaABrbergMcJu+Cw=
|
xorm.io/xorm v1.0.1 h1:/lITxpJtkZauNpdzj+L9CN/3OQxZaABrbergMcJu+Cw=
|
||||||
xorm.io/xorm v1.0.1/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY=
|
xorm.io/xorm v1.0.1/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY=
|
||||||
|
xorm.io/xorm v1.0.2 h1:kZlCh9rqd1AzGwWitcrEEqHE1h1eaZE/ujU5/2tWEtg=
|
||||||
|
xorm.io/xorm v1.0.2/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY=
|
||||||
|
|
|
@ -17,15 +17,6 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"code.vikunja.io/api/pkg/config"
|
|
||||||
"code.vikunja.io/api/pkg/files"
|
|
||||||
"code.vikunja.io/api/pkg/log"
|
|
||||||
"code.vikunja.io/api/pkg/mail"
|
|
||||||
"code.vikunja.io/api/pkg/migration"
|
|
||||||
"code.vikunja.io/api/pkg/models"
|
|
||||||
migrator "code.vikunja.io/api/pkg/modules/migration"
|
|
||||||
"code.vikunja.io/api/pkg/red"
|
|
||||||
"code.vikunja.io/api/pkg/user"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"os"
|
"os"
|
||||||
|
@ -54,48 +45,3 @@ func Execute() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will only fullInit config, redis, logger but no db connection.
|
|
||||||
func lightInit() {
|
|
||||||
// Init the config
|
|
||||||
config.InitConfig()
|
|
||||||
|
|
||||||
// Init redis
|
|
||||||
red.InitRedis()
|
|
||||||
|
|
||||||
// Set logger
|
|
||||||
log.InitLogger()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initializes all kinds of things in the right order
|
|
||||||
func fullInit() {
|
|
||||||
|
|
||||||
lightInit()
|
|
||||||
|
|
||||||
// Run the migrations
|
|
||||||
migration.Migrate(nil)
|
|
||||||
|
|
||||||
// Set Engine
|
|
||||||
err := models.SetEngine()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
err = user.InitDB()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
err = files.SetEngine()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
err = migrator.InitDB()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the files handler
|
|
||||||
files.InitFileHandler()
|
|
||||||
|
|
||||||
// Start the mail daemon
|
|
||||||
mail.StartMailDaemon()
|
|
||||||
}
|
|
||||||
|
|
43
pkg/cmd/dump.go
Normal file
43
pkg/cmd/dump.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.vikunja.io/api/pkg/initialize"
|
||||||
|
"code.vikunja.io/api/pkg/log"
|
||||||
|
"code.vikunja.io/api/pkg/modules/dump"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(dumpCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var dumpCmd = &cobra.Command{
|
||||||
|
Use: "dump",
|
||||||
|
Short: "Dump all vikunja data into a zip file. Includes config, files and db.",
|
||||||
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
initialize.FullInit()
|
||||||
|
},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
filename := "vikunja-dump_" + time.Now().Format("2006-01-02_15-03-05") + ".zip"
|
||||||
|
if err := dump.Dump(filename); err != nil {
|
||||||
|
log.Critical(err.Error())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.vikunja.io/api/pkg/initialize"
|
||||||
"code.vikunja.io/api/pkg/migration"
|
"code.vikunja.io/api/pkg/migration"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -36,7 +37,7 @@ var migrateCmd = &cobra.Command{
|
||||||
Use: "migrate",
|
Use: "migrate",
|
||||||
Short: "Run all database migrations which didn't already run.",
|
Short: "Run all database migrations which didn't already run.",
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
lightInit()
|
initialize.LightInit()
|
||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
migration.Migrate(nil)
|
migration.Migrate(nil)
|
||||||
|
|
42
pkg/cmd/restore.go
Normal file
42
pkg/cmd/restore.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.vikunja.io/api/pkg/initialize"
|
||||||
|
"code.vikunja.io/api/pkg/log"
|
||||||
|
"code.vikunja.io/api/pkg/modules/dump"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(restoreCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var restoreCmd = &cobra.Command{
|
||||||
|
Use: "restore [filename]",
|
||||||
|
Short: "Restores all vikunja data from a vikunja dump.",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
initialize.FullInit()
|
||||||
|
},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if err := dump.Restore(args[0]); err != nil {
|
||||||
|
log.Critical(err.Error())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.vikunja.io/api/pkg/initialize"
|
||||||
"code.vikunja.io/api/pkg/log"
|
"code.vikunja.io/api/pkg/log"
|
||||||
"code.vikunja.io/api/pkg/mail"
|
"code.vikunja.io/api/pkg/mail"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -31,7 +32,7 @@ var testmailCmd = &cobra.Command{
|
||||||
Short: "Send a test mail using the configured smtp connection",
|
Short: "Send a test mail using the configured smtp connection",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
lightInit()
|
initialize.LightInit()
|
||||||
|
|
||||||
// Start the mail daemon
|
// Start the mail daemon
|
||||||
mail.StartMailDaemon()
|
mail.StartMailDaemon()
|
||||||
|
|
|
@ -31,6 +31,5 @@ var versionCmd = &cobra.Command{
|
||||||
Short: "Print the version number of Vikunja",
|
Short: "Print the version number of Vikunja",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
fmt.Printf("Vikunja api version %s\n", version.Version)
|
fmt.Printf("Vikunja api version %s\n", version.Version)
|
||||||
fmt.Printf("Built at %s\n", version.BuildTime)
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"code.vikunja.io/api/pkg/config"
|
"code.vikunja.io/api/pkg/config"
|
||||||
|
"code.vikunja.io/api/pkg/initialize"
|
||||||
"code.vikunja.io/api/pkg/log"
|
"code.vikunja.io/api/pkg/log"
|
||||||
"code.vikunja.io/api/pkg/routes"
|
"code.vikunja.io/api/pkg/routes"
|
||||||
"code.vikunja.io/api/pkg/swagger"
|
"code.vikunja.io/api/pkg/swagger"
|
||||||
|
@ -37,12 +38,12 @@ var webCmd = &cobra.Command{
|
||||||
Use: "web",
|
Use: "web",
|
||||||
Short: "Starts the rest api web server",
|
Short: "Starts the rest api web server",
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
fullInit()
|
initialize.FullInit()
|
||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
// Version notification
|
// Version notification
|
||||||
log.Infof("Vikunja version %s, built at %s", version.Version, version.BuildTime)
|
log.Infof("Vikunja version %s", version.Version)
|
||||||
|
|
||||||
// Additional swagger information
|
// Additional swagger information
|
||||||
swagger.SwaggerInfo.Version = version.Version
|
swagger.SwaggerInfo.Version = version.Version
|
||||||
|
|
|
@ -49,6 +49,7 @@ const (
|
||||||
ServiceTimeZone Key = `service.timezone`
|
ServiceTimeZone Key = `service.timezone`
|
||||||
ServiceEnableTaskComments Key = `service.enabletaskcomments`
|
ServiceEnableTaskComments Key = `service.enabletaskcomments`
|
||||||
ServiceEnableTotp Key = `service.enabletotp`
|
ServiceEnableTotp Key = `service.enabletotp`
|
||||||
|
ServiceSentryDsn Key = `service.sentrydsn`
|
||||||
|
|
||||||
DatabaseType Key = `database.type`
|
DatabaseType Key = `database.type`
|
||||||
DatabaseHost Key = `database.host`
|
DatabaseHost Key = `database.host`
|
||||||
|
|
17
pkg/db/db.go
17
pkg/db/db.go
|
@ -168,3 +168,20 @@ func initSqliteEngine() (engine *xorm.Engine, err error) {
|
||||||
|
|
||||||
return xorm.NewEngine("sqlite3", path)
|
return xorm.NewEngine("sqlite3", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WipeEverything wipes all tables and their data. Use with caution...
|
||||||
|
func WipeEverything() error {
|
||||||
|
|
||||||
|
tables, err := x.DBMetas()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range tables {
|
||||||
|
if err := x.DropTables(t.Name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
54
pkg/db/dump.go
Normal file
54
pkg/db/dump.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package db
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
// Dump dumps all database tables
|
||||||
|
func Dump() (data map[string][]byte, err error) {
|
||||||
|
tables, err := x.DBMetas()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data = make(map[string][]byte, len(tables))
|
||||||
|
for _, table := range tables {
|
||||||
|
entries := []map[string]interface{}{}
|
||||||
|
err := x.Table(table.Name).Find(&entries)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data[table.Name], err = json.Marshal(entries)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore restores a table with all its entries
|
||||||
|
func Restore(table string, contents []map[string]interface{}) (err error) {
|
||||||
|
|
||||||
|
for _, content := range contents {
|
||||||
|
if _, err := x.Table(table).Insert(content); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
41
pkg/files/dump.go
Normal file
41
pkg/files/dump.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package files
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Dump dumps all saved files
|
||||||
|
// This only includes the raw files, no db entries.
|
||||||
|
func Dump() (allFiles map[int64]io.ReadCloser, err error) {
|
||||||
|
files := []*File{}
|
||||||
|
err = x.Find(&files)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
allFiles = make(map[int64]io.ReadCloser, len(files))
|
||||||
|
for _, file := range files {
|
||||||
|
if err := file.LoadFileByID(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
allFiles[file.ID] = file.File
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -96,7 +96,7 @@ func Create(f io.ReadCloser, realname string, realsize uint64, a web.Auth) (file
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the file to storage with its new ID as path
|
// Save the file to storage with its new ID as path
|
||||||
err = afs.WriteReader(file.getFileName(), f)
|
err = file.Save(f)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,3 +113,8 @@ func (f *File) Delete() (err error) {
|
||||||
err = afs.Remove(f.getFileName())
|
err = afs.Remove(f.getFileName())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save saves a file to storage
|
||||||
|
func (f *File) Save(fcontent io.ReadCloser) error {
|
||||||
|
return afs.WriteReader(f.getFileName(), fcontent)
|
||||||
|
}
|
||||||
|
|
79
pkg/initialize/init.go
Normal file
79
pkg/initialize/init.go
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.vikunja.io/api/pkg/config"
|
||||||
|
"code.vikunja.io/api/pkg/files"
|
||||||
|
"code.vikunja.io/api/pkg/log"
|
||||||
|
"code.vikunja.io/api/pkg/mail"
|
||||||
|
"code.vikunja.io/api/pkg/migration"
|
||||||
|
"code.vikunja.io/api/pkg/models"
|
||||||
|
migrator "code.vikunja.io/api/pkg/modules/migration"
|
||||||
|
"code.vikunja.io/api/pkg/red"
|
||||||
|
"code.vikunja.io/api/pkg/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LightInit will only fullInit config, redis, logger but no db connection.
|
||||||
|
func LightInit() {
|
||||||
|
// Init the config
|
||||||
|
config.InitConfig()
|
||||||
|
|
||||||
|
// Init redis
|
||||||
|
red.InitRedis()
|
||||||
|
|
||||||
|
// Set logger
|
||||||
|
log.InitLogger()
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitEngines intializes all db connections
|
||||||
|
func InitEngines() {
|
||||||
|
err := models.SetEngine()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
err = user.InitDB()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
err = files.SetEngine()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
err = migrator.InitDB()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullInit initializes all kinds of things in the right order
|
||||||
|
func FullInit() {
|
||||||
|
|
||||||
|
LightInit()
|
||||||
|
|
||||||
|
// Run the migrations
|
||||||
|
migration.Migrate(nil)
|
||||||
|
|
||||||
|
// Set Engine
|
||||||
|
InitEngines()
|
||||||
|
|
||||||
|
// Initialize the files handler
|
||||||
|
files.InitFileHandler()
|
||||||
|
|
||||||
|
// Start the mail daemon
|
||||||
|
mail.StartMailDaemon()
|
||||||
|
}
|
|
@ -178,15 +178,10 @@ func TestList(t *testing.T) {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields, "title: non zero value required")
|
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields, "title: non zero value required")
|
||||||
})
|
})
|
||||||
t.Run("Almost empty title", func(t *testing.T) {
|
|
||||||
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"list": "1"}, `{"title":"nn"}`)
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(3|250)")
|
|
||||||
})
|
|
||||||
t.Run("Title too long", func(t *testing.T) {
|
t.Run("Title too long", func(t *testing.T) {
|
||||||
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"list": "1"}, `{"title":"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea taki"}`)
|
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"list": "1"}, `{"title":"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea taki"}`)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(3|250)")
|
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(1|250)")
|
||||||
})
|
})
|
||||||
t.Run("Rights check", func(t *testing.T) {
|
t.Run("Rights check", func(t *testing.T) {
|
||||||
t.Run("Forbidden", func(t *testing.T) {
|
t.Run("Forbidden", func(t *testing.T) {
|
||||||
|
@ -371,15 +366,10 @@ func TestList(t *testing.T) {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields, "title: non zero value required")
|
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields, "title: non zero value required")
|
||||||
})
|
})
|
||||||
t.Run("Almost empty title", func(t *testing.T) {
|
|
||||||
_, err := testHandler.testCreateWithUser(nil, map[string]string{"namespace": "1"}, `{"title":"nn"}`)
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(3|250)")
|
|
||||||
})
|
|
||||||
t.Run("Title too long", func(t *testing.T) {
|
t.Run("Title too long", func(t *testing.T) {
|
||||||
_, err := testHandler.testCreateWithUser(nil, map[string]string{"namespace": "1"}, `{"title":"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea taki"}`)
|
_, err := testHandler.testCreateWithUser(nil, map[string]string{"namespace": "1"}, `{"title":"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea taki"}`)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(3|250)")
|
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(1|250)")
|
||||||
})
|
})
|
||||||
t.Run("Rights check", func(t *testing.T) {
|
t.Run("Rights check", func(t *testing.T) {
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,15 @@ func Rollback(migrationID string) {
|
||||||
log.Info("Rolled back successfully.")
|
log.Info("Rolled back successfully.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MigrateTo executes all migrations up to a certain point
|
||||||
|
func MigrateTo(migrationID string, x *xorm.Engine) error {
|
||||||
|
m := initMigration(x)
|
||||||
|
if err := m.MigrateTo(migrationID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Deletes a column from a table. All arguments are strings, to let them be standalone and not depending on any struct.
|
// Deletes a column from a table. All arguments are strings, to let them be standalone and not depending on any struct.
|
||||||
func dropTableColum(x *xorm.Engine, tableName, col string) error {
|
func dropTableColum(x *xorm.Engine, tableName, col string) error {
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ type Label struct {
|
||||||
// The unique, numeric id of this label.
|
// The unique, numeric id of this label.
|
||||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"label"`
|
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"label"`
|
||||||
// The title of the lable. You'll see this one on tasks associated with it.
|
// The title of the lable. You'll see this one on tasks associated with it.
|
||||||
Title string `xorm:"varchar(250) not null" json:"title" valid:"runelength(3|250)" minLength:"3" maxLength:"250"`
|
Title string `xorm:"varchar(250) not null" json:"title" valid:"runelength(1|250)" minLength:"3" maxLength:"250"`
|
||||||
// The label description.
|
// The label description.
|
||||||
Description string `xorm:"longtext null" json:"description"`
|
Description string `xorm:"longtext null" json:"description"`
|
||||||
// The color this label has
|
// The color this label has
|
||||||
|
|
|
@ -32,7 +32,7 @@ type List struct {
|
||||||
// The unique, numeric id of this list.
|
// The unique, numeric id of this list.
|
||||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"list"`
|
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"list"`
|
||||||
// The title of the list. You'll see this in the namespace overview.
|
// The title of the list. You'll see this in the namespace overview.
|
||||||
Title string `xorm:"varchar(250) not null" json:"title" valid:"required,runelength(3|250)" minLength:"3" maxLength:"250"`
|
Title string `xorm:"varchar(250) not null" json:"title" valid:"required,runelength(1|250)" minLength:"3" maxLength:"250"`
|
||||||
// The description of the list.
|
// The description of the list.
|
||||||
Description string `xorm:"longtext null" json:"description"`
|
Description string `xorm:"longtext null" json:"description"`
|
||||||
// The unique list short identifier. Used to build task identifiers.
|
// The unique list short identifier. Used to build task identifiers.
|
||||||
|
|
|
@ -31,7 +31,7 @@ type Namespace struct {
|
||||||
// The unique, numeric id of this namespace.
|
// The unique, numeric id of this namespace.
|
||||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"namespace"`
|
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"namespace"`
|
||||||
// The name of this namespace.
|
// The name of this namespace.
|
||||||
Title string `xorm:"varchar(250) not null" json:"title" valid:"required,runelength(5|250)" minLength:"5" maxLength:"250"`
|
Title string `xorm:"varchar(250) not null" json:"title" valid:"required,runelength(1|250)" minLength:"5" maxLength:"250"`
|
||||||
// The description of the namespace
|
// The description of the namespace
|
||||||
Description string `xorm:"longtext null" json:"description"`
|
Description string `xorm:"longtext null" json:"description"`
|
||||||
OwnerID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
OwnerID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
||||||
|
|
|
@ -38,7 +38,7 @@ type Task struct {
|
||||||
// The unique, numeric id of this task.
|
// The unique, numeric id of this task.
|
||||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"listtask"`
|
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"listtask"`
|
||||||
// The task text. This is what you'll see in the list.
|
// The task text. This is what you'll see in the list.
|
||||||
Title string `xorm:"varchar(250) not null" json:"title" valid:"runelength(3|250)" minLength:"3" maxLength:"250"`
|
Title string `xorm:"varchar(250) not null" json:"title" valid:"runelength(1|250)" minLength:"3" maxLength:"250"`
|
||||||
// The task description.
|
// The task description.
|
||||||
Description string `xorm:"longtext null" json:"description"`
|
Description string `xorm:"longtext null" json:"description"`
|
||||||
// Whether a task is done or not.
|
// Whether a task is done or not.
|
||||||
|
|
|
@ -29,7 +29,7 @@ type Team struct {
|
||||||
// The unique, numeric id of this team.
|
// The unique, numeric id of this team.
|
||||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"team"`
|
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id" param:"team"`
|
||||||
// The name of this team.
|
// The name of this team.
|
||||||
Name string `xorm:"varchar(250) not null" json:"name" valid:"required,runelength(5|250)" minLength:"5" maxLength:"250"`
|
Name string `xorm:"varchar(250) not null" json:"name" valid:"required,runelength(1|250)" minLength:"5" maxLength:"250"`
|
||||||
// The team's description.
|
// The team's description.
|
||||||
Description string `xorm:"longtext null" json:"description"`
|
Description string `xorm:"longtext null" json:"description"`
|
||||||
CreatedByID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
CreatedByID int64 `xorm:"int(11) not null INDEX" json:"-"`
|
||||||
|
|
146
pkg/modules/dump/dump.go
Normal file
146
pkg/modules/dump/dump.go
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package dump
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"code.vikunja.io/api/pkg/db"
|
||||||
|
"code.vikunja.io/api/pkg/files"
|
||||||
|
"code.vikunja.io/api/pkg/log"
|
||||||
|
"code.vikunja.io/api/pkg/version"
|
||||||
|
"fmt"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Change to deflate to gain better compression
|
||||||
|
// see http://golang.org/pkg/archive/zip/#pkg-constants
|
||||||
|
const compressionUsed = zip.Deflate
|
||||||
|
|
||||||
|
// Dump creates a zip file with all vikunja files at filename
|
||||||
|
func Dump(filename string) error {
|
||||||
|
dumpFile, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error opening dump file: %s", err)
|
||||||
|
}
|
||||||
|
defer dumpFile.Close()
|
||||||
|
|
||||||
|
dumpWriter := zip.NewWriter(dumpFile)
|
||||||
|
defer dumpWriter.Close()
|
||||||
|
|
||||||
|
// Config
|
||||||
|
log.Info("Start dumping config file...")
|
||||||
|
err = writeFileToZip(viper.ConfigFileUsed(), dumpWriter)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error saving config file: %s", err)
|
||||||
|
}
|
||||||
|
log.Info("Dumped config file")
|
||||||
|
|
||||||
|
// Version
|
||||||
|
log.Info("Start dumping version file...")
|
||||||
|
err = writeBytesToZip("VERSION", []byte(version.Version), dumpWriter)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error saving version: %s", err)
|
||||||
|
}
|
||||||
|
log.Info("Dumped version")
|
||||||
|
|
||||||
|
// Database
|
||||||
|
log.Info("Start dumping database...")
|
||||||
|
data, err := db.Dump()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error saving database data: %s", err)
|
||||||
|
}
|
||||||
|
for t, d := range data {
|
||||||
|
err = writeBytesToZip("database/"+t+".json", d, dumpWriter)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error writing database table %s: %s", t, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Info("Dumped database")
|
||||||
|
|
||||||
|
// Files
|
||||||
|
log.Info("Start dumping files...")
|
||||||
|
allFiles, err := files.Dump()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error saving file: %s", err)
|
||||||
|
}
|
||||||
|
for fid, file := range allFiles {
|
||||||
|
header := &zip.FileHeader{
|
||||||
|
Name: "files/" + strconv.FormatInt(fid, 10),
|
||||||
|
Method: compressionUsed,
|
||||||
|
}
|
||||||
|
w, err := dumpWriter.CreateHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = io.Copy(w, file)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error writing file %d: %s", fid, err)
|
||||||
|
}
|
||||||
|
_ = file.Close()
|
||||||
|
}
|
||||||
|
log.Infof("Dumped files")
|
||||||
|
|
||||||
|
log.Info("Done creating dump")
|
||||||
|
log.Infof("Dump file saved at %s", filename)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeFileToZip(filename string, writer *zip.Writer) error {
|
||||||
|
// #nosec
|
||||||
|
fileToZip, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fileToZip.Close()
|
||||||
|
|
||||||
|
// Get the file information
|
||||||
|
info, err := fileToZip.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
header, err := zip.FileInfoHeader(info)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
header.Name = info.Name()
|
||||||
|
header.Method = compressionUsed
|
||||||
|
|
||||||
|
w, err := writer.CreateHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = io.Copy(w, fileToZip)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeBytesToZip(filename string, data []byte, writer *zip.Writer) (err error) {
|
||||||
|
header := &zip.FileHeader{
|
||||||
|
Name: filename,
|
||||||
|
Method: compressionUsed,
|
||||||
|
}
|
||||||
|
w, err := writer.CreateHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = w.Write(data)
|
||||||
|
return
|
||||||
|
}
|
217
pkg/modules/dump/restore.go
Normal file
217
pkg/modules/dump/restore.go
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package dump
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"code.vikunja.io/api/pkg/db"
|
||||||
|
"code.vikunja.io/api/pkg/files"
|
||||||
|
"code.vikunja.io/api/pkg/initialize"
|
||||||
|
"code.vikunja.io/api/pkg/log"
|
||||||
|
"code.vikunja.io/api/pkg/migration"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"src.techknowlogick.com/xormigrate"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const maxConfigSize = 5 * 1024 * 1024 // 5 MB, should be largely enough
|
||||||
|
|
||||||
|
// Restore takes a zip file name and restores it
|
||||||
|
func Restore(filename string) error {
|
||||||
|
|
||||||
|
r, err := zip.OpenReader(filename)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not open zip file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Warning("Restoring a dump will wipe your current installation!")
|
||||||
|
log.Warning("To confirm, please type 'Yes, I understand' and confirm with enter:")
|
||||||
|
cr := bufio.NewReader(os.Stdin)
|
||||||
|
text, err := cr.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not read confirmation message: %s", err)
|
||||||
|
}
|
||||||
|
if text != "Yes, I understand\n" {
|
||||||
|
return fmt.Errorf("invalid confirmation message")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the configFile, database and files files
|
||||||
|
var configFile *zip.File
|
||||||
|
dbfiles := make(map[string]*zip.File)
|
||||||
|
filesFiles := make(map[string]*zip.File)
|
||||||
|
for _, file := range r.File {
|
||||||
|
if strings.HasPrefix(file.Name, "config") {
|
||||||
|
configFile = file
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(file.Name, "database/") {
|
||||||
|
fname := strings.ReplaceAll(file.Name, "database/", "")
|
||||||
|
dbfiles[fname[:len(fname)-5]] = file
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(file.Name, "files/") {
|
||||||
|
filesFiles[strings.ReplaceAll(file.Name, "files/", "")] = file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if configFile == nil {
|
||||||
|
return fmt.Errorf("dump does not contain a config file")
|
||||||
|
}
|
||||||
|
|
||||||
|
///////
|
||||||
|
// Restore the config file
|
||||||
|
if configFile.UncompressedSize64 > maxConfigSize {
|
||||||
|
return fmt.Errorf("config file too large, is %d, max size is %d", configFile.UncompressedSize64, maxConfigSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile, err := os.OpenFile(configFile.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, configFile.Mode())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not open config file for writing: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfgr, err := configFile.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// #nosec - We eliminated the potential decompression bomb by erroring out above if the file is larger than a threshold.
|
||||||
|
_, err = io.Copy(outFile, cfgr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not create config file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = cfgr.Close()
|
||||||
|
_ = outFile.Close()
|
||||||
|
|
||||||
|
log.Infof("The config file has been restored to '%s'.", configFile.Name)
|
||||||
|
log.Infof("You can now make changes to it, hit enter when you're done.")
|
||||||
|
if _, err := bufio.NewReader(os.Stdin).ReadString('\n'); err != nil {
|
||||||
|
return fmt.Errorf("could not read from stdin: %s", err)
|
||||||
|
}
|
||||||
|
log.Info("Restoring...")
|
||||||
|
|
||||||
|
// Init the configFile again since the restored configuration is most likely different from the one before
|
||||||
|
initialize.LightInit()
|
||||||
|
initialize.InitEngines()
|
||||||
|
files.InitFileHandler()
|
||||||
|
|
||||||
|
///////
|
||||||
|
// Restore the db
|
||||||
|
// Start by wiping everything
|
||||||
|
if err := db.WipeEverything(); err != nil {
|
||||||
|
return fmt.Errorf("could not wipe database: %s", err)
|
||||||
|
}
|
||||||
|
log.Info("Wiped database.")
|
||||||
|
|
||||||
|
// Because we don't explicitly saved the table definitions, we take the last ran db migration from the dump
|
||||||
|
// and execute everything until that point.
|
||||||
|
migrations := dbfiles["migration"]
|
||||||
|
rc, err := migrations.Open()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not open migrations: %s", err)
|
||||||
|
}
|
||||||
|
defer rc.Close()
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if _, err := buf.ReadFrom(rc); err != nil {
|
||||||
|
return fmt.Errorf("could not read migrations: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ms := []*xormigrate.Migration{}
|
||||||
|
if err := json.Unmarshal(buf.Bytes(), &ms); err != nil {
|
||||||
|
return fmt.Errorf("could not read migrations: %s", err)
|
||||||
|
}
|
||||||
|
sort.Slice(ms, func(i, j int) bool {
|
||||||
|
return ms[i].ID > ms[j].ID
|
||||||
|
})
|
||||||
|
|
||||||
|
lastMigration := ms[len(ms)-1]
|
||||||
|
if err := migration.MigrateTo(lastMigration.ID, nil); err != nil {
|
||||||
|
return fmt.Errorf("could not create db structure: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore all db data
|
||||||
|
for table, d := range dbfiles {
|
||||||
|
content, err := unmarshalFileToJSON(d)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not read table %s: %s", table, err)
|
||||||
|
}
|
||||||
|
if err := db.Restore(table, content); err != nil {
|
||||||
|
return fmt.Errorf("could not restore table data for table %s: %s", table, err)
|
||||||
|
}
|
||||||
|
log.Infof("Restored table %s", table)
|
||||||
|
}
|
||||||
|
log.Infof("Restored %d tables", len(dbfiles))
|
||||||
|
|
||||||
|
// Run migrations again to migrate a potentially outdated dump
|
||||||
|
migration.Migrate(nil)
|
||||||
|
|
||||||
|
///////
|
||||||
|
// Restore Files
|
||||||
|
for i, file := range filesFiles {
|
||||||
|
id, err := strconv.ParseInt(i, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not parse file id %s: %s", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f := &files.File{ID: id}
|
||||||
|
|
||||||
|
fc, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not open file %s: %s", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := f.Save(fc); err != nil {
|
||||||
|
return fmt.Errorf("could not save file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = fc.Close()
|
||||||
|
log.Infof("Restored file %s", i)
|
||||||
|
}
|
||||||
|
log.Infof("Restored %d files.", len(filesFiles))
|
||||||
|
|
||||||
|
///////
|
||||||
|
// Done
|
||||||
|
log.Infof("Done restoring dump.")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarshalFileToJSON(file *zip.File) (contents []map[string]interface{}, err error) {
|
||||||
|
rc, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rc.Close()
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if _, err := buf.ReadFrom(rc); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
contents = []map[string]interface{}{}
|
||||||
|
if err := json.Unmarshal(buf.Bytes(), &contents); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -45,6 +45,9 @@ func RegisterUser(c echo.Context) error {
|
||||||
if err := c.Bind(&datUser); err != nil {
|
if err := c.Bind(&datUser); err != nil {
|
||||||
return c.JSON(http.StatusBadRequest, models.Message{"No or invalid user model provided."})
|
return c.JSON(http.StatusBadRequest, models.Message{"No or invalid user model provided."})
|
||||||
}
|
}
|
||||||
|
if datUser == nil {
|
||||||
|
return c.JSON(http.StatusBadRequest, models.Message{"No or invalid user model provided."})
|
||||||
|
}
|
||||||
|
|
||||||
// Insert the user
|
// Insert the user
|
||||||
newUser, err := user.CreateUser(datUser.APIFormat())
|
newUser, err := user.CreateUser(datUser.APIFormat())
|
||||||
|
|
|
@ -59,13 +59,17 @@ import (
|
||||||
"code.vikunja.io/api/pkg/routes/caldav"
|
"code.vikunja.io/api/pkg/routes/caldav"
|
||||||
_ "code.vikunja.io/api/pkg/swagger" // To generate swagger docs
|
_ "code.vikunja.io/api/pkg/swagger" // To generate swagger docs
|
||||||
"code.vikunja.io/api/pkg/user"
|
"code.vikunja.io/api/pkg/user"
|
||||||
|
"code.vikunja.io/api/pkg/version"
|
||||||
"code.vikunja.io/web"
|
"code.vikunja.io/web"
|
||||||
"code.vikunja.io/web/handler"
|
"code.vikunja.io/web/handler"
|
||||||
"github.com/asaskevich/govalidator"
|
"github.com/asaskevich/govalidator"
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
sentryecho "github.com/getsentry/sentry-go/echo"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
elog "github.com/labstack/gommon/log"
|
elog "github.com/labstack/gommon/log"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CustomValidator is a dummy struct to use govalidator with echo
|
// CustomValidator is a dummy struct to use govalidator with echo
|
||||||
|
@ -116,6 +120,42 @@ func NewEcho() *echo.Echo {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// panic recover
|
||||||
|
e.Use(middleware.Recover())
|
||||||
|
|
||||||
|
if config.ServiceSentryDsn.GetString() != "" {
|
||||||
|
if err := sentry.Init(sentry.ClientOptions{
|
||||||
|
Dsn: config.ServiceSentryDsn.GetString(),
|
||||||
|
AttachStacktrace: true,
|
||||||
|
Release: version.Version,
|
||||||
|
}); err != nil {
|
||||||
|
log.Criticalf("Sentry init failed: %s", err)
|
||||||
|
}
|
||||||
|
defer sentry.Flush(5 * time.Second)
|
||||||
|
|
||||||
|
e.Use(sentryecho.New(sentryecho.Options{
|
||||||
|
Repanic: true,
|
||||||
|
}))
|
||||||
|
|
||||||
|
e.HTTPErrorHandler = func(err error, c echo.Context) {
|
||||||
|
// Only capture errors not already handled by echo
|
||||||
|
if _, ok := err.(*echo.HTTPError); !ok {
|
||||||
|
hub := sentryecho.GetHubFromContext(c)
|
||||||
|
if hub != nil {
|
||||||
|
hub.WithScope(func(scope *sentry.Scope) {
|
||||||
|
scope.SetExtra("url", c.Request().URL)
|
||||||
|
hub.CaptureException(err)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
sentry.CaptureException(err)
|
||||||
|
log.Debugf("Could not add context for sending error '%s' to sentry", err.Error())
|
||||||
|
}
|
||||||
|
log.Debugf("Error '%s' sent to sentry", err.Error())
|
||||||
|
}
|
||||||
|
e.DefaultHTTPErrorHandler(err, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Validation
|
// Validation
|
||||||
e.Validator = &CustomValidator{}
|
e.Validator = &CustomValidator{}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ type User struct {
|
||||||
// The unique, numeric id of this user.
|
// The unique, numeric id of this user.
|
||||||
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"`
|
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"`
|
||||||
// The username of the user. Is always unique.
|
// The username of the user. Is always unique.
|
||||||
Username string `xorm:"varchar(250) not null unique" json:"username" valid:"length(3|250)" minLength:"3" maxLength:"250"`
|
Username string `xorm:"varchar(250) not null unique" json:"username" valid:"length(1|250)" minLength:"3" maxLength:"250"`
|
||||||
Password string `xorm:"varchar(250) not null" json:"-"`
|
Password string `xorm:"varchar(250) not null" json:"-"`
|
||||||
// The user's email address.
|
// The user's email address.
|
||||||
Email string `xorm:"varchar(250) null" json:"email,omitempty" valid:"email,length(0|250)" maxLength:"250"`
|
Email string `xorm:"varchar(250) null" json:"email,omitempty" valid:"email,length(0|250)" maxLength:"250"`
|
||||||
|
|
|
@ -21,6 +21,3 @@ package version
|
||||||
|
|
||||||
// Version sets the version to be printed to the user. Gets overwritten by "make release" or "make build" with last git commit or tag.
|
// Version sets the version to be printed to the user. Gets overwritten by "make release" or "make build" with last git commit or tag.
|
||||||
var Version = "0.7"
|
var Version = "0.7"
|
||||||
|
|
||||||
// BuildTime contains the build time of vikunja.
|
|
||||||
var BuildTime = ""
|
|
||||||
|
|
2
vendor/code.vikunja.io/web/go.mod
generated
vendored
2
vendor/code.vikunja.io/web/go.mod
generated
vendored
|
@ -1,5 +1,7 @@
|
||||||
module code.vikunja.io/web
|
module code.vikunja.io/web
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f
|
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
|
|
19
vendor/github.com/getsentry/sentry-go/.craft.yml
generated
vendored
Normal file
19
vendor/github.com/getsentry/sentry-go/.craft.yml
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
minVersion: '0.9.2'
|
||||||
|
github:
|
||||||
|
owner: getsentry
|
||||||
|
repo: sentry-go
|
||||||
|
preReleaseCommand: bash scripts/craft-pre-release.sh
|
||||||
|
changelogPolicy: simple
|
||||||
|
statusProvider:
|
||||||
|
name: github
|
||||||
|
config:
|
||||||
|
contexts:
|
||||||
|
- Travis CI - Branch
|
||||||
|
targets:
|
||||||
|
- name: github
|
||||||
|
includeNames: /none/
|
||||||
|
tagPrefix: v
|
||||||
|
- name: registry
|
||||||
|
type: sdk
|
||||||
|
config:
|
||||||
|
canonical: "github:getsentry/sentry-go"
|
6
vendor/github.com/getsentry/sentry-go/.gitignore
generated
vendored
Normal file
6
vendor/github.com/getsentry/sentry-go/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
coverage.txt
|
||||||
|
|
||||||
|
# Just my personal way of tracking stuff — Kamil
|
||||||
|
FIXME.md
|
||||||
|
TODO.md
|
||||||
|
!NOTES.md
|
50
vendor/github.com/getsentry/sentry-go/.golangci.yml
generated
vendored
Normal file
50
vendor/github.com/getsentry/sentry-go/.golangci.yml
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
linters:
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- bodyclose
|
||||||
|
- deadcode
|
||||||
|
- depguard
|
||||||
|
- dogsled
|
||||||
|
- dupl
|
||||||
|
- errcheck
|
||||||
|
- gochecknoglobals
|
||||||
|
- gochecknoinits
|
||||||
|
- goconst
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- golint
|
||||||
|
- gosec
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- interfacer
|
||||||
|
- lll
|
||||||
|
- maligned
|
||||||
|
- misspell
|
||||||
|
- nakedret
|
||||||
|
- prealloc
|
||||||
|
- scopelint
|
||||||
|
- staticcheck
|
||||||
|
- structcheck
|
||||||
|
- typecheck
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- unused
|
||||||
|
- varcheck
|
||||||
|
run:
|
||||||
|
skip-dirs:
|
||||||
|
- echo
|
||||||
|
- example/echo
|
||||||
|
issues:
|
||||||
|
exclude:
|
||||||
|
- "not declared by package utf8"
|
||||||
|
- "unicode/utf8/utf8.go"
|
||||||
|
exclude-rules:
|
||||||
|
- path: _test\.go
|
||||||
|
linters:
|
||||||
|
- prealloc
|
||||||
|
- path: errors_test\.go
|
||||||
|
linters:
|
||||||
|
- unused
|
49
vendor/github.com/getsentry/sentry-go/.travis.yml
generated
vendored
Normal file
49
vendor/github.com/getsentry/sentry-go/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.12.x
|
||||||
|
- 1.13.x
|
||||||
|
- 1.14.x
|
||||||
|
- master
|
||||||
|
|
||||||
|
env:
|
||||||
|
- GO111MODULE=on GOFLAGS=-mod=readonly
|
||||||
|
- GO111MODULE=off
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- name: "Module support outside of GOPATH"
|
||||||
|
go: stable
|
||||||
|
before_script: >-
|
||||||
|
mv $GOPATH/src/github.com/getsentry/sentry-go ~/sentry-go &&
|
||||||
|
cd ~/sentry-go &&
|
||||||
|
export GOPATH= &&
|
||||||
|
go env GOPATH
|
||||||
|
script: >-
|
||||||
|
go test ./... &&
|
||||||
|
go test ./... -race
|
||||||
|
allow_failures:
|
||||||
|
- go: master
|
||||||
|
fast_finish: true
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/v1.19.1/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.19.1
|
||||||
|
# Fetch origin/master. This is required for `git merge-base` when testing a
|
||||||
|
# branch, since Travis clones only the target branch.
|
||||||
|
- git fetch origin master:remotes/origin/master
|
||||||
|
|
||||||
|
script:
|
||||||
|
- golangci-lint run --new-from-rev=$(git merge-base origin/master HEAD)
|
||||||
|
- go build ./...
|
||||||
|
- go test ./...
|
||||||
|
- go test ./... -race
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
webhooks:
|
||||||
|
urls:
|
||||||
|
- https://zeus.ci/hooks/befe9810-9285-11e9-b01a-0a580a281808/public/provider/travis/webhook
|
||||||
|
on_success: always
|
||||||
|
on_failure: always
|
||||||
|
on_start: always
|
||||||
|
on_cancel: always
|
||||||
|
on_error: always
|
226
vendor/github.com/getsentry/sentry-go/CHANGELOG.md
generated
vendored
Normal file
226
vendor/github.com/getsentry/sentry-go/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
- "I am running away from my responsibilities. And it feels good." – Michael Scott, Season 4, "Money"
|
||||||
|
|
||||||
|
## v0.6.1
|
||||||
|
|
||||||
|
- fix: Use NewEvent to init Event struct (#220)
|
||||||
|
|
||||||
|
_NOTE:_
|
||||||
|
A change introduced in v0.6.0 with the intent of avoiding allocations made a
|
||||||
|
pattern used in official examples break in certain circumstances (attempting
|
||||||
|
to write to a nil map).
|
||||||
|
This release reverts the change such that maps in the Event struct are always
|
||||||
|
allocated.
|
||||||
|
|
||||||
|
## v0.6.0
|
||||||
|
|
||||||
|
- feat: Read module dependencies from runtime/debug (#199)
|
||||||
|
- feat: Support chained errors using Unwrap (#206)
|
||||||
|
- feat: Report chain of errors when available (#185)
|
||||||
|
- **[breaking]** fix: Accept http.RoundTripper to customize transport (#205)
|
||||||
|
Before the SDK accepted a concrete value of type `*http.Transport` in
|
||||||
|
`ClientOptions`, now it accepts any value implementing the `http.RoundTripper`
|
||||||
|
interface. Note that `*http.Transport` implements `http.RoundTripper`, so most
|
||||||
|
code bases will continue to work unchanged.
|
||||||
|
Users of custom transport gain the ability to pass in other implementations of
|
||||||
|
`http.RoundTripper` and may be able to simplify their code bases.
|
||||||
|
- fix: Do not panic when scope event processor drops event (#192)
|
||||||
|
- **[breaking]** fix: Use time.Time for timestamps (#191)
|
||||||
|
Users of sentry-go typically do not need to manipulate timestamps manually.
|
||||||
|
For those who do, the field type changed from `int64` to `time.Time`, which
|
||||||
|
should be more convenient to use. The recommended way to get the current time
|
||||||
|
is `time.Now().UTC()`.
|
||||||
|
- fix: Report usage error including stack trace (#189)
|
||||||
|
- feat: Add Exception.ThreadID field (#183)
|
||||||
|
- ci: Test against Go 1.14, drop 1.11 (#170)
|
||||||
|
- feat: Limit reading bytes from request bodies (#168)
|
||||||
|
- **[breaking]** fix: Rename fasthttp integration package sentryhttp => sentryfasthttp
|
||||||
|
The current recommendation is to use a named import, in which case existing
|
||||||
|
code should not require any change:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
sentryfasthttp "github.com/getsentry/sentry-go/fasthttp"
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
_NOTE:_
|
||||||
|
This version includes some new features and a few breaking changes, none of
|
||||||
|
which should pose troubles with upgrading. Most code bases should be able to
|
||||||
|
upgrade without any changes.
|
||||||
|
|
||||||
|
## v0.5.1
|
||||||
|
|
||||||
|
- fix: Ignore err.Cause() when it is nil (#160)
|
||||||
|
|
||||||
|
## v0.5.0
|
||||||
|
|
||||||
|
- fix: Synchronize access to HTTPTransport.disabledUntil (#158)
|
||||||
|
- docs: Update Flush documentation (#153)
|
||||||
|
- fix: HTTPTransport.Flush panic and data race (#140)
|
||||||
|
|
||||||
|
_NOTE:_
|
||||||
|
This version changes the implementation of the default transport, modifying the
|
||||||
|
behavior of `sentry.Flush`. The previous behavior was to wait until there were
|
||||||
|
no buffered events; new concurrent events kept `Flush` from returning. The new
|
||||||
|
behavior is to wait until the last event prior to the call to `Flush` has been
|
||||||
|
sent or the timeout; new concurrent events have no effect. The new behavior is
|
||||||
|
inline with the [Unified API
|
||||||
|
Guidelines](https://docs.sentry.io/development/sdk-dev/unified-api/).
|
||||||
|
|
||||||
|
We have updated the documentation and examples to clarify that `Flush` is meant
|
||||||
|
to be called typically only once before program termination, to wait for
|
||||||
|
in-flight events to be sent to Sentry. Calling `Flush` after every event is not
|
||||||
|
recommended, as it introduces unnecessary latency to the surrounding function.
|
||||||
|
Please verify the usage of `sentry.Flush` in your code base.
|
||||||
|
|
||||||
|
## v0.4.0
|
||||||
|
|
||||||
|
- fix(stacktrace): Correctly report package names (#127)
|
||||||
|
- fix(stacktrace): Do not rely on AbsPath of files (#123)
|
||||||
|
- build: Require github.com/ugorji/go@v1.1.7 (#110)
|
||||||
|
- fix: Correctly store last event id (#99)
|
||||||
|
- fix: Include request body in event payload (#94)
|
||||||
|
- build: Reset go.mod version to 1.11 (#109)
|
||||||
|
- fix: Eliminate data race in modules integration (#105)
|
||||||
|
- feat: Add support for path prefixes in the DSN (#102)
|
||||||
|
- feat: Add HTTPClient option (#86)
|
||||||
|
- feat: Extract correct type and value from top-most error (#85)
|
||||||
|
- feat: Check for broken pipe errors in Gin integration (#82)
|
||||||
|
- fix: Client.CaptureMessage accept nil EventModifier (#72)
|
||||||
|
|
||||||
|
## v0.3.1
|
||||||
|
|
||||||
|
- feat: Send extra information exposed by the Go runtime (#76)
|
||||||
|
- fix: Handle new lines in module integration (#65)
|
||||||
|
- fix: Make sure that cache is locked when updating for contextifyFramesIntegration
|
||||||
|
- ref: Update Iris integration and example to version 12
|
||||||
|
- misc: Remove indirect dependencies in order to move them to separate go.mod files
|
||||||
|
|
||||||
|
## v0.3.0
|
||||||
|
|
||||||
|
- feat: Retry event marshalling without contextual data if the first pass fails
|
||||||
|
- fix: Include `url.Parse` error in `DsnParseError`
|
||||||
|
- fix: Make more `Scope` methods safe for concurrency
|
||||||
|
- fix: Synchronize concurrent access to `Hub.client`
|
||||||
|
- ref: Remove mutex from `Scope` exported API
|
||||||
|
- ref: Remove mutex from `Hub` exported API
|
||||||
|
- ref: Compile regexps for `filterFrames` only once
|
||||||
|
- ref: Change `SampleRate` type to `float64`
|
||||||
|
- doc: `Scope.Clear` not safe for concurrent use
|
||||||
|
- ci: Test sentry-go with `go1.13`, drop `go1.10`
|
||||||
|
|
||||||
|
_NOTE:_
|
||||||
|
This version removes some of the internal APIs that landed publicly (namely `Hub/Scope` mutex structs) and may require (but shouldn't) some changes to your code.
|
||||||
|
It's not done through major version update, as we are still in `0.x` stage.
|
||||||
|
|
||||||
|
## v0.2.1
|
||||||
|
|
||||||
|
- fix: Run `Contextify` integration on `Threads` as well
|
||||||
|
|
||||||
|
## v0.2.0
|
||||||
|
|
||||||
|
- feat: Add `SetTransaction()` method on the `Scope`
|
||||||
|
- feat: `fasthttp` framework support with `sentryfasthttp` package
|
||||||
|
- fix: Add `RWMutex` locks to internal `Hub` and `Scope` changes
|
||||||
|
|
||||||
|
## v0.1.3
|
||||||
|
|
||||||
|
- feat: Move frames context reading into `contextifyFramesIntegration` (#28)
|
||||||
|
|
||||||
|
_NOTE:_
|
||||||
|
In case of any performance issues due to source contexts IO, you can let us know and turn off the integration in the meantime with:
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.Init(sentry.ClientOptions{
|
||||||
|
Integrations: func(integrations []sentry.Integration) []sentry.Integration {
|
||||||
|
var filteredIntegrations []sentry.Integration
|
||||||
|
for _, integration := range integrations {
|
||||||
|
if integration.Name() == "ContextifyFrames" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filteredIntegrations = append(filteredIntegrations, integration)
|
||||||
|
}
|
||||||
|
return filteredIntegrations
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## v0.1.2
|
||||||
|
|
||||||
|
- feat: Better source code location resolution and more useful inapp frames (#26)
|
||||||
|
- feat: Use `noopTransport` when no `Dsn` provided (#27)
|
||||||
|
- ref: Allow empty `Dsn` instead of returning an error (#22)
|
||||||
|
- fix: Use `NewScope` instead of literal struct inside a `scope.Clear` call (#24)
|
||||||
|
- fix: Add to `WaitGroup` before the request is put inside a buffer (#25)
|
||||||
|
|
||||||
|
## v0.1.1
|
||||||
|
|
||||||
|
- fix: Check for initialized `Client` in `AddBreadcrumbs` (#20)
|
||||||
|
- build: Bump version when releasing with Craft (#19)
|
||||||
|
|
||||||
|
## v0.1.0
|
||||||
|
|
||||||
|
- First stable release! \o/
|
||||||
|
|
||||||
|
## v0.0.1-beta.5
|
||||||
|
|
||||||
|
- feat: **[breaking]** Add `NewHTTPTransport` and `NewHTTPSyncTransport` which accepts all transport options
|
||||||
|
- feat: New `HTTPSyncTransport` that blocks after each call
|
||||||
|
- feat: New `Echo` integration
|
||||||
|
- ref: **[breaking]** Remove `BufferSize` option from `ClientOptions` and move it to `HTTPTransport` instead
|
||||||
|
- ref: Export default `HTTPTransport`
|
||||||
|
- ref: Export `net/http` integration handler
|
||||||
|
- ref: Set `Request` instantly in the package handlers, not in `recoverWithSentry` so it can be accessed later on
|
||||||
|
- ci: Add craft config
|
||||||
|
|
||||||
|
## v0.0.1-beta.4
|
||||||
|
|
||||||
|
- feat: `IgnoreErrors` client option and corresponding integration
|
||||||
|
- ref: Reworked `net/http` integration, wrote better example and complete readme
|
||||||
|
- ref: Reworked `Gin` integration, wrote better example and complete readme
|
||||||
|
- ref: Reworked `Iris` integration, wrote better example and complete readme
|
||||||
|
- ref: Reworked `Negroni` integration, wrote better example and complete readme
|
||||||
|
- ref: Reworked `Martini` integration, wrote better example and complete readme
|
||||||
|
- ref: Remove `Handle()` from frameworks handlers and return it directly from New
|
||||||
|
|
||||||
|
## v0.0.1-beta.3
|
||||||
|
|
||||||
|
- feat: `Iris` framework support with `sentryiris` package
|
||||||
|
- feat: `Gin` framework support with `sentrygin` package
|
||||||
|
- feat: `Martini` framework support with `sentrymartini` package
|
||||||
|
- feat: `Negroni` framework support with `sentrynegroni` package
|
||||||
|
- feat: Add `Hub.Clone()` for easier frameworks integration
|
||||||
|
- feat: Return `EventID` from `Recovery` methods
|
||||||
|
- feat: Add `NewScope` and `NewEvent` functions and use them in the whole codebase
|
||||||
|
- feat: Add `AddEventProcessor` to the `Client`
|
||||||
|
- fix: Operate on requests body copy instead of the original
|
||||||
|
- ref: Try to read source files from the root directory, based on the filename as well, to make it work on AWS Lambda
|
||||||
|
- ref: Remove `gocertifi` dependence and document how to provide your own certificates
|
||||||
|
- ref: **[breaking]** Remove `Decorate` and `DecorateFunc` methods in favor of `sentryhttp` package
|
||||||
|
- ref: **[breaking]** Allow for integrations to live on the client, by passing client instance in `SetupOnce` method
|
||||||
|
- ref: **[breaking]** Remove `GetIntegration` from the `Hub`
|
||||||
|
- ref: **[breaking]** Remove `GlobalEventProcessors` getter from the public API
|
||||||
|
|
||||||
|
## v0.0.1-beta.2
|
||||||
|
|
||||||
|
- feat: Add `AttachStacktrace` client option to include stacktrace for messages
|
||||||
|
- feat: Add `BufferSize` client option to configure transport buffer size
|
||||||
|
- feat: Add `SetRequest` method on a `Scope` to control `Request` context data
|
||||||
|
- feat: Add `FromHTTPRequest` for `Request` type for easier extraction
|
||||||
|
- ref: Extract `Request` information more accurately
|
||||||
|
- fix: Attach `ServerName`, `Release`, `Dist`, `Environment` options to the event
|
||||||
|
- fix: Don't log events dropped due to full transport buffer as sent
|
||||||
|
- fix: Don't panic and create an appropriate event when called `CaptureException` or `Recover` with `nil` value
|
||||||
|
|
||||||
|
## v0.0.1-beta
|
||||||
|
|
||||||
|
- Initial release
|
53
vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md
generated
vendored
Normal file
53
vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
## Community
|
||||||
|
|
||||||
|
The public-facing channels for support and development of Sentry SDKs can be found on [Discord](https://discord.gg/Ww9hbqr).
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ go test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Watch mode
|
||||||
|
|
||||||
|
Use: https://github.com/cespare/reflex
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ reflex -g '*.go' -d "none" -- sh -c 'printf "\n"; go test'
|
||||||
|
```
|
||||||
|
|
||||||
|
### With data race detection
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ go test -race
|
||||||
|
```
|
||||||
|
|
||||||
|
### Coverage
|
||||||
|
```console
|
||||||
|
$ go test -race -coverprofile=coverage.txt -covermode=atomic && go tool cover -html coverage.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Linting
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ golangci-lint run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Release
|
||||||
|
|
||||||
|
1. Update `CHANGELOG.md` with new version in `vX.X.X` format title and list of changes.
|
||||||
|
|
||||||
|
The command below can be used to get a list of changes since the last tag, with the format used in `CHANGELOG.md`:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ git log --no-merges --format=%s $(git describe --abbrev=0).. | sed 's/^/- /'
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Commit with `misc: vX.X.X changelog` commit message and push to `master`.
|
||||||
|
|
||||||
|
3. Let [`craft`](https://github.com/getsentry/craft) do the rest:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ craft prepare X.X.X
|
||||||
|
$ craft publish X.X.X
|
||||||
|
```
|
9
vendor/github.com/getsentry/sentry-go/LICENSE
generated
vendored
Normal file
9
vendor/github.com/getsentry/sentry-go/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Copyright (c) 2019 Sentry (https://sentry.io) and individual contributors.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
392
vendor/github.com/getsentry/sentry-go/MIGRATION.md
generated
vendored
Normal file
392
vendor/github.com/getsentry/sentry-go/MIGRATION.md
generated
vendored
Normal file
|
@ -0,0 +1,392 @@
|
||||||
|
# `raven-go` to `sentry-go` Migration Guide
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
go get github.com/getsentry/raven-go
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
go get github.com/getsentry/sentry-go@v0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/getsentry/raven-go"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
raven.SetDSN("___PUBLIC_DSN___")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := sentry.Init(sentry.ClientOptions{
|
||||||
|
Dsn: "___PUBLIC_DSN___",
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Sentry initialization failed: %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
SetDSN()
|
||||||
|
SetDefaultLoggerName()
|
||||||
|
SetDebug()
|
||||||
|
SetEnvironment()
|
||||||
|
SetRelease()
|
||||||
|
SetSampleRate()
|
||||||
|
SetIgnoreErrors()
|
||||||
|
SetIncludePaths()
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.Init(sentry.ClientOptions{
|
||||||
|
Dsn: "___PUBLIC_DSN___",
|
||||||
|
DebugWriter: os.Stderr,
|
||||||
|
Debug: true,
|
||||||
|
Environment: "environment",
|
||||||
|
Release: "release",
|
||||||
|
SampleRate: 0.5,
|
||||||
|
// IgnoreErrors: TBD,
|
||||||
|
// IncludePaths: TBD
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Available options: see [Configuration](https://docs.sentry.io/platforms/go/config/) section.
|
||||||
|
|
||||||
|
### Providing SSL Certificates
|
||||||
|
|
||||||
|
By default, TLS uses the host's root CA set. If you don't have `ca-certificates` (which should be your go-to way of fixing the issue of missing certificates) and want to use `gocertifi` instead, you can provide pre-loaded cert files as one of the options to the `sentry.Init` call:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/certifi/gocertifi"
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
sentryClientOptions := sentry.ClientOptions{
|
||||||
|
Dsn: "___PUBLIC_DSN___",
|
||||||
|
}
|
||||||
|
|
||||||
|
rootCAs, err := gocertifi.CACerts()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Couldn't load CA Certificates: %v\n", err)
|
||||||
|
} else {
|
||||||
|
sentryClientOptions.CaCerts = rootCAs
|
||||||
|
}
|
||||||
|
|
||||||
|
sentry.Init(sentryClientOptions)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Capturing Errors
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
f, err := os.Open("filename.ext")
|
||||||
|
if err != nil {
|
||||||
|
raven.CaptureError(err, nil)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
f, err := os.Open("filename.ext")
|
||||||
|
if err != nil {
|
||||||
|
sentry.CaptureException(err)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Capturing Panics
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
raven.CapturePanic(func() {
|
||||||
|
// do all of the scary things here
|
||||||
|
}, nil)
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
func() {
|
||||||
|
defer sentry.Recover()
|
||||||
|
// do all of the scary things here
|
||||||
|
}()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Capturing Messages
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
raven.CaptureMessage("Something bad happened and I would like to know about that")
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.CaptureMessage("Something bad happened and I would like to know about that")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Capturing Events
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
packet := &raven.Packet{
|
||||||
|
Message: "Hand-crafted event",
|
||||||
|
Extra: &raven.Extra{
|
||||||
|
"runtime.Version": runtime.Version(),
|
||||||
|
"runtime.NumCPU": runtime.NumCPU(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
raven.Capture(packet)
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
event := &sentry.NewEvent()
|
||||||
|
event.Message = "Hand-crafted event"
|
||||||
|
event.Extra["runtime.Version"] = runtime.Version()
|
||||||
|
event.Extra["runtime.NumCPU"] = runtime.NumCPU()
|
||||||
|
|
||||||
|
sentry.CaptureEvent(event)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Additional Data
|
||||||
|
|
||||||
|
See Context section.
|
||||||
|
|
||||||
|
### Event Sampling
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
raven.SetSampleRate(0.25)
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.Init(sentry.ClientOptions{
|
||||||
|
SampleRate: 0.25,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Awaiting the response (not recommended)
|
||||||
|
|
||||||
|
```go
|
||||||
|
raven.CaptureMessageAndWait("Something bad happened and I would like to know about that")
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.CaptureMessage("Something bad happened and I would like to know about that")
|
||||||
|
|
||||||
|
if sentry.Flush(time.Second * 2) {
|
||||||
|
// event delivered
|
||||||
|
} else {
|
||||||
|
// timeout reached
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
### Per-event
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
raven.CaptureError(err, map[string]string{"browser": "Firefox"}, &raven.Http{
|
||||||
|
Method: "GET",
|
||||||
|
URL: "https://example.com/raven-go"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.WithScope(func(scope *sentry.Scope) {
|
||||||
|
scope.SetTag("browser", "Firefox")
|
||||||
|
scope.SetContext("Request", map[string]string{
|
||||||
|
"Method": "GET",
|
||||||
|
"URL": "https://example.com/raven-go",
|
||||||
|
})
|
||||||
|
sentry.CaptureException(err)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Globally
|
||||||
|
|
||||||
|
#### SetHttpContext
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
raven.SetHttpContext(&raven.Http{
|
||||||
|
Method: "GET",
|
||||||
|
URL: "https://example.com/raven-go",
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
||||||
|
scope.SetContext("Request", map[string]string{
|
||||||
|
"Method": "GET",
|
||||||
|
"URL": "https://example.com/raven-go",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### SetTagsContext
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
t := map[string]string{"day": "Friday", "sport": "Weightlifting"}
|
||||||
|
raven.SetTagsContext(map[string]string{"day": "Friday", "sport": "Weightlifting"})
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
||||||
|
scope.SetTags(map[string]string{"day": "Friday", "sport": "Weightlifting"})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### SetUserContext
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
raven.SetUserContext(&raven.User{
|
||||||
|
ID: "1337",
|
||||||
|
Username: "kamilogorek",
|
||||||
|
Email: "kamil@sentry.io",
|
||||||
|
IP: "127.0.0.1",
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
||||||
|
scope.SetUser(sentry.User{
|
||||||
|
ID: "1337",
|
||||||
|
Username: "kamilogorek",
|
||||||
|
Email: "kamil@sentry.io",
|
||||||
|
IPAddress: "127.0.0.1",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ClearContext
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
raven.ClearContext()
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
||||||
|
scope.Clear()
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### WrapWithExtra
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
path := "filename.ext"
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
err = raven.WrapWithExtra(err, map[string]string{"path": path, "cwd": os.Getwd()}
|
||||||
|
raven.CaptureError(err, nil)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
// use `sentry.WithScope`, see "Context / Per-event Section"
|
||||||
|
path := "filename.ext"
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
sentry.WithScope(func(scope *sentry.Scope) {
|
||||||
|
sentry.SetExtras(map[string]interface{}{"path": path, "cwd": os.Getwd())
|
||||||
|
sentry.CaptureException(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integrations
|
||||||
|
|
||||||
|
### net/http
|
||||||
|
|
||||||
|
raven-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
mux := http.NewServeMux
|
||||||
|
http.Handle("/", raven.Recoverer(mux))
|
||||||
|
|
||||||
|
// or
|
||||||
|
|
||||||
|
func root(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
http.HandleFunc("/", raven.RecoveryHandler(root))
|
||||||
|
```
|
||||||
|
|
||||||
|
sentry-go
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentryHandler := sentryhttp.New(sentryhttp.Options{
|
||||||
|
Repanic: false,
|
||||||
|
WaitForDelivery: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
mux := http.NewServeMux
|
||||||
|
http.Handle("/", sentryHandler.Handle(mux))
|
||||||
|
|
||||||
|
// or
|
||||||
|
|
||||||
|
func root(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
http.HandleFunc("/", sentryHandler.HandleFunc(root))
|
||||||
|
```
|
190
vendor/github.com/getsentry/sentry-go/README.md
generated
vendored
Normal file
190
vendor/github.com/getsentry/sentry-go/README.md
generated
vendored
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://sentry.io" target="_blank" align="center">
|
||||||
|
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
|
||||||
|
</a>
|
||||||
|
<br />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# Official Sentry SDK for Go
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.com/getsentry/sentry-go.svg?branch=master)](https://travis-ci.com/getsentry/sentry-go)
|
||||||
|
[![Go Report Card](https://goreportcard.com/badge/github.com/getsentry/sentry-go)](https://goreportcard.com/report/github.com/getsentry/sentry-go)
|
||||||
|
[![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr)
|
||||||
|
[![GoDoc](https://godoc.org/github.com/getsentry/sentry-go?status.svg)](https://godoc.org/github.com/getsentry/sentry-go)
|
||||||
|
[![go.dev](https://img.shields.io/badge/go.dev-pkg-007d9c.svg?style=flat)](https://pkg.go.dev/github.com/getsentry/sentry-go)
|
||||||
|
|
||||||
|
`sentry-go` provides a Sentry client implementation for the Go programming
|
||||||
|
language. This is the next line of the Go SDK for [Sentry](https://sentry.io/),
|
||||||
|
intended to replace the `raven-go` package.
|
||||||
|
|
||||||
|
> Looking for the old `raven-go` SDK documentation? See the Legacy client section [here](https://docs.sentry.io/clients/go/).
|
||||||
|
> If you want to start using sentry-go instead, check out the [migration guide](https://docs.sentry.io/platforms/go/migration/).
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
The only requirement is a Go compiler.
|
||||||
|
|
||||||
|
We verify this package against the 3 most recent releases of Go. Those are the
|
||||||
|
supported versions. The exact versions are defined in
|
||||||
|
[`.travis.yml`](.travis.yml).
|
||||||
|
|
||||||
|
In addition, we run tests against the current master branch of the Go toolchain,
|
||||||
|
though support for this configuration is best-effort.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
`sentry-go` can be installed like any other Go library through `go get`:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ go get github.com/getsentry/sentry-go
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, if you are already using
|
||||||
|
[Go Modules](https://github.com/golang/go/wiki/Modules), you may specify a
|
||||||
|
version number as well:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ go get github.com/getsentry/sentry-go@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Check out the [list of released versions](https://pkg.go.dev/github.com/getsentry/sentry-go?tab=versions).
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
To use `sentry-go`, you’ll need to import the `sentry-go` package and initialize
|
||||||
|
it with your DSN and other [options](https://godoc.org/github.com/getsentry/sentry-go#ClientOptions).
|
||||||
|
|
||||||
|
If not specified in the SDK initialization, the
|
||||||
|
[DSN](https://docs.sentry.io/error-reporting/configuration/?platform=go#dsn),
|
||||||
|
[Release](https://docs.sentry.io/workflow/releases/?platform=go) and
|
||||||
|
[Environment](https://docs.sentry.io/enriching-error-data/environments/?platform=go)
|
||||||
|
are read from the environment variables `SENTRY_DSN`, `SENTRY_RELEASE` and
|
||||||
|
`SENTRY_ENVIRONMENT`, respectively.
|
||||||
|
|
||||||
|
More on this in the [Configuration](https://docs.sentry.io/platforms/go/config/)
|
||||||
|
section of the official Sentry documentation.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The SDK must be initialized with a call to `sentry.Init`. The default transport
|
||||||
|
is asynchronous and thus most programs should call `sentry.Flush` to wait until
|
||||||
|
buffered events are sent to Sentry right before the program terminates.
|
||||||
|
|
||||||
|
Typically, `sentry.Init` is called in the beginning of `func main` and
|
||||||
|
`sentry.Flush` is [deferred](https://golang.org/ref/spec#Defer_statements) right
|
||||||
|
after.
|
||||||
|
|
||||||
|
> Note that if the program terminates with a call to
|
||||||
|
> [`os.Exit`](https://golang.org/pkg/os/#Exit), either directly or indirectly
|
||||||
|
> via another function like `log.Fatal`, deferred functions are not run.
|
||||||
|
>
|
||||||
|
> In that case, and if it is important for you to report outstanding events
|
||||||
|
> before terminating the program, arrange for `sentry.Flush` to be called before
|
||||||
|
> the program terminates.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// This is an example program that makes an HTTP request and prints response
|
||||||
|
// headers. Whenever a request fails, the error is reported to Sentry.
|
||||||
|
//
|
||||||
|
// Try it by running:
|
||||||
|
//
|
||||||
|
// go run main.go
|
||||||
|
// go run main.go https://sentry.io
|
||||||
|
// go run main.go bad-url
|
||||||
|
//
|
||||||
|
// To actually report events to Sentry, set the DSN either by editing the
|
||||||
|
// appropriate line below or setting the environment variable SENTRY_DSN to
|
||||||
|
// match the DSN of your Sentry project.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
log.Fatalf("usage: %s URL", os.Args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
err := sentry.Init(sentry.ClientOptions{
|
||||||
|
// Either set your DSN here or set the SENTRY_DSN environment variable.
|
||||||
|
Dsn: "",
|
||||||
|
// Enable printing of SDK debug messages.
|
||||||
|
// Useful when getting started or trying to figure something out.
|
||||||
|
Debug: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("sentry.Init: %s", err)
|
||||||
|
}
|
||||||
|
// Flush buffered events before the program terminates.
|
||||||
|
// Set the timeout to the maximum duration the program can afford to wait.
|
||||||
|
defer sentry.Flush(2 * time.Second)
|
||||||
|
|
||||||
|
resp, err := http.Get(os.Args[1])
|
||||||
|
if err != nil {
|
||||||
|
sentry.CaptureException(err)
|
||||||
|
log.Printf("reported to Sentry: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
for header, values := range resp.Header {
|
||||||
|
for _, value := range values {
|
||||||
|
fmt.Printf("%s=%s\n", header, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For your convenience, this example is available at
|
||||||
|
[`example/basic/main.go`](example/basic/main.go).
|
||||||
|
There are also more examples in the
|
||||||
|
[example](example) directory.
|
||||||
|
|
||||||
|
For more detailed information about how to get the most out of `sentry-go`,
|
||||||
|
checkout the official documentation:
|
||||||
|
|
||||||
|
- [Configuration](https://docs.sentry.io/platforms/go/config)
|
||||||
|
- [Error Reporting](https://docs.sentry.io/error-reporting/quickstart?platform=go)
|
||||||
|
- [Enriching Error Data](https://docs.sentry.io/enriching-error-data/context?platform=go)
|
||||||
|
- [Transports](https://docs.sentry.io/platforms/go/transports)
|
||||||
|
- [Integrations](https://docs.sentry.io/platforms/go/integrations)
|
||||||
|
- [net/http](https://docs.sentry.io/platforms/go/http)
|
||||||
|
- [echo](https://docs.sentry.io/platforms/go/echo)
|
||||||
|
- [fasthttp](https://docs.sentry.io/platforms/go/fasthttp)
|
||||||
|
- [gin](https://docs.sentry.io/platforms/go/gin)
|
||||||
|
- [iris](https://docs.sentry.io/platforms/go/iris)
|
||||||
|
- [martini](https://docs.sentry.io/platforms/go/martini)
|
||||||
|
- [negroni](https://docs.sentry.io/platforms/go/negroni)
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
- [Bug Tracker](https://github.com/getsentry/sentry-go/issues)
|
||||||
|
- [GitHub Project](https://github.com/getsentry/sentry-go)
|
||||||
|
- [![GoDoc](https://godoc.org/github.com/getsentry/sentry-go?status.svg)](https://godoc.org/github.com/getsentry/sentry-go)
|
||||||
|
- [![go.dev](https://img.shields.io/badge/go.dev-pkg-007d9c.svg?style=flat)](https://pkg.go.dev/github.com/getsentry/sentry-go)
|
||||||
|
- [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/go/)
|
||||||
|
- [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks)
|
||||||
|
- [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr)
|
||||||
|
- [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](http://stackoverflow.com/questions/tagged/sentry)
|
||||||
|
- [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry)
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Licensed under
|
||||||
|
[The 2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause), see
|
||||||
|
[`LICENSE`](LICENSE).
|
||||||
|
|
||||||
|
## Community
|
||||||
|
|
||||||
|
Join Sentry's [`#go` channel on Discord](https://discord.gg/Ww9hbqr) to get
|
||||||
|
involved and help us improve the SDK!
|
487
vendor/github.com/getsentry/sentry-go/client.go
generated
vendored
Normal file
487
vendor/github.com/getsentry/sentry-go/client.go
generated
vendored
Normal file
|
@ -0,0 +1,487 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/x509"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// maxErrorDepth is the maximum number of errors reported in a chain of errors.
|
||||||
|
// This protects the SDK from an arbitrarily long chain of wrapped errors.
|
||||||
|
//
|
||||||
|
// An additional consideration is that arguably reporting a long chain of errors
|
||||||
|
// is of little use when debugging production errors with Sentry. The Sentry UI
|
||||||
|
// is not optimized for long chains either. The top-level error together with a
|
||||||
|
// stack trace is often the most useful information.
|
||||||
|
const maxErrorDepth = 10
|
||||||
|
|
||||||
|
// usageError is used to report to Sentry an SDK usage error.
|
||||||
|
//
|
||||||
|
// It is not exported because it is never returned by any function or method in
|
||||||
|
// the exported API.
|
||||||
|
type usageError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logger is an instance of log.Logger that is use to provide debug information about running Sentry Client
|
||||||
|
// can be enabled by either using `Logger.SetOutput` directly or with `Debug` client option
|
||||||
|
var Logger = log.New(ioutil.Discard, "[Sentry] ", log.LstdFlags) //nolint: gochecknoglobals
|
||||||
|
|
||||||
|
type EventProcessor func(event *Event, hint *EventHint) *Event
|
||||||
|
|
||||||
|
type EventModifier interface {
|
||||||
|
ApplyToEvent(event *Event, hint *EventHint) *Event
|
||||||
|
}
|
||||||
|
|
||||||
|
var globalEventProcessors []EventProcessor //nolint: gochecknoglobals
|
||||||
|
|
||||||
|
func AddGlobalEventProcessor(processor EventProcessor) {
|
||||||
|
globalEventProcessors = append(globalEventProcessors, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Integration allows for registering a functions that modify or discard captured events.
|
||||||
|
type Integration interface {
|
||||||
|
Name() string
|
||||||
|
SetupOnce(client *Client)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientOptions that configures a SDK Client
|
||||||
|
type ClientOptions struct {
|
||||||
|
// The DSN to use. If the DSN is not set, the client is effectively disabled.
|
||||||
|
Dsn string
|
||||||
|
// In debug mode, the debug information is printed to stdout to help you understand what
|
||||||
|
// sentry is doing.
|
||||||
|
Debug bool
|
||||||
|
// Configures whether SDK should generate and attach stacktraces to pure capture message calls.
|
||||||
|
AttachStacktrace bool
|
||||||
|
// The sample rate for event submission (0.0 - 1.0, defaults to 1.0).
|
||||||
|
SampleRate float64
|
||||||
|
// List of regexp strings that will be used to match against event's message
|
||||||
|
// and if applicable, caught errors type and value.
|
||||||
|
// If the match is found, then a whole event will be dropped.
|
||||||
|
IgnoreErrors []string
|
||||||
|
// Before send callback.
|
||||||
|
BeforeSend func(event *Event, hint *EventHint) *Event
|
||||||
|
// Before breadcrumb add callback.
|
||||||
|
BeforeBreadcrumb func(breadcrumb *Breadcrumb, hint *BreadcrumbHint) *Breadcrumb
|
||||||
|
// Integrations to be installed on the current Client, receives default integrations
|
||||||
|
Integrations func([]Integration) []Integration
|
||||||
|
// io.Writer implementation that should be used with the `Debug` mode
|
||||||
|
DebugWriter io.Writer
|
||||||
|
// The transport to use.
|
||||||
|
// This is an instance of a struct implementing `Transport` interface.
|
||||||
|
// Defaults to `httpTransport` from `transport.go`
|
||||||
|
Transport Transport
|
||||||
|
// The server name to be reported.
|
||||||
|
ServerName string
|
||||||
|
// The release to be sent with events.
|
||||||
|
Release string
|
||||||
|
// The dist to be sent with events.
|
||||||
|
Dist string
|
||||||
|
// The environment to be sent with events.
|
||||||
|
Environment string
|
||||||
|
// Maximum number of breadcrumbs.
|
||||||
|
MaxBreadcrumbs int
|
||||||
|
// An optional pointer to `http.Client` that will be used with a default HTTPTransport.
|
||||||
|
// Using your own client will make HTTPTransport, HTTPProxy, HTTPSProxy and CaCerts options ignored.
|
||||||
|
HTTPClient *http.Client
|
||||||
|
// An optional pointer to `http.Transport` that will be used with a default HTTPTransport.
|
||||||
|
// Using your own transport will make HTTPProxy, HTTPSProxy and CaCerts options ignored.
|
||||||
|
HTTPTransport http.RoundTripper
|
||||||
|
// An optional HTTP proxy to use.
|
||||||
|
// This will default to the `http_proxy` environment variable.
|
||||||
|
// or `https_proxy` if that one exists.
|
||||||
|
HTTPProxy string
|
||||||
|
// An optional HTTPS proxy to use.
|
||||||
|
// This will default to the `HTTPS_PROXY` environment variable
|
||||||
|
// or `http_proxy` if that one exists.
|
||||||
|
HTTPSProxy string
|
||||||
|
// An optional CaCerts to use.
|
||||||
|
// Defaults to `gocertifi.CACerts()`.
|
||||||
|
CaCerts *x509.CertPool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client is the underlying processor that's used by the main API and `Hub` instances.
|
||||||
|
type Client struct {
|
||||||
|
options ClientOptions
|
||||||
|
dsn *Dsn
|
||||||
|
eventProcessors []EventProcessor
|
||||||
|
integrations []Integration
|
||||||
|
Transport Transport
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient creates and returns an instance of `Client` configured using `ClientOptions`.
|
||||||
|
func NewClient(options ClientOptions) (*Client, error) {
|
||||||
|
if options.Debug {
|
||||||
|
debugWriter := options.DebugWriter
|
||||||
|
if debugWriter == nil {
|
||||||
|
debugWriter = os.Stdout
|
||||||
|
}
|
||||||
|
Logger.SetOutput(debugWriter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.Dsn == "" {
|
||||||
|
options.Dsn = os.Getenv("SENTRY_DSN")
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.Release == "" {
|
||||||
|
options.Release = os.Getenv("SENTRY_RELEASE")
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.Environment == "" {
|
||||||
|
options.Environment = os.Getenv("SENTRY_ENVIRONMENT")
|
||||||
|
}
|
||||||
|
|
||||||
|
var dsn *Dsn
|
||||||
|
if options.Dsn != "" {
|
||||||
|
var err error
|
||||||
|
dsn, err = NewDsn(options.Dsn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client := Client{
|
||||||
|
options: options,
|
||||||
|
dsn: dsn,
|
||||||
|
}
|
||||||
|
|
||||||
|
client.setupTransport()
|
||||||
|
client.setupIntegrations()
|
||||||
|
|
||||||
|
return &client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) setupTransport() {
|
||||||
|
transport := client.options.Transport
|
||||||
|
|
||||||
|
if transport == nil {
|
||||||
|
if client.options.Dsn == "" {
|
||||||
|
transport = new(noopTransport)
|
||||||
|
} else {
|
||||||
|
transport = NewHTTPTransport()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transport.Configure(client.options)
|
||||||
|
client.Transport = transport
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) setupIntegrations() {
|
||||||
|
integrations := []Integration{
|
||||||
|
new(contextifyFramesIntegration),
|
||||||
|
new(environmentIntegration),
|
||||||
|
new(modulesIntegration),
|
||||||
|
new(ignoreErrorsIntegration),
|
||||||
|
}
|
||||||
|
|
||||||
|
if client.options.Integrations != nil {
|
||||||
|
integrations = client.options.Integrations(integrations)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, integration := range integrations {
|
||||||
|
if client.integrationAlreadyInstalled(integration.Name()) {
|
||||||
|
Logger.Printf("Integration %s is already installed\n", integration.Name())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
client.integrations = append(client.integrations, integration)
|
||||||
|
integration.SetupOnce(client)
|
||||||
|
Logger.Printf("Integration installed: %s\n", integration.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddEventProcessor adds an event processor to the client.
|
||||||
|
func (client *Client) AddEventProcessor(processor EventProcessor) {
|
||||||
|
client.eventProcessors = append(client.eventProcessors, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options return `ClientOptions` for the current `Client`.
|
||||||
|
func (client Client) Options() ClientOptions {
|
||||||
|
return client.options
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureMessage captures an arbitrary message.
|
||||||
|
func (client *Client) CaptureMessage(message string, hint *EventHint, scope EventModifier) *EventID {
|
||||||
|
event := client.eventFromMessage(message, LevelInfo)
|
||||||
|
return client.CaptureEvent(event, hint, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureException captures an error.
|
||||||
|
func (client *Client) CaptureException(exception error, hint *EventHint, scope EventModifier) *EventID {
|
||||||
|
event := client.eventFromException(exception, LevelError)
|
||||||
|
return client.CaptureEvent(event, hint, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureEvent captures an event on the currently active client if any.
|
||||||
|
//
|
||||||
|
// The event must already be assembled. Typically code would instead use
|
||||||
|
// the utility methods like `CaptureException`. The return value is the
|
||||||
|
// event ID. In case Sentry is disabled or event was dropped, the return value will be nil.
|
||||||
|
func (client *Client) CaptureEvent(event *Event, hint *EventHint, scope EventModifier) *EventID {
|
||||||
|
return client.processEvent(event, hint, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recover captures a panic.
|
||||||
|
// Returns `EventID` if successfully, or `nil` if there's no error to recover from.
|
||||||
|
func (client *Client) Recover(err interface{}, hint *EventHint, scope EventModifier) *EventID {
|
||||||
|
if err == nil {
|
||||||
|
err = recover()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if err, ok := err.(error); ok {
|
||||||
|
event := client.eventFromException(err, LevelFatal)
|
||||||
|
return client.CaptureEvent(event, hint, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err, ok := err.(string); ok {
|
||||||
|
event := client.eventFromMessage(err, LevelFatal)
|
||||||
|
return client.CaptureEvent(event, hint, scope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recover captures a panic and passes relevant context object.
|
||||||
|
// Returns `EventID` if successfully, or `nil` if there's no error to recover from.
|
||||||
|
func (client *Client) RecoverWithContext(
|
||||||
|
ctx context.Context,
|
||||||
|
err interface{},
|
||||||
|
hint *EventHint,
|
||||||
|
scope EventModifier,
|
||||||
|
) *EventID {
|
||||||
|
if err == nil {
|
||||||
|
err = recover()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if hint.Context == nil && ctx != nil {
|
||||||
|
hint.Context = ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
if err, ok := err.(error); ok {
|
||||||
|
event := client.eventFromException(err, LevelFatal)
|
||||||
|
return client.CaptureEvent(event, hint, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err, ok := err.(string); ok {
|
||||||
|
event := client.eventFromMessage(err, LevelFatal)
|
||||||
|
return client.CaptureEvent(event, hint, scope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush waits until the underlying Transport sends any buffered events to the
|
||||||
|
// Sentry server, blocking for at most the given timeout. It returns false if
|
||||||
|
// the timeout was reached. In that case, some events may not have been sent.
|
||||||
|
//
|
||||||
|
// Flush should be called before terminating the program to avoid
|
||||||
|
// unintentionally dropping events.
|
||||||
|
//
|
||||||
|
// Do not call Flush indiscriminately after every call to CaptureEvent,
|
||||||
|
// CaptureException or CaptureMessage. Instead, to have the SDK send events over
|
||||||
|
// the network synchronously, configure it to use the HTTPSyncTransport in the
|
||||||
|
// call to Init.
|
||||||
|
func (client *Client) Flush(timeout time.Duration) bool {
|
||||||
|
return client.Transport.Flush(timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) eventFromMessage(message string, level Level) *Event {
|
||||||
|
event := NewEvent()
|
||||||
|
event.Level = level
|
||||||
|
event.Message = message
|
||||||
|
|
||||||
|
if client.Options().AttachStacktrace {
|
||||||
|
event.Threads = []Thread{{
|
||||||
|
Stacktrace: NewStacktrace(),
|
||||||
|
Crashed: false,
|
||||||
|
Current: true,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) eventFromException(exception error, level Level) *Event {
|
||||||
|
err := exception
|
||||||
|
if err == nil {
|
||||||
|
err = usageError{fmt.Errorf("%s called with nil error", callerFunctionName())}
|
||||||
|
}
|
||||||
|
|
||||||
|
event := NewEvent()
|
||||||
|
event.Level = level
|
||||||
|
|
||||||
|
for i := 0; i < maxErrorDepth && err != nil; i++ {
|
||||||
|
event.Exception = append(event.Exception, Exception{
|
||||||
|
Value: err.Error(),
|
||||||
|
Type: reflect.TypeOf(err).String(),
|
||||||
|
Stacktrace: ExtractStacktrace(err),
|
||||||
|
})
|
||||||
|
switch previous := err.(type) {
|
||||||
|
case interface{ Unwrap() error }:
|
||||||
|
err = previous.Unwrap()
|
||||||
|
case interface{ Cause() error }:
|
||||||
|
err = previous.Cause()
|
||||||
|
default:
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a trace of the current stack to the most recent error in a chain if
|
||||||
|
// it doesn't have a stack trace yet.
|
||||||
|
// We only add to the most recent error to avoid duplication and because the
|
||||||
|
// current stack is most likely unrelated to errors deeper in the chain.
|
||||||
|
if event.Exception[0].Stacktrace == nil {
|
||||||
|
event.Exception[0].Stacktrace = NewStacktrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
// event.Exception should be sorted such that the most recent error is last.
|
||||||
|
reverse(event.Exception)
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverse reverses the slice a in place.
|
||||||
|
func reverse(a []Exception) {
|
||||||
|
for i := len(a)/2 - 1; i >= 0; i-- {
|
||||||
|
opp := len(a) - 1 - i
|
||||||
|
a[i], a[opp] = a[opp], a[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) processEvent(event *Event, hint *EventHint, scope EventModifier) *EventID {
|
||||||
|
options := client.Options()
|
||||||
|
|
||||||
|
// TODO: Reconsider if its worth going away from default implementation
|
||||||
|
// of other SDKs. In Go zero value (default) for float32 is 0.0,
|
||||||
|
// which means that if someone uses ClientOptions{} struct directly
|
||||||
|
// and we would not check for 0 here, we'd skip all events by default
|
||||||
|
if options.SampleRate != 0.0 {
|
||||||
|
randomFloat := rand.New(rand.NewSource(time.Now().UnixNano())).Float64()
|
||||||
|
if randomFloat > options.SampleRate {
|
||||||
|
Logger.Println("Event dropped due to SampleRate hit.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if event = client.prepareEvent(event, hint, scope); event == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.BeforeSend != nil {
|
||||||
|
h := &EventHint{}
|
||||||
|
if hint != nil {
|
||||||
|
h = hint
|
||||||
|
}
|
||||||
|
if event = options.BeforeSend(event, h); event == nil {
|
||||||
|
Logger.Println("Event dropped due to BeforeSend callback.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client.Transport.SendEvent(event)
|
||||||
|
|
||||||
|
return &event.EventID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) prepareEvent(event *Event, hint *EventHint, scope EventModifier) *Event {
|
||||||
|
if event.EventID == "" {
|
||||||
|
event.EventID = EventID(uuid())
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.Timestamp.IsZero() {
|
||||||
|
event.Timestamp = time.Now().UTC()
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.Level == "" {
|
||||||
|
event.Level = LevelInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.ServerName == "" {
|
||||||
|
if client.Options().ServerName != "" {
|
||||||
|
event.ServerName = client.Options().ServerName
|
||||||
|
} else if hostname, err := os.Hostname(); err == nil {
|
||||||
|
event.ServerName = hostname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.Release == "" && client.Options().Release != "" {
|
||||||
|
event.Release = client.Options().Release
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.Dist == "" && client.Options().Dist != "" {
|
||||||
|
event.Dist = client.Options().Dist
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.Environment == "" && client.Options().Environment != "" {
|
||||||
|
event.Environment = client.Options().Environment
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Platform = "go"
|
||||||
|
event.Sdk = SdkInfo{
|
||||||
|
Name: "sentry.go",
|
||||||
|
Version: Version,
|
||||||
|
Integrations: client.listIntegrations(),
|
||||||
|
Packages: []SdkPackage{{
|
||||||
|
Name: "sentry-go",
|
||||||
|
Version: Version,
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
if scope != nil {
|
||||||
|
event = scope.ApplyToEvent(event, hint)
|
||||||
|
if event == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, processor := range client.eventProcessors {
|
||||||
|
id := event.EventID
|
||||||
|
event = processor(event, hint)
|
||||||
|
if event == nil {
|
||||||
|
Logger.Printf("Event dropped by one of the Client EventProcessors: %s\n", id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, processor := range globalEventProcessors {
|
||||||
|
id := event.EventID
|
||||||
|
event = processor(event, hint)
|
||||||
|
if event == nil {
|
||||||
|
Logger.Printf("Event dropped by one of the Global EventProcessors: %s\n", id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client Client) listIntegrations() []string {
|
||||||
|
integrations := make([]string, 0, len(client.integrations))
|
||||||
|
for _, integration := range client.integrations {
|
||||||
|
integrations = append(integrations, integration.Name())
|
||||||
|
}
|
||||||
|
sort.Strings(integrations)
|
||||||
|
return integrations
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client Client) integrationAlreadyInstalled(name string) bool {
|
||||||
|
for _, integration := range client.integrations {
|
||||||
|
if integration.Name() == name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
188
vendor/github.com/getsentry/sentry-go/dsn.go
generated
vendored
Normal file
188
vendor/github.com/getsentry/sentry-go/dsn.go
generated
vendored
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type scheme string
|
||||||
|
|
||||||
|
const (
|
||||||
|
schemeHTTP scheme = "http"
|
||||||
|
schemeHTTPS scheme = "https"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (scheme scheme) defaultPort() int {
|
||||||
|
switch scheme {
|
||||||
|
case schemeHTTPS:
|
||||||
|
return 443
|
||||||
|
case schemeHTTP:
|
||||||
|
return 80
|
||||||
|
default:
|
||||||
|
return 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DsnParseError struct {
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e DsnParseError) Error() string {
|
||||||
|
return "[Sentry] DsnParseError: " + e.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dsn is used as the remote address source to client transport.
|
||||||
|
type Dsn struct {
|
||||||
|
scheme scheme
|
||||||
|
publicKey string
|
||||||
|
secretKey string
|
||||||
|
host string
|
||||||
|
port int
|
||||||
|
path string
|
||||||
|
projectID int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDsn creates an instance of `Dsn` by parsing provided url in a `string` format.
|
||||||
|
// If Dsn is not set the client is effectively disabled.
|
||||||
|
func NewDsn(rawURL string) (*Dsn, error) {
|
||||||
|
// Parse
|
||||||
|
parsedURL, err := url.Parse(rawURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &DsnParseError{fmt.Sprintf("invalid url: %v", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scheme
|
||||||
|
var scheme scheme
|
||||||
|
switch parsedURL.Scheme {
|
||||||
|
case "http":
|
||||||
|
scheme = schemeHTTP
|
||||||
|
case "https":
|
||||||
|
scheme = schemeHTTPS
|
||||||
|
default:
|
||||||
|
return nil, &DsnParseError{"invalid scheme"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicKey
|
||||||
|
publicKey := parsedURL.User.Username()
|
||||||
|
if publicKey == "" {
|
||||||
|
return nil, &DsnParseError{"empty username"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretKey
|
||||||
|
var secretKey string
|
||||||
|
if parsedSecretKey, ok := parsedURL.User.Password(); ok {
|
||||||
|
secretKey = parsedSecretKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Host
|
||||||
|
host := parsedURL.Hostname()
|
||||||
|
if host == "" {
|
||||||
|
return nil, &DsnParseError{"empty host"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Port
|
||||||
|
var port int
|
||||||
|
if parsedURL.Port() != "" {
|
||||||
|
parsedPort, err := strconv.Atoi(parsedURL.Port())
|
||||||
|
if err != nil {
|
||||||
|
return nil, &DsnParseError{"invalid port"}
|
||||||
|
}
|
||||||
|
port = parsedPort
|
||||||
|
} else {
|
||||||
|
port = scheme.defaultPort()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProjectID
|
||||||
|
if len(parsedURL.Path) == 0 || parsedURL.Path == "/" {
|
||||||
|
return nil, &DsnParseError{"empty project id"}
|
||||||
|
}
|
||||||
|
pathSegments := strings.Split(parsedURL.Path[1:], "/")
|
||||||
|
projectID, err := strconv.Atoi(pathSegments[len(pathSegments)-1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, &DsnParseError{"invalid project id"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path
|
||||||
|
var path string
|
||||||
|
if len(pathSegments) > 1 {
|
||||||
|
path = "/" + strings.Join(pathSegments[0:len(pathSegments)-1], "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Dsn{
|
||||||
|
scheme: scheme,
|
||||||
|
publicKey: publicKey,
|
||||||
|
secretKey: secretKey,
|
||||||
|
host: host,
|
||||||
|
port: port,
|
||||||
|
path: path,
|
||||||
|
projectID: projectID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String formats Dsn struct into a valid string url
|
||||||
|
func (dsn Dsn) String() string {
|
||||||
|
var url string
|
||||||
|
url += fmt.Sprintf("%s://%s", dsn.scheme, dsn.publicKey)
|
||||||
|
if dsn.secretKey != "" {
|
||||||
|
url += fmt.Sprintf(":%s", dsn.secretKey)
|
||||||
|
}
|
||||||
|
url += fmt.Sprintf("@%s", dsn.host)
|
||||||
|
if dsn.port != dsn.scheme.defaultPort() {
|
||||||
|
url += fmt.Sprintf(":%d", dsn.port)
|
||||||
|
}
|
||||||
|
if dsn.path != "" {
|
||||||
|
url += dsn.path
|
||||||
|
}
|
||||||
|
url += fmt.Sprintf("/%d", dsn.projectID)
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
// StoreAPIURL returns assembled url to be used in the transport.
|
||||||
|
// It points to configures Sentry instance.
|
||||||
|
func (dsn Dsn) StoreAPIURL() *url.URL {
|
||||||
|
var rawURL string
|
||||||
|
rawURL += fmt.Sprintf("%s://%s", dsn.scheme, dsn.host)
|
||||||
|
if dsn.port != dsn.scheme.defaultPort() {
|
||||||
|
rawURL += fmt.Sprintf(":%d", dsn.port)
|
||||||
|
}
|
||||||
|
if dsn.path != "" {
|
||||||
|
rawURL += dsn.path
|
||||||
|
}
|
||||||
|
rawURL += fmt.Sprintf("/api/%d/store/", dsn.projectID)
|
||||||
|
parsedURL, _ := url.Parse(rawURL)
|
||||||
|
return parsedURL
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequestHeaders returns all the necessary headers that have to be used in the transport.
|
||||||
|
func (dsn Dsn) RequestHeaders() map[string]string {
|
||||||
|
auth := fmt.Sprintf("Sentry sentry_version=%s, sentry_timestamp=%d, "+
|
||||||
|
"sentry_client=sentry.go/%s, sentry_key=%s", apiVersion, time.Now().Unix(), Version, dsn.publicKey)
|
||||||
|
|
||||||
|
if dsn.secretKey != "" {
|
||||||
|
auth = fmt.Sprintf("%s, sentry_secret=%s", auth, dsn.secretKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
return map[string]string{
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Sentry-Auth": auth,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dsn Dsn) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(dsn.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dsn *Dsn) UnmarshalJSON(data []byte) error {
|
||||||
|
var str string
|
||||||
|
_ = json.Unmarshal(data, &str)
|
||||||
|
newDsn, err := NewDsn(str)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*dsn = *newDsn
|
||||||
|
return nil
|
||||||
|
}
|
135
vendor/github.com/getsentry/sentry-go/echo/README.md
generated
vendored
Normal file
135
vendor/github.com/getsentry/sentry-go/echo/README.md
generated
vendored
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://sentry.io" target="_blank" align="center">
|
||||||
|
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
|
||||||
|
</a>
|
||||||
|
<br />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# Official Sentry Echo Handler for Sentry-go SDK
|
||||||
|
|
||||||
|
**Godoc:** https://godoc.org/github.com/getsentry/sentry-go/echo
|
||||||
|
|
||||||
|
**Example:** https://github.com/getsentry/sentry-go/tree/master/example/echo
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go get github.com/getsentry/sentry-go/echo
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
sentryecho "github.com/getsentry/sentry-go/echo"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/labstack/echo/v4/middleware"
|
||||||
|
)
|
||||||
|
|
||||||
|
// To initialize Sentry's handler, you need to initialize Sentry itself beforehand
|
||||||
|
if err := sentry.Init(sentry.ClientOptions{
|
||||||
|
Dsn: "your-public-dsn",
|
||||||
|
}); err != nil {
|
||||||
|
fmt.Printf("Sentry initialization failed: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then create your app
|
||||||
|
app := echo.New()
|
||||||
|
|
||||||
|
app.Use(middleware.Logger())
|
||||||
|
app.Use(middleware.Recover())
|
||||||
|
|
||||||
|
// Once it's done, you can attach the handler as one of your middleware
|
||||||
|
app.Use(sentryecho.New(sentryecho.Options{}))
|
||||||
|
|
||||||
|
// Set up routes
|
||||||
|
app.GET("/", func(ctx echo.Context) error {
|
||||||
|
return ctx.String(http.StatusOK, "Hello, World!")
|
||||||
|
})
|
||||||
|
|
||||||
|
// And run it
|
||||||
|
app.Logger.Fatal(app.Start(":3000"))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
`sentryecho` accepts a struct of `Options` that allows you to configure how the handler will behave.
|
||||||
|
|
||||||
|
Currently it respects 3 options:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Repanic configures whether Sentry should repanic after recovery, in most cases it should be set to true,
|
||||||
|
// as echo includes its own Recover middleware that handles http responses.
|
||||||
|
Repanic bool
|
||||||
|
// WaitForDelivery configures whether you want to block the request before moving forward with the response.
|
||||||
|
// Because Echo's `Recover` handler doesn't restart the application,
|
||||||
|
// it's safe to either skip this option or set it to `false`.
|
||||||
|
WaitForDelivery bool
|
||||||
|
// Timeout for the event delivery requests.
|
||||||
|
Timeout time.Duration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
`sentryecho` attaches an instance of `*sentry.Hub` (https://godoc.org/github.com/getsentry/sentry-go#Hub) to the `echo.Context`, which makes it available throughout the rest of the request's lifetime.
|
||||||
|
You can access it by using the `sentryecho.GetHubFromContext()` method on the context itself in any of your proceeding middleware and routes.
|
||||||
|
And it should be used instead of the global `sentry.CaptureMessage`, `sentry.CaptureException`, or any other calls, as it keeps the separation of data between the requests.
|
||||||
|
|
||||||
|
**Keep in mind that `*sentry.Hub` won't be available in middleware attached before to `sentryecho`!**
|
||||||
|
|
||||||
|
```go
|
||||||
|
app := echo.New()
|
||||||
|
|
||||||
|
app.Use(middleware.Logger())
|
||||||
|
app.Use(middleware.Recover())
|
||||||
|
|
||||||
|
app.Use(sentryecho.New(sentryecho.Options{
|
||||||
|
Repanic: true,
|
||||||
|
}))
|
||||||
|
|
||||||
|
app.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
return func(ctx echo.Context) error {
|
||||||
|
if hub := sentryecho.GetHubFromContext(ctx); hub != nil {
|
||||||
|
hub.Scope().SetTag("someRandomTag", "maybeYouNeedIt")
|
||||||
|
}
|
||||||
|
return next(ctx)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.GET("/", func(ctx echo.Context) error {
|
||||||
|
if hub := sentryecho.GetHubFromContext(ctx); hub != nil {
|
||||||
|
hub.WithScope(func(scope *sentry.Scope) {
|
||||||
|
scope.SetExtra("unwantedQuery", "someQueryDataMaybe")
|
||||||
|
hub.CaptureMessage("User provided unwanted query string, but we recovered just fine")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ctx.String(http.StatusOK, "Hello, World!")
|
||||||
|
})
|
||||||
|
|
||||||
|
app.GET("/foo", func(ctx echo.Context) error {
|
||||||
|
// sentryecho handler will catch it just fine. Also, because we attached "someRandomTag"
|
||||||
|
// in the middleware before, it will be sent through as well
|
||||||
|
panic("y tho")
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Logger.Fatal(app.Start(":3000"))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Accessing Request in `BeforeSend` callback
|
||||||
|
|
||||||
|
```go
|
||||||
|
sentry.Init(sentry.ClientOptions{
|
||||||
|
Dsn: "your-public-dsn",
|
||||||
|
BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
|
||||||
|
if hint.Context != nil {
|
||||||
|
if req, ok := hint.Context.Value(sentry.RequestContextKey).(*http.Request); ok {
|
||||||
|
// You have access to the original Request here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return event
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
87
vendor/github.com/getsentry/sentry-go/echo/sentryecho.go
generated
vendored
Normal file
87
vendor/github.com/getsentry/sentry-go/echo/sentryecho.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
package sentryecho
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
const valuesKey = "sentry"
|
||||||
|
|
||||||
|
type handler struct {
|
||||||
|
repanic bool
|
||||||
|
waitForDelivery bool
|
||||||
|
timeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
// Repanic configures whether Sentry should repanic after recovery, in most cases it should be set to true,
|
||||||
|
// as echo includes it's own Recover middleware what handles http responses.
|
||||||
|
Repanic bool
|
||||||
|
// WaitForDelivery configures whether you want to block the request before moving forward with the response.
|
||||||
|
// Because Echo's `Recover` handler doesn't restart the application,
|
||||||
|
// it's safe to either skip this option or set it to `false`.
|
||||||
|
WaitForDelivery bool
|
||||||
|
// Timeout for the event delivery requests.
|
||||||
|
Timeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a function that satisfies echo.HandlerFunc interface
|
||||||
|
// It can be used with Use() methods.
|
||||||
|
func New(options Options) echo.MiddlewareFunc {
|
||||||
|
handler := handler{
|
||||||
|
repanic: false,
|
||||||
|
timeout: time.Second * 2,
|
||||||
|
waitForDelivery: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.Repanic {
|
||||||
|
handler.repanic = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.Timeout != 0 {
|
||||||
|
handler.timeout = options.Timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.WaitForDelivery {
|
||||||
|
handler.waitForDelivery = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler.handle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) handle(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
return func(ctx echo.Context) error {
|
||||||
|
hub := sentry.CurrentHub().Clone()
|
||||||
|
hub.Scope().SetRequest(ctx.Request())
|
||||||
|
ctx.Set(valuesKey, hub)
|
||||||
|
defer h.recoverWithSentry(hub, ctx.Request())
|
||||||
|
return next(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) recoverWithSentry(hub *sentry.Hub, r *http.Request) {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
eventID := hub.RecoverWithContext(
|
||||||
|
context.WithValue(r.Context(), sentry.RequestContextKey, r),
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
if eventID != nil && h.waitForDelivery {
|
||||||
|
hub.Flush(h.timeout)
|
||||||
|
}
|
||||||
|
if h.repanic {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHubFromContext retrieves attached *sentry.Hub instance from echo.Context.
|
||||||
|
func GetHubFromContext(ctx echo.Context) *sentry.Hub {
|
||||||
|
if hub, ok := ctx.Get(valuesKey).(*sentry.Hub); ok {
|
||||||
|
return hub
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
35
vendor/github.com/getsentry/sentry-go/go.mod
generated
vendored
Normal file
35
vendor/github.com/getsentry/sentry-go/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
module github.com/getsentry/sentry-go
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/ajg/form v1.5.1 // indirect
|
||||||
|
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
|
||||||
|
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect
|
||||||
|
github.com/gin-gonic/gin v1.4.0
|
||||||
|
github.com/go-errors/errors v1.0.1
|
||||||
|
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab
|
||||||
|
github.com/google/go-cmp v0.4.0
|
||||||
|
github.com/google/go-querystring v1.0.0 // indirect
|
||||||
|
github.com/imkira/go-interpol v1.1.0 // indirect
|
||||||
|
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
|
||||||
|
github.com/kataras/iris/v12 v12.0.1
|
||||||
|
github.com/labstack/echo/v4 v4.1.11
|
||||||
|
github.com/moul/http2curl v1.0.0 // indirect
|
||||||
|
github.com/onsi/ginkgo v1.10.3 // indirect
|
||||||
|
github.com/onsi/gomega v1.7.1 // indirect
|
||||||
|
github.com/pingcap/errors v0.11.4
|
||||||
|
github.com/pkg/errors v0.8.1
|
||||||
|
github.com/sergi/go-diff v1.0.0 // indirect
|
||||||
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
|
github.com/ugorji/go v1.1.7 // indirect
|
||||||
|
github.com/urfave/negroni v1.0.0
|
||||||
|
github.com/valyala/fasthttp v1.6.0
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||||
|
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
|
||||||
|
github.com/yudai/gojsondiff v1.0.0 // indirect
|
||||||
|
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
|
||||||
|
github.com/yudai/pp v2.0.1+incompatible // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43
|
250
vendor/github.com/getsentry/sentry-go/go.sum
generated
vendored
Normal file
250
vendor/github.com/getsentry/sentry-go/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||||
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a h1:3SgJcK9l5uPdBC/X17wanyJAMxM33+4ZhEIV96MIH8U=
|
||||||
|
github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw=
|
||||||
|
github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible h1:rZgFj+Gtf3NMi/U5FvCvhzaxzW/TaPYgUYx3bAPz9DE=
|
||||||
|
github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
|
||||||
|
github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc=
|
||||||
|
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
|
||||||
|
github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7 h1:mreN1m/5VJ/Zc3b4pzj9qU6D9SRQ6Vm+3KfI328t3S8=
|
||||||
|
github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM=
|
||||||
|
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 h1:WDC6ySpJzbxGWFh4aMxFFC28wwGp5pEuoTtvA4q/qQ4=
|
||||||
|
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
|
||||||
|
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||||
|
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||||
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible h1:Ppm0npCCsmuR9oQaBtRuZcmILVE74aXE+AmrJj8L2ns=
|
||||||
|
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
||||||
|
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
|
||||||
|
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||||
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
|
||||||
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||||
|
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||||
|
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 h1:DddqAaWDpywytcG8w/qoQ5sAN8X12d3Z3koB0C3Rxsc=
|
||||||
|
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
||||||
|
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||||
|
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||||
|
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 h1:GY1+t5Dr9OKADM64SYnQjw/w99HMYvQ0A8/JoUkxVmc=
|
||||||
|
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8=
|
||||||
|
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||||
|
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
|
||||||
|
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||||
|
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
|
||||||
|
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||||
|
github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI=
|
||||||
|
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
||||||
|
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||||
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
|
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk=
|
||||||
|
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||||
|
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||||
|
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||||
|
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||||
|
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||||
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||||
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||||
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
|
||||||
|
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/iris-contrib/blackfriday v2.0.0+incompatible h1:o5sHQHHm0ToHUlAJSTjW9UWicjJSDDauOOQ2AHuIVp4=
|
||||||
|
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
|
||||||
|
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
|
||||||
|
github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI=
|
||||||
|
github.com/iris-contrib/schema v0.0.1 h1:10g/WnoRR+U+XXHWKBHeNy/+tZmM2kcAVGLOsz+yaDA=
|
||||||
|
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
|
||||||
|
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||||
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 h1:rhqTjzJlm7EbkELJDKMTU7udov+Se0xZkWmugr6zGok=
|
||||||
|
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
|
||||||
|
github.com/juju/loggo v0.0.0-20180524022052-584905176618 h1:MK144iBQF9hTSwBW/9eJm034bVoG30IshVm688T2hi8=
|
||||||
|
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
|
||||||
|
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073 h1:WQM1NildKThwdP7qWrNAFGzp4ijNLw8RlgENkaI4MJs=
|
||||||
|
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
|
||||||
|
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
|
||||||
|
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
||||||
|
github.com/kataras/golog v0.0.9 h1:J7Dl82843nbKQDrQM/abbNJZvQjS6PfmkkffhOTXEpM=
|
||||||
|
github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk=
|
||||||
|
github.com/kataras/iris/v12 v12.0.1 h1:Wo5S7GMWv5OAzJmvFTvss/C4TS1W0uo6LkDlSymT4rM=
|
||||||
|
github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U=
|
||||||
|
github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw=
|
||||||
|
github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d h1:V5Rs9ztEWdp58oayPq/ulmlqJJZeJP6pP79uP3qjcao=
|
||||||
|
github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0=
|
||||||
|
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
|
github.com/klauspost/compress v1.9.0 h1:GhthINjveNZAdFUD8QoQYfjxnOONZgztK/Yr6M23UTY=
|
||||||
|
github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
|
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/labstack/echo/v4 v4.1.11 h1:z0BZoArY4FqdpUEl+wlHp4hnr/oSR6MTmQmv8OHSoww=
|
||||||
|
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||||
|
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
||||||
|
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||||
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
|
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||||
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
|
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
||||||
|
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||||
|
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||||
|
github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg=
|
||||||
|
github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ=
|
||||||
|
github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s=
|
||||||
|
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
|
||||||
|
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||||
|
github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM=
|
||||||
|
github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4=
|
||||||
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
|
||||||
|
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||||
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||||
|
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||||
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
|
github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s=
|
||||||
|
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
|
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||||
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||||
|
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||||
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 h1:BasDe+IErOQKrMVXab7UayvSlIpiyGwRvuX3EKYY7UA=
|
||||||
|
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
|
||||||
|
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||||
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
|
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
|
||||||
|
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasthttp v1.6.0 h1:uWF8lgKmeaIewWVPwi4GRq2P6+R46IgYZdxWtM+GtEY=
|
||||||
|
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||||
|
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
|
||||||
|
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||||
|
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY=
|
||||||
|
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
|
||||||
|
github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
|
||||||
|
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||||
|
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
|
||||||
|
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||||
|
github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
|
||||||
|
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
||||||
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||||
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
||||||
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||||
|
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||||
|
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
|
||||||
|
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||||
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU=
|
||||||
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||||
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
364
vendor/github.com/getsentry/sentry-go/hub.go
generated
vendored
Normal file
364
vendor/github.com/getsentry/sentry-go/hub.go
generated
vendored
Normal file
|
@ -0,0 +1,364 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type contextKey int
|
||||||
|
|
||||||
|
// HubContextKey is a context key used to store Hub on any context.Context type
|
||||||
|
const HubContextKey = contextKey(1)
|
||||||
|
|
||||||
|
// RequestContextKey is a context key used to store http.Request on the context passed to RecoverWithContext
|
||||||
|
const RequestContextKey = contextKey(2)
|
||||||
|
|
||||||
|
// Default maximum number of breadcrumbs added to an event. Can be overwritten `maxBreadcrumbs` option.
|
||||||
|
const defaultMaxBreadcrumbs = 30
|
||||||
|
|
||||||
|
// Absolute maximum number of breadcrumbs added to an event.
|
||||||
|
// The `maxBreadcrumbs` option cannot be higher than this value.
|
||||||
|
const maxBreadcrumbs = 100
|
||||||
|
|
||||||
|
// Initial instance of the Hub that has no `Client` bound and an empty `Scope`
|
||||||
|
var currentHub = NewHub(nil, NewScope()) //nolint: gochecknoglobals
|
||||||
|
|
||||||
|
// Hub is the central object that manages scopes and clients.
|
||||||
|
//
|
||||||
|
// This can be used to capture events and manage the scope.
|
||||||
|
// The default hub that is available automatically.
|
||||||
|
//
|
||||||
|
// In most situations developers do not need to interface the hub. Instead
|
||||||
|
// toplevel convenience functions are exposed that will automatically dispatch
|
||||||
|
// to global (`CurrentHub`) hub. In some situations this might not be
|
||||||
|
// possible in which case it might become necessary to manually work with the
|
||||||
|
// hub. This is for instance the case when working with async code.
|
||||||
|
type Hub struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
stack *stack
|
||||||
|
lastEventID EventID
|
||||||
|
}
|
||||||
|
|
||||||
|
type layer struct {
|
||||||
|
// mu protects concurrent reads and writes to client.
|
||||||
|
mu sync.RWMutex
|
||||||
|
client *Client
|
||||||
|
// scope is read-only, not protected by mu.
|
||||||
|
scope *Scope
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client returns the layer's client. Safe for concurrent use.
|
||||||
|
func (l *layer) Client() *Client {
|
||||||
|
l.mu.RLock()
|
||||||
|
defer l.mu.RUnlock()
|
||||||
|
return l.client
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetClient sets the layer's client. Safe for concurrent use.
|
||||||
|
func (l *layer) SetClient(c *Client) {
|
||||||
|
l.mu.Lock()
|
||||||
|
defer l.mu.Unlock()
|
||||||
|
l.client = c
|
||||||
|
}
|
||||||
|
|
||||||
|
type stack []*layer
|
||||||
|
|
||||||
|
// NewHub returns an instance of a `Hub` with provided `Client` and `Scope` bound.
|
||||||
|
func NewHub(client *Client, scope *Scope) *Hub {
|
||||||
|
hub := Hub{
|
||||||
|
stack: &stack{{
|
||||||
|
client: client,
|
||||||
|
scope: scope,
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
return &hub
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentHub returns an instance of previously initialized `Hub` stored in the global namespace.
|
||||||
|
func CurrentHub() *Hub {
|
||||||
|
return currentHub
|
||||||
|
}
|
||||||
|
|
||||||
|
// LastEventID returns an ID of last captured event for the current `Hub`.
|
||||||
|
func (hub *Hub) LastEventID() EventID {
|
||||||
|
return hub.lastEventID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hub *Hub) stackTop() *layer {
|
||||||
|
hub.mu.RLock()
|
||||||
|
defer hub.mu.RUnlock()
|
||||||
|
|
||||||
|
stack := hub.stack
|
||||||
|
if stack == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
stackLen := len(*stack)
|
||||||
|
if stackLen == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
top := (*stack)[stackLen-1]
|
||||||
|
|
||||||
|
return top
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns a copy of the current Hub with top-most scope and client copied over.
|
||||||
|
func (hub *Hub) Clone() *Hub {
|
||||||
|
top := hub.stackTop()
|
||||||
|
if top == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
scope := top.scope
|
||||||
|
if scope != nil {
|
||||||
|
scope = scope.Clone()
|
||||||
|
}
|
||||||
|
return NewHub(top.Client(), scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scope returns top-level `Scope` of the current `Hub` or `nil` if no `Scope` is bound.
|
||||||
|
func (hub *Hub) Scope() *Scope {
|
||||||
|
top := hub.stackTop()
|
||||||
|
if top == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return top.scope
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scope returns top-level `Client` of the current `Hub` or `nil` if no `Client` is bound.
|
||||||
|
func (hub *Hub) Client() *Client {
|
||||||
|
top := hub.stackTop()
|
||||||
|
if top == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return top.Client()
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushScope pushes a new scope for the current `Hub` and reuses previously bound `Client`.
|
||||||
|
func (hub *Hub) PushScope() *Scope {
|
||||||
|
top := hub.stackTop()
|
||||||
|
|
||||||
|
var client *Client
|
||||||
|
if top != nil {
|
||||||
|
client = top.Client()
|
||||||
|
}
|
||||||
|
|
||||||
|
var scope *Scope
|
||||||
|
if top != nil && top.scope != nil {
|
||||||
|
scope = top.scope.Clone()
|
||||||
|
} else {
|
||||||
|
scope = NewScope()
|
||||||
|
}
|
||||||
|
|
||||||
|
hub.mu.Lock()
|
||||||
|
defer hub.mu.Unlock()
|
||||||
|
|
||||||
|
*hub.stack = append(*hub.stack, &layer{
|
||||||
|
client: client,
|
||||||
|
scope: scope,
|
||||||
|
})
|
||||||
|
|
||||||
|
return scope
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushScope pops the most recent scope for the current `Hub`.
|
||||||
|
func (hub *Hub) PopScope() {
|
||||||
|
hub.mu.Lock()
|
||||||
|
defer hub.mu.Unlock()
|
||||||
|
|
||||||
|
stack := *hub.stack
|
||||||
|
stackLen := len(stack)
|
||||||
|
if stackLen > 0 {
|
||||||
|
*hub.stack = stack[0 : stackLen-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindClient binds a new `Client` for the current `Hub`.
|
||||||
|
func (hub *Hub) BindClient(client *Client) {
|
||||||
|
top := hub.stackTop()
|
||||||
|
if top != nil {
|
||||||
|
top.SetClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithScope temporarily pushes a scope for a single call.
|
||||||
|
//
|
||||||
|
// A shorthand for:
|
||||||
|
// PushScope()
|
||||||
|
// f(scope)
|
||||||
|
// PopScope()
|
||||||
|
func (hub *Hub) WithScope(f func(scope *Scope)) {
|
||||||
|
scope := hub.PushScope()
|
||||||
|
defer hub.PopScope()
|
||||||
|
f(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigureScope invokes a function that can modify the current scope.
|
||||||
|
//
|
||||||
|
// The function is passed a mutable reference to the `Scope` so that modifications
|
||||||
|
// can be performed.
|
||||||
|
func (hub *Hub) ConfigureScope(f func(scope *Scope)) {
|
||||||
|
scope := hub.Scope()
|
||||||
|
f(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureEvent calls the method of a same name on currently bound `Client` instance
|
||||||
|
// passing it a top-level `Scope`.
|
||||||
|
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||||
|
func (hub *Hub) CaptureEvent(event *Event) *EventID {
|
||||||
|
client, scope := hub.Client(), hub.Scope()
|
||||||
|
if client == nil || scope == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
eventID := client.CaptureEvent(event, nil, scope)
|
||||||
|
if eventID != nil {
|
||||||
|
hub.lastEventID = *eventID
|
||||||
|
} else {
|
||||||
|
hub.lastEventID = ""
|
||||||
|
}
|
||||||
|
return eventID
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureMessage calls the method of a same name on currently bound `Client` instance
|
||||||
|
// passing it a top-level `Scope`.
|
||||||
|
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||||
|
func (hub *Hub) CaptureMessage(message string) *EventID {
|
||||||
|
client, scope := hub.Client(), hub.Scope()
|
||||||
|
if client == nil || scope == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
eventID := client.CaptureMessage(message, nil, scope)
|
||||||
|
if eventID != nil {
|
||||||
|
hub.lastEventID = *eventID
|
||||||
|
} else {
|
||||||
|
hub.lastEventID = ""
|
||||||
|
}
|
||||||
|
return eventID
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureException calls the method of a same name on currently bound `Client` instance
|
||||||
|
// passing it a top-level `Scope`.
|
||||||
|
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||||
|
func (hub *Hub) CaptureException(exception error) *EventID {
|
||||||
|
client, scope := hub.Client(), hub.Scope()
|
||||||
|
if client == nil || scope == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
eventID := client.CaptureException(exception, &EventHint{OriginalException: exception}, scope)
|
||||||
|
if eventID != nil {
|
||||||
|
hub.lastEventID = *eventID
|
||||||
|
} else {
|
||||||
|
hub.lastEventID = ""
|
||||||
|
}
|
||||||
|
return eventID
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddBreadcrumb records a new breadcrumb.
|
||||||
|
//
|
||||||
|
// The total number of breadcrumbs that can be recorded are limited by the
|
||||||
|
// configuration on the client.
|
||||||
|
func (hub *Hub) AddBreadcrumb(breadcrumb *Breadcrumb, hint *BreadcrumbHint) {
|
||||||
|
client := hub.Client()
|
||||||
|
|
||||||
|
// If there's no client, just store it on the scope straight away
|
||||||
|
if client == nil {
|
||||||
|
hub.Scope().AddBreadcrumb(breadcrumb, maxBreadcrumbs)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
options := client.Options()
|
||||||
|
max := defaultMaxBreadcrumbs
|
||||||
|
|
||||||
|
if options.MaxBreadcrumbs != 0 {
|
||||||
|
max = options.MaxBreadcrumbs
|
||||||
|
}
|
||||||
|
|
||||||
|
if max < 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.BeforeBreadcrumb != nil {
|
||||||
|
h := &BreadcrumbHint{}
|
||||||
|
if hint != nil {
|
||||||
|
h = hint
|
||||||
|
}
|
||||||
|
if breadcrumb = options.BeforeBreadcrumb(breadcrumb, h); breadcrumb == nil {
|
||||||
|
Logger.Println("breadcrumb dropped due to BeforeBreadcrumb callback.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if max > maxBreadcrumbs {
|
||||||
|
max = maxBreadcrumbs
|
||||||
|
}
|
||||||
|
hub.Scope().AddBreadcrumb(breadcrumb, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recover calls the method of a same name on currently bound `Client` instance
|
||||||
|
// passing it a top-level `Scope`.
|
||||||
|
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||||
|
func (hub *Hub) Recover(err interface{}) *EventID {
|
||||||
|
if err == nil {
|
||||||
|
err = recover()
|
||||||
|
}
|
||||||
|
client, scope := hub.Client(), hub.Scope()
|
||||||
|
if client == nil || scope == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return client.Recover(err, &EventHint{RecoveredException: err}, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecoverWithContext calls the method of a same name on currently bound `Client` instance
|
||||||
|
// passing it a top-level `Scope`.
|
||||||
|
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||||
|
func (hub *Hub) RecoverWithContext(ctx context.Context, err interface{}) *EventID {
|
||||||
|
if err == nil {
|
||||||
|
err = recover()
|
||||||
|
}
|
||||||
|
client, scope := hub.Client(), hub.Scope()
|
||||||
|
if client == nil || scope == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return client.RecoverWithContext(ctx, err, &EventHint{RecoveredException: err}, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush waits until the underlying Transport sends any buffered events to the
|
||||||
|
// Sentry server, blocking for at most the given timeout. It returns false if
|
||||||
|
// the timeout was reached. In that case, some events may not have been sent.
|
||||||
|
//
|
||||||
|
// Flush should be called before terminating the program to avoid
|
||||||
|
// unintentionally dropping events.
|
||||||
|
//
|
||||||
|
// Do not call Flush indiscriminately after every call to CaptureEvent,
|
||||||
|
// CaptureException or CaptureMessage. Instead, to have the SDK send events over
|
||||||
|
// the network synchronously, configure it to use the HTTPSyncTransport in the
|
||||||
|
// call to Init.
|
||||||
|
func (hub *Hub) Flush(timeout time.Duration) bool {
|
||||||
|
client := hub.Client()
|
||||||
|
|
||||||
|
if client == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.Flush(timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasHubOnContext checks whether `Hub` instance is bound to a given `Context` struct.
|
||||||
|
func HasHubOnContext(ctx context.Context) bool {
|
||||||
|
_, ok := ctx.Value(HubContextKey).(*Hub)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHubFromContext tries to retrieve `Hub` instance from the given `Context` struct
|
||||||
|
// or return `nil` if one is not found.
|
||||||
|
func GetHubFromContext(ctx context.Context) *Hub {
|
||||||
|
if hub, ok := ctx.Value(HubContextKey).(*Hub); ok {
|
||||||
|
return hub
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetHubOnContext stores given `Hub` instance on the `Context` struct and returns a new `Context`.
|
||||||
|
func SetHubOnContext(ctx context.Context, hub *Hub) context.Context {
|
||||||
|
return context.WithValue(ctx, HubContextKey, hub)
|
||||||
|
}
|
271
vendor/github.com/getsentry/sentry-go/integrations.go
generated
vendored
Normal file
271
vendor/github.com/getsentry/sentry-go/integrations.go
generated
vendored
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"runtime"
|
||||||
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// Modules Integration
|
||||||
|
// ================================
|
||||||
|
|
||||||
|
type modulesIntegration struct {
|
||||||
|
once sync.Once
|
||||||
|
modules map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mi *modulesIntegration) Name() string {
|
||||||
|
return "Modules"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mi *modulesIntegration) SetupOnce(client *Client) {
|
||||||
|
client.AddEventProcessor(mi.processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mi *modulesIntegration) processor(event *Event, hint *EventHint) *Event {
|
||||||
|
if len(event.Modules) == 0 {
|
||||||
|
mi.once.Do(func() {
|
||||||
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
Logger.Print("The Modules integration is not available in binaries built without module support.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mi.modules = extractModules(info)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
event.Modules = mi.modules
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractModules(info *debug.BuildInfo) map[string]string {
|
||||||
|
modules := map[string]string{
|
||||||
|
info.Main.Path: info.Main.Version,
|
||||||
|
}
|
||||||
|
for _, dep := range info.Deps {
|
||||||
|
ver := dep.Version
|
||||||
|
if dep.Replace != nil {
|
||||||
|
ver += fmt.Sprintf(" => %s %s", dep.Replace.Path, dep.Replace.Version)
|
||||||
|
}
|
||||||
|
modules[dep.Path] = strings.TrimSuffix(ver, " ")
|
||||||
|
}
|
||||||
|
return modules
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// Environment Integration
|
||||||
|
// ================================
|
||||||
|
|
||||||
|
type environmentIntegration struct{}
|
||||||
|
|
||||||
|
func (ei *environmentIntegration) Name() string {
|
||||||
|
return "Environment"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ei *environmentIntegration) SetupOnce(client *Client) {
|
||||||
|
client.AddEventProcessor(ei.processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ei *environmentIntegration) processor(event *Event, hint *EventHint) *Event {
|
||||||
|
if event.Contexts == nil {
|
||||||
|
event.Contexts = make(map[string]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Contexts["device"] = map[string]interface{}{
|
||||||
|
"arch": runtime.GOARCH,
|
||||||
|
"num_cpu": runtime.NumCPU(),
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Contexts["os"] = map[string]interface{}{
|
||||||
|
"name": runtime.GOOS,
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Contexts["runtime"] = map[string]interface{}{
|
||||||
|
"name": "go",
|
||||||
|
"version": runtime.Version(),
|
||||||
|
"go_numroutines": runtime.NumGoroutine(),
|
||||||
|
"go_maxprocs": runtime.GOMAXPROCS(0),
|
||||||
|
"go_numcgocalls": runtime.NumCgoCall(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// Ignore Errors Integration
|
||||||
|
// ================================
|
||||||
|
|
||||||
|
type ignoreErrorsIntegration struct {
|
||||||
|
ignoreErrors []*regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iei *ignoreErrorsIntegration) Name() string {
|
||||||
|
return "IgnoreErrors"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iei *ignoreErrorsIntegration) SetupOnce(client *Client) {
|
||||||
|
iei.ignoreErrors = transformStringsIntoRegexps(client.Options().IgnoreErrors)
|
||||||
|
client.AddEventProcessor(iei.processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iei *ignoreErrorsIntegration) processor(event *Event, hint *EventHint) *Event {
|
||||||
|
suspects := getIgnoreErrorsSuspects(event)
|
||||||
|
|
||||||
|
for _, suspect := range suspects {
|
||||||
|
for _, pattern := range iei.ignoreErrors {
|
||||||
|
if pattern.Match([]byte(suspect)) {
|
||||||
|
Logger.Printf("Event dropped due to being matched by `IgnoreErrors` option."+
|
||||||
|
"| Value matched: %s | Filter used: %s", suspect, pattern)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func transformStringsIntoRegexps(strings []string) []*regexp.Regexp {
|
||||||
|
var exprs []*regexp.Regexp
|
||||||
|
|
||||||
|
for _, s := range strings {
|
||||||
|
r, err := regexp.Compile(s)
|
||||||
|
if err == nil {
|
||||||
|
exprs = append(exprs, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exprs
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIgnoreErrorsSuspects(event *Event) []string {
|
||||||
|
suspects := []string{}
|
||||||
|
|
||||||
|
if event.Message != "" {
|
||||||
|
suspects = append(suspects, event.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ex := range event.Exception {
|
||||||
|
suspects = append(suspects, ex.Type)
|
||||||
|
suspects = append(suspects, ex.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return suspects
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// Contextify Frames Integration
|
||||||
|
// ================================
|
||||||
|
|
||||||
|
type contextifyFramesIntegration struct {
|
||||||
|
sr sourceReader
|
||||||
|
contextLines int
|
||||||
|
cachedLocations sync.Map
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfi *contextifyFramesIntegration) Name() string {
|
||||||
|
return "ContextifyFrames"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfi *contextifyFramesIntegration) SetupOnce(client *Client) {
|
||||||
|
cfi.sr = newSourceReader()
|
||||||
|
cfi.contextLines = 5
|
||||||
|
|
||||||
|
client.AddEventProcessor(cfi.processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfi *contextifyFramesIntegration) processor(event *Event, hint *EventHint) *Event {
|
||||||
|
// Range over all exceptions
|
||||||
|
for _, ex := range event.Exception {
|
||||||
|
// If it has no stacktrace, just bail out
|
||||||
|
if ex.Stacktrace == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it does, it should have frames, so try to contextify them
|
||||||
|
ex.Stacktrace.Frames = cfi.contextify(ex.Stacktrace.Frames)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range over all threads
|
||||||
|
for _, th := range event.Threads {
|
||||||
|
// If it has no stacktrace, just bail out
|
||||||
|
if th.Stacktrace == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it does, it should have frames, so try to contextify them
|
||||||
|
th.Stacktrace.Frames = cfi.contextify(th.Stacktrace.Frames)
|
||||||
|
}
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfi *contextifyFramesIntegration) contextify(frames []Frame) []Frame {
|
||||||
|
contextifiedFrames := make([]Frame, 0, len(frames))
|
||||||
|
|
||||||
|
for _, frame := range frames {
|
||||||
|
if !frame.InApp {
|
||||||
|
contextifiedFrames = append(contextifiedFrames, frame)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var path string
|
||||||
|
|
||||||
|
if cachedPath, ok := cfi.cachedLocations.Load(frame.AbsPath); ok {
|
||||||
|
if p, ok := cachedPath.(string); ok {
|
||||||
|
path = p
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Optimize for happy path here
|
||||||
|
if fileExists(frame.AbsPath) {
|
||||||
|
path = frame.AbsPath
|
||||||
|
} else {
|
||||||
|
path = cfi.findNearbySourceCodeLocation(frame.AbsPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if path == "" {
|
||||||
|
contextifiedFrames = append(contextifiedFrames, frame)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
lines, contextLine := cfi.sr.readContextLines(path, frame.Lineno, cfi.contextLines)
|
||||||
|
contextifiedFrames = append(contextifiedFrames, cfi.addContextLinesToFrame(frame, lines, contextLine))
|
||||||
|
}
|
||||||
|
|
||||||
|
return contextifiedFrames
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfi *contextifyFramesIntegration) findNearbySourceCodeLocation(originalPath string) string {
|
||||||
|
trimmedPath := strings.TrimPrefix(originalPath, "/")
|
||||||
|
components := strings.Split(trimmedPath, "/")
|
||||||
|
|
||||||
|
for len(components) > 0 {
|
||||||
|
components = components[1:]
|
||||||
|
possibleLocation := strings.Join(components, "/")
|
||||||
|
|
||||||
|
if fileExists(possibleLocation) {
|
||||||
|
cfi.cachedLocations.Store(originalPath, possibleLocation)
|
||||||
|
return possibleLocation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfi.cachedLocations.Store(originalPath, "")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfi *contextifyFramesIntegration) addContextLinesToFrame(frame Frame, lines [][]byte, contextLine int) Frame {
|
||||||
|
for i, line := range lines {
|
||||||
|
switch {
|
||||||
|
case i < contextLine:
|
||||||
|
frame.PreContext = append(frame.PreContext, string(line))
|
||||||
|
case i == contextLine:
|
||||||
|
frame.ContextLine = string(line)
|
||||||
|
default:
|
||||||
|
frame.PostContext = append(frame.PostContext, string(line))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return frame
|
||||||
|
}
|
221
vendor/github.com/getsentry/sentry-go/interfaces.go
generated
vendored
Normal file
221
vendor/github.com/getsentry/sentry-go/interfaces.go
generated
vendored
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Protocol Docs (kinda)
|
||||||
|
// https://github.com/getsentry/rust-sentry-types/blob/master/src/protocol/v7.rs
|
||||||
|
|
||||||
|
// Level marks the severity of the event
|
||||||
|
type Level string
|
||||||
|
|
||||||
|
const (
|
||||||
|
LevelDebug Level = "debug"
|
||||||
|
LevelInfo Level = "info"
|
||||||
|
LevelWarning Level = "warning"
|
||||||
|
LevelError Level = "error"
|
||||||
|
LevelFatal Level = "fatal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.sentry.io/development/sdk-dev/event-payloads/sdk/
|
||||||
|
type SdkInfo struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
Integrations []string `json:"integrations,omitempty"`
|
||||||
|
Packages []SdkPackage `json:"packages,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SdkPackage struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: This type could be more useful, as map of interface{} is too generic
|
||||||
|
// and requires a lot of type assertions in beforeBreadcrumb calls
|
||||||
|
// plus it could just be `map[string]interface{}` then
|
||||||
|
type BreadcrumbHint map[string]interface{}
|
||||||
|
|
||||||
|
// https://docs.sentry.io/development/sdk-dev/event-payloads/breadcrumbs/
|
||||||
|
type Breadcrumb struct {
|
||||||
|
Category string `json:"category,omitempty"`
|
||||||
|
Data map[string]interface{} `json:"data,omitempty"`
|
||||||
|
Level Level `json:"level,omitempty"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Breadcrumb) MarshalJSON() ([]byte, error) {
|
||||||
|
type alias Breadcrumb
|
||||||
|
// encoding/json doesn't support the "omitempty" option for struct types.
|
||||||
|
// See https://golang.org/issues/11939.
|
||||||
|
// This implementation of MarshalJSON shadows the original Timestamp field
|
||||||
|
// forcing it to be omitted when the Timestamp is the zero value of
|
||||||
|
// time.Time.
|
||||||
|
if b.Timestamp.IsZero() {
|
||||||
|
return json.Marshal(&struct {
|
||||||
|
*alias
|
||||||
|
Timestamp json.RawMessage `json:"timestamp,omitempty"`
|
||||||
|
}{
|
||||||
|
alias: (*alias)(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return json.Marshal(&struct {
|
||||||
|
*alias
|
||||||
|
}{
|
||||||
|
alias: (*alias)(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://docs.sentry.io/development/sdk-dev/event-payloads/user/
|
||||||
|
type User struct {
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IPAddress string `json:"ip_address,omitempty"`
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://docs.sentry.io/development/sdk-dev/event-payloads/request/
|
||||||
|
type Request struct {
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
Method string `json:"method,omitempty"`
|
||||||
|
Data string `json:"data,omitempty"`
|
||||||
|
QueryString string `json:"query_string,omitempty"`
|
||||||
|
Cookies string `json:"cookies,omitempty"`
|
||||||
|
Headers map[string]string `json:"headers,omitempty"`
|
||||||
|
Env map[string]string `json:"env,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRequest returns a new Sentry Request from the given http.Request.
|
||||||
|
//
|
||||||
|
// NewRequest avoids operations that depend on network access. In particular, it
|
||||||
|
// does not read r.Body.
|
||||||
|
func NewRequest(r *http.Request) *Request {
|
||||||
|
protocol := schemeHTTP
|
||||||
|
if r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https" {
|
||||||
|
protocol = schemeHTTPS
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("%s://%s%s", protocol, r.Host, r.URL.Path)
|
||||||
|
|
||||||
|
// We read only the first Cookie header because of the specification:
|
||||||
|
// https://tools.ietf.org/html/rfc6265#section-5.4
|
||||||
|
// When the user agent generates an HTTP request, the user agent MUST NOT
|
||||||
|
// attach more than one Cookie header field.
|
||||||
|
cookies := r.Header.Get("Cookie")
|
||||||
|
|
||||||
|
headers := make(map[string]string, len(r.Header))
|
||||||
|
for k, v := range r.Header {
|
||||||
|
headers[k] = strings.Join(v, ",")
|
||||||
|
}
|
||||||
|
headers["Host"] = r.Host
|
||||||
|
|
||||||
|
var env map[string]string
|
||||||
|
if addr, port, err := net.SplitHostPort(r.RemoteAddr); err == nil {
|
||||||
|
env = map[string]string{"REMOTE_ADDR": addr, "REMOTE_PORT": port}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Request{
|
||||||
|
URL: url,
|
||||||
|
Method: r.Method,
|
||||||
|
QueryString: r.URL.RawQuery,
|
||||||
|
Cookies: cookies,
|
||||||
|
Headers: headers,
|
||||||
|
Env: env,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://docs.sentry.io/development/sdk-dev/event-payloads/exception/
|
||||||
|
type Exception struct {
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
Module string `json:"module,omitempty"`
|
||||||
|
ThreadID string `json:"thread_id,omitempty"`
|
||||||
|
Stacktrace *Stacktrace `json:"stacktrace,omitempty"`
|
||||||
|
RawStacktrace *Stacktrace `json:"raw_stacktrace,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventID string
|
||||||
|
|
||||||
|
// https://docs.sentry.io/development/sdk-dev/event-payloads/
|
||||||
|
type Event struct {
|
||||||
|
Breadcrumbs []*Breadcrumb `json:"breadcrumbs,omitempty"`
|
||||||
|
Contexts map[string]interface{} `json:"contexts,omitempty"`
|
||||||
|
Dist string `json:"dist,omitempty"`
|
||||||
|
Environment string `json:"environment,omitempty"`
|
||||||
|
EventID EventID `json:"event_id,omitempty"`
|
||||||
|
Extra map[string]interface{} `json:"extra,omitempty"`
|
||||||
|
Fingerprint []string `json:"fingerprint,omitempty"`
|
||||||
|
Level Level `json:"level,omitempty"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
Platform string `json:"platform,omitempty"`
|
||||||
|
Release string `json:"release,omitempty"`
|
||||||
|
Sdk SdkInfo `json:"sdk,omitempty"`
|
||||||
|
ServerName string `json:"server_name,omitempty"`
|
||||||
|
Threads []Thread `json:"threads,omitempty"`
|
||||||
|
Tags map[string]string `json:"tags,omitempty"`
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
Transaction string `json:"transaction,omitempty"`
|
||||||
|
User User `json:"user,omitempty"`
|
||||||
|
Logger string `json:"logger,omitempty"`
|
||||||
|
Modules map[string]string `json:"modules,omitempty"`
|
||||||
|
Request *Request `json:"request,omitempty"`
|
||||||
|
Exception []Exception `json:"exception,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Event) MarshalJSON() ([]byte, error) {
|
||||||
|
type alias Event
|
||||||
|
// encoding/json doesn't support the "omitempty" option for struct types.
|
||||||
|
// See https://golang.org/issues/11939.
|
||||||
|
// This implementation of MarshalJSON shadows the original Timestamp field
|
||||||
|
// forcing it to be omitted when the Timestamp is the zero value of
|
||||||
|
// time.Time.
|
||||||
|
if e.Timestamp.IsZero() {
|
||||||
|
return json.Marshal(&struct {
|
||||||
|
*alias
|
||||||
|
Timestamp json.RawMessage `json:"timestamp,omitempty"`
|
||||||
|
}{
|
||||||
|
alias: (*alias)(e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return json.Marshal(&struct {
|
||||||
|
*alias
|
||||||
|
}{
|
||||||
|
alias: (*alias)(e),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEvent() *Event {
|
||||||
|
event := Event{
|
||||||
|
Contexts: make(map[string]interface{}),
|
||||||
|
Extra: make(map[string]interface{}),
|
||||||
|
Tags: make(map[string]string),
|
||||||
|
Modules: make(map[string]string),
|
||||||
|
}
|
||||||
|
return &event
|
||||||
|
}
|
||||||
|
|
||||||
|
type Thread struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Stacktrace *Stacktrace `json:"stacktrace,omitempty"`
|
||||||
|
RawStacktrace *Stacktrace `json:"raw_stacktrace,omitempty"`
|
||||||
|
Crashed bool `json:"crashed,omitempty"`
|
||||||
|
Current bool `json:"current,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventHint struct {
|
||||||
|
Data interface{}
|
||||||
|
EventID string
|
||||||
|
OriginalException error
|
||||||
|
RecoveredException interface{}
|
||||||
|
Context context.Context
|
||||||
|
Request *http.Request
|
||||||
|
Response *http.Response
|
||||||
|
}
|
416
vendor/github.com/getsentry/sentry-go/scope.go
generated
vendored
Normal file
416
vendor/github.com/getsentry/sentry-go/scope.go
generated
vendored
Normal file
|
@ -0,0 +1,416 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Scope holds contextual data for the current scope.
|
||||||
|
//
|
||||||
|
// The scope is an object that can cloned efficiently and stores data that
|
||||||
|
// is locally relevant to an event. For instance the scope will hold recorded
|
||||||
|
// breadcrumbs and similar information.
|
||||||
|
//
|
||||||
|
// The scope can be interacted with in two ways:
|
||||||
|
//
|
||||||
|
// 1. the scope is routinely updated with information by functions such as
|
||||||
|
// `AddBreadcrumb` which will modify the currently top-most scope.
|
||||||
|
// 2. the topmost scope can also be configured through the `ConfigureScope`
|
||||||
|
// method.
|
||||||
|
//
|
||||||
|
// Note that the scope can only be modified but not inspected.
|
||||||
|
// Only the client can use the scope to extract information currently.
|
||||||
|
type Scope struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
breadcrumbs []*Breadcrumb
|
||||||
|
user User
|
||||||
|
tags map[string]string
|
||||||
|
contexts map[string]interface{}
|
||||||
|
extra map[string]interface{}
|
||||||
|
fingerprint []string
|
||||||
|
level Level
|
||||||
|
transaction string
|
||||||
|
request *http.Request
|
||||||
|
// requestBody holds a reference to the original request.Body.
|
||||||
|
requestBody interface {
|
||||||
|
// Bytes returns bytes from the original body, lazily buffered as the
|
||||||
|
// original body is read.
|
||||||
|
Bytes() []byte
|
||||||
|
// Overflow returns true if the body is larger than the maximum buffer
|
||||||
|
// size.
|
||||||
|
Overflow() bool
|
||||||
|
}
|
||||||
|
eventProcessors []EventProcessor
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewScope() *Scope {
|
||||||
|
scope := Scope{
|
||||||
|
breadcrumbs: make([]*Breadcrumb, 0),
|
||||||
|
tags: make(map[string]string),
|
||||||
|
contexts: make(map[string]interface{}),
|
||||||
|
extra: make(map[string]interface{}),
|
||||||
|
fingerprint: make([]string, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
return &scope
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddBreadcrumb adds new breadcrumb to the current scope
|
||||||
|
// and optionally throws the old one if limit is reached.
|
||||||
|
func (scope *Scope) AddBreadcrumb(breadcrumb *Breadcrumb, limit int) {
|
||||||
|
if breadcrumb.Timestamp.IsZero() {
|
||||||
|
breadcrumb.Timestamp = time.Now().UTC()
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
breadcrumbs := append(scope.breadcrumbs, breadcrumb)
|
||||||
|
if len(breadcrumbs) > limit {
|
||||||
|
scope.breadcrumbs = breadcrumbs[1 : limit+1]
|
||||||
|
} else {
|
||||||
|
scope.breadcrumbs = breadcrumbs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearBreadcrumbs clears all breadcrumbs from the current scope.
|
||||||
|
func (scope *Scope) ClearBreadcrumbs() {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.breadcrumbs = []*Breadcrumb{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUser sets the user for the current scope.
|
||||||
|
func (scope *Scope) SetUser(user User) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.user = user
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRequest sets the request for the current scope.
|
||||||
|
func (scope *Scope) SetRequest(r *http.Request) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.request = r
|
||||||
|
|
||||||
|
if r == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't buffer request body if we know it is oversized.
|
||||||
|
if r.ContentLength > maxRequestBodyBytes {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Don't buffer if there is no body.
|
||||||
|
if r.Body == nil || r.Body == http.NoBody {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buf := &limitedBuffer{Capacity: maxRequestBodyBytes}
|
||||||
|
r.Body = readCloser{
|
||||||
|
Reader: io.TeeReader(r.Body, buf),
|
||||||
|
Closer: r.Body,
|
||||||
|
}
|
||||||
|
scope.requestBody = buf
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRequestBody sets the request body for the current scope.
|
||||||
|
//
|
||||||
|
// This method should only be called when the body bytes are already available
|
||||||
|
// in memory. Typically, the request body is buffered lazily from the
|
||||||
|
// Request.Body from SetRequest.
|
||||||
|
func (scope *Scope) SetRequestBody(b []byte) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
capacity := maxRequestBodyBytes
|
||||||
|
overflow := false
|
||||||
|
if len(b) > capacity {
|
||||||
|
overflow = true
|
||||||
|
b = b[:capacity]
|
||||||
|
}
|
||||||
|
scope.requestBody = &limitedBuffer{
|
||||||
|
Capacity: capacity,
|
||||||
|
Buffer: *bytes.NewBuffer(b),
|
||||||
|
overflow: overflow,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// maxRequestBodyBytes is the default maximum request body size to send to
|
||||||
|
// Sentry.
|
||||||
|
const maxRequestBodyBytes = 10 * 1024
|
||||||
|
|
||||||
|
// A limitedBuffer is like a bytes.Buffer, but limited to store at most Capacity
|
||||||
|
// bytes. Any writes past the capacity are silently discarded, similar to
|
||||||
|
// ioutil.Discard.
|
||||||
|
type limitedBuffer struct {
|
||||||
|
Capacity int
|
||||||
|
|
||||||
|
bytes.Buffer
|
||||||
|
overflow bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write implements io.Writer.
|
||||||
|
func (b *limitedBuffer) Write(p []byte) (n int, err error) {
|
||||||
|
// Silently ignore writes after overflow.
|
||||||
|
if b.overflow {
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
left := b.Capacity - b.Len()
|
||||||
|
if left < 0 {
|
||||||
|
left = 0
|
||||||
|
}
|
||||||
|
if len(p) > left {
|
||||||
|
b.overflow = true
|
||||||
|
p = p[:left]
|
||||||
|
}
|
||||||
|
return b.Buffer.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overflow returns true if the limitedBuffer discarded bytes written to it.
|
||||||
|
func (b *limitedBuffer) Overflow() bool {
|
||||||
|
return b.overflow
|
||||||
|
}
|
||||||
|
|
||||||
|
// readCloser combines an io.Reader and an io.Closer to implement io.ReadCloser.
|
||||||
|
type readCloser struct {
|
||||||
|
io.Reader
|
||||||
|
io.Closer
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTag adds a tag to the current scope.
|
||||||
|
func (scope *Scope) SetTag(key, value string) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.tags[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTags assigns multiple tags to the current scope.
|
||||||
|
func (scope *Scope) SetTags(tags map[string]string) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
for k, v := range tags {
|
||||||
|
scope.tags[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveTag removes a tag from the current scope.
|
||||||
|
func (scope *Scope) RemoveTag(key string) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
delete(scope.tags, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContext adds a context to the current scope.
|
||||||
|
func (scope *Scope) SetContext(key string, value interface{}) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.contexts[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContexts assigns multiple contexts to the current scope.
|
||||||
|
func (scope *Scope) SetContexts(contexts map[string]interface{}) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
for k, v := range contexts {
|
||||||
|
scope.contexts[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveContext removes a context from the current scope.
|
||||||
|
func (scope *Scope) RemoveContext(key string) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
delete(scope.contexts, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExtra adds an extra to the current scope.
|
||||||
|
func (scope *Scope) SetExtra(key string, value interface{}) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.extra[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExtras assigns multiple extras to the current scope.
|
||||||
|
func (scope *Scope) SetExtras(extra map[string]interface{}) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
for k, v := range extra {
|
||||||
|
scope.extra[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveExtra removes a extra from the current scope.
|
||||||
|
func (scope *Scope) RemoveExtra(key string) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
delete(scope.extra, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFingerprint sets new fingerprint for the current scope.
|
||||||
|
func (scope *Scope) SetFingerprint(fingerprint []string) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.fingerprint = fingerprint
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLevel sets new level for the current scope.
|
||||||
|
func (scope *Scope) SetLevel(level Level) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.level = level
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTransaction sets new transaction name for the current transaction.
|
||||||
|
func (scope *Scope) SetTransaction(transactionName string) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.transaction = transactionName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns a copy of the current scope with all data copied over.
|
||||||
|
func (scope *Scope) Clone() *Scope {
|
||||||
|
scope.mu.RLock()
|
||||||
|
defer scope.mu.RUnlock()
|
||||||
|
|
||||||
|
clone := NewScope()
|
||||||
|
clone.user = scope.user
|
||||||
|
clone.breadcrumbs = make([]*Breadcrumb, len(scope.breadcrumbs))
|
||||||
|
copy(clone.breadcrumbs, scope.breadcrumbs)
|
||||||
|
for key, value := range scope.tags {
|
||||||
|
clone.tags[key] = value
|
||||||
|
}
|
||||||
|
for key, value := range scope.contexts {
|
||||||
|
clone.contexts[key] = value
|
||||||
|
}
|
||||||
|
for key, value := range scope.extra {
|
||||||
|
clone.extra[key] = value
|
||||||
|
}
|
||||||
|
clone.fingerprint = make([]string, len(scope.fingerprint))
|
||||||
|
copy(clone.fingerprint, scope.fingerprint)
|
||||||
|
clone.level = scope.level
|
||||||
|
clone.transaction = scope.transaction
|
||||||
|
clone.request = scope.request
|
||||||
|
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear removes the data from the current scope. Not safe for concurrent use.
|
||||||
|
func (scope *Scope) Clear() {
|
||||||
|
*scope = *NewScope()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddEventProcessor adds an event processor to the current scope.
|
||||||
|
func (scope *Scope) AddEventProcessor(processor EventProcessor) {
|
||||||
|
scope.mu.Lock()
|
||||||
|
defer scope.mu.Unlock()
|
||||||
|
|
||||||
|
scope.eventProcessors = append(scope.eventProcessors, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplyToEvent takes the data from the current scope and attaches it to the event.
|
||||||
|
func (scope *Scope) ApplyToEvent(event *Event, hint *EventHint) *Event {
|
||||||
|
scope.mu.RLock()
|
||||||
|
defer scope.mu.RUnlock()
|
||||||
|
|
||||||
|
if len(scope.breadcrumbs) > 0 {
|
||||||
|
if event.Breadcrumbs == nil {
|
||||||
|
event.Breadcrumbs = []*Breadcrumb{}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Breadcrumbs = append(event.Breadcrumbs, scope.breadcrumbs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(scope.tags) > 0 {
|
||||||
|
if event.Tags == nil {
|
||||||
|
event.Tags = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range scope.tags {
|
||||||
|
event.Tags[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(scope.contexts) > 0 {
|
||||||
|
if event.Contexts == nil {
|
||||||
|
event.Contexts = make(map[string]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range scope.contexts {
|
||||||
|
event.Contexts[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(scope.extra) > 0 {
|
||||||
|
if event.Extra == nil {
|
||||||
|
event.Extra = make(map[string]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range scope.extra {
|
||||||
|
event.Extra[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reflect.DeepEqual(event.User, User{})) {
|
||||||
|
event.User = scope.user
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.Fingerprint == nil || len(event.Fingerprint) == 0) &&
|
||||||
|
len(scope.fingerprint) > 0 {
|
||||||
|
event.Fingerprint = make([]string, len(scope.fingerprint))
|
||||||
|
copy(event.Fingerprint, scope.fingerprint)
|
||||||
|
}
|
||||||
|
|
||||||
|
if scope.level != "" {
|
||||||
|
event.Level = scope.level
|
||||||
|
}
|
||||||
|
|
||||||
|
if scope.transaction != "" {
|
||||||
|
event.Transaction = scope.transaction
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.Request == nil && scope.request != nil {
|
||||||
|
event.Request = NewRequest(scope.request)
|
||||||
|
// NOTE: The SDK does not attempt to send partial request body data.
|
||||||
|
//
|
||||||
|
// The reason being that Sentry's ingest pipeline and UI are optimized
|
||||||
|
// to show structured data. Additionally, tooling around PII scrubbing
|
||||||
|
// relies on structured data; truncated request bodies would create
|
||||||
|
// invalid payloads that are more prone to leaking PII data.
|
||||||
|
//
|
||||||
|
// Users can still send more data along their events if they want to,
|
||||||
|
// for example using Event.Extra.
|
||||||
|
if scope.requestBody != nil && !scope.requestBody.Overflow() {
|
||||||
|
event.Request.Data = string(scope.requestBody.Bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, processor := range scope.eventProcessors {
|
||||||
|
id := event.EventID
|
||||||
|
event = processor(event, hint)
|
||||||
|
if event == nil {
|
||||||
|
Logger.Printf("Event dropped by one of the Scope EventProcessors: %s\n", id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
135
vendor/github.com/getsentry/sentry-go/sentry.go
generated
vendored
Normal file
135
vendor/github.com/getsentry/sentry-go/sentry.go
generated
vendored
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Version is the version of the sentry-go SDK.
|
||||||
|
const Version = "0.6.1"
|
||||||
|
|
||||||
|
// apiVersion is the minimum version of the Sentry API compatible with the
|
||||||
|
// sentry-go SDK.
|
||||||
|
const apiVersion = "7"
|
||||||
|
|
||||||
|
// Init initializes whole SDK by creating new `Client` and binding it to the current `Hub`
|
||||||
|
func Init(options ClientOptions) error {
|
||||||
|
hub := CurrentHub()
|
||||||
|
client, err := NewClient(options)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
hub.BindClient(client)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddBreadcrumb records a new breadcrumb.
|
||||||
|
//
|
||||||
|
// The total number of breadcrumbs that can be recorded are limited by the
|
||||||
|
// configuration on the client.
|
||||||
|
func AddBreadcrumb(breadcrumb *Breadcrumb) {
|
||||||
|
hub := CurrentHub()
|
||||||
|
hub.AddBreadcrumb(breadcrumb, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureMessage captures an arbitrary message.
|
||||||
|
func CaptureMessage(message string) *EventID {
|
||||||
|
hub := CurrentHub()
|
||||||
|
return hub.CaptureMessage(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureException captures an error.
|
||||||
|
func CaptureException(exception error) *EventID {
|
||||||
|
hub := CurrentHub()
|
||||||
|
return hub.CaptureException(exception)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureEvent captures an event on the currently active client if any.
|
||||||
|
//
|
||||||
|
// The event must already be assembled. Typically code would instead use
|
||||||
|
// the utility methods like `CaptureException`. The return value is the
|
||||||
|
// event ID. In case Sentry is disabled or event was dropped, the return value will be nil.
|
||||||
|
func CaptureEvent(event *Event) *EventID {
|
||||||
|
hub := CurrentHub()
|
||||||
|
return hub.CaptureEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recover captures a panic.
|
||||||
|
func Recover() *EventID {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
hub := CurrentHub()
|
||||||
|
return hub.Recover(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recover captures a panic and passes relevant context object.
|
||||||
|
func RecoverWithContext(ctx context.Context) *EventID {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
var hub *Hub
|
||||||
|
|
||||||
|
if HasHubOnContext(ctx) {
|
||||||
|
hub = GetHubFromContext(ctx)
|
||||||
|
} else {
|
||||||
|
hub = CurrentHub()
|
||||||
|
}
|
||||||
|
|
||||||
|
return hub.RecoverWithContext(ctx, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithScope temporarily pushes a scope for a single call.
|
||||||
|
//
|
||||||
|
// This function takes one argument, a callback that executes
|
||||||
|
// in the context of that scope.
|
||||||
|
//
|
||||||
|
// This is useful when extra data should be send with a single capture call
|
||||||
|
// for instance a different level or tags
|
||||||
|
func WithScope(f func(scope *Scope)) {
|
||||||
|
hub := CurrentHub()
|
||||||
|
hub.WithScope(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigureScope invokes a function that can modify the current scope.
|
||||||
|
//
|
||||||
|
// The function is passed a mutable reference to the `Scope` so that modifications
|
||||||
|
// can be performed.
|
||||||
|
func ConfigureScope(f func(scope *Scope)) {
|
||||||
|
hub := CurrentHub()
|
||||||
|
hub.ConfigureScope(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushScope pushes a new scope.
|
||||||
|
func PushScope() {
|
||||||
|
hub := CurrentHub()
|
||||||
|
hub.PushScope()
|
||||||
|
}
|
||||||
|
|
||||||
|
// PopScope pushes a new scope.
|
||||||
|
func PopScope() {
|
||||||
|
hub := CurrentHub()
|
||||||
|
hub.PopScope()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush waits until the underlying Transport sends any buffered events to the
|
||||||
|
// Sentry server, blocking for at most the given timeout. It returns false if
|
||||||
|
// the timeout was reached. In that case, some events may not have been sent.
|
||||||
|
//
|
||||||
|
// Flush should be called before terminating the program to avoid
|
||||||
|
// unintentionally dropping events.
|
||||||
|
//
|
||||||
|
// Do not call Flush indiscriminately after every call to CaptureEvent,
|
||||||
|
// CaptureException or CaptureMessage. Instead, to have the SDK send events over
|
||||||
|
// the network synchronously, configure it to use the HTTPSyncTransport in the
|
||||||
|
// call to Init.
|
||||||
|
func Flush(timeout time.Duration) bool {
|
||||||
|
hub := CurrentHub()
|
||||||
|
return hub.Flush(timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LastEventID returns an ID of last captured event.
|
||||||
|
func LastEventID() EventID {
|
||||||
|
hub := CurrentHub()
|
||||||
|
return hub.LastEventID()
|
||||||
|
}
|
69
vendor/github.com/getsentry/sentry-go/sourcereader.go
generated
vendored
Normal file
69
vendor/github.com/getsentry/sentry-go/sourcereader.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type sourceReader struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
cache map[string][][]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSourceReader() sourceReader {
|
||||||
|
return sourceReader{
|
||||||
|
cache: make(map[string][][]byte),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sr *sourceReader) readContextLines(filename string, line, context int) ([][]byte, int) {
|
||||||
|
sr.mu.Lock()
|
||||||
|
defer sr.mu.Unlock()
|
||||||
|
|
||||||
|
lines, ok := sr.cache[filename]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
data, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
sr.cache[filename] = nil
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
lines = bytes.Split(data, []byte{'\n'})
|
||||||
|
sr.cache[filename] = lines
|
||||||
|
}
|
||||||
|
|
||||||
|
return sr.calculateContextLines(lines, line, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// `contextLine` points to a line that caused an issue itself, in relation to returned slice
|
||||||
|
func (sr *sourceReader) calculateContextLines(lines [][]byte, line, context int) ([][]byte, int) {
|
||||||
|
// Stacktrace lines are 1-indexed, slices are 0-indexed
|
||||||
|
line--
|
||||||
|
|
||||||
|
contextLine := context
|
||||||
|
|
||||||
|
if lines == nil || line >= len(lines) || line < 0 {
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if context < 0 {
|
||||||
|
context = 0
|
||||||
|
contextLine = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
start := line - context
|
||||||
|
|
||||||
|
if start < 0 {
|
||||||
|
contextLine += start
|
||||||
|
start = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
end := line + context + 1
|
||||||
|
|
||||||
|
if end > len(lines) {
|
||||||
|
end = len(lines)
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines[start:end], contextLine
|
||||||
|
}
|
283
vendor/github.com/getsentry/sentry-go/stacktrace.go
generated
vendored
Normal file
283
vendor/github.com/getsentry/sentry-go/stacktrace.go
generated
vendored
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go/build"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const unknown string = "unknown"
|
||||||
|
|
||||||
|
// The module download is split into two parts: downloading the go.mod and downloading the actual code.
|
||||||
|
// If you have dependencies only needed for tests, then they will show up in your go.mod,
|
||||||
|
// and go get will download their go.mods, but it will not download their code.
|
||||||
|
// The test-only dependencies get downloaded only when you need it, such as the first time you run go test.
|
||||||
|
//
|
||||||
|
// https://github.com/golang/go/issues/26913#issuecomment-411976222
|
||||||
|
|
||||||
|
// Stacktrace holds information about the frames of the stack.
|
||||||
|
type Stacktrace struct {
|
||||||
|
Frames []Frame `json:"frames,omitempty"`
|
||||||
|
FramesOmitted []uint `json:"frames_omitted,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStacktrace creates a stacktrace using `runtime.Callers`.
|
||||||
|
func NewStacktrace() *Stacktrace {
|
||||||
|
pcs := make([]uintptr, 100)
|
||||||
|
n := runtime.Callers(1, pcs)
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
frames := extractFrames(pcs[:n])
|
||||||
|
frames = filterFrames(frames)
|
||||||
|
|
||||||
|
stacktrace := Stacktrace{
|
||||||
|
Frames: frames,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &stacktrace
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtractStacktrace creates a new `Stacktrace` based on the given `error` object.
|
||||||
|
// TODO: Make it configurable so that anyone can provide their own implementation?
|
||||||
|
// Use of reflection allows us to not have a hard dependency on any given package, so we don't have to import it
|
||||||
|
func ExtractStacktrace(err error) *Stacktrace {
|
||||||
|
method := extractReflectedStacktraceMethod(err)
|
||||||
|
|
||||||
|
if !method.IsValid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pcs := extractPcs(method)
|
||||||
|
|
||||||
|
if len(pcs) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
frames := extractFrames(pcs)
|
||||||
|
frames = filterFrames(frames)
|
||||||
|
|
||||||
|
stacktrace := Stacktrace{
|
||||||
|
Frames: frames,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &stacktrace
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractReflectedStacktraceMethod(err error) reflect.Value {
|
||||||
|
var method reflect.Value
|
||||||
|
|
||||||
|
// https://github.com/pingcap/errors
|
||||||
|
methodGetStackTracer := reflect.ValueOf(err).MethodByName("GetStackTracer")
|
||||||
|
// https://github.com/pkg/errors
|
||||||
|
methodStackTrace := reflect.ValueOf(err).MethodByName("StackTrace")
|
||||||
|
// https://github.com/go-errors/errors
|
||||||
|
methodStackFrames := reflect.ValueOf(err).MethodByName("StackFrames")
|
||||||
|
|
||||||
|
if methodGetStackTracer.IsValid() {
|
||||||
|
stacktracer := methodGetStackTracer.Call(make([]reflect.Value, 0))[0]
|
||||||
|
stacktracerStackTrace := reflect.ValueOf(stacktracer).MethodByName("StackTrace")
|
||||||
|
|
||||||
|
if stacktracerStackTrace.IsValid() {
|
||||||
|
method = stacktracerStackTrace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if methodStackTrace.IsValid() {
|
||||||
|
method = methodStackTrace
|
||||||
|
}
|
||||||
|
|
||||||
|
if methodStackFrames.IsValid() {
|
||||||
|
method = methodStackFrames
|
||||||
|
}
|
||||||
|
|
||||||
|
return method
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractPcs(method reflect.Value) []uintptr {
|
||||||
|
var pcs []uintptr
|
||||||
|
|
||||||
|
stacktrace := method.Call(make([]reflect.Value, 0))[0]
|
||||||
|
|
||||||
|
if stacktrace.Kind() != reflect.Slice {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < stacktrace.Len(); i++ {
|
||||||
|
pc := stacktrace.Index(i)
|
||||||
|
|
||||||
|
if pc.Kind() == reflect.Uintptr {
|
||||||
|
pcs = append(pcs, uintptr(pc.Uint()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if pc.Kind() == reflect.Struct {
|
||||||
|
field := pc.FieldByName("ProgramCounter")
|
||||||
|
if field.IsValid() && field.Kind() == reflect.Uintptr {
|
||||||
|
pcs = append(pcs, uintptr(field.Uint()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pcs
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://docs.sentry.io/development/sdk-dev/event-payloads/stacktrace/
|
||||||
|
type Frame struct {
|
||||||
|
Function string `json:"function,omitempty"`
|
||||||
|
Symbol string `json:"symbol,omitempty"`
|
||||||
|
Module string `json:"module,omitempty"`
|
||||||
|
Package string `json:"package,omitempty"`
|
||||||
|
Filename string `json:"filename,omitempty"`
|
||||||
|
AbsPath string `json:"abs_path,omitempty"`
|
||||||
|
Lineno int `json:"lineno,omitempty"`
|
||||||
|
Colno int `json:"colno,omitempty"`
|
||||||
|
PreContext []string `json:"pre_context,omitempty"`
|
||||||
|
ContextLine string `json:"context_line,omitempty"`
|
||||||
|
PostContext []string `json:"post_context,omitempty"`
|
||||||
|
InApp bool `json:"in_app,omitempty"`
|
||||||
|
Vars map[string]interface{} `json:"vars,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFrame assembles a stacktrace frame out of `runtime.Frame`.
|
||||||
|
func NewFrame(f runtime.Frame) Frame {
|
||||||
|
abspath := f.File
|
||||||
|
filename := f.File
|
||||||
|
function := f.Function
|
||||||
|
var pkg string
|
||||||
|
|
||||||
|
if filename != "" {
|
||||||
|
filename = filepath.Base(filename)
|
||||||
|
} else {
|
||||||
|
filename = unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
if abspath == "" {
|
||||||
|
abspath = unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
if function != "" {
|
||||||
|
pkg, function = splitQualifiedFunctionName(function)
|
||||||
|
}
|
||||||
|
|
||||||
|
frame := Frame{
|
||||||
|
AbsPath: abspath,
|
||||||
|
Filename: filename,
|
||||||
|
Lineno: f.Line,
|
||||||
|
Module: pkg,
|
||||||
|
Function: function,
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.InApp = isInAppFrame(frame)
|
||||||
|
|
||||||
|
return frame
|
||||||
|
}
|
||||||
|
|
||||||
|
// splitQualifiedFunctionName splits a package path-qualified function name into
|
||||||
|
// package name and function name. Such qualified names are found in
|
||||||
|
// runtime.Frame.Function values.
|
||||||
|
func splitQualifiedFunctionName(name string) (pkg string, fun string) {
|
||||||
|
pkg = packageName(name)
|
||||||
|
fun = strings.TrimPrefix(name, pkg+".")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractFrames(pcs []uintptr) []Frame {
|
||||||
|
var frames []Frame
|
||||||
|
callersFrames := runtime.CallersFrames(pcs)
|
||||||
|
|
||||||
|
for {
|
||||||
|
callerFrame, more := callersFrames.Next()
|
||||||
|
|
||||||
|
frames = append([]Frame{
|
||||||
|
NewFrame(callerFrame),
|
||||||
|
}, frames...)
|
||||||
|
|
||||||
|
if !more {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames
|
||||||
|
}
|
||||||
|
|
||||||
|
// filterFrames filters out stack frames that are not meant to be reported to
|
||||||
|
// Sentry. Those are frames internal to the SDK or Go.
|
||||||
|
func filterFrames(frames []Frame) []Frame {
|
||||||
|
if len(frames) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
filteredFrames := make([]Frame, 0, len(frames))
|
||||||
|
|
||||||
|
for _, frame := range frames {
|
||||||
|
// Skip Go internal frames.
|
||||||
|
if frame.Module == "runtime" || frame.Module == "testing" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Skip Sentry internal frames, except for frames in _test packages (for
|
||||||
|
// testing).
|
||||||
|
if strings.HasPrefix(frame.Module, "github.com/getsentry/sentry-go") &&
|
||||||
|
!strings.HasSuffix(frame.Module, "_test") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filteredFrames = append(filteredFrames, frame)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredFrames
|
||||||
|
}
|
||||||
|
|
||||||
|
func isInAppFrame(frame Frame) bool {
|
||||||
|
if strings.HasPrefix(frame.AbsPath, build.Default.GOROOT) ||
|
||||||
|
strings.Contains(frame.Module, "vendor") ||
|
||||||
|
strings.Contains(frame.Module, "third_party") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func callerFunctionName() string {
|
||||||
|
pcs := make([]uintptr, 1)
|
||||||
|
runtime.Callers(3, pcs)
|
||||||
|
callersFrames := runtime.CallersFrames(pcs)
|
||||||
|
callerFrame, _ := callersFrames.Next()
|
||||||
|
return baseName(callerFrame.Function)
|
||||||
|
}
|
||||||
|
|
||||||
|
// packageName returns the package part of the symbol name, or the empty string
|
||||||
|
// if there is none.
|
||||||
|
// It replicates https://golang.org/pkg/debug/gosym/#Sym.PackageName, avoiding a
|
||||||
|
// dependency on debug/gosym.
|
||||||
|
func packageName(name string) string {
|
||||||
|
// A prefix of "type." and "go." is a compiler-generated symbol that doesn't belong to any package.
|
||||||
|
// See variable reservedimports in cmd/compile/internal/gc/subr.go
|
||||||
|
if strings.HasPrefix(name, "go.") || strings.HasPrefix(name, "type.") {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
pathend := strings.LastIndex(name, "/")
|
||||||
|
if pathend < 0 {
|
||||||
|
pathend = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if i := strings.Index(name[pathend:], "."); i != -1 {
|
||||||
|
return name[:pathend+i]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// baseName returns the symbol name without the package or receiver name.
|
||||||
|
// It replicates https://golang.org/pkg/debug/gosym/#Sym.BaseName, avoiding a
|
||||||
|
// dependency on debug/gosym.
|
||||||
|
func baseName(name string) string {
|
||||||
|
if i := strings.LastIndex(name, "."); i != -1 {
|
||||||
|
return name[i+1:]
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
447
vendor/github.com/getsentry/sentry-go/transport.go
generated
vendored
Normal file
447
vendor/github.com/getsentry/sentry-go/transport.go
generated
vendored
Normal file
|
@ -0,0 +1,447 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultBufferSize = 30
|
||||||
|
const defaultRetryAfter = time.Second * 60
|
||||||
|
const defaultTimeout = time.Second * 30
|
||||||
|
|
||||||
|
// Transport is used by the `Client` to deliver events to remote server.
|
||||||
|
type Transport interface {
|
||||||
|
Flush(timeout time.Duration) bool
|
||||||
|
Configure(options ClientOptions)
|
||||||
|
SendEvent(event *Event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProxyConfig(options ClientOptions) func(*http.Request) (*url.URL, error) {
|
||||||
|
if options.HTTPSProxy != "" {
|
||||||
|
return func(_ *http.Request) (*url.URL, error) {
|
||||||
|
return url.Parse(options.HTTPSProxy)
|
||||||
|
}
|
||||||
|
} else if options.HTTPProxy != "" {
|
||||||
|
return func(_ *http.Request) (*url.URL, error) {
|
||||||
|
return url.Parse(options.HTTPProxy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return http.ProxyFromEnvironment
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTLSConfig(options ClientOptions) *tls.Config {
|
||||||
|
if options.CaCerts != nil {
|
||||||
|
return &tls.Config{
|
||||||
|
RootCAs: options.CaCerts,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func retryAfter(now time.Time, r *http.Response) time.Duration {
|
||||||
|
retryAfterHeader := r.Header["Retry-After"]
|
||||||
|
|
||||||
|
if retryAfterHeader == nil {
|
||||||
|
return defaultRetryAfter
|
||||||
|
}
|
||||||
|
|
||||||
|
if date, err := time.Parse(time.RFC1123, retryAfterHeader[0]); err == nil {
|
||||||
|
return date.Sub(now)
|
||||||
|
}
|
||||||
|
|
||||||
|
if seconds, err := strconv.Atoi(retryAfterHeader[0]); err == nil {
|
||||||
|
return time.Second * time.Duration(seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultRetryAfter
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRequestBodyFromEvent(event *Event) []byte {
|
||||||
|
body, err := json.Marshal(event)
|
||||||
|
if err == nil {
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
||||||
|
partialMarshallMessage := "Original event couldn't be marshalled. Succeeded by stripping the data " +
|
||||||
|
"that uses interface{} type. Please verify that the data you attach to the scope is serializable."
|
||||||
|
// Try to serialize the event, with all the contextual data that allows for interface{} stripped.
|
||||||
|
event.Breadcrumbs = nil
|
||||||
|
event.Contexts = nil
|
||||||
|
event.Extra = map[string]interface{}{
|
||||||
|
"info": partialMarshallMessage,
|
||||||
|
}
|
||||||
|
body, err = json.Marshal(event)
|
||||||
|
if err == nil {
|
||||||
|
Logger.Println(partialMarshallMessage)
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should _only_ happen when Event.Exception[0].Stacktrace.Frames[0].Vars is unserializable
|
||||||
|
// Which won't ever happen, as we don't use it now (although it's the part of public interface accepted by Sentry)
|
||||||
|
// Juuust in case something, somehow goes utterly wrong.
|
||||||
|
Logger.Println("Event couldn't be marshalled, even with stripped contextual data. Skipping delivery. " +
|
||||||
|
"Please notify the SDK owners with possibly broken payload.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// HTTPTransport
|
||||||
|
// ================================
|
||||||
|
|
||||||
|
// A batch groups items that are processed sequentially.
|
||||||
|
type batch struct {
|
||||||
|
items chan *http.Request
|
||||||
|
started chan struct{} // closed to signal items started to be worked on
|
||||||
|
done chan struct{} // closed to signal completion of all items
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTPTransport is a default implementation of `Transport` interface used by `Client`.
|
||||||
|
type HTTPTransport struct {
|
||||||
|
dsn *Dsn
|
||||||
|
client *http.Client
|
||||||
|
transport http.RoundTripper
|
||||||
|
|
||||||
|
// buffer is a channel of batches. Calling Flush terminates work on the
|
||||||
|
// current in-flight items and starts a new batch for subsequent events.
|
||||||
|
buffer chan batch
|
||||||
|
|
||||||
|
start sync.Once
|
||||||
|
|
||||||
|
// Size of the transport buffer. Defaults to 30.
|
||||||
|
BufferSize int
|
||||||
|
// HTTP Client request timeout. Defaults to 30 seconds.
|
||||||
|
Timeout time.Duration
|
||||||
|
|
||||||
|
mu sync.RWMutex
|
||||||
|
disabledUntil time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHTTPTransport returns a new pre-configured instance of HTTPTransport
|
||||||
|
func NewHTTPTransport() *HTTPTransport {
|
||||||
|
transport := HTTPTransport{
|
||||||
|
BufferSize: defaultBufferSize,
|
||||||
|
Timeout: defaultTimeout,
|
||||||
|
}
|
||||||
|
return &transport
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure is called by the `Client` itself, providing it it's own `ClientOptions`.
|
||||||
|
func (t *HTTPTransport) Configure(options ClientOptions) {
|
||||||
|
dsn, err := NewDsn(options.Dsn)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Printf("%v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.dsn = dsn
|
||||||
|
|
||||||
|
// A buffered channel with capacity 1 works like a mutex, ensuring only one
|
||||||
|
// goroutine can access the current batch at a given time. Access is
|
||||||
|
// synchronized by reading from and writing to the channel.
|
||||||
|
t.buffer = make(chan batch, 1)
|
||||||
|
t.buffer <- batch{
|
||||||
|
items: make(chan *http.Request, t.BufferSize),
|
||||||
|
started: make(chan struct{}),
|
||||||
|
done: make(chan struct{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.HTTPTransport != nil {
|
||||||
|
t.transport = options.HTTPTransport
|
||||||
|
} else {
|
||||||
|
t.transport = &http.Transport{
|
||||||
|
Proxy: getProxyConfig(options),
|
||||||
|
TLSClientConfig: getTLSConfig(options),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.HTTPClient != nil {
|
||||||
|
t.client = options.HTTPClient
|
||||||
|
} else {
|
||||||
|
t.client = &http.Client{
|
||||||
|
Transport: t.transport,
|
||||||
|
Timeout: t.Timeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.start.Do(func() {
|
||||||
|
go t.worker()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendEvent assembles a new packet out of `Event` and sends it to remote server.
|
||||||
|
func (t *HTTPTransport) SendEvent(event *Event) {
|
||||||
|
if t.dsn == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.mu.RLock()
|
||||||
|
disabled := time.Now().Before(t.disabledUntil)
|
||||||
|
t.mu.RUnlock()
|
||||||
|
if disabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body := getRequestBodyFromEvent(event)
|
||||||
|
if body == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
request, _ := http.NewRequest(
|
||||||
|
http.MethodPost,
|
||||||
|
t.dsn.StoreAPIURL().String(),
|
||||||
|
bytes.NewBuffer(body),
|
||||||
|
)
|
||||||
|
|
||||||
|
for headerKey, headerValue := range t.dsn.RequestHeaders() {
|
||||||
|
request.Header.Set(headerKey, headerValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// <-t.buffer is equivalent to acquiring a lock to access the current batch.
|
||||||
|
// A few lines below, t.buffer <- b releases the lock.
|
||||||
|
//
|
||||||
|
// The lock must be held during the select block below to guarantee that
|
||||||
|
// b.items is not closed while trying to send to it. Remember that sending
|
||||||
|
// on a closed channel panics.
|
||||||
|
//
|
||||||
|
// Note that the select block takes a bounded amount of CPU time because of
|
||||||
|
// the default case that is executed if sending on b.items would block. That
|
||||||
|
// is, the event is dropped if it cannot be sent immediately to the b.items
|
||||||
|
// channel (used as a queue).
|
||||||
|
b := <-t.buffer
|
||||||
|
|
||||||
|
select {
|
||||||
|
case b.items <- request:
|
||||||
|
Logger.Printf(
|
||||||
|
"Sending %s event [%s] to %s project: %d\n",
|
||||||
|
event.Level,
|
||||||
|
event.EventID,
|
||||||
|
t.dsn.host,
|
||||||
|
t.dsn.projectID,
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
Logger.Println("Event dropped due to transport buffer being full.")
|
||||||
|
}
|
||||||
|
|
||||||
|
t.buffer <- b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush waits until any buffered events are sent to the Sentry server, blocking
|
||||||
|
// for at most the given timeout. It returns false if the timeout was reached.
|
||||||
|
// In that case, some events may not have been sent.
|
||||||
|
//
|
||||||
|
// Flush should be called before terminating the program to avoid
|
||||||
|
// unintentionally dropping events.
|
||||||
|
//
|
||||||
|
// Do not call Flush indiscriminately after every call to SendEvent. Instead, to
|
||||||
|
// have the SDK send events over the network synchronously, configure it to use
|
||||||
|
// the HTTPSyncTransport in the call to Init.
|
||||||
|
func (t *HTTPTransport) Flush(timeout time.Duration) bool {
|
||||||
|
toolate := time.After(timeout)
|
||||||
|
|
||||||
|
// Wait until processing the current batch has started or the timeout.
|
||||||
|
//
|
||||||
|
// We must wait until the worker has seen the current batch, because it is
|
||||||
|
// the only way b.done will be closed. If we do not wait, there is a
|
||||||
|
// possible execution flow in which b.done is never closed, and the only way
|
||||||
|
// out of Flush would be waiting for the timeout, which is undesired.
|
||||||
|
var b batch
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case b = <-t.buffer:
|
||||||
|
select {
|
||||||
|
case <-b.started:
|
||||||
|
goto started
|
||||||
|
default:
|
||||||
|
t.buffer <- b
|
||||||
|
}
|
||||||
|
case <-toolate:
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
started:
|
||||||
|
// Signal that there won't be any more items in this batch, so that the
|
||||||
|
// worker inner loop can end.
|
||||||
|
close(b.items)
|
||||||
|
// Start a new batch for subsequent events.
|
||||||
|
t.buffer <- batch{
|
||||||
|
items: make(chan *http.Request, t.BufferSize),
|
||||||
|
started: make(chan struct{}),
|
||||||
|
done: make(chan struct{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until the current batch is done or the timeout.
|
||||||
|
select {
|
||||||
|
case <-b.done:
|
||||||
|
Logger.Println("Buffer flushed successfully.")
|
||||||
|
return true
|
||||||
|
case <-toolate:
|
||||||
|
goto fail
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
Logger.Println("Buffer flushing reached the timeout.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HTTPTransport) worker() {
|
||||||
|
for b := range t.buffer {
|
||||||
|
// Signal that processing of the current batch has started.
|
||||||
|
close(b.started)
|
||||||
|
|
||||||
|
// Return the batch to the buffer so that other goroutines can use it.
|
||||||
|
// Equivalent to releasing a lock.
|
||||||
|
t.buffer <- b
|
||||||
|
|
||||||
|
// Process all batch items.
|
||||||
|
for request := range b.items {
|
||||||
|
t.mu.RLock()
|
||||||
|
disabled := time.Now().Before(t.disabledUntil)
|
||||||
|
t.mu.RUnlock()
|
||||||
|
if disabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := t.client.Do(request)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
Logger.Printf("There was an issue with sending an event: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if response != nil && response.StatusCode == http.StatusTooManyRequests {
|
||||||
|
deadline := time.Now().Add(retryAfter(time.Now(), response))
|
||||||
|
t.mu.Lock()
|
||||||
|
t.disabledUntil = deadline
|
||||||
|
t.mu.Unlock()
|
||||||
|
Logger.Printf("Too many requests, backing off till: %s\n", deadline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal that processing of the batch is done.
|
||||||
|
close(b.done)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// HTTPSyncTransport
|
||||||
|
// ================================
|
||||||
|
|
||||||
|
// HTTPSyncTransport is an implementation of `Transport` interface which blocks after each captured event.
|
||||||
|
type HTTPSyncTransport struct {
|
||||||
|
dsn *Dsn
|
||||||
|
client *http.Client
|
||||||
|
transport http.RoundTripper
|
||||||
|
disabledUntil time.Time
|
||||||
|
|
||||||
|
// HTTP Client request timeout. Defaults to 30 seconds.
|
||||||
|
Timeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHTTPSyncTransport returns a new pre-configured instance of HTTPSyncTransport
|
||||||
|
func NewHTTPSyncTransport() *HTTPSyncTransport {
|
||||||
|
transport := HTTPSyncTransport{
|
||||||
|
Timeout: defaultTimeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &transport
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure is called by the `Client` itself, providing it it's own `ClientOptions`.
|
||||||
|
func (t *HTTPSyncTransport) Configure(options ClientOptions) {
|
||||||
|
dsn, err := NewDsn(options.Dsn)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Printf("%v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.dsn = dsn
|
||||||
|
|
||||||
|
if options.HTTPTransport != nil {
|
||||||
|
t.transport = options.HTTPTransport
|
||||||
|
} else {
|
||||||
|
t.transport = &http.Transport{
|
||||||
|
Proxy: getProxyConfig(options),
|
||||||
|
TLSClientConfig: getTLSConfig(options),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.HTTPClient != nil {
|
||||||
|
t.client = options.HTTPClient
|
||||||
|
} else {
|
||||||
|
t.client = &http.Client{
|
||||||
|
Transport: t.transport,
|
||||||
|
Timeout: t.Timeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendEvent assembles a new packet out of `Event` and sends it to remote server.
|
||||||
|
func (t *HTTPSyncTransport) SendEvent(event *Event) {
|
||||||
|
if t.dsn == nil || time.Now().Before(t.disabledUntil) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body := getRequestBodyFromEvent(event)
|
||||||
|
if body == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
request, _ := http.NewRequest(
|
||||||
|
http.MethodPost,
|
||||||
|
t.dsn.StoreAPIURL().String(),
|
||||||
|
bytes.NewBuffer(body),
|
||||||
|
)
|
||||||
|
|
||||||
|
for headerKey, headerValue := range t.dsn.RequestHeaders() {
|
||||||
|
request.Header.Set(headerKey, headerValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Printf(
|
||||||
|
"Sending %s event [%s] to %s project: %d\n",
|
||||||
|
event.Level,
|
||||||
|
event.EventID,
|
||||||
|
t.dsn.host,
|
||||||
|
t.dsn.projectID,
|
||||||
|
)
|
||||||
|
|
||||||
|
response, err := t.client.Do(request)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
Logger.Printf("There was an issue with sending an event: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if response != nil && response.StatusCode == http.StatusTooManyRequests {
|
||||||
|
t.disabledUntil = time.Now().Add(retryAfter(time.Now(), response))
|
||||||
|
Logger.Printf("Too many requests, backing off till: %s\n", t.disabledUntil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush is a no-op for HTTPSyncTransport. It always returns true immediately.
|
||||||
|
func (t *HTTPSyncTransport) Flush(_ time.Duration) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================
|
||||||
|
// noopTransport
|
||||||
|
// ================================
|
||||||
|
|
||||||
|
// noopTransport is an implementation of `Transport` interface which drops all the events.
|
||||||
|
// Only used internally when an empty DSN is provided, which effectively disables the SDK.
|
||||||
|
type noopTransport struct{}
|
||||||
|
|
||||||
|
func (t *noopTransport) Configure(options ClientOptions) {
|
||||||
|
Logger.Println("Sentry client initialized with an empty DSN. Using noopTransport. No events will be delivered.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *noopTransport) SendEvent(event *Event) {
|
||||||
|
Logger.Println("Event dropped due to noopTransport usage.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *noopTransport) Flush(_ time.Duration) bool {
|
||||||
|
return true
|
||||||
|
}
|
34
vendor/github.com/getsentry/sentry-go/util.go
generated
vendored
Normal file
34
vendor/github.com/getsentry/sentry-go/util.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func uuid() string {
|
||||||
|
id := make([]byte, 16)
|
||||||
|
_, _ = io.ReadFull(rand.Reader, id)
|
||||||
|
id[6] &= 0x0F // clear version
|
||||||
|
id[6] |= 0x40 // set version to 4 (random uuid)
|
||||||
|
id[8] &= 0x3F // clear variant
|
||||||
|
id[8] |= 0x80 // set to IETF variant
|
||||||
|
return hex.EncodeToString(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileExists(fileName string) bool {
|
||||||
|
if _, err := os.Stat(fileName); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint: deadcode, unused
|
||||||
|
func prettyPrint(data interface{}) {
|
||||||
|
dbg, _ := json.MarshalIndent(data, "", " ")
|
||||||
|
fmt.Println(string(dbg))
|
||||||
|
}
|
14
vendor/github.com/golang/protobuf/proto/buffer.go
generated
vendored
14
vendor/github.com/golang/protobuf/proto/buffer.go
generated
vendored
|
@ -33,8 +33,8 @@ func SizeVarint(v uint64) int {
|
||||||
return protowire.SizeVarint(v)
|
return protowire.SizeVarint(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeVarint parses a varint encoded integer from b, returning the
|
// DecodeVarint parses a varint encoded integer from b,
|
||||||
// integer value and the length of the varint.
|
// returning the integer value and the length of the varint.
|
||||||
// It returns (0, 0) if there is a parse error.
|
// It returns (0, 0) if there is a parse error.
|
||||||
func DecodeVarint(b []byte) (uint64, int) {
|
func DecodeVarint(b []byte) (uint64, int) {
|
||||||
v, n := protowire.ConsumeVarint(b)
|
v, n := protowire.ConsumeVarint(b)
|
||||||
|
@ -112,9 +112,9 @@ func (b *Buffer) Marshal(m Message) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal parses the wire-format message in the buffer and places the decoded results in m.
|
// Unmarshal parses the wire-format message in the buffer and
|
||||||
//
|
// places the decoded results in m.
|
||||||
// Unlike proto.Unmarshal, this does not reset the message before starting to unmarshal.
|
// It does not reset m before unmarshaling.
|
||||||
func (b *Buffer) Unmarshal(m Message) error {
|
func (b *Buffer) Unmarshal(m Message) error {
|
||||||
err := UnmarshalMerge(b.Unread(), m)
|
err := UnmarshalMerge(b.Unread(), m)
|
||||||
b.idx = len(b.buf)
|
b.idx = len(b.buf)
|
||||||
|
@ -260,7 +260,7 @@ func (b *Buffer) DecodeStringBytes() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeMessage consumes a length-prefixed message from the buffer.
|
// DecodeMessage consumes a length-prefixed message from the buffer.
|
||||||
// It does not reset m.
|
// It does not reset m before unmarshaling.
|
||||||
func (b *Buffer) DecodeMessage(m Message) error {
|
func (b *Buffer) DecodeMessage(m Message) error {
|
||||||
v, err := b.DecodeRawBytes(false)
|
v, err := b.DecodeRawBytes(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -272,7 +272,7 @@ func (b *Buffer) DecodeMessage(m Message) error {
|
||||||
// DecodeGroup consumes a message group from the buffer.
|
// DecodeGroup consumes a message group from the buffer.
|
||||||
// It assumes that the start group marker has already been consumed and
|
// It assumes that the start group marker has already been consumed and
|
||||||
// consumes all bytes until (and including the end group marker).
|
// consumes all bytes until (and including the end group marker).
|
||||||
// It does not reset m.
|
// It does not reset m before unmarshaling.
|
||||||
func (b *Buffer) DecodeGroup(m Message) error {
|
func (b *Buffer) DecodeGroup(m Message) error {
|
||||||
v, n, err := consumeGroup(b.buf[b.idx:])
|
v, n, err := consumeGroup(b.buf[b.idx:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
33
vendor/github.com/golang/protobuf/proto/deprecated.go
generated
vendored
33
vendor/github.com/golang/protobuf/proto/deprecated.go
generated
vendored
|
@ -9,6 +9,8 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
protoV2 "google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -82,11 +84,30 @@ func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32,
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
// Deprecated: Do not use; this type existed for intenal-use only.
|
||||||
type InternalMessageInfo struct{}
|
type InternalMessageInfo struct{}
|
||||||
|
|
||||||
func (*InternalMessageInfo) DiscardUnknown(Message) { panic("not implemented") }
|
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||||
func (*InternalMessageInfo) Marshal([]byte, Message, bool) ([]byte, error) { panic("not implemented") }
|
func (*InternalMessageInfo) DiscardUnknown(m Message) {
|
||||||
func (*InternalMessageInfo) Merge(Message, Message) { panic("not implemented") }
|
DiscardUnknown(m)
|
||||||
func (*InternalMessageInfo) Size(Message) int { panic("not implemented") }
|
}
|
||||||
func (*InternalMessageInfo) Unmarshal(Message, []byte) error { panic("not implemented") }
|
|
||||||
|
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||||
|
func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) {
|
||||||
|
return protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||||
|
func (*InternalMessageInfo) Merge(dst, src Message) {
|
||||||
|
protoV2.Merge(MessageV2(dst), MessageV2(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||||
|
func (*InternalMessageInfo) Size(m Message) int {
|
||||||
|
return protoV2.Size(MessageV2(m))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Do not use; this method existed for intenal-use only.
|
||||||
|
func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error {
|
||||||
|
return protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m))
|
||||||
|
}
|
||||||
|
|
4
vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
4
vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
|
@ -68,7 +68,7 @@ func HasExtension(m Message, xt *ExtensionDesc) (has bool) {
|
||||||
return has
|
return has
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearExtension removes the the exntesion field from m
|
// ClearExtension removes the extension field from m
|
||||||
// either as an explicitly populated field or as an unknown field.
|
// either as an explicitly populated field or as an unknown field.
|
||||||
func ClearExtension(m Message, xt *ExtensionDesc) {
|
func ClearExtension(m Message, xt *ExtensionDesc) {
|
||||||
mr := MessageReflect(m)
|
mr := MessageReflect(m)
|
||||||
|
@ -108,7 +108,7 @@ func ClearAllExtensions(m Message) {
|
||||||
clearUnknown(mr, mr.Descriptor().ExtensionRanges())
|
clearUnknown(mr, mr.Descriptor().ExtensionRanges())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExtension retrieves a proto2 extended field from pb.
|
// GetExtension retrieves a proto2 extended field from m.
|
||||||
//
|
//
|
||||||
// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
|
// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
|
||||||
// then GetExtension parses the encoded field and returns a Go value of the specified type.
|
// then GetExtension parses the encoded field and returns a Go value of the specified type.
|
||||||
|
|
10
vendor/github.com/golang/protobuf/proto/registry.go
generated
vendored
10
vendor/github.com/golang/protobuf/proto/registry.go
generated
vendored
|
@ -29,7 +29,7 @@ var fileCache sync.Map // map[filePath]fileDescGZIP
|
||||||
// RegisterFile is called from generated code to register the compressed
|
// RegisterFile is called from generated code to register the compressed
|
||||||
// FileDescriptorProto with the file path for a proto source file.
|
// FileDescriptorProto with the file path for a proto source file.
|
||||||
//
|
//
|
||||||
// Deprecated: Use protoregistry.GlobalFiles.Register instead.
|
// Deprecated: Use protoregistry.GlobalFiles.RegisterFile instead.
|
||||||
func RegisterFile(s filePath, d fileDescGZIP) {
|
func RegisterFile(s filePath, d fileDescGZIP) {
|
||||||
// Decompress the descriptor.
|
// Decompress the descriptor.
|
||||||
zr, err := gzip.NewReader(bytes.NewReader(d))
|
zr, err := gzip.NewReader(bytes.NewReader(d))
|
||||||
|
@ -53,7 +53,7 @@ func RegisterFile(s filePath, d fileDescGZIP) {
|
||||||
// FileDescriptor returns the compressed FileDescriptorProto given the file path
|
// FileDescriptor returns the compressed FileDescriptorProto given the file path
|
||||||
// for a proto source file. It returns nil if not found.
|
// for a proto source file. It returns nil if not found.
|
||||||
//
|
//
|
||||||
// Deprecated: Use protoregistry.GlobalFiles.RangeFilesByPath instead.
|
// Deprecated: Use protoregistry.GlobalFiles.FindFileByPath instead.
|
||||||
func FileDescriptor(s filePath) fileDescGZIP {
|
func FileDescriptor(s filePath) fileDescGZIP {
|
||||||
if v, ok := fileCache.Load(s); ok {
|
if v, ok := fileCache.Load(s); ok {
|
||||||
return v.(fileDescGZIP)
|
return v.(fileDescGZIP)
|
||||||
|
@ -98,7 +98,7 @@ var numFilesCache sync.Map // map[protoreflect.FullName]int
|
||||||
// RegisterEnum is called from the generated code to register the mapping of
|
// RegisterEnum is called from the generated code to register the mapping of
|
||||||
// enum value names to enum numbers for the enum identified by s.
|
// enum value names to enum numbers for the enum identified by s.
|
||||||
//
|
//
|
||||||
// Deprecated: Use protoregistry.GlobalTypes.Register instead.
|
// Deprecated: Use protoregistry.GlobalTypes.RegisterEnum instead.
|
||||||
func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) {
|
func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) {
|
||||||
if _, ok := enumCache.Load(s); ok {
|
if _, ok := enumCache.Load(s); ok {
|
||||||
panic("proto: duplicate enum registered: " + s)
|
panic("proto: duplicate enum registered: " + s)
|
||||||
|
@ -181,7 +181,7 @@ var messageTypeCache sync.Map // map[messageName]reflect.Type
|
||||||
// RegisterType is called from generated code to register the message Go type
|
// RegisterType is called from generated code to register the message Go type
|
||||||
// for a message of the given name.
|
// for a message of the given name.
|
||||||
//
|
//
|
||||||
// Deprecated: Use protoregistry.GlobalTypes.Register instead.
|
// Deprecated: Use protoregistry.GlobalTypes.RegisterMessage instead.
|
||||||
func RegisterType(m Message, s messageName) {
|
func RegisterType(m Message, s messageName) {
|
||||||
mt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s))
|
mt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s))
|
||||||
if err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil {
|
if err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil {
|
||||||
|
@ -280,7 +280,7 @@ func MessageName(m Message) messageName {
|
||||||
// RegisterExtension is called from the generated code to register
|
// RegisterExtension is called from the generated code to register
|
||||||
// the extension descriptor.
|
// the extension descriptor.
|
||||||
//
|
//
|
||||||
// Deprecated: Use protoregistry.GlobalTypes.Register instead.
|
// Deprecated: Use protoregistry.GlobalTypes.RegisterExtension instead.
|
||||||
func RegisterExtension(d *ExtensionDesc) {
|
func RegisterExtension(d *ExtensionDesc) {
|
||||||
if err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil {
|
if err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
8
vendor/github.com/golang/protobuf/proto/text_encode.go
generated
vendored
8
vendor/github.com/golang/protobuf/proto/text_encode.go
generated
vendored
|
@ -94,16 +94,16 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// MarshalText writes the proto text format of m to w.
|
// MarshalText writes the proto text format of m to w.
|
||||||
func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
|
func MarshalText(w io.Writer, m Message) error { return defaultTextMarshaler.Marshal(w, m) }
|
||||||
|
|
||||||
// MarshalTextString returns a proto text formatted string of m.
|
// MarshalTextString returns a proto text formatted string of m.
|
||||||
func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
|
func MarshalTextString(m Message) string { return defaultTextMarshaler.Text(m) }
|
||||||
|
|
||||||
// CompactText writes the compact proto text format of m to w.
|
// CompactText writes the compact proto text format of m to w.
|
||||||
func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
|
func CompactText(w io.Writer, m Message) error { return compactTextMarshaler.Marshal(w, m) }
|
||||||
|
|
||||||
// CompactTextString returns a compact proto text formatted string of m.
|
// CompactTextString returns a compact proto text formatted string of m.
|
||||||
func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }
|
func CompactTextString(m Message) string { return compactTextMarshaler.Text(m) }
|
||||||
|
|
||||||
var (
|
var (
|
||||||
newline = []byte("\n")
|
newline = []byte("\n")
|
||||||
|
|
1
vendor/github.com/prometheus/client_golang/prometheus/desc.go
generated
vendored
1
vendor/github.com/prometheus/client_golang/prometheus/desc.go
generated
vendored
|
@ -20,6 +20,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/cespare/xxhash/v2"
|
"github.com/cespare/xxhash/v2"
|
||||||
|
//lint:ignore SA1019 Need to keep deprecated package for compatibility.
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
|
|
||||||
|
|
1
vendor/github.com/prometheus/client_golang/prometheus/histogram.go
generated
vendored
1
vendor/github.com/prometheus/client_golang/prometheus/histogram.go
generated
vendored
|
@ -22,6 +22,7 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
//lint:ignore SA1019 Need to keep deprecated package for compatibility.
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
|
|
1
vendor/github.com/prometheus/client_golang/prometheus/metric.go
generated
vendored
1
vendor/github.com/prometheus/client_golang/prometheus/metric.go
generated
vendored
|
@ -17,6 +17,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
//lint:ignore SA1019 Need to keep deprecated package for compatibility.
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
|
|
||||||
|
|
54
vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go
generated
vendored
54
vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go
generated
vendored
|
@ -98,7 +98,7 @@
|
||||||
// requestCount = promauto.With(reg).NewCounterVec(
|
// requestCount = promauto.With(reg).NewCounterVec(
|
||||||
// prometheus.CounterOpts{
|
// prometheus.CounterOpts{
|
||||||
// Name: "http_requests_total",
|
// Name: "http_requests_total",
|
||||||
// Help: "Total number of HTTP requests by status code end method.",
|
// Help: "Total number of HTTP requests by status code and method.",
|
||||||
// },
|
// },
|
||||||
// []string{"code", "method"},
|
// []string{"code", "method"},
|
||||||
// )
|
// )
|
||||||
|
@ -117,7 +117,7 @@
|
||||||
// requestCount = factory.NewCounterVec(
|
// requestCount = factory.NewCounterVec(
|
||||||
// prometheus.CounterOpts{
|
// prometheus.CounterOpts{
|
||||||
// Name: "http_requests_total",
|
// Name: "http_requests_total",
|
||||||
// Help: "Total number of HTTP requests by status code end method.",
|
// Help: "Total number of HTTP requests by status code and method.",
|
||||||
// },
|
// },
|
||||||
// []string{"code", "method"},
|
// []string{"code", "method"},
|
||||||
// )
|
// )
|
||||||
|
@ -127,29 +127,30 @@
|
||||||
// separate package?
|
// separate package?
|
||||||
//
|
//
|
||||||
// The main problem is that registration may fail, e.g. if a metric inconsistent
|
// The main problem is that registration may fail, e.g. if a metric inconsistent
|
||||||
// with the newly to be registered one is already registered. Therefore, the
|
// with or equal to the newly to be registered one is already registered.
|
||||||
// Register method in the prometheus.Registerer interface returns an error, and
|
// Therefore, the Register method in the prometheus.Registerer interface returns
|
||||||
// the same is the case for the top-level prometheus.Register function that
|
// an error, and the same is the case for the top-level prometheus.Register
|
||||||
// registers with the global registry. The prometheus package also provides
|
// function that registers with the global registry. The prometheus package also
|
||||||
// MustRegister versions for both. They panic if the registration fails, and
|
// provides MustRegister versions for both. They panic if the registration
|
||||||
// they clearly call this out by using the Must… idiom. Panicking is a bit
|
// fails, and they clearly call this out by using the Must… idiom. Panicking is
|
||||||
// problematic here because it doesn't just happen on input provided by the
|
// problematic in this case because it doesn't just happen on input provided by
|
||||||
// caller that is invalid on its own. Things are a bit more subtle here: Metric
|
// the caller that is invalid on its own. Things are a bit more subtle here:
|
||||||
// creation and registration tend to be spread widely over the codebase. It can
|
// Metric creation and registration tend to be spread widely over the
|
||||||
// easily happen that an incompatible metric is added to an unrelated part of
|
// codebase. It can easily happen that an incompatible metric is added to an
|
||||||
// the code, and suddenly code that used to work perfectly fine starts to panic
|
// unrelated part of the code, and suddenly code that used to work perfectly
|
||||||
// (provided that the registration of the newly added metric happens before the
|
// fine starts to panic (provided that the registration of the newly added
|
||||||
// registration of the previously existing metric). This may come as an even
|
// metric happens before the registration of the previously existing
|
||||||
// bigger surprise with the global registry, where simply importing another
|
// metric). This may come as an even bigger surprise with the global registry,
|
||||||
// package can trigger a panic (if the newly imported package registers metrics
|
// where simply importing another package can trigger a panic (if the newly
|
||||||
// in its init function). At least, in the prometheus package, creation of
|
// imported package registers metrics in its init function). At least, in the
|
||||||
// metrics and other collectors is separate from registration. You first create
|
// prometheus package, creation of metrics and other collectors is separate from
|
||||||
// the metric, and then you decide explicitly if you want to register it with a
|
// registration. You first create the metric, and then you decide explicitly if
|
||||||
// local or the global registry, and if you want to handle the error or risk a
|
// you want to register it with a local or the global registry, and if you want
|
||||||
// panic. With the constructors in the promauto package, registration is
|
// to handle the error or risk a panic. With the constructors in the promauto
|
||||||
// automatic, and if it fails, it will always panic. Furthermore, the
|
// package, registration is automatic, and if it fails, it will always
|
||||||
// constructors will often be called in the var section of a file, which means
|
// panic. Furthermore, the constructors will often be called in the var section
|
||||||
// that panicking will happen as a side effect of merely importing a package.
|
// of a file, which means that panicking will happen as a side effect of merely
|
||||||
|
// importing a package.
|
||||||
//
|
//
|
||||||
// A separate package allows conservative users to entirely ignore it. And
|
// A separate package allows conservative users to entirely ignore it. And
|
||||||
// whoever wants to use it, will do so explicitly, with an opportunity to read
|
// whoever wants to use it, will do so explicitly, with an opportunity to read
|
||||||
|
@ -252,7 +253,8 @@ type Factory struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// With creates a Factory using the provided Registerer for registration of the
|
// With creates a Factory using the provided Registerer for registration of the
|
||||||
// created Collectors.
|
// created Collectors. If the provided Registerer is nil, the returned Factory
|
||||||
|
// creates Collectors that are not registered with any Registerer.
|
||||||
func With(r prometheus.Registerer) Factory { return Factory{r} }
|
func With(r prometheus.Registerer) Factory { return Factory{r} }
|
||||||
|
|
||||||
// NewCounter works like the function of the same name in the prometheus package
|
// NewCounter works like the function of the same name in the prometheus package
|
||||||
|
|
1
vendor/github.com/prometheus/client_golang/prometheus/registry.go
generated
vendored
1
vendor/github.com/prometheus/client_golang/prometheus/registry.go
generated
vendored
|
@ -26,6 +26,7 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/cespare/xxhash/v2"
|
"github.com/cespare/xxhash/v2"
|
||||||
|
//lint:ignore SA1019 Need to keep deprecated package for compatibility.
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/prometheus/common/expfmt"
|
"github.com/prometheus/common/expfmt"
|
||||||
|
|
||||||
|
|
1
vendor/github.com/prometheus/client_golang/prometheus/summary.go
generated
vendored
1
vendor/github.com/prometheus/client_golang/prometheus/summary.go
generated
vendored
|
@ -23,6 +23,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/beorn7/perks/quantile"
|
"github.com/beorn7/perks/quantile"
|
||||||
|
//lint:ignore SA1019 Need to keep deprecated package for compatibility.
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
|
|
1
vendor/github.com/prometheus/client_golang/prometheus/value.go
generated
vendored
1
vendor/github.com/prometheus/client_golang/prometheus/value.go
generated
vendored
|
@ -19,6 +19,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
//lint:ignore SA1019 Need to keep deprecated package for compatibility.
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/golang/protobuf/ptypes"
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
|
||||||
|
|
14
vendor/github.com/prometheus/client_golang/prometheus/wrap.go
generated
vendored
14
vendor/github.com/prometheus/client_golang/prometheus/wrap.go
generated
vendored
|
@ -17,6 +17,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
//lint:ignore SA1019 Need to keep deprecated package for compatibility.
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
|
@ -27,7 +28,8 @@ import (
|
||||||
// registered with the wrapped Registerer in a modified way. The modified
|
// registered with the wrapped Registerer in a modified way. The modified
|
||||||
// Collector adds the provided Labels to all Metrics it collects (as
|
// Collector adds the provided Labels to all Metrics it collects (as
|
||||||
// ConstLabels). The Metrics collected by the unmodified Collector must not
|
// ConstLabels). The Metrics collected by the unmodified Collector must not
|
||||||
// duplicate any of those labels.
|
// duplicate any of those labels. Wrapping a nil value is valid, resulting
|
||||||
|
// in a no-op Registerer.
|
||||||
//
|
//
|
||||||
// WrapRegistererWith provides a way to add fixed labels to a subset of
|
// WrapRegistererWith provides a way to add fixed labels to a subset of
|
||||||
// Collectors. It should not be used to add fixed labels to all metrics exposed.
|
// Collectors. It should not be used to add fixed labels to all metrics exposed.
|
||||||
|
@ -50,6 +52,7 @@ func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
|
||||||
// Registerer. Collectors registered with the returned Registerer will be
|
// Registerer. Collectors registered with the returned Registerer will be
|
||||||
// registered with the wrapped Registerer in a modified way. The modified
|
// registered with the wrapped Registerer in a modified way. The modified
|
||||||
// Collector adds the provided prefix to the name of all Metrics it collects.
|
// Collector adds the provided prefix to the name of all Metrics it collects.
|
||||||
|
// Wrapping a nil value is valid, resulting in a no-op Registerer.
|
||||||
//
|
//
|
||||||
// WrapRegistererWithPrefix is useful to have one place to prefix all metrics of
|
// WrapRegistererWithPrefix is useful to have one place to prefix all metrics of
|
||||||
// a sub-system. To make this work, register metrics of the sub-system with the
|
// a sub-system. To make this work, register metrics of the sub-system with the
|
||||||
|
@ -80,6 +83,9 @@ type wrappingRegisterer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *wrappingRegisterer) Register(c Collector) error {
|
func (r *wrappingRegisterer) Register(c Collector) error {
|
||||||
|
if r.wrappedRegisterer == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return r.wrappedRegisterer.Register(&wrappingCollector{
|
return r.wrappedRegisterer.Register(&wrappingCollector{
|
||||||
wrappedCollector: c,
|
wrappedCollector: c,
|
||||||
prefix: r.prefix,
|
prefix: r.prefix,
|
||||||
|
@ -88,6 +94,9 @@ func (r *wrappingRegisterer) Register(c Collector) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *wrappingRegisterer) MustRegister(cs ...Collector) {
|
func (r *wrappingRegisterer) MustRegister(cs ...Collector) {
|
||||||
|
if r.wrappedRegisterer == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, c := range cs {
|
for _, c := range cs {
|
||||||
if err := r.Register(c); err != nil {
|
if err := r.Register(c); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -96,6 +105,9 @@ func (r *wrappingRegisterer) MustRegister(cs ...Collector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *wrappingRegisterer) Unregister(c Collector) bool {
|
func (r *wrappingRegisterer) Unregister(c Collector) bool {
|
||||||
|
if r.wrappedRegisterer == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return r.wrappedRegisterer.Unregister(&wrappingCollector{
|
return r.wrappedRegisterer.Unregister(&wrappingCollector{
|
||||||
wrappedCollector: c,
|
wrappedCollector: c,
|
||||||
prefix: r.prefix,
|
prefix: r.prefix,
|
||||||
|
|
4
vendor/github.com/prometheus/common/model/time.go
generated
vendored
4
vendor/github.com/prometheus/common/model/time.go
generated
vendored
|
@ -186,6 +186,10 @@ var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$")
|
||||||
// ParseDuration parses a string into a time.Duration, assuming that a year
|
// ParseDuration parses a string into a time.Duration, assuming that a year
|
||||||
// always has 365d, a week always has 7d, and a day always has 24h.
|
// always has 365d, a week always has 7d, and a day always has 24h.
|
||||||
func ParseDuration(durationStr string) (Duration, error) {
|
func ParseDuration(durationStr string) (Duration, error) {
|
||||||
|
// Allow 0 without a unit.
|
||||||
|
if durationStr == "0" {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
matches := durationRE.FindStringSubmatch(durationStr)
|
matches := durationRE.FindStringSubmatch(durationStr)
|
||||||
if len(matches) != 3 {
|
if len(matches) != 3 {
|
||||||
return 0, fmt.Errorf("not a valid duration string: %q", durationStr)
|
return 0, fmt.Errorf("not a valid duration string: %q", durationStr)
|
||||||
|
|
11
vendor/github.com/prometheus/procfs/Makefile.common
generated
vendored
11
vendor/github.com/prometheus/procfs/Makefile.common
generated
vendored
|
@ -150,6 +150,17 @@ else
|
||||||
$(GO) get $(GOOPTS) -t ./...
|
$(GO) get $(GOOPTS) -t ./...
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
.PHONY: update-go-deps
|
||||||
|
update-go-deps:
|
||||||
|
@echo ">> updating Go dependencies"
|
||||||
|
@for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \
|
||||||
|
$(GO) get $$m; \
|
||||||
|
done
|
||||||
|
GO111MODULE=$(GO111MODULE) $(GO) mod tidy
|
||||||
|
ifneq (,$(wildcard vendor))
|
||||||
|
GO111MODULE=$(GO111MODULE) $(GO) mod vendor
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: common-test-short
|
.PHONY: common-test-short
|
||||||
common-test-short: $(GOTEST_DIR)
|
common-test-short: $(GOTEST_DIR)
|
||||||
@echo ">> running short tests"
|
@echo ">> running short tests"
|
||||||
|
|
265
vendor/github.com/prometheus/procfs/cpuinfo.go
generated
vendored
265
vendor/github.com/prometheus/procfs/cpuinfo.go
generated
vendored
|
@ -11,11 +11,15 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -52,6 +56,11 @@ type CPUInfo struct {
|
||||||
PowerManagement string
|
PowerManagement string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
cpuinfoClockRegexp = regexp.MustCompile(`([\d.]+)`)
|
||||||
|
cpuinfoS390XProcessorRegexp = regexp.MustCompile(`^processor\s+(\d+):.*`)
|
||||||
|
)
|
||||||
|
|
||||||
// CPUInfo returns information about current system CPUs.
|
// CPUInfo returns information about current system CPUs.
|
||||||
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
|
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
|
||||||
func (fs FS) CPUInfo() ([]CPUInfo, error) {
|
func (fs FS) CPUInfo() ([]CPUInfo, error) {
|
||||||
|
@ -62,14 +71,26 @@ func (fs FS) CPUInfo() ([]CPUInfo, error) {
|
||||||
return parseCPUInfo(data)
|
return parseCPUInfo(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseCPUInfo parses data from /proc/cpuinfo
|
func parseCPUInfoX86(info []byte) ([]CPUInfo, error) {
|
||||||
func parseCPUInfo(info []byte) ([]CPUInfo, error) {
|
|
||||||
cpuinfo := []CPUInfo{}
|
|
||||||
i := -1
|
|
||||||
scanner := bufio.NewScanner(bytes.NewReader(info))
|
scanner := bufio.NewScanner(bytes.NewReader(info))
|
||||||
|
|
||||||
|
// find the first "processor" line
|
||||||
|
firstLine := firstNonEmptyLine(scanner)
|
||||||
|
if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
|
||||||
|
return nil, errors.New("invalid cpuinfo file: " + firstLine)
|
||||||
|
}
|
||||||
|
field := strings.SplitN(firstLine, ": ", 2)
|
||||||
|
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
firstcpu := CPUInfo{Processor: uint(v)}
|
||||||
|
cpuinfo := []CPUInfo{firstcpu}
|
||||||
|
i := 0
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
if strings.TrimSpace(line) == "" {
|
if !strings.Contains(line, ":") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
field := strings.SplitN(line, ": ", 2)
|
field := strings.SplitN(line, ": ", 2)
|
||||||
|
@ -82,7 +103,7 @@ func parseCPUInfo(info []byte) ([]CPUInfo, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cpuinfo[i].Processor = uint(v)
|
cpuinfo[i].Processor = uint(v)
|
||||||
case "vendor_id":
|
case "vendor", "vendor_id":
|
||||||
cpuinfo[i].VendorID = field[1]
|
cpuinfo[i].VendorID = field[1]
|
||||||
case "cpu family":
|
case "cpu family":
|
||||||
cpuinfo[i].CPUFamily = field[1]
|
cpuinfo[i].CPUFamily = field[1]
|
||||||
|
@ -163,5 +184,237 @@ func parseCPUInfo(info []byte) ([]CPUInfo, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cpuinfo, nil
|
return cpuinfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseCPUInfoARM(info []byte) ([]CPUInfo, error) {
|
||||||
|
scanner := bufio.NewScanner(bytes.NewReader(info))
|
||||||
|
|
||||||
|
firstLine := firstNonEmptyLine(scanner)
|
||||||
|
match, _ := regexp.MatchString("^[Pp]rocessor", firstLine)
|
||||||
|
if !match || !strings.Contains(firstLine, ":") {
|
||||||
|
return nil, errors.New("invalid cpuinfo file: " + firstLine)
|
||||||
|
}
|
||||||
|
field := strings.SplitN(firstLine, ": ", 2)
|
||||||
|
cpuinfo := []CPUInfo{}
|
||||||
|
featuresLine := ""
|
||||||
|
commonCPUInfo := CPUInfo{}
|
||||||
|
i := 0
|
||||||
|
if strings.TrimSpace(field[0]) == "Processor" {
|
||||||
|
commonCPUInfo = CPUInfo{ModelName: field[1]}
|
||||||
|
i = -1
|
||||||
|
} else {
|
||||||
|
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
firstcpu := CPUInfo{Processor: uint(v)}
|
||||||
|
cpuinfo = []CPUInfo{firstcpu}
|
||||||
|
}
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if !strings.Contains(line, ":") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
field := strings.SplitN(line, ": ", 2)
|
||||||
|
switch strings.TrimSpace(field[0]) {
|
||||||
|
case "processor":
|
||||||
|
cpuinfo = append(cpuinfo, commonCPUInfo) // start of the next processor
|
||||||
|
i++
|
||||||
|
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cpuinfo[i].Processor = uint(v)
|
||||||
|
case "BogoMIPS":
|
||||||
|
if i == -1 {
|
||||||
|
cpuinfo = append(cpuinfo, commonCPUInfo) // There is only one processor
|
||||||
|
i++
|
||||||
|
cpuinfo[i].Processor = 0
|
||||||
|
}
|
||||||
|
v, err := strconv.ParseFloat(field[1], 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cpuinfo[i].BogoMips = v
|
||||||
|
case "Features":
|
||||||
|
featuresLine = line
|
||||||
|
case "model name":
|
||||||
|
cpuinfo[i].ModelName = field[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fields := strings.SplitN(featuresLine, ": ", 2)
|
||||||
|
for i := range cpuinfo {
|
||||||
|
cpuinfo[i].Flags = strings.Fields(fields[1])
|
||||||
|
}
|
||||||
|
return cpuinfo, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {
|
||||||
|
scanner := bufio.NewScanner(bytes.NewReader(info))
|
||||||
|
|
||||||
|
firstLine := firstNonEmptyLine(scanner)
|
||||||
|
if !strings.HasPrefix(firstLine, "vendor_id") || !strings.Contains(firstLine, ":") {
|
||||||
|
return nil, errors.New("invalid cpuinfo file: " + firstLine)
|
||||||
|
}
|
||||||
|
field := strings.SplitN(firstLine, ": ", 2)
|
||||||
|
cpuinfo := []CPUInfo{}
|
||||||
|
commonCPUInfo := CPUInfo{VendorID: field[1]}
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if !strings.Contains(line, ":") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
field := strings.SplitN(line, ": ", 2)
|
||||||
|
switch strings.TrimSpace(field[0]) {
|
||||||
|
case "bogomips per cpu":
|
||||||
|
v, err := strconv.ParseFloat(field[1], 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
commonCPUInfo.BogoMips = v
|
||||||
|
case "features":
|
||||||
|
commonCPUInfo.Flags = strings.Fields(field[1])
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(line, "processor") {
|
||||||
|
match := cpuinfoS390XProcessorRegexp.FindStringSubmatch(line)
|
||||||
|
if len(match) < 2 {
|
||||||
|
return nil, errors.New("Invalid line found in cpuinfo: " + line)
|
||||||
|
}
|
||||||
|
cpu := commonCPUInfo
|
||||||
|
v, err := strconv.ParseUint(match[1], 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cpu.Processor = uint(v)
|
||||||
|
cpuinfo = append(cpuinfo, cpu)
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(line, "cpu number") {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if !strings.Contains(line, ":") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
field := strings.SplitN(line, ": ", 2)
|
||||||
|
switch strings.TrimSpace(field[0]) {
|
||||||
|
case "cpu number":
|
||||||
|
i++
|
||||||
|
case "cpu MHz dynamic":
|
||||||
|
clock := cpuinfoClockRegexp.FindString(strings.TrimSpace(field[1]))
|
||||||
|
v, err := strconv.ParseFloat(clock, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cpuinfo[i].CPUMHz = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cpuinfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseCPUInfoMips(info []byte) ([]CPUInfo, error) {
|
||||||
|
scanner := bufio.NewScanner(bytes.NewReader(info))
|
||||||
|
|
||||||
|
// find the first "processor" line
|
||||||
|
firstLine := firstNonEmptyLine(scanner)
|
||||||
|
if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") {
|
||||||
|
return nil, errors.New("invalid cpuinfo file: " + firstLine)
|
||||||
|
}
|
||||||
|
field := strings.SplitN(firstLine, ": ", 2)
|
||||||
|
cpuinfo := []CPUInfo{}
|
||||||
|
systemType := field[1]
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if !strings.Contains(line, ":") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
field := strings.SplitN(line, ": ", 2)
|
||||||
|
switch strings.TrimSpace(field[0]) {
|
||||||
|
case "processor":
|
||||||
|
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
i = int(v)
|
||||||
|
cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor
|
||||||
|
cpuinfo[i].Processor = uint(v)
|
||||||
|
cpuinfo[i].VendorID = systemType
|
||||||
|
case "cpu model":
|
||||||
|
cpuinfo[i].ModelName = field[1]
|
||||||
|
case "BogoMIPS":
|
||||||
|
v, err := strconv.ParseFloat(field[1], 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cpuinfo[i].BogoMips = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cpuinfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseCPUInfoPPC(info []byte) ([]CPUInfo, error) {
|
||||||
|
scanner := bufio.NewScanner(bytes.NewReader(info))
|
||||||
|
|
||||||
|
firstLine := firstNonEmptyLine(scanner)
|
||||||
|
if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
|
||||||
|
return nil, errors.New("invalid cpuinfo file: " + firstLine)
|
||||||
|
}
|
||||||
|
field := strings.SplitN(firstLine, ": ", 2)
|
||||||
|
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
firstcpu := CPUInfo{Processor: uint(v)}
|
||||||
|
cpuinfo := []CPUInfo{firstcpu}
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if !strings.Contains(line, ":") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
field := strings.SplitN(line, ": ", 2)
|
||||||
|
switch strings.TrimSpace(field[0]) {
|
||||||
|
case "processor":
|
||||||
|
cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor
|
||||||
|
i++
|
||||||
|
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cpuinfo[i].Processor = uint(v)
|
||||||
|
case "cpu":
|
||||||
|
cpuinfo[i].VendorID = field[1]
|
||||||
|
case "clock":
|
||||||
|
clock := cpuinfoClockRegexp.FindString(strings.TrimSpace(field[1]))
|
||||||
|
v, err := strconv.ParseFloat(clock, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cpuinfo[i].CPUMHz = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cpuinfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// firstNonEmptyLine advances the scanner to the first non-empty line
|
||||||
|
// and returns the contents of that line
|
||||||
|
func firstNonEmptyLine(scanner *bufio.Scanner) string {
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if strings.TrimSpace(line) != "" {
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
18
vendor/github.com/prometheus/procfs/cpuinfo_arm.go
generated
vendored
Normal file
18
vendor/github.com/prometheus/procfs/cpuinfo_arm.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoARM
|
19
vendor/github.com/prometheus/procfs/cpuinfo_arm64.go
generated
vendored
Normal file
19
vendor/github.com/prometheus/procfs/cpuinfo_arm64.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build arm64
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoARM
|
19
vendor/github.com/prometheus/procfs/cpuinfo_default.go
generated
vendored
Normal file
19
vendor/github.com/prometheus/procfs/cpuinfo_default.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build 386 amd64
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoX86
|
18
vendor/github.com/prometheus/procfs/cpuinfo_mips.go
generated
vendored
Normal file
18
vendor/github.com/prometheus/procfs/cpuinfo_mips.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoMips
|
18
vendor/github.com/prometheus/procfs/cpuinfo_mips64.go
generated
vendored
Normal file
18
vendor/github.com/prometheus/procfs/cpuinfo_mips64.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoMips
|
18
vendor/github.com/prometheus/procfs/cpuinfo_mips64le.go
generated
vendored
Normal file
18
vendor/github.com/prometheus/procfs/cpuinfo_mips64le.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoMips
|
18
vendor/github.com/prometheus/procfs/cpuinfo_mipsle.go
generated
vendored
Normal file
18
vendor/github.com/prometheus/procfs/cpuinfo_mipsle.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoMips
|
18
vendor/github.com/prometheus/procfs/cpuinfo_ppc64.go
generated
vendored
Normal file
18
vendor/github.com/prometheus/procfs/cpuinfo_ppc64.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoPPC
|
18
vendor/github.com/prometheus/procfs/cpuinfo_ppc64le.go
generated
vendored
Normal file
18
vendor/github.com/prometheus/procfs/cpuinfo_ppc64le.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoPPC
|
18
vendor/github.com/prometheus/procfs/cpuinfo_s390x.go
generated
vendored
Normal file
18
vendor/github.com/prometheus/procfs/cpuinfo_s390x.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
var parseCPUInfo = parseCPUInfoS390X
|
737
vendor/github.com/prometheus/procfs/fixtures.ttar
generated
vendored
737
vendor/github.com/prometheus/procfs/fixtures.ttar
generated
vendored
|
@ -173,6 +173,283 @@ Lines: 1
|
||||||
411605849 93680043 79
|
411605849 93680043 79
|
||||||
Mode: 644
|
Mode: 644
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/proc/26231/smaps
|
||||||
|
Lines: 252
|
||||||
|
00400000-00cb1000 r-xp 00000000 fd:01 952273 /bin/alertmanager
|
||||||
|
Size: 8900 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 2952 kB
|
||||||
|
Pss: 2952 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 2952 kB
|
||||||
|
Private_Dirty: 0 kB
|
||||||
|
Referenced: 2864 kB
|
||||||
|
Anonymous: 0 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 0 kB
|
||||||
|
SwapPss: 0 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd ex mr mw me dw sd
|
||||||
|
00cb1000-016b0000 r--p 008b1000 fd:01 952273 /bin/alertmanager
|
||||||
|
Size: 10236 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 6152 kB
|
||||||
|
Pss: 6152 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 6152 kB
|
||||||
|
Private_Dirty: 0 kB
|
||||||
|
Referenced: 5308 kB
|
||||||
|
Anonymous: 0 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 0 kB
|
||||||
|
SwapPss: 0 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd mr mw me dw sd
|
||||||
|
016b0000-0171a000 rw-p 012b0000 fd:01 952273 /bin/alertmanager
|
||||||
|
Size: 424 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 176 kB
|
||||||
|
Pss: 176 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 84 kB
|
||||||
|
Private_Dirty: 92 kB
|
||||||
|
Referenced: 176 kB
|
||||||
|
Anonymous: 92 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 12 kB
|
||||||
|
SwapPss: 12 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd wr mr mw me dw ac sd
|
||||||
|
0171a000-0173f000 rw-p 00000000 00:00 0
|
||||||
|
Size: 148 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 76 kB
|
||||||
|
Pss: 76 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 0 kB
|
||||||
|
Private_Dirty: 76 kB
|
||||||
|
Referenced: 76 kB
|
||||||
|
Anonymous: 76 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 0 kB
|
||||||
|
SwapPss: 0 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd wr mr mw me ac sd
|
||||||
|
c000000000-c000400000 rw-p 00000000 00:00 0
|
||||||
|
Size: 4096 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 2564 kB
|
||||||
|
Pss: 2564 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 20 kB
|
||||||
|
Private_Dirty: 2544 kB
|
||||||
|
Referenced: 2544 kB
|
||||||
|
Anonymous: 2564 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 1100 kB
|
||||||
|
SwapPss: 1100 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd wr mr mw me ac sd
|
||||||
|
c000400000-c001600000 rw-p 00000000 00:00 0
|
||||||
|
Size: 18432 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 16024 kB
|
||||||
|
Pss: 16024 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 5864 kB
|
||||||
|
Private_Dirty: 10160 kB
|
||||||
|
Referenced: 11944 kB
|
||||||
|
Anonymous: 16024 kB
|
||||||
|
LazyFree: 5848 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 440 kB
|
||||||
|
SwapPss: 440 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd wr mr mw me ac sd nh
|
||||||
|
c001600000-c004000000 rw-p 00000000 00:00 0
|
||||||
|
Size: 43008 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 0 kB
|
||||||
|
Pss: 0 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 0 kB
|
||||||
|
Private_Dirty: 0 kB
|
||||||
|
Referenced: 0 kB
|
||||||
|
Anonymous: 0 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 0 kB
|
||||||
|
SwapPss: 0 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd wr mr mw me ac sd
|
||||||
|
7f0ab95ca000-7f0abbb7b000 rw-p 00000000 00:00 0
|
||||||
|
Size: 38596 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 1992 kB
|
||||||
|
Pss: 1992 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 476 kB
|
||||||
|
Private_Dirty: 1516 kB
|
||||||
|
Referenced: 1828 kB
|
||||||
|
Anonymous: 1992 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 384 kB
|
||||||
|
SwapPss: 384 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd wr mr mw me ac sd
|
||||||
|
7ffc07ecf000-7ffc07ef0000 rw-p 00000000 00:00 0 [stack]
|
||||||
|
Size: 132 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 8 kB
|
||||||
|
Pss: 8 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 0 kB
|
||||||
|
Private_Dirty: 8 kB
|
||||||
|
Referenced: 8 kB
|
||||||
|
Anonymous: 8 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 4 kB
|
||||||
|
SwapPss: 4 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd wr mr mw me gd ac
|
||||||
|
7ffc07f9e000-7ffc07fa1000 r--p 00000000 00:00 0 [vvar]
|
||||||
|
Size: 12 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 0 kB
|
||||||
|
Pss: 0 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 0 kB
|
||||||
|
Private_Dirty: 0 kB
|
||||||
|
Referenced: 0 kB
|
||||||
|
Anonymous: 0 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 0 kB
|
||||||
|
SwapPss: 0 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd mr pf io de dd sd
|
||||||
|
7ffc07fa1000-7ffc07fa3000 r-xp 00000000 00:00 0 [vdso]
|
||||||
|
Size: 8 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 4 kB
|
||||||
|
Pss: 0 kB
|
||||||
|
Shared_Clean: 4 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 0 kB
|
||||||
|
Private_Dirty: 0 kB
|
||||||
|
Referenced: 4 kB
|
||||||
|
Anonymous: 0 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 0 kB
|
||||||
|
SwapPss: 0 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd ex mr mw me de sd
|
||||||
|
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
|
||||||
|
Size: 4 kB
|
||||||
|
KernelPageSize: 4 kB
|
||||||
|
MMUPageSize: 4 kB
|
||||||
|
Rss: 0 kB
|
||||||
|
Pss: 0 kB
|
||||||
|
Shared_Clean: 0 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 0 kB
|
||||||
|
Private_Dirty: 0 kB
|
||||||
|
Referenced: 0 kB
|
||||||
|
Anonymous: 0 kB
|
||||||
|
LazyFree: 0 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 0 kB
|
||||||
|
SwapPss: 0 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
VmFlags: rd ex
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/proc/26231/smaps_rollup
|
||||||
|
Lines: 17
|
||||||
|
00400000-ffffffffff601000 ---p 00000000 00:00 0 [rollup]
|
||||||
|
Rss: 29948 kB
|
||||||
|
Pss: 29944 kB
|
||||||
|
Shared_Clean: 4 kB
|
||||||
|
Shared_Dirty: 0 kB
|
||||||
|
Private_Clean: 15548 kB
|
||||||
|
Private_Dirty: 14396 kB
|
||||||
|
Referenced: 24752 kB
|
||||||
|
Anonymous: 20756 kB
|
||||||
|
LazyFree: 5848 kB
|
||||||
|
AnonHugePages: 0 kB
|
||||||
|
ShmemPmdMapped: 0 kB
|
||||||
|
Shared_Hugetlb: 0 kB
|
||||||
|
Private_Hugetlb: 0 kB
|
||||||
|
Swap: 1940 kB
|
||||||
|
SwapPss: 1940 kB
|
||||||
|
Locked: 0 kB
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Path: fixtures/proc/26231/stat
|
Path: fixtures/proc/26231/stat
|
||||||
Lines: 1
|
Lines: 1
|
||||||
26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0
|
26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0
|
||||||
|
@ -235,6 +512,11 @@ voluntary_ctxt_switches: 4742839
|
||||||
nonvoluntary_ctxt_switches: 1727500
|
nonvoluntary_ctxt_switches: 1727500
|
||||||
Mode: 644
|
Mode: 644
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/proc/26231/wchan
|
||||||
|
Lines: 1
|
||||||
|
poll_schedule_timeoutEOF
|
||||||
|
Mode: 664
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Directory: fixtures/proc/26232
|
Directory: fixtures/proc/26232
|
||||||
Mode: 755
|
Mode: 755
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -310,6 +592,11 @@ Lines: 1
|
||||||
33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0
|
33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
Mode: 644
|
Mode: 644
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/proc/26232/wchan
|
||||||
|
Lines: 1
|
||||||
|
0EOF
|
||||||
|
Mode: 664
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Directory: fixtures/proc/26233
|
Directory: fixtures/proc/26233
|
||||||
Mode: 755
|
Mode: 755
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -1554,7 +1841,7 @@ max keysize : 32
|
||||||
Mode: 444
|
Mode: 444
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Path: fixtures/proc/diskstats
|
Path: fixtures/proc/diskstats
|
||||||
Lines: 49
|
Lines: 52
|
||||||
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
|
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
|
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
|
||||||
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
|
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
@ -1604,11 +1891,45 @@ Lines: 49
|
||||||
8 0 sdb 326552 841 9657779 84 41822 2895 1972905 5007 0 60730 67070 68851 0 1925173784 11130
|
8 0 sdb 326552 841 9657779 84 41822 2895 1972905 5007 0 60730 67070 68851 0 1925173784 11130
|
||||||
8 1 sdb1 231 3 34466 4 24 23 106 0 0 64 64 0 0 0 0
|
8 1 sdb1 231 3 34466 4 24 23 106 0 0 64 64 0 0 0 0
|
||||||
8 2 sdb2 326310 838 9622281 67 40726 2872 1972799 4924 0 58250 64567 68851 0 1925173784 11130
|
8 2 sdb2 326310 838 9622281 67 40726 2872 1972799 4924 0 58250 64567 68851 0 1925173784 11130
|
||||||
|
8 0 sdc 14202 71 579164 21861 2995 1589 180500 40875 0 11628 55200 0 0 0 0 127 182
|
||||||
|
8 1 sdc1 1027 0 13795 5021 2 0 4096 3 0 690 4579 0 0 0 0 0 0
|
||||||
|
8 2 sdc2 13126 71 561749 16802 2830 1589 176404 40620 0 10931 50449 0 0 0 0 0 0
|
||||||
Mode: 664
|
Mode: 664
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Directory: fixtures/proc/fs
|
Directory: fixtures/proc/fs
|
||||||
Mode: 755
|
Mode: 755
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/proc/fs/fscache
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/proc/fs/fscache/stats
|
||||||
|
Lines: 24
|
||||||
|
FS-Cache statistics
|
||||||
|
Cookies: idx=3 dat=67877 spc=0
|
||||||
|
Objects: alc=67473 nal=0 avl=67473 ded=388
|
||||||
|
ChkAux : non=12 ok=33 upd=44 obs=55
|
||||||
|
Pages : mrk=547164 unc=364577
|
||||||
|
Acquire: n=67880 nul=98 noc=25 ok=67780 nbf=39 oom=26
|
||||||
|
Lookups: n=67473 neg=67470 pos=58 crt=67473 tmo=85
|
||||||
|
Invals : n=14 run=13
|
||||||
|
Updates: n=7 nul=3 run=8
|
||||||
|
Relinqs: n=394 nul=1 wcr=2 rtr=3
|
||||||
|
AttrChg: n=6 ok=5 nbf=4 oom=3 run=2
|
||||||
|
Allocs : n=20 ok=19 wt=18 nbf=17 int=16
|
||||||
|
Allocs : ops=15 owt=14 abt=13
|
||||||
|
Retrvls: n=151959 ok=82823 wt=23467 nod=69136 nbf=15 int=69 oom=43
|
||||||
|
Retrvls: ops=151959 owt=42747 abt=44
|
||||||
|
Stores : n=225565 ok=225565 agn=12 nbf=13 oom=14
|
||||||
|
Stores : ops=69156 run=294721 pgs=225565 rxd=225565 olm=43
|
||||||
|
VmScan : nos=364512 gon=2 bsy=43 can=12 wt=66
|
||||||
|
Ops : pend=42753 run=221129 enq=628798 can=11 rej=88
|
||||||
|
Ops : ini=377538 dfr=27 rel=377538 gc=37
|
||||||
|
CacheOp: alo=1 luo=2 luc=3 gro=4
|
||||||
|
CacheOp: inv=5 upo=6 dro=7 pto=8 atc=9 syn=10
|
||||||
|
CacheOp: rap=11 ras=12 alp=13 als=14 wrp=15 ucp=16 dsp=17
|
||||||
|
CacheEv: nsp=18 stl=19 rtr=20 cul=21EOF
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Directory: fixtures/proc/fs/xfs
|
Directory: fixtures/proc/fs/xfs
|
||||||
Mode: 755
|
Mode: 755
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -2025,6 +2346,32 @@ Mode: 644
|
||||||
Directory: fixtures/proc/sys
|
Directory: fixtures/proc/sys
|
||||||
Mode: 775
|
Mode: 775
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/proc/sys/kernel
|
||||||
|
Mode: 775
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/proc/sys/kernel/random
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/proc/sys/kernel/random/entropy_avail
|
||||||
|
Lines: 1
|
||||||
|
3943
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/proc/sys/kernel/random/poolsize
|
||||||
|
Lines: 1
|
||||||
|
4096
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/proc/sys/kernel/random/urandom_min_reseed_secs
|
||||||
|
Lines: 1
|
||||||
|
60
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/proc/sys/kernel/random/write_wakeup_threshold
|
||||||
|
Lines: 1
|
||||||
|
3072
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Directory: fixtures/proc/sys/vm
|
Directory: fixtures/proc/sys/vm
|
||||||
Mode: 775
|
Mode: 775
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -2526,6 +2873,237 @@ Mode: 664
|
||||||
Directory: fixtures/sys/block/sda
|
Directory: fixtures/sys/block/sda
|
||||||
Mode: 775
|
Mode: 775
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/sys/block/sda/queue
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/add_random
|
||||||
|
Lines: 1
|
||||||
|
1
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/chunk_sectors
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/dax
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/discard_granularity
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/discard_max_bytes
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/discard_max_hw_bytes
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/discard_zeroes_data
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/fua
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/hw_sector_size
|
||||||
|
Lines: 1
|
||||||
|
512
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/io_poll
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/io_poll_delay
|
||||||
|
Lines: 1
|
||||||
|
-1
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/io_timeout
|
||||||
|
Lines: 1
|
||||||
|
30000
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/sys/block/sda/queue/iosched
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/back_seek_max
|
||||||
|
Lines: 1
|
||||||
|
16384
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/back_seek_penalty
|
||||||
|
Lines: 1
|
||||||
|
2
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/fifo_expire_async
|
||||||
|
Lines: 1
|
||||||
|
250
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/fifo_expire_sync
|
||||||
|
Lines: 1
|
||||||
|
125
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/low_latency
|
||||||
|
Lines: 1
|
||||||
|
1
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/max_budget
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/slice_idle
|
||||||
|
Lines: 1
|
||||||
|
8
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/slice_idle_us
|
||||||
|
Lines: 1
|
||||||
|
8000
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/strict_guarantees
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iosched/timeout_sync
|
||||||
|
Lines: 1
|
||||||
|
125
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/iostats
|
||||||
|
Lines: 1
|
||||||
|
1
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/logical_block_size
|
||||||
|
Lines: 1
|
||||||
|
512
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/max_discard_segments
|
||||||
|
Lines: 1
|
||||||
|
1
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/max_hw_sectors_kb
|
||||||
|
Lines: 1
|
||||||
|
32767
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/max_integrity_segments
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/max_sectors_kb
|
||||||
|
Lines: 1
|
||||||
|
1280
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/max_segment_size
|
||||||
|
Lines: 1
|
||||||
|
65536
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/max_segments
|
||||||
|
Lines: 1
|
||||||
|
168
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/minimum_io_size
|
||||||
|
Lines: 1
|
||||||
|
512
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/nomerges
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/nr_requests
|
||||||
|
Lines: 1
|
||||||
|
64
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/nr_zones
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/optimal_io_size
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/physical_block_size
|
||||||
|
Lines: 1
|
||||||
|
512
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/read_ahead_kb
|
||||||
|
Lines: 1
|
||||||
|
128
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/rotational
|
||||||
|
Lines: 1
|
||||||
|
1
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/rq_affinity
|
||||||
|
Lines: 1
|
||||||
|
1
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/scheduler
|
||||||
|
Lines: 1
|
||||||
|
mq-deadline kyber [bfq] none
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/wbt_lat_usec
|
||||||
|
Lines: 1
|
||||||
|
75000
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/write_cache
|
||||||
|
Lines: 1
|
||||||
|
write back
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/write_same_max_bytes
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/write_zeroes_max_bytes
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/block/sda/queue/zoned
|
||||||
|
Lines: 1
|
||||||
|
none
|
||||||
|
Mode: 444
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Path: fixtures/sys/block/sda/stat
|
Path: fixtures/sys/block/sda/stat
|
||||||
Lines: 1
|
Lines: 1
|
||||||
9652963 396792 759304206 412943 8422549 6731723 286915323 13947418 0 5658367 19174573 1 2 3 12
|
9652963 396792 759304206 412943 8422549 6731723 286915323 13947418 0 5658367 19174573 1 2 3 12
|
||||||
|
@ -2534,6 +3112,140 @@ Mode: 664
|
||||||
Directory: fixtures/sys/class
|
Directory: fixtures/sys/class
|
||||||
Mode: 775
|
Mode: 775
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/sys/class/fc_host
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/sys/class/fc_host/host0
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/dev_loss_tmo
|
||||||
|
Lines: 1
|
||||||
|
30
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/fabric_name
|
||||||
|
Lines: 1
|
||||||
|
0x0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/node_name
|
||||||
|
Lines: 1
|
||||||
|
0x2000e0071bce95f2
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/port_id
|
||||||
|
Lines: 1
|
||||||
|
0x000002
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/port_name
|
||||||
|
Lines: 1
|
||||||
|
0x1000e0071bce95f2
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/port_state
|
||||||
|
Lines: 1
|
||||||
|
Online
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/port_type
|
||||||
|
Lines: 1
|
||||||
|
Point-To-Point (direct nport connection)
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/speed
|
||||||
|
Lines: 1
|
||||||
|
16 Gbit
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Directory: fixtures/sys/class/fc_host/host0/statistics
|
||||||
|
Mode: 755
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/dumped_frames
|
||||||
|
Lines: 1
|
||||||
|
0xffffffffffffffff
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/error_frames
|
||||||
|
Lines: 1
|
||||||
|
0x0
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/fcp_packet_aborts
|
||||||
|
Lines: 1
|
||||||
|
0x13
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/invalid_crc_count
|
||||||
|
Lines: 1
|
||||||
|
0x2
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/invalid_tx_word_count
|
||||||
|
Lines: 1
|
||||||
|
0x8
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/link_failure_count
|
||||||
|
Lines: 1
|
||||||
|
0x9
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/loss_of_signal_count
|
||||||
|
Lines: 1
|
||||||
|
0x11
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/loss_of_sync_count
|
||||||
|
Lines: 1
|
||||||
|
0x10
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/nos_count
|
||||||
|
Lines: 1
|
||||||
|
0x12
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/rx_frames
|
||||||
|
Lines: 1
|
||||||
|
0x3
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/rx_words
|
||||||
|
Lines: 1
|
||||||
|
0x4
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/seconds_since_last_reset
|
||||||
|
Lines: 1
|
||||||
|
0x7
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/tx_frames
|
||||||
|
Lines: 1
|
||||||
|
0x5
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/statistics/tx_words
|
||||||
|
Lines: 1
|
||||||
|
0x6
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/supported_classes
|
||||||
|
Lines: 1
|
||||||
|
Class 3
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/supported_speeds
|
||||||
|
Lines: 1
|
||||||
|
4 Gbit, 8 Gbit, 16 Gbit
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/fc_host/host0/symbolic_name
|
||||||
|
Lines: 1
|
||||||
|
Emulex SN1100E2P FV12.4.270.3 DV12.4.0.0. HN:gotest. OS:Linux
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Directory: fixtures/sys/class/infiniband
|
Directory: fixtures/sys/class/infiniband
|
||||||
Mode: 755
|
Mode: 755
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -2564,6 +3276,11 @@ Mode: 755
|
||||||
Directory: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters
|
Directory: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters
|
||||||
Mode: 755
|
Mode: 755
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/VL15_dropped
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 664
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/excessive_buffer_overrun_errors
|
Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/excessive_buffer_overrun_errors
|
||||||
Lines: 1
|
Lines: 1
|
||||||
0
|
0
|
||||||
|
@ -2665,6 +3382,11 @@ Mode: 755
|
||||||
Directory: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters
|
Directory: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters
|
||||||
Mode: 755
|
Mode: 755
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/VL15_dropped
|
||||||
|
Lines: 1
|
||||||
|
0
|
||||||
|
Mode: 664
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/excessive_buffer_overrun_errors
|
Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/excessive_buffer_overrun_errors
|
||||||
Lines: 1
|
Lines: 1
|
||||||
0
|
0
|
||||||
|
@ -3109,7 +3831,7 @@ Mode: 664
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Path: fixtures/sys/class/thermal/thermal_zone1/temp
|
Path: fixtures/sys/class/thermal/thermal_zone1/temp
|
||||||
Lines: 1
|
Lines: 1
|
||||||
44000
|
-44000
|
||||||
Mode: 664
|
Mode: 664
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Path: fixtures/sys/class/thermal/thermal_zone1/type
|
Path: fixtures/sys/class/thermal/thermal_zone1/type
|
||||||
|
@ -4287,6 +5009,17 @@ Lines: 1
|
||||||
0
|
0
|
||||||
Mode: 644
|
Mode: 644
|
||||||
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/writeback_rate_debug
|
||||||
|
Lines: 7
|
||||||
|
rate: 1.1M/sec
|
||||||
|
dirty: 20.4G
|
||||||
|
target: 20.4G
|
||||||
|
proportional: 427.5k
|
||||||
|
integral: 790.0k
|
||||||
|
change: 321.5k/sec
|
||||||
|
next io: 17ms
|
||||||
|
Mode: 644
|
||||||
|
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/btree_cache_size
|
Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/btree_cache_size
|
||||||
Lines: 1
|
Lines: 1
|
||||||
0
|
0
|
||||||
|
|
422
vendor/github.com/prometheus/procfs/fscache.go
generated
vendored
Normal file
422
vendor/github.com/prometheus/procfs/fscache.go
generated
vendored
Normal file
|
@ -0,0 +1,422 @@
|
||||||
|
// Copyright 2019 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Fscacheinfo represents fscache statistics.
|
||||||
|
type Fscacheinfo struct {
|
||||||
|
// Number of index cookies allocated
|
||||||
|
IndexCookiesAllocated uint64
|
||||||
|
// data storage cookies allocated
|
||||||
|
DataStorageCookiesAllocated uint64
|
||||||
|
// Number of special cookies allocated
|
||||||
|
SpecialCookiesAllocated uint64
|
||||||
|
// Number of objects allocated
|
||||||
|
ObjectsAllocated uint64
|
||||||
|
// Number of object allocation failures
|
||||||
|
ObjectAllocationsFailure uint64
|
||||||
|
// Number of objects that reached the available state
|
||||||
|
ObjectsAvailable uint64
|
||||||
|
// Number of objects that reached the dead state
|
||||||
|
ObjectsDead uint64
|
||||||
|
// Number of objects that didn't have a coherency check
|
||||||
|
ObjectsWithoutCoherencyCheck uint64
|
||||||
|
// Number of objects that passed a coherency check
|
||||||
|
ObjectsWithCoherencyCheck uint64
|
||||||
|
// Number of objects that needed a coherency data update
|
||||||
|
ObjectsNeedCoherencyCheckUpdate uint64
|
||||||
|
// Number of objects that were declared obsolete
|
||||||
|
ObjectsDeclaredObsolete uint64
|
||||||
|
// Number of pages marked as being cached
|
||||||
|
PagesMarkedAsBeingCached uint64
|
||||||
|
// Number of uncache page requests seen
|
||||||
|
UncachePagesRequestSeen uint64
|
||||||
|
// Number of acquire cookie requests seen
|
||||||
|
AcquireCookiesRequestSeen uint64
|
||||||
|
// Number of acq reqs given a NULL parent
|
||||||
|
AcquireRequestsWithNullParent uint64
|
||||||
|
// Number of acq reqs rejected due to no cache available
|
||||||
|
AcquireRequestsRejectedNoCacheAvailable uint64
|
||||||
|
// Number of acq reqs succeeded
|
||||||
|
AcquireRequestsSucceeded uint64
|
||||||
|
// Number of acq reqs rejected due to error
|
||||||
|
AcquireRequestsRejectedDueToError uint64
|
||||||
|
// Number of acq reqs failed on ENOMEM
|
||||||
|
AcquireRequestsFailedDueToEnomem uint64
|
||||||
|
// Number of lookup calls made on cache backends
|
||||||
|
LookupsNumber uint64
|
||||||
|
// Number of negative lookups made
|
||||||
|
LookupsNegative uint64
|
||||||
|
// Number of positive lookups made
|
||||||
|
LookupsPositive uint64
|
||||||
|
// Number of objects created by lookup
|
||||||
|
ObjectsCreatedByLookup uint64
|
||||||
|
// Number of lookups timed out and requeued
|
||||||
|
LookupsTimedOutAndRequed uint64
|
||||||
|
InvalidationsNumber uint64
|
||||||
|
InvalidationsRunning uint64
|
||||||
|
// Number of update cookie requests seen
|
||||||
|
UpdateCookieRequestSeen uint64
|
||||||
|
// Number of upd reqs given a NULL parent
|
||||||
|
UpdateRequestsWithNullParent uint64
|
||||||
|
// Number of upd reqs granted CPU time
|
||||||
|
UpdateRequestsRunning uint64
|
||||||
|
// Number of relinquish cookie requests seen
|
||||||
|
RelinquishCookiesRequestSeen uint64
|
||||||
|
// Number of rlq reqs given a NULL parent
|
||||||
|
RelinquishCookiesWithNullParent uint64
|
||||||
|
// Number of rlq reqs waited on completion of creation
|
||||||
|
RelinquishRequestsWaitingCompleteCreation uint64
|
||||||
|
// Relinqs rtr
|
||||||
|
RelinquishRetries uint64
|
||||||
|
// Number of attribute changed requests seen
|
||||||
|
AttributeChangedRequestsSeen uint64
|
||||||
|
// Number of attr changed requests queued
|
||||||
|
AttributeChangedRequestsQueued uint64
|
||||||
|
// Number of attr changed rejected -ENOBUFS
|
||||||
|
AttributeChangedRejectDueToEnobufs uint64
|
||||||
|
// Number of attr changed failed -ENOMEM
|
||||||
|
AttributeChangedFailedDueToEnomem uint64
|
||||||
|
// Number of attr changed ops given CPU time
|
||||||
|
AttributeChangedOps uint64
|
||||||
|
// Number of allocation requests seen
|
||||||
|
AllocationRequestsSeen uint64
|
||||||
|
// Number of successful alloc reqs
|
||||||
|
AllocationOkRequests uint64
|
||||||
|
// Number of alloc reqs that waited on lookup completion
|
||||||
|
AllocationWaitingOnLookup uint64
|
||||||
|
// Number of alloc reqs rejected -ENOBUFS
|
||||||
|
AllocationsRejectedDueToEnobufs uint64
|
||||||
|
// Number of alloc reqs aborted -ERESTARTSYS
|
||||||
|
AllocationsAbortedDueToErestartsys uint64
|
||||||
|
// Number of alloc reqs submitted
|
||||||
|
AllocationOperationsSubmitted uint64
|
||||||
|
// Number of alloc reqs waited for CPU time
|
||||||
|
AllocationsWaitedForCPU uint64
|
||||||
|
// Number of alloc reqs aborted due to object death
|
||||||
|
AllocationsAbortedDueToObjectDeath uint64
|
||||||
|
// Number of retrieval (read) requests seen
|
||||||
|
RetrievalsReadRequests uint64
|
||||||
|
// Number of successful retr reqs
|
||||||
|
RetrievalsOk uint64
|
||||||
|
// Number of retr reqs that waited on lookup completion
|
||||||
|
RetrievalsWaitingLookupCompletion uint64
|
||||||
|
// Number of retr reqs returned -ENODATA
|
||||||
|
RetrievalsReturnedEnodata uint64
|
||||||
|
// Number of retr reqs rejected -ENOBUFS
|
||||||
|
RetrievalsRejectedDueToEnobufs uint64
|
||||||
|
// Number of retr reqs aborted -ERESTARTSYS
|
||||||
|
RetrievalsAbortedDueToErestartsys uint64
|
||||||
|
// Number of retr reqs failed -ENOMEM
|
||||||
|
RetrievalsFailedDueToEnomem uint64
|
||||||
|
// Number of retr reqs submitted
|
||||||
|
RetrievalsRequests uint64
|
||||||
|
// Number of retr reqs waited for CPU time
|
||||||
|
RetrievalsWaitingCPU uint64
|
||||||
|
// Number of retr reqs aborted due to object death
|
||||||
|
RetrievalsAbortedDueToObjectDeath uint64
|
||||||
|
// Number of storage (write) requests seen
|
||||||
|
StoreWriteRequests uint64
|
||||||
|
// Number of successful store reqs
|
||||||
|
StoreSuccessfulRequests uint64
|
||||||
|
// Number of store reqs on a page already pending storage
|
||||||
|
StoreRequestsOnPendingStorage uint64
|
||||||
|
// Number of store reqs rejected -ENOBUFS
|
||||||
|
StoreRequestsRejectedDueToEnobufs uint64
|
||||||
|
// Number of store reqs failed -ENOMEM
|
||||||
|
StoreRequestsFailedDueToEnomem uint64
|
||||||
|
// Number of store reqs submitted
|
||||||
|
StoreRequestsSubmitted uint64
|
||||||
|
// Number of store reqs granted CPU time
|
||||||
|
StoreRequestsRunning uint64
|
||||||
|
// Number of pages given store req processing time
|
||||||
|
StorePagesWithRequestsProcessing uint64
|
||||||
|
// Number of store reqs deleted from tracking tree
|
||||||
|
StoreRequestsDeleted uint64
|
||||||
|
// Number of store reqs over store limit
|
||||||
|
StoreRequestsOverStoreLimit uint64
|
||||||
|
// Number of release reqs against pages with no pending store
|
||||||
|
ReleaseRequestsAgainstPagesWithNoPendingStorage uint64
|
||||||
|
// Number of release reqs against pages stored by time lock granted
|
||||||
|
ReleaseRequestsAgainstPagesStoredByTimeLockGranted uint64
|
||||||
|
// Number of release reqs ignored due to in-progress store
|
||||||
|
ReleaseRequestsIgnoredDueToInProgressStore uint64
|
||||||
|
// Number of page stores cancelled due to release req
|
||||||
|
PageStoresCancelledByReleaseRequests uint64
|
||||||
|
VmscanWaiting uint64
|
||||||
|
// Number of times async ops added to pending queues
|
||||||
|
OpsPending uint64
|
||||||
|
// Number of times async ops given CPU time
|
||||||
|
OpsRunning uint64
|
||||||
|
// Number of times async ops queued for processing
|
||||||
|
OpsEnqueued uint64
|
||||||
|
// Number of async ops cancelled
|
||||||
|
OpsCancelled uint64
|
||||||
|
// Number of async ops rejected due to object lookup/create failure
|
||||||
|
OpsRejected uint64
|
||||||
|
// Number of async ops initialised
|
||||||
|
OpsInitialised uint64
|
||||||
|
// Number of async ops queued for deferred release
|
||||||
|
OpsDeferred uint64
|
||||||
|
// Number of async ops released (should equal ini=N when idle)
|
||||||
|
OpsReleased uint64
|
||||||
|
// Number of deferred-release async ops garbage collected
|
||||||
|
OpsGarbageCollected uint64
|
||||||
|
// Number of in-progress alloc_object() cache ops
|
||||||
|
CacheopAllocationsinProgress uint64
|
||||||
|
// Number of in-progress lookup_object() cache ops
|
||||||
|
CacheopLookupObjectInProgress uint64
|
||||||
|
// Number of in-progress lookup_complete() cache ops
|
||||||
|
CacheopLookupCompleteInPorgress uint64
|
||||||
|
// Number of in-progress grab_object() cache ops
|
||||||
|
CacheopGrabObjectInProgress uint64
|
||||||
|
CacheopInvalidations uint64
|
||||||
|
// Number of in-progress update_object() cache ops
|
||||||
|
CacheopUpdateObjectInProgress uint64
|
||||||
|
// Number of in-progress drop_object() cache ops
|
||||||
|
CacheopDropObjectInProgress uint64
|
||||||
|
// Number of in-progress put_object() cache ops
|
||||||
|
CacheopPutObjectInProgress uint64
|
||||||
|
// Number of in-progress attr_changed() cache ops
|
||||||
|
CacheopAttributeChangeInProgress uint64
|
||||||
|
// Number of in-progress sync_cache() cache ops
|
||||||
|
CacheopSyncCacheInProgress uint64
|
||||||
|
// Number of in-progress read_or_alloc_page() cache ops
|
||||||
|
CacheopReadOrAllocPageInProgress uint64
|
||||||
|
// Number of in-progress read_or_alloc_pages() cache ops
|
||||||
|
CacheopReadOrAllocPagesInProgress uint64
|
||||||
|
// Number of in-progress allocate_page() cache ops
|
||||||
|
CacheopAllocatePageInProgress uint64
|
||||||
|
// Number of in-progress allocate_pages() cache ops
|
||||||
|
CacheopAllocatePagesInProgress uint64
|
||||||
|
// Number of in-progress write_page() cache ops
|
||||||
|
CacheopWritePagesInProgress uint64
|
||||||
|
// Number of in-progress uncache_page() cache ops
|
||||||
|
CacheopUncachePagesInProgress uint64
|
||||||
|
// Number of in-progress dissociate_pages() cache ops
|
||||||
|
CacheopDissociatePagesInProgress uint64
|
||||||
|
// Number of object lookups/creations rejected due to lack of space
|
||||||
|
CacheevLookupsAndCreationsRejectedLackSpace uint64
|
||||||
|
// Number of stale objects deleted
|
||||||
|
CacheevStaleObjectsDeleted uint64
|
||||||
|
// Number of objects retired when relinquished
|
||||||
|
CacheevRetiredWhenReliquished uint64
|
||||||
|
// Number of objects culled
|
||||||
|
CacheevObjectsCulled uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fscacheinfo returns information about current fscache statistics.
|
||||||
|
// See https://www.kernel.org/doc/Documentation/filesystems/caching/fscache.txt
|
||||||
|
func (fs FS) Fscacheinfo() (Fscacheinfo, error) {
|
||||||
|
b, err := util.ReadFileNoStat(fs.proc.Path("fs/fscache/stats"))
|
||||||
|
if err != nil {
|
||||||
|
return Fscacheinfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
m, err := parseFscacheinfo(bytes.NewReader(b))
|
||||||
|
if err != nil {
|
||||||
|
return Fscacheinfo{}, fmt.Errorf("failed to parse Fscacheinfo: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return *m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setFSCacheFields(fields []string, setFields ...*uint64) error {
|
||||||
|
var err error
|
||||||
|
if len(fields) < len(setFields) {
|
||||||
|
return fmt.Errorf("Insufficient number of fields, expected %v, got %v", len(setFields), len(fields))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range setFields {
|
||||||
|
*setFields[i], err = strconv.ParseUint(strings.Split(fields[i], "=")[1], 0, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseFscacheinfo(r io.Reader) (*Fscacheinfo, error) {
|
||||||
|
var m Fscacheinfo
|
||||||
|
s := bufio.NewScanner(r)
|
||||||
|
for s.Scan() {
|
||||||
|
fields := strings.Fields(s.Text())
|
||||||
|
if len(fields) < 2 {
|
||||||
|
return nil, fmt.Errorf("malformed Fscacheinfo line: %q", s.Text())
|
||||||
|
}
|
||||||
|
|
||||||
|
switch fields[0] {
|
||||||
|
case "Cookies:":
|
||||||
|
err := setFSCacheFields(fields[1:], &m.IndexCookiesAllocated, &m.DataStorageCookiesAllocated,
|
||||||
|
&m.SpecialCookiesAllocated)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "Objects:":
|
||||||
|
err := setFSCacheFields(fields[1:], &m.ObjectsAllocated, &m.ObjectAllocationsFailure,
|
||||||
|
&m.ObjectsAvailable, &m.ObjectsDead)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "ChkAux":
|
||||||
|
err := setFSCacheFields(fields[2:], &m.ObjectsWithoutCoherencyCheck, &m.ObjectsWithCoherencyCheck,
|
||||||
|
&m.ObjectsNeedCoherencyCheckUpdate, &m.ObjectsDeclaredObsolete)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "Pages":
|
||||||
|
err := setFSCacheFields(fields[2:], &m.PagesMarkedAsBeingCached, &m.UncachePagesRequestSeen)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "Acquire:":
|
||||||
|
err := setFSCacheFields(fields[1:], &m.AcquireCookiesRequestSeen, &m.AcquireRequestsWithNullParent,
|
||||||
|
&m.AcquireRequestsRejectedNoCacheAvailable, &m.AcquireRequestsSucceeded, &m.AcquireRequestsRejectedDueToError,
|
||||||
|
&m.AcquireRequestsFailedDueToEnomem)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "Lookups:":
|
||||||
|
err := setFSCacheFields(fields[1:], &m.LookupsNumber, &m.LookupsNegative, &m.LookupsPositive,
|
||||||
|
&m.ObjectsCreatedByLookup, &m.LookupsTimedOutAndRequed)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "Invals":
|
||||||
|
err := setFSCacheFields(fields[2:], &m.InvalidationsNumber, &m.InvalidationsRunning)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "Updates:":
|
||||||
|
err := setFSCacheFields(fields[1:], &m.UpdateCookieRequestSeen, &m.UpdateRequestsWithNullParent,
|
||||||
|
&m.UpdateRequestsRunning)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "Relinqs:":
|
||||||
|
err := setFSCacheFields(fields[1:], &m.RelinquishCookiesRequestSeen, &m.RelinquishCookiesWithNullParent,
|
||||||
|
&m.RelinquishRequestsWaitingCompleteCreation, &m.RelinquishRetries)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "AttrChg:":
|
||||||
|
err := setFSCacheFields(fields[1:], &m.AttributeChangedRequestsSeen, &m.AttributeChangedRequestsQueued,
|
||||||
|
&m.AttributeChangedRejectDueToEnobufs, &m.AttributeChangedFailedDueToEnomem, &m.AttributeChangedOps)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "Allocs":
|
||||||
|
if strings.Split(fields[2], "=")[0] == "n" {
|
||||||
|
err := setFSCacheFields(fields[2:], &m.AllocationRequestsSeen, &m.AllocationOkRequests,
|
||||||
|
&m.AllocationWaitingOnLookup, &m.AllocationsRejectedDueToEnobufs, &m.AllocationsAbortedDueToErestartsys)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := setFSCacheFields(fields[2:], &m.AllocationOperationsSubmitted, &m.AllocationsWaitedForCPU,
|
||||||
|
&m.AllocationsAbortedDueToObjectDeath)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "Retrvls:":
|
||||||
|
if strings.Split(fields[1], "=")[0] == "n" {
|
||||||
|
err := setFSCacheFields(fields[1:], &m.RetrievalsReadRequests, &m.RetrievalsOk, &m.RetrievalsWaitingLookupCompletion,
|
||||||
|
&m.RetrievalsReturnedEnodata, &m.RetrievalsRejectedDueToEnobufs, &m.RetrievalsAbortedDueToErestartsys,
|
||||||
|
&m.RetrievalsFailedDueToEnomem)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := setFSCacheFields(fields[1:], &m.RetrievalsRequests, &m.RetrievalsWaitingCPU, &m.RetrievalsAbortedDueToObjectDeath)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "Stores":
|
||||||
|
if strings.Split(fields[2], "=")[0] == "n" {
|
||||||
|
err := setFSCacheFields(fields[2:], &m.StoreWriteRequests, &m.StoreSuccessfulRequests,
|
||||||
|
&m.StoreRequestsOnPendingStorage, &m.StoreRequestsRejectedDueToEnobufs, &m.StoreRequestsFailedDueToEnomem)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := setFSCacheFields(fields[2:], &m.StoreRequestsSubmitted, &m.StoreRequestsRunning,
|
||||||
|
&m.StorePagesWithRequestsProcessing, &m.StoreRequestsDeleted, &m.StoreRequestsOverStoreLimit)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "VmScan":
|
||||||
|
err := setFSCacheFields(fields[2:], &m.ReleaseRequestsAgainstPagesWithNoPendingStorage,
|
||||||
|
&m.ReleaseRequestsAgainstPagesStoredByTimeLockGranted, &m.ReleaseRequestsIgnoredDueToInProgressStore,
|
||||||
|
&m.PageStoresCancelledByReleaseRequests, &m.VmscanWaiting)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
case "Ops":
|
||||||
|
if strings.Split(fields[2], "=")[0] == "pend" {
|
||||||
|
err := setFSCacheFields(fields[2:], &m.OpsPending, &m.OpsRunning, &m.OpsEnqueued, &m.OpsCancelled, &m.OpsRejected)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := setFSCacheFields(fields[2:], &m.OpsInitialised, &m.OpsDeferred, &m.OpsReleased, &m.OpsGarbageCollected)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "CacheOp:":
|
||||||
|
if strings.Split(fields[1], "=")[0] == "alo" {
|
||||||
|
err := setFSCacheFields(fields[1:], &m.CacheopAllocationsinProgress, &m.CacheopLookupObjectInProgress,
|
||||||
|
&m.CacheopLookupCompleteInPorgress, &m.CacheopGrabObjectInProgress)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
} else if strings.Split(fields[1], "=")[0] == "inv" {
|
||||||
|
err := setFSCacheFields(fields[1:], &m.CacheopInvalidations, &m.CacheopUpdateObjectInProgress,
|
||||||
|
&m.CacheopDropObjectInProgress, &m.CacheopPutObjectInProgress, &m.CacheopAttributeChangeInProgress,
|
||||||
|
&m.CacheopSyncCacheInProgress)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := setFSCacheFields(fields[1:], &m.CacheopReadOrAllocPageInProgress, &m.CacheopReadOrAllocPagesInProgress,
|
||||||
|
&m.CacheopAllocatePageInProgress, &m.CacheopAllocatePagesInProgress, &m.CacheopWritePagesInProgress,
|
||||||
|
&m.CacheopUncachePagesInProgress, &m.CacheopDissociatePagesInProgress)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "CacheEv:":
|
||||||
|
err := setFSCacheFields(fields[1:], &m.CacheevLookupsAndCreationsRejectedLackSpace, &m.CacheevStaleObjectsDeleted,
|
||||||
|
&m.CacheevRetiredWhenReliquished, &m.CacheevObjectsCulled)
|
||||||
|
if err != nil {
|
||||||
|
return &m, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &m, nil
|
||||||
|
}
|
9
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
9
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
|
@ -73,6 +73,15 @@ func ReadUintFromFile(path string) (uint64, error) {
|
||||||
return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
|
return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadIntFromFile reads a file and attempts to parse a int64 from it.
|
||||||
|
func ReadIntFromFile(path string) (int64, error) {
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64)
|
||||||
|
}
|
||||||
|
|
||||||
// ParseBool parses a string into a boolean pointer.
|
// ParseBool parses a string into a boolean pointer.
|
||||||
func ParseBool(b string) *bool {
|
func ParseBool(b string) *bool {
|
||||||
var truth bool
|
var truth bool
|
||||||
|
|
62
vendor/github.com/prometheus/procfs/kernel_random.go
generated
vendored
Normal file
62
vendor/github.com/prometheus/procfs/kernel_random.go
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KernelRandom contains information about to the kernel's random number generator.
|
||||||
|
type KernelRandom struct {
|
||||||
|
// EntropyAvaliable gives the available entropy, in bits.
|
||||||
|
EntropyAvaliable *uint64
|
||||||
|
// PoolSize gives the size of the entropy pool, in bytes.
|
||||||
|
PoolSize *uint64
|
||||||
|
// URandomMinReseedSeconds is the number of seconds after which the DRNG will be reseeded.
|
||||||
|
URandomMinReseedSeconds *uint64
|
||||||
|
// WriteWakeupThreshold the number of bits of entropy below which we wake up processes
|
||||||
|
// that do a select(2) or poll(2) for write access to /dev/random.
|
||||||
|
WriteWakeupThreshold *uint64
|
||||||
|
// ReadWakeupThreshold is the number of bits of entropy required for waking up processes that sleep
|
||||||
|
// waiting for entropy from /dev/random.
|
||||||
|
ReadWakeupThreshold *uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// KernelRandom returns values from /proc/sys/kernel/random.
|
||||||
|
func (fs FS) KernelRandom() (KernelRandom, error) {
|
||||||
|
random := KernelRandom{}
|
||||||
|
|
||||||
|
for file, p := range map[string]**uint64{
|
||||||
|
"entropy_avail": &random.EntropyAvaliable,
|
||||||
|
"poolsize": &random.PoolSize,
|
||||||
|
"urandom_min_reseed_secs": &random.URandomMinReseedSeconds,
|
||||||
|
"write_wakeup_threshold": &random.WriteWakeupThreshold,
|
||||||
|
"read_wakeup_threshold": &random.ReadWakeupThreshold,
|
||||||
|
} {
|
||||||
|
val, err := util.ReadUintFromFile(fs.proc.Path("sys", "kernel", "random", file))
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return random, err
|
||||||
|
}
|
||||||
|
*p = &val
|
||||||
|
}
|
||||||
|
|
||||||
|
return random, nil
|
||||||
|
}
|
2
vendor/github.com/prometheus/procfs/mdstat.go
generated
vendored
2
vendor/github.com/prometheus/procfs/mdstat.go
generated
vendored
|
@ -52,7 +52,7 @@ type MDStat struct {
|
||||||
func (fs FS) MDStat() ([]MDStat, error) {
|
func (fs FS) MDStat() ([]MDStat, error) {
|
||||||
data, err := ioutil.ReadFile(fs.proc.Path("mdstat"))
|
data, err := ioutil.ReadFile(fs.proc.Path("mdstat"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error parsing mdstat %s: %s", fs.proc.Path("mdstat"), err)
|
return nil, err
|
||||||
}
|
}
|
||||||
mdstat, err := parseMDStat(data)
|
mdstat, err := parseMDStat(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
8
vendor/github.com/prometheus/procfs/mountinfo.go
generated
vendored
8
vendor/github.com/prometheus/procfs/mountinfo.go
generated
vendored
|
@ -77,7 +77,7 @@ func parseMountInfoString(mountString string) (*MountInfo, error) {
|
||||||
|
|
||||||
mountInfo := strings.Split(mountString, " ")
|
mountInfo := strings.Split(mountString, " ")
|
||||||
mountInfoLength := len(mountInfo)
|
mountInfoLength := len(mountInfo)
|
||||||
if mountInfoLength < 11 {
|
if mountInfoLength < 10 {
|
||||||
return nil, fmt.Errorf("couldn't find enough fields in mount string: %s", mountString)
|
return nil, fmt.Errorf("couldn't find enough fields in mount string: %s", mountString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ func mountOptionsParseOptionalFields(o []string) (map[string]string, error) {
|
||||||
return optionalFields, nil
|
return optionalFields, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses the mount options, superblock options.
|
// mountOptionsParser parses the mount options, superblock options.
|
||||||
func mountOptionsParser(mountOptions string) map[string]string {
|
func mountOptionsParser(mountOptions string) map[string]string {
|
||||||
opts := make(map[string]string)
|
opts := make(map[string]string)
|
||||||
options := strings.Split(mountOptions, ",")
|
options := strings.Split(mountOptions, ",")
|
||||||
|
@ -161,7 +161,7 @@ func mountOptionsParser(mountOptions string) map[string]string {
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves mountinfo information from `/proc/self/mountinfo`.
|
// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`.
|
||||||
func GetMounts() ([]*MountInfo, error) {
|
func GetMounts() ([]*MountInfo, error) {
|
||||||
data, err := util.ReadFileNoStat("/proc/self/mountinfo")
|
data, err := util.ReadFileNoStat("/proc/self/mountinfo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -170,7 +170,7 @@ func GetMounts() ([]*MountInfo, error) {
|
||||||
return parseMountInfo(data)
|
return parseMountInfo(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.
|
// GetProcMounts retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.
|
||||||
func GetProcMounts(pid int) ([]*MountInfo, error) {
|
func GetProcMounts(pid int) ([]*MountInfo, error) {
|
||||||
data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/mountinfo", pid))
|
data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/mountinfo", pid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
20
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
20
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
|
@ -186,6 +186,8 @@ type NFSOperationStats struct {
|
||||||
CumulativeTotalResponseMilliseconds uint64
|
CumulativeTotalResponseMilliseconds uint64
|
||||||
// Duration from when a request was enqueued to when it was completely handled.
|
// Duration from when a request was enqueued to when it was completely handled.
|
||||||
CumulativeTotalRequestMilliseconds uint64
|
CumulativeTotalRequestMilliseconds uint64
|
||||||
|
// The count of operations that complete with tk_status < 0. These statuses usually indicate error conditions.
|
||||||
|
Errors uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// A NFSTransportStats contains statistics for the NFS mount RPC requests and
|
// A NFSTransportStats contains statistics for the NFS mount RPC requests and
|
||||||
|
@ -494,8 +496,8 @@ func parseNFSEventsStats(ss []string) (*NFSEventsStats, error) {
|
||||||
// line is reached.
|
// line is reached.
|
||||||
func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
||||||
const (
|
const (
|
||||||
// Number of expected fields in each per-operation statistics set
|
// Minimum number of expected fields in each per-operation statistics set
|
||||||
numFields = 9
|
minFields = 9
|
||||||
)
|
)
|
||||||
|
|
||||||
var ops []NFSOperationStats
|
var ops []NFSOperationStats
|
||||||
|
@ -508,12 +510,12 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ss) != numFields {
|
if len(ss) < minFields {
|
||||||
return nil, fmt.Errorf("invalid NFS per-operations stats: %v", ss)
|
return nil, fmt.Errorf("invalid NFS per-operations stats: %v", ss)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip string operation name for integers
|
// Skip string operation name for integers
|
||||||
ns := make([]uint64, 0, numFields-1)
|
ns := make([]uint64, 0, minFields-1)
|
||||||
for _, st := range ss[1:] {
|
for _, st := range ss[1:] {
|
||||||
n, err := strconv.ParseUint(st, 10, 64)
|
n, err := strconv.ParseUint(st, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -523,7 +525,7 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
||||||
ns = append(ns, n)
|
ns = append(ns, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
ops = append(ops, NFSOperationStats{
|
opStats := NFSOperationStats{
|
||||||
Operation: strings.TrimSuffix(ss[0], ":"),
|
Operation: strings.TrimSuffix(ss[0], ":"),
|
||||||
Requests: ns[0],
|
Requests: ns[0],
|
||||||
Transmissions: ns[1],
|
Transmissions: ns[1],
|
||||||
|
@ -533,7 +535,13 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
||||||
CumulativeQueueMilliseconds: ns[5],
|
CumulativeQueueMilliseconds: ns[5],
|
||||||
CumulativeTotalResponseMilliseconds: ns[6],
|
CumulativeTotalResponseMilliseconds: ns[6],
|
||||||
CumulativeTotalRequestMilliseconds: ns[7],
|
CumulativeTotalRequestMilliseconds: ns[7],
|
||||||
})
|
}
|
||||||
|
|
||||||
|
if len(ns) > 8 {
|
||||||
|
opStats.Errors = ns[8]
|
||||||
|
}
|
||||||
|
|
||||||
|
ops = append(ops, opStats)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ops, s.Err()
|
return ops, s.Err()
|
||||||
|
|
2
vendor/github.com/prometheus/procfs/net_conntrackstat.go
generated
vendored
2
vendor/github.com/prometheus/procfs/net_conntrackstat.go
generated
vendored
|
@ -38,7 +38,7 @@ type ConntrackStatEntry struct {
|
||||||
SearchRestart uint64
|
SearchRestart uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves netfilter's conntrack statistics, split by CPU cores
|
// ConntrackStat retrieves netfilter's conntrack statistics, split by CPU cores
|
||||||
func (fs FS) ConntrackStat() ([]ConntrackStatEntry, error) {
|
func (fs FS) ConntrackStat() ([]ConntrackStatEntry, error) {
|
||||||
return readConntrackStat(fs.proc.Path("net", "stat", "nf_conntrack"))
|
return readConntrackStat(fs.proc.Path("net", "stat", "nf_conntrack"))
|
||||||
}
|
}
|
||||||
|
|
21
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
21
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
|
@ -134,6 +134,27 @@ func (p Proc) CmdLine() ([]string, error) {
|
||||||
return strings.Split(string(bytes.TrimRight(data, string("\x00"))), string(byte(0))), nil
|
return strings.Split(string(bytes.TrimRight(data, string("\x00"))), string(byte(0))), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wchan returns the wchan (wait channel) of a process.
|
||||||
|
func (p Proc) Wchan() (string, error) {
|
||||||
|
f, err := os.Open(p.path("wchan"))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
wchan := string(data)
|
||||||
|
if wchan == "" || wchan == "0" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return wchan, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Comm returns the command name of a process.
|
// Comm returns the command name of a process.
|
||||||
func (p Proc) Comm() (string, error) {
|
func (p Proc) Comm() (string, error) {
|
||||||
data, err := util.ReadFileNoStat(p.path("comm"))
|
data, err := util.ReadFileNoStat(p.path("comm"))
|
||||||
|
|
98
vendor/github.com/prometheus/procfs/proc_cgroup.go
generated
vendored
Normal file
98
vendor/github.com/prometheus/procfs/proc_cgroup.go
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cgroup models one line from /proc/[pid]/cgroup. Each Cgroup struct describes the the placement of a PID inside a
|
||||||
|
// specific control hierarchy. The kernel has two cgroup APIs, v1 and v2. v1 has one hierarchy per available resource
|
||||||
|
// controller, while v2 has one unified hierarchy shared by all controllers. Regardless of v1 or v2, all hierarchies
|
||||||
|
// contain all running processes, so the question answerable with a Cgroup struct is 'where is this process in
|
||||||
|
// this hierarchy' (where==what path on the specific cgroupfs). By prefixing this path with the mount point of
|
||||||
|
// *this specific* hierarchy, you can locate the relevant pseudo-files needed to read/set the data for this PID
|
||||||
|
// in this hierarchy
|
||||||
|
//
|
||||||
|
// Also see http://man7.org/linux/man-pages/man7/cgroups.7.html
|
||||||
|
type Cgroup struct {
|
||||||
|
// HierarchyID that can be matched to a named hierarchy using /proc/cgroups. Cgroups V2 only has one
|
||||||
|
// hierarchy, so HierarchyID is always 0. For cgroups v1 this is a unique ID number
|
||||||
|
HierarchyID int
|
||||||
|
// Controllers using this hierarchy of processes. Controllers are also known as subsystems. For
|
||||||
|
// Cgroups V2 this may be empty, as all active controllers use the same hierarchy
|
||||||
|
Controllers []string
|
||||||
|
// Path of this control group, relative to the mount point of the cgroupfs representing this specific
|
||||||
|
// hierarchy
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseCgroupString parses each line of the /proc/[pid]/cgroup file
|
||||||
|
// Line format is hierarchyID:[controller1,controller2]:path
|
||||||
|
func parseCgroupString(cgroupStr string) (*Cgroup, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
fields := strings.Split(cgroupStr, ":")
|
||||||
|
if len(fields) < 3 {
|
||||||
|
return nil, fmt.Errorf("at least 3 fields required, found %d fields in cgroup string: %s", len(fields), cgroupStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
cgroup := &Cgroup{
|
||||||
|
Path: fields[2],
|
||||||
|
Controllers: nil,
|
||||||
|
}
|
||||||
|
cgroup.HierarchyID, err = strconv.Atoi(fields[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse hierarchy ID")
|
||||||
|
}
|
||||||
|
if fields[1] != "" {
|
||||||
|
ssNames := strings.Split(fields[1], ",")
|
||||||
|
cgroup.Controllers = append(cgroup.Controllers, ssNames...)
|
||||||
|
}
|
||||||
|
return cgroup, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseCgroups reads each line of the /proc/[pid]/cgroup file
|
||||||
|
func parseCgroups(data []byte) ([]Cgroup, error) {
|
||||||
|
var cgroups []Cgroup
|
||||||
|
scanner := bufio.NewScanner(bytes.NewReader(data))
|
||||||
|
for scanner.Scan() {
|
||||||
|
mountString := scanner.Text()
|
||||||
|
parsedMounts, err := parseCgroupString(mountString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cgroups = append(cgroups, *parsedMounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := scanner.Err()
|
||||||
|
return cgroups, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cgroups reads from /proc/<pid>/cgroups and returns a []*Cgroup struct locating this PID in each process
|
||||||
|
// control hierarchy running on this system. On every system (v1 and v2), all hierarchies contain all processes,
|
||||||
|
// so the len of the returned struct is equal to the number of active hierarchies on this system
|
||||||
|
func (p Proc) Cgroups() ([]Cgroup, error) {
|
||||||
|
data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/cgroup", p.PID))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return parseCgroups(data)
|
||||||
|
}
|
2
vendor/github.com/prometheus/procfs/proc_fdinfo.go
generated
vendored
2
vendor/github.com/prometheus/procfs/proc_fdinfo.go
generated
vendored
|
@ -41,7 +41,7 @@ type ProcFDInfo struct {
|
||||||
Flags string
|
Flags string
|
||||||
// Mount point ID
|
// Mount point ID
|
||||||
MntID string
|
MntID string
|
||||||
// List of inotify lines (structed) in the fdinfo file (kernel 3.8+ only)
|
// List of inotify lines (structured) in the fdinfo file (kernel 3.8+ only)
|
||||||
InotifyInfos []InotifyInfo
|
InotifyInfos []InotifyInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
vendor/github.com/prometheus/procfs/proc_maps.go
generated
vendored
3
vendor/github.com/prometheus/procfs/proc_maps.go
generated
vendored
|
@ -11,7 +11,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// +build !windows
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
package procfs
|
package procfs
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import (
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ProcMapPermissions contains permission settings read from /proc/[pid]/maps
|
||||||
type ProcMapPermissions struct {
|
type ProcMapPermissions struct {
|
||||||
// mapping has the [R]ead flag set
|
// mapping has the [R]ead flag set
|
||||||
Read bool
|
Read bool
|
||||||
|
|
165
vendor/github.com/prometheus/procfs/proc_smaps.go
generated
vendored
Normal file
165
vendor/github.com/prometheus/procfs/proc_smaps.go
generated
vendored
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
// Copyright 2020 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package procfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus/procfs/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// match the header line before each mapped zone in /proc/pid/smaps
|
||||||
|
procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProcSMapsRollup struct {
|
||||||
|
// Amount of the mapping that is currently resident in RAM
|
||||||
|
Rss uint64
|
||||||
|
// Process's proportional share of this mapping
|
||||||
|
Pss uint64
|
||||||
|
// Size in bytes of clean shared pages
|
||||||
|
SharedClean uint64
|
||||||
|
// Size in bytes of dirty shared pages
|
||||||
|
SharedDirty uint64
|
||||||
|
// Size in bytes of clean private pages
|
||||||
|
PrivateClean uint64
|
||||||
|
// Size in bytes of dirty private pages
|
||||||
|
PrivateDirty uint64
|
||||||
|
// Amount of memory currently marked as referenced or accessed
|
||||||
|
Referenced uint64
|
||||||
|
// Amount of memory that does not belong to any file
|
||||||
|
Anonymous uint64
|
||||||
|
// Amount would-be-anonymous memory currently on swap
|
||||||
|
Swap uint64
|
||||||
|
// Process's proportional memory on swap
|
||||||
|
SwapPss uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcSMapsRollup reads from /proc/[pid]/smaps_rollup to get summed memory information of the
|
||||||
|
// process.
|
||||||
|
//
|
||||||
|
// If smaps_rollup does not exists (require kernel >= 4.15), the content of /proc/pid/smaps will
|
||||||
|
// we read and summed.
|
||||||
|
func (p Proc) ProcSMapsRollup() (ProcSMapsRollup, error) {
|
||||||
|
data, err := util.ReadFileNoStat(p.path("smaps_rollup"))
|
||||||
|
if err != nil && os.IsNotExist(err) {
|
||||||
|
return p.procSMapsRollupManual()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return ProcSMapsRollup{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(string(data), "\n")
|
||||||
|
smaps := ProcSMapsRollup{}
|
||||||
|
|
||||||
|
// skip first line which don't contains information we need
|
||||||
|
lines = lines[1:]
|
||||||
|
for _, line := range lines {
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := smaps.parseLine(line); err != nil {
|
||||||
|
return ProcSMapsRollup{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return smaps, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read /proc/pid/smaps and do the roll-up in Go code.
|
||||||
|
func (p Proc) procSMapsRollupManual() (ProcSMapsRollup, error) {
|
||||||
|
file, err := os.Open(p.path("smaps"))
|
||||||
|
if err != nil {
|
||||||
|
return ProcSMapsRollup{}, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
smaps := ProcSMapsRollup{}
|
||||||
|
scan := bufio.NewScanner(file)
|
||||||
|
|
||||||
|
for scan.Scan() {
|
||||||
|
line := scan.Text()
|
||||||
|
|
||||||
|
if procSMapsHeaderLine.MatchString(line) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := smaps.parseLine(line); err != nil {
|
||||||
|
return ProcSMapsRollup{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return smaps, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ProcSMapsRollup) parseLine(line string) error {
|
||||||
|
kv := strings.SplitN(line, ":", 2)
|
||||||
|
if len(kv) != 2 {
|
||||||
|
fmt.Println(line)
|
||||||
|
return errors.New("invalid net/dev line, missing colon")
|
||||||
|
}
|
||||||
|
|
||||||
|
k := kv[0]
|
||||||
|
if k == "VmFlags" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v := strings.TrimSpace(kv[1])
|
||||||
|
v = strings.TrimRight(v, " kB")
|
||||||
|
|
||||||
|
vKBytes, err := strconv.ParseUint(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
vBytes := vKBytes * 1024
|
||||||
|
|
||||||
|
s.addValue(k, v, vKBytes, vBytes)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ProcSMapsRollup) addValue(k string, vString string, vUint uint64, vUintBytes uint64) {
|
||||||
|
switch k {
|
||||||
|
case "Rss":
|
||||||
|
s.Rss += vUintBytes
|
||||||
|
case "Pss":
|
||||||
|
s.Pss += vUintBytes
|
||||||
|
case "Shared_Clean":
|
||||||
|
s.SharedClean += vUintBytes
|
||||||
|
case "Shared_Dirty":
|
||||||
|
s.SharedDirty += vUintBytes
|
||||||
|
case "Private_Clean":
|
||||||
|
s.PrivateClean += vUintBytes
|
||||||
|
case "Private_Dirty":
|
||||||
|
s.PrivateDirty += vUintBytes
|
||||||
|
case "Referenced":
|
||||||
|
s.Referenced += vUintBytes
|
||||||
|
case "Anonymous":
|
||||||
|
s.Anonymous += vUintBytes
|
||||||
|
case "Swap":
|
||||||
|
s.Swap += vUintBytes
|
||||||
|
case "SwapPss":
|
||||||
|
s.SwapPss += vUintBytes
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user