@@ -1,13 +1,13 @@ | |||||
module backfeed | module backfeed | ||||
go 1.18 | |||||
go 1.19 | |||||
require ( | require ( | ||||
github.com/globocom/go-redis-prometheus v0.4.0 | github.com/globocom/go-redis-prometheus v0.4.0 | ||||
github.com/go-redis/redis/v8 v8.11.4 | |||||
github.com/go-redis/redis/v8 v8.11.5 | |||||
github.com/gorilla/mux v1.8.0 | github.com/gorilla/mux v1.8.0 | ||||
github.com/prometheus/client_golang v1.12.1 | |||||
github.com/tevino/abool/v2 v2.0.1 | |||||
github.com/prometheus/client_golang v1.12.2 | |||||
github.com/tevino/abool/v2 v2.1.0 | |||||
) | ) | ||||
require ( | require ( | ||||
@@ -17,8 +17,8 @@ require ( | |||||
github.com/golang/protobuf v1.5.2 // indirect | github.com/golang/protobuf v1.5.2 // indirect | ||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect | github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect | ||||
github.com/prometheus/client_model v0.2.0 // indirect | github.com/prometheus/client_model v0.2.0 // indirect | ||||
github.com/prometheus/common v0.32.1 // indirect | |||||
github.com/prometheus/procfs v0.7.3 // indirect | |||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect | |||||
google.golang.org/protobuf v1.26.0 // indirect | |||||
github.com/prometheus/common v0.37.0 // indirect | |||||
github.com/prometheus/procfs v0.8.0 // indirect | |||||
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 // indirect | |||||
google.golang.org/protobuf v1.28.1 // indirect | |||||
) | ) |
@@ -108,15 +108,16 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 | |||||
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-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= | github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= | ||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= | github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= | ||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= | |||||
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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= | ||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= | |||||
github.com/go-redis/redis/v8 v8.3.3/go.mod h1:jszGxBCez8QA1HWSmQxJO9Y82kNibbUmeYhKWrBejTU= | github.com/go-redis/redis/v8 v8.3.3/go.mod h1:jszGxBCez8QA1HWSmQxJO9Y82kNibbUmeYhKWrBejTU= | ||||
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= | |||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= | |||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= | |||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= | |||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= | github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= | ||||
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-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= | |||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= | github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= | ||||
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= | ||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||||
@@ -163,8 +164,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ | |||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= | |||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | |||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= | |||||
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/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= | ||||
@@ -269,7 +269,6 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi | |||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= | github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= | ||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= | ||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= | github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= | ||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= | |||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= | github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= | ||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= | github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= | ||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= | github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= | ||||
@@ -277,14 +276,12 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W | |||||
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.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= | ||||
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= | github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= | ||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= | |||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= | |||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= | |||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= | ||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= | ||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= | ||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= | github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= | ||||
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= | |||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= | |||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= | |||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= | ||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= | github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= | ||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= | github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= | ||||
@@ -314,8 +311,9 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD | |||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= | github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= | ||||
github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= | github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= | ||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= | github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= | ||||
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= | |||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= | github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= | ||||
github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= | |||||
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= | |||||
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/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | ||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||
@@ -329,8 +327,9 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 | |||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= | github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= | ||||
github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= | github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= | ||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= | github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= | ||||
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= | |||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= | github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= | ||||
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= | |||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= | |||||
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/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.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= | ||||
@@ -338,8 +337,9 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx | |||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= | ||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= | github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= | ||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= | github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= | ||||
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= | |||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= | github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= | ||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= | |||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= | |||||
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= | ||||
@@ -365,11 +365,10 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ | |||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | 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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | |||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | ||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
github.com/tevino/abool/v2 v2.0.1 h1:OF7FC5V5z3yAWyixbc32ecEzrgAJCsPkVOsPM2qoZPI= | |||||
github.com/tevino/abool/v2 v2.0.1/go.mod h1:+Lmlqk6bHDWHqN1cbxqhwEAwMPXgc8I1SDEamtseuXY= | |||||
github.com/tevino/abool/v2 v2.1.0 h1:7w+Vf9f/5gmKT4m4qkayb33/92M+Um45F2BkHOR+L/c= | |||||
github.com/tevino/abool/v2 v2.1.0/go.mod h1:+Lmlqk6bHDWHqN1cbxqhwEAwMPXgc8I1SDEamtseuXY= | |||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | ||||
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.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | ||||
@@ -377,7 +376,6 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q | |||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | |||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= | go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= | ||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= | go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= | ||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= | go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= | ||||
@@ -469,16 +467,17 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R | |||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | ||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | |||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= | |||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo= | |||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= | |||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= | |||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= | |||||
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/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= | golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= | ||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= | |||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
@@ -487,7 +486,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ | |||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
@@ -534,20 +532,24 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w | |||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= | |||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 h1:9vYwv7OjYaky/tlAeD7C4oC9EsPTlaFl1H2jS++V+ME= | |||||
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | |||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.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/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/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= | |||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= | |||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | |||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/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-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= | ||||
@@ -598,11 +600,9 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY | |||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | |||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= | |||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= | google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= | ||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= | ||||
@@ -686,8 +686,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD | |||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= | ||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= | ||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= | |||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= | |||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | |||||
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/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
@@ -53,7 +53,6 @@ type ProjectBackfeedManager struct { | |||||
Name string | Name string | ||||
BackfeedRedis *redis.ClusterClient | BackfeedRedis *redis.ClusterClient | ||||
ProjectRedis *redis.Client | ProjectRedis *redis.Client | ||||
LegacyRedis *redis.Client | |||||
//Lock sync.RWMutex | //Lock sync.RWMutex | ||||
ProjectConfig ProjectConfig | ProjectConfig ProjectConfig | ||||
} | } | ||||
@@ -151,8 +150,15 @@ func (that *ProjectBackfeedManager) Do() { | |||||
break | break | ||||
default: | default: | ||||
} | } | ||||
now := time.Now() | |||||
resultMap := map[string]*redis.Cmd{} | resultMap := map[string]*redis.Cmd{} | ||||
pipe := that.BackfeedRedis.Pipeline() | pipe := that.BackfeedRedis.Pipeline() | ||||
lastTS := make([]interface{}, 0, len(keyMap)*2) | |||||
for key := range keyMap { | |||||
lastTS = append(lastTS, key) | |||||
lastTS = append(lastTS, fmt.Sprintf("%d", now.Unix())) | |||||
} | |||||
pipe.HSet(context.Background(), ":last_ts", lastTS...) | |||||
for key, items := range keyMap { | for key, items := range keyMap { | ||||
args := []interface{}{ | args := []interface{}{ | ||||
"bf.madd", | "bf.madd", | ||||
@@ -163,8 +169,7 @@ func (that *ProjectBackfeedManager) Do() { | |||||
} | } | ||||
resultMap[key] = pipe.Do(context.Background(), args...) | resultMap[key] = pipe.Do(context.Background(), args...) | ||||
} | } | ||||
_, err := pipe.Exec(context.Background()) | |||||
if err != nil { | |||||
if _, err := pipe.Exec(context.Background()); err != nil { | |||||
log.Printf("%s", err) | log.Printf("%s", err) | ||||
} | } | ||||
var sAddItems []interface{} | var sAddItems []interface{} | ||||
@@ -185,28 +190,7 @@ func (that *ProjectBackfeedManager) Do() { | |||||
} | } | ||||
dupes := wrapped - len(sAddItems) | dupes := wrapped - len(sAddItems) | ||||
if len(sAddItems) != 0 { | if len(sAddItems) != 0 { | ||||
args := []interface{}{ | |||||
"bf.mexists", | |||||
that.Name, | |||||
} | |||||
args = append(args, sAddItems...) | |||||
res, err := that.LegacyRedis.Do(context.Background(), args...).BoolSlice() | |||||
if err != nil { | |||||
log.Printf("unable to dedupe against %s legacy backfeed: %s", that.Name, err) | |||||
} else if len(res) == len(sAddItems) { | |||||
var filteredSAddItems []interface{} | |||||
for i, v := range res { | |||||
if !v { | |||||
filteredSAddItems = append(filteredSAddItems, sAddItems[i]) | |||||
} | |||||
} | |||||
sAddItems = filteredSAddItems | |||||
} | |||||
} | |||||
if len(sAddItems) != 0 { | |||||
err := that.ProjectRedis.SAdd(context.Background(), fmt.Sprintf("%s:todo:backfeed", that.Name), sAddItems...).Err() | |||||
if err != nil { | |||||
if err := that.ProjectRedis.SAdd(context.Background(), fmt.Sprintf("%s:todo:backfeed", that.Name), sAddItems...).Err(); err != nil { | |||||
log.Printf("failed to sadd items for %s: %s", that.Name, err) | log.Printf("failed to sadd items for %s: %s", that.Name, err) | ||||
} | } | ||||
} | } | ||||
@@ -223,7 +207,6 @@ type GlobalBackfeedManager struct { | |||||
ActiveSlugs map[string]string | ActiveSlugs map[string]string | ||||
TrackerRedis *redis.Client | TrackerRedis *redis.Client | ||||
BackfeedRedis *redis.ClusterClient | BackfeedRedis *redis.ClusterClient | ||||
LegacyRedis *redis.Client | |||||
Lock sync.RWMutex | Lock sync.RWMutex | ||||
Populated *abool.AtomicBool | Populated *abool.AtomicBool | ||||
} | } | ||||
@@ -256,8 +239,7 @@ func (that *GlobalBackfeedManager) RefreshFeeds() error { | |||||
continue | continue | ||||
} | } | ||||
config := ProjectConfig{} | config := ProjectConfig{} | ||||
err := json.Unmarshal([]byte(configString), &config) | |||||
if err != nil { | |||||
if err := json.Unmarshal([]byte(configString), &config); err != nil { | |||||
continue | continue | ||||
} | } | ||||
projectConfigs[project] = config | projectConfigs[project] = config | ||||
@@ -296,7 +278,6 @@ func (that *GlobalBackfeedManager) RefreshFeeds() error { | |||||
BackfeedRedis: that.BackfeedRedis, | BackfeedRedis: that.BackfeedRedis, | ||||
Name: project, | Name: project, | ||||
ProjectConfig: projectConfig, | ProjectConfig: projectConfig, | ||||
LegacyRedis: that.LegacyRedis, | |||||
} | } | ||||
if projectConfig.RedisConfig != nil { | if projectConfig.RedisConfig != nil { | ||||
projectBackfeedManager.ProjectRedis = redis.NewClient(&redis.Options{ | projectBackfeedManager.ProjectRedis = redis.NewClient(&redis.Options{ | ||||
@@ -440,15 +421,13 @@ func (that *GlobalBackfeedManager) HandleLegacy(res http.ResponseWriter, req *ht | |||||
SecondaryShard: secondaryShard, | SecondaryShard: secondaryShard, | ||||
Item: bcopy, | Item: bcopy, | ||||
} | } | ||||
err := projectBackfeedManager.PushItem(req.Context(), item) | |||||
if err != nil { | |||||
if err := projectBackfeedManager.PushItem(req.Context(), item); err != nil { | |||||
WriteResponse(res, http.StatusServiceUnavailable, err) | WriteResponse(res, http.StatusServiceUnavailable, err) | ||||
return | return | ||||
} | } | ||||
n++ | n++ | ||||
} | } | ||||
err := scanner.Err() | |||||
if err != nil { | |||||
if err := scanner.Err(); err != nil { | |||||
WriteResponse(res, statusCode, err) | WriteResponse(res, statusCode, err) | ||||
return | return | ||||
} | } | ||||
@@ -461,16 +440,10 @@ func (that *GlobalBackfeedManager) HandleHealth(res http.ResponseWriter, req *ht | |||||
WriteResponse(res, http.StatusServiceUnavailable, fmt.Errorf("%s", "backfeed not populated")) | WriteResponse(res, http.StatusServiceUnavailable, fmt.Errorf("%s", "backfeed not populated")) | ||||
return | return | ||||
} | } | ||||
err := that.LegacyRedis.Ping(req.Context()).Err() | |||||
if err != nil { | |||||
WriteResponse(res, http.StatusInternalServerError, fmt.Errorf("failed to ping legacy redis: %s", err)) | |||||
return | |||||
} | |||||
err = that.BackfeedRedis.ForEachShard(req.Context(), func(ctx context.Context, client *redis.Client) error { | |||||
if err := that.BackfeedRedis.ForEachShard(req.Context(), func(ctx context.Context, client *redis.Client) error { | |||||
client.ClientGetName(ctx) | client.ClientGetName(ctx) | ||||
return client.Ping(ctx).Err() | return client.Ping(ctx).Err() | ||||
}) | |||||
if err != nil { | |||||
}); err != nil { | |||||
WriteResponse(res, http.StatusInternalServerError, fmt.Errorf("failed to ping backfeed redis: %s", err)) | WriteResponse(res, http.StatusInternalServerError, fmt.Errorf("failed to ping backfeed redis: %s", err)) | ||||
return | return | ||||
} | } | ||||
@@ -549,15 +522,13 @@ func main() { | |||||
ActiveSlugs: map[string]string{}, | ActiveSlugs: map[string]string{}, | ||||
TrackerRedis: trackerRedisClient, | TrackerRedis: trackerRedisClient, | ||||
BackfeedRedis: backfeedRedisClient, | BackfeedRedis: backfeedRedisClient, | ||||
LegacyRedis: legacyRedisClient, | |||||
Populated: abool.New(), | Populated: abool.New(), | ||||
} | } | ||||
globalBackfeedManager.Context, globalBackfeedManager.Cancel = context.WithCancel(context.Background()) | globalBackfeedManager.Context, globalBackfeedManager.Cancel = context.WithCancel(context.Background()) | ||||
defer globalBackfeedManager.CancelAllFeeds() | defer globalBackfeedManager.CancelAllFeeds() | ||||
err = globalBackfeedManager.RefreshFeeds() | |||||
if err != nil { | |||||
if err := globalBackfeedManager.RefreshFeeds(); err != nil { | |||||
log.Panicf("unable to set up backfeed projects: %s", err) | log.Panicf("unable to set up backfeed projects: %s", err) | ||||
} | } | ||||
r := mux.NewRouter() | r := mux.NewRouter() | ||||
@@ -606,8 +577,7 @@ func main() { | |||||
return | return | ||||
case <-ticker.C: | case <-ticker.C: | ||||
} | } | ||||
err = globalBackfeedManager.RefreshFeeds() | |||||
if err != nil { | |||||
if err := globalBackfeedManager.RefreshFeeds(); err != nil { | |||||
log.Printf("unable to refresh backfeed projects: %s", err) | log.Printf("unable to refresh backfeed projects: %s", err) | ||||
} | } | ||||
} | } | ||||
@@ -2,26 +2,3 @@ run: | |||||
concurrency: 8 | concurrency: 8 | ||||
deadline: 5m | deadline: 5m | ||||
tests: false | tests: false | ||||
linters: | |||||
enable-all: true | |||||
disable: | |||||
- funlen | |||||
- gochecknoglobals | |||||
- gochecknoinits | |||||
- gocognit | |||||
- goconst | |||||
- godox | |||||
- gosec | |||||
- maligned | |||||
- wsl | |||||
- gomnd | |||||
- goerr113 | |||||
- exhaustive | |||||
- nestif | |||||
- nlreturn | |||||
- exhaustivestruct | |||||
- wrapcheck | |||||
- errorlint | |||||
- cyclop | |||||
- forcetypeassert | |||||
- forbidigo |
@@ -1,3 +1,31 @@ | |||||
## [8.11.5](https://github.com/go-redis/redis/compare/v8.11.4...v8.11.5) (2022-03-17) | |||||
### Bug Fixes | |||||
* add missing Expire methods to Cmdable ([17e3b43](https://github.com/go-redis/redis/commit/17e3b43879d516437ada71cf9c0deac6a382ed9a)) | |||||
* add whitespace for avoid unlikely colisions ([7f7c181](https://github.com/go-redis/redis/commit/7f7c1817617cfec909efb13d14ad22ef05a6ad4c)) | |||||
* example/otel compile error ([#2028](https://github.com/go-redis/redis/issues/2028)) ([187c07c](https://github.com/go-redis/redis/commit/187c07c41bf68dc3ab280bc3a925e960bbef6475)) | |||||
* **extra/redisotel:** set span.kind attribute to client ([065b200](https://github.com/go-redis/redis/commit/065b200070b41e6e949710b4f9e01b50ccc60ab2)) | |||||
* format ([96f53a0](https://github.com/go-redis/redis/commit/96f53a0159a28affa94beec1543a62234e7f8b32)) | |||||
* invalid type assert in stringArg ([de6c131](https://github.com/go-redis/redis/commit/de6c131865b8263400c8491777b295035f2408e4)) | |||||
* rename Golang to Go ([#2030](https://github.com/go-redis/redis/issues/2030)) ([b82a2d9](https://github.com/go-redis/redis/commit/b82a2d9d4d2de7b7cbe8fcd4895be62dbcacacbc)) | |||||
* set timeout for WAIT command. Fixes [#1963](https://github.com/go-redis/redis/issues/1963) ([333fee1](https://github.com/go-redis/redis/commit/333fee1a8fd98a2fbff1ab187c1b03246a7eb01f)) | |||||
* update some argument counts in pre-allocs ([f6974eb](https://github.com/go-redis/redis/commit/f6974ebb5c40a8adf90d2cacab6dc297f4eba4c2)) | |||||
### Features | |||||
* Add redis v7's NX, XX, GT, LT expire variants ([e19bbb2](https://github.com/go-redis/redis/commit/e19bbb26e2e395c6e077b48d80d79e99f729a8b8)) | |||||
* add support for acl sentinel auth in universal client ([ab0ccc4](https://github.com/go-redis/redis/commit/ab0ccc47413f9b2a6eabc852fed5005a3ee1af6e)) | |||||
* add support for COPY command ([#2016](https://github.com/go-redis/redis/issues/2016)) ([730afbc](https://github.com/go-redis/redis/commit/730afbcffb93760e8a36cc06cfe55ab102b693a7)) | |||||
* add support for passing extra attributes added to spans ([39faaa1](https://github.com/go-redis/redis/commit/39faaa171523834ba527c9789710c4fde87f5a2e)) | |||||
* add support for time.Duration write and scan ([2f1b74e](https://github.com/go-redis/redis/commit/2f1b74e20cdd7719b2aecf0768d3e3ae7c3e781b)) | |||||
* **redisotel:** ability to override TracerProvider ([#1998](https://github.com/go-redis/redis/issues/1998)) ([bf8d4aa](https://github.com/go-redis/redis/commit/bf8d4aa60c00366cda2e98c3ddddc8cf68507417)) | |||||
* set net.peer.name and net.peer.port in otel example ([69bf454](https://github.com/go-redis/redis/commit/69bf454f706204211cd34835f76b2e8192d3766d)) | |||||
## [8.11.4](https://github.com/go-redis/redis/compare/v8.11.3...v8.11.4) (2021-10-04) | ## [8.11.4](https://github.com/go-redis/redis/compare/v8.11.3...v8.11.4) (2021-10-04) | ||||
@@ -1,19 +1,16 @@ | |||||
<p align="center"> | |||||
<a href="https://uptrace.dev/?utm_source=gh-redis&utm_campaign=gh-redis-banner1"> | |||||
<img src="https://raw.githubusercontent.com/uptrace/roadmap/master/banner1.png" alt="All-in-one tool to optimize performance and monitor errors & logs"> | |||||
</a> | |||||
</p> | |||||
# Redis client for Golang | |||||
# Redis client for Go | |||||
![build workflow](https://github.com/go-redis/redis/actions/workflows/build.yml/badge.svg) | ![build workflow](https://github.com/go-redis/redis/actions/workflows/build.yml/badge.svg) | ||||
[![PkgGoDev](https://pkg.go.dev/badge/github.com/go-redis/redis/v8)](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) | [![PkgGoDev](https://pkg.go.dev/badge/github.com/go-redis/redis/v8)](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) | ||||
[![Documentation](https://img.shields.io/badge/redis-documentation-informational)](https://redis.uptrace.dev/) | [![Documentation](https://img.shields.io/badge/redis-documentation-informational)](https://redis.uptrace.dev/) | ||||
[![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj) | |||||
- To ask questions, join [Discord](https://discord.gg/rWtp5Aj) or use | |||||
[Discussions](https://github.com/go-redis/redis/discussions). | |||||
- [Newsletter](https://blog.uptrace.dev/pages/newsletter.html) to get latest updates. | |||||
go-redis is brought to you by :star: [**uptrace/uptrace**](https://github.com/uptrace/uptrace). | |||||
Uptrace is an open source and blazingly fast **distributed tracing** backend powered by | |||||
OpenTelemetry and ClickHouse. Give it a star as well! | |||||
## Resources | |||||
- [Discussions](https://github.com/go-redis/redis/discussions) | |||||
- [Documentation](https://redis.uptrace.dev) | - [Documentation](https://redis.uptrace.dev) | ||||
- [Reference](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) | - [Reference](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) | ||||
- [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples) | - [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples) | ||||
@@ -22,15 +19,14 @@ | |||||
Other projects you may like: | Other projects you may like: | ||||
- [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite. | - [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite. | ||||
- [treemux](https://github.com/vmihailenco/treemux) - high-speed, flexible, tree-based HTTP router | |||||
for Go. | |||||
- [BunRouter](https://bunrouter.uptrace.dev/) - fast and flexible HTTP router for Go. | |||||
## Ecosystem | ## Ecosystem | ||||
- [Redis Mock](https://github.com/go-redis/redismock). | |||||
- [Distributed Locks](https://github.com/bsm/redislock). | |||||
- [Redis Cache](https://github.com/go-redis/cache). | |||||
- [Rate limiting](https://github.com/go-redis/redis_rate). | |||||
- [Redis Mock](https://github.com/go-redis/redismock) | |||||
- [Distributed Locks](https://github.com/bsm/redislock) | |||||
- [Redis Cache](https://github.com/go-redis/cache) | |||||
- [Rate limiting](https://github.com/go-redis/redis_rate) | |||||
## Features | ## Features | ||||
@@ -39,16 +35,16 @@ Other projects you may like: | |||||
[circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support. | [circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support. | ||||
- [Pub/Sub](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#PubSub). | - [Pub/Sub](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#PubSub). | ||||
- [Transactions](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline). | - [Transactions](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline). | ||||
- [Pipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-Pipeline) and | |||||
[TxPipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline). | |||||
- [Pipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.Pipeline) and | |||||
[TxPipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.TxPipeline). | |||||
- [Scripting](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Script). | - [Scripting](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Script). | ||||
- [Timeouts](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options). | - [Timeouts](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options). | ||||
- [Redis Sentinel](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewFailoverClient). | - [Redis Sentinel](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewFailoverClient). | ||||
- [Redis Cluster](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewClusterClient). | - [Redis Cluster](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewClusterClient). | ||||
- [Cluster of Redis Servers](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-NewClusterClient--ManualSetup) | |||||
- [Cluster of Redis Servers](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-NewClusterClient-ManualSetup) | |||||
without using cluster mode and Redis Sentinel. | without using cluster mode and Redis Sentinel. | ||||
- [Ring](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewRing). | - [Ring](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewRing). | ||||
- [Instrumentation](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#ex-package--Instrumentation). | |||||
- [Instrumentation](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-package-Instrumentation). | |||||
## Installation | ## Installation | ||||
@@ -72,6 +68,7 @@ go get github.com/go-redis/redis/v8 | |||||
import ( | import ( | ||||
"context" | "context" | ||||
"github.com/go-redis/redis/v8" | "github.com/go-redis/redis/v8" | ||||
"fmt" | |||||
) | ) | ||||
var ctx = context.Background() | var ctx = context.Background() | ||||
@@ -20,7 +20,7 @@ type Cmder interface { | |||||
String() string | String() string | ||||
stringArg(int) string | stringArg(int) string | ||||
firstKeyPos() int8 | firstKeyPos() int8 | ||||
setFirstKeyPos(int8) | |||||
SetFirstKeyPos(int8) | |||||
readTimeout() *time.Duration | readTimeout() *time.Duration | ||||
readReply(rd *proto.Reader) error | readReply(rd *proto.Reader) error | ||||
@@ -151,15 +151,21 @@ func (cmd *baseCmd) stringArg(pos int) string { | |||||
if pos < 0 || pos >= len(cmd.args) { | if pos < 0 || pos >= len(cmd.args) { | ||||
return "" | return "" | ||||
} | } | ||||
s, _ := cmd.args[pos].(string) | |||||
return s | |||||
arg := cmd.args[pos] | |||||
switch v := arg.(type) { | |||||
case string: | |||||
return v | |||||
default: | |||||
// TODO: consider using appendArg | |||||
return fmt.Sprint(v) | |||||
} | |||||
} | } | ||||
func (cmd *baseCmd) firstKeyPos() int8 { | func (cmd *baseCmd) firstKeyPos() int8 { | ||||
return cmd.keyPos | return cmd.keyPos | ||||
} | } | ||||
func (cmd *baseCmd) setFirstKeyPos(keyPos int8) { | |||||
func (cmd *baseCmd) SetFirstKeyPos(keyPos int8) { | |||||
cmd.keyPos = keyPos | cmd.keyPos = keyPos | ||||
} | } | ||||
@@ -96,6 +96,10 @@ type Cmdable interface { | |||||
Exists(ctx context.Context, keys ...string) *IntCmd | Exists(ctx context.Context, keys ...string) *IntCmd | ||||
Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd | Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd | ||||
ExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd | ExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd | ||||
ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd | |||||
ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd | |||||
ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd | |||||
ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd | |||||
Keys(ctx context.Context, pattern string) *StringSliceCmd | Keys(ctx context.Context, pattern string) *StringSliceCmd | ||||
Migrate(ctx context.Context, host, port, key string, db int, timeout time.Duration) *StatusCmd | Migrate(ctx context.Context, host, port, key string, db int, timeout time.Duration) *StatusCmd | ||||
Move(ctx context.Context, key string, db int) *BoolCmd | Move(ctx context.Context, key string, db int) *BoolCmd | ||||
@@ -139,6 +143,7 @@ type Cmdable interface { | |||||
SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd | SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd | ||||
SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd | SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd | ||||
StrLen(ctx context.Context, key string) *IntCmd | StrLen(ctx context.Context, key string) *IntCmd | ||||
Copy(ctx context.Context, sourceKey string, destKey string, db int, replace bool) *IntCmd | |||||
GetBit(ctx context.Context, key string, offset int64) *IntCmd | GetBit(ctx context.Context, key string, offset int64) *IntCmd | ||||
SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd | SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd | ||||
@@ -431,6 +436,7 @@ func (c statefulCmdable) AuthACL(ctx context.Context, username, password string) | |||||
func (c cmdable) Wait(ctx context.Context, numSlaves int, timeout time.Duration) *IntCmd { | func (c cmdable) Wait(ctx context.Context, numSlaves int, timeout time.Duration) *IntCmd { | ||||
cmd := NewIntCmd(ctx, "wait", numSlaves, int(timeout/time.Millisecond)) | cmd := NewIntCmd(ctx, "wait", numSlaves, int(timeout/time.Millisecond)) | ||||
cmd.setReadTimeout(timeout) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -525,7 +531,37 @@ func (c cmdable) Exists(ctx context.Context, keys ...string) *IntCmd { | |||||
} | } | ||||
func (c cmdable) Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd { | func (c cmdable) Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd { | ||||
cmd := NewBoolCmd(ctx, "expire", key, formatSec(ctx, expiration)) | |||||
return c.expire(ctx, key, expiration, "") | |||||
} | |||||
func (c cmdable) ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd { | |||||
return c.expire(ctx, key, expiration, "NX") | |||||
} | |||||
func (c cmdable) ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd { | |||||
return c.expire(ctx, key, expiration, "XX") | |||||
} | |||||
func (c cmdable) ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd { | |||||
return c.expire(ctx, key, expiration, "GT") | |||||
} | |||||
func (c cmdable) ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd { | |||||
return c.expire(ctx, key, expiration, "LT") | |||||
} | |||||
func (c cmdable) expire( | |||||
ctx context.Context, key string, expiration time.Duration, mode string, | |||||
) *BoolCmd { | |||||
args := make([]interface{}, 3, 4) | |||||
args[0] = "expire" | |||||
args[1] = key | |||||
args[2] = formatSec(ctx, expiration) | |||||
if mode != "" { | |||||
args = append(args, mode) | |||||
} | |||||
cmd := NewBoolCmd(ctx, args...) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -990,6 +1026,16 @@ func (c cmdable) StrLen(ctx context.Context, key string) *IntCmd { | |||||
return cmd | return cmd | ||||
} | } | ||||
func (c cmdable) Copy(ctx context.Context, sourceKey, destKey string, db int, replace bool) *IntCmd { | |||||
args := []interface{}{"copy", sourceKey, destKey, "DB", db} | |||||
if replace { | |||||
args = append(args, "REPLACE") | |||||
} | |||||
cmd := NewIntCmd(ctx, args...) | |||||
_ = c(ctx, cmd) | |||||
return cmd | |||||
} | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
func (c cmdable) GetBit(ctx context.Context, key string, offset int64) *IntCmd { | func (c cmdable) GetBit(ctx context.Context, key string, offset int64) *IntCmd { | ||||
@@ -1778,7 +1824,7 @@ type XReadArgs struct { | |||||
} | } | ||||
func (c cmdable) XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd { | func (c cmdable) XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd { | ||||
args := make([]interface{}, 0, 5+len(a.Streams)) | |||||
args := make([]interface{}, 0, 6+len(a.Streams)) | |||||
args = append(args, "xread") | args = append(args, "xread") | ||||
keyPos := int8(1) | keyPos := int8(1) | ||||
@@ -1802,7 +1848,7 @@ func (c cmdable) XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd { | |||||
if a.Block >= 0 { | if a.Block >= 0 { | ||||
cmd.setReadTimeout(a.Block) | cmd.setReadTimeout(a.Block) | ||||
} | } | ||||
cmd.setFirstKeyPos(keyPos) | |||||
cmd.SetFirstKeyPos(keyPos) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -1860,7 +1906,7 @@ type XReadGroupArgs struct { | |||||
} | } | ||||
func (c cmdable) XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSliceCmd { | func (c cmdable) XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSliceCmd { | ||||
args := make([]interface{}, 0, 8+len(a.Streams)) | |||||
args := make([]interface{}, 0, 10+len(a.Streams)) | |||||
args = append(args, "xreadgroup", "group", a.Group, a.Consumer) | args = append(args, "xreadgroup", "group", a.Group, a.Consumer) | ||||
keyPos := int8(4) | keyPos := int8(4) | ||||
@@ -1886,7 +1932,7 @@ func (c cmdable) XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSlic | |||||
if a.Block >= 0 { | if a.Block >= 0 { | ||||
cmd.setReadTimeout(a.Block) | cmd.setReadTimeout(a.Block) | ||||
} | } | ||||
cmd.setFirstKeyPos(keyPos) | |||||
cmd.SetFirstKeyPos(keyPos) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -1957,7 +2003,7 @@ func (c cmdable) XAutoClaimJustID(ctx context.Context, a *XAutoClaimArgs) *XAuto | |||||
} | } | ||||
func xAutoClaimArgs(ctx context.Context, a *XAutoClaimArgs) []interface{} { | func xAutoClaimArgs(ctx context.Context, a *XAutoClaimArgs) []interface{} { | ||||
args := make([]interface{}, 0, 9) | |||||
args := make([]interface{}, 0, 8) | |||||
args = append(args, "xautoclaim", a.Stream, a.Group, a.Consumer, formatMs(ctx, a.MinIdle), a.Start) | args = append(args, "xautoclaim", a.Stream, a.Group, a.Consumer, formatMs(ctx, a.MinIdle), a.Start) | ||||
if a.Count > 0 { | if a.Count > 0 { | ||||
args = append(args, "count", a.Count) | args = append(args, "count", a.Count) | ||||
@@ -1989,7 +2035,7 @@ func (c cmdable) XClaimJustID(ctx context.Context, a *XClaimArgs) *StringSliceCm | |||||
} | } | ||||
func xClaimArgs(a *XClaimArgs) []interface{} { | func xClaimArgs(a *XClaimArgs) []interface{} { | ||||
args := make([]interface{}, 0, 4+len(a.Messages)) | |||||
args := make([]interface{}, 0, 5+len(a.Messages)) | |||||
args = append(args, | args = append(args, | ||||
"xclaim", | "xclaim", | ||||
a.Stream, | a.Stream, | ||||
@@ -2362,7 +2408,7 @@ func (c cmdable) ZInterStore(ctx context.Context, destination string, store *ZSt | |||||
args = append(args, "zinterstore", destination, len(store.Keys)) | args = append(args, "zinterstore", destination, len(store.Keys)) | ||||
args = store.appendArgs(args) | args = store.appendArgs(args) | ||||
cmd := NewIntCmd(ctx, args...) | cmd := NewIntCmd(ctx, args...) | ||||
cmd.setFirstKeyPos(3) | |||||
cmd.SetFirstKeyPos(3) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -2372,7 +2418,7 @@ func (c cmdable) ZInter(ctx context.Context, store *ZStore) *StringSliceCmd { | |||||
args = append(args, "zinter", len(store.Keys)) | args = append(args, "zinter", len(store.Keys)) | ||||
args = store.appendArgs(args) | args = store.appendArgs(args) | ||||
cmd := NewStringSliceCmd(ctx, args...) | cmd := NewStringSliceCmd(ctx, args...) | ||||
cmd.setFirstKeyPos(2) | |||||
cmd.SetFirstKeyPos(2) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -2383,7 +2429,7 @@ func (c cmdable) ZInterWithScores(ctx context.Context, store *ZStore) *ZSliceCmd | |||||
args = store.appendArgs(args) | args = store.appendArgs(args) | ||||
args = append(args, "withscores") | args = append(args, "withscores") | ||||
cmd := NewZSliceCmd(ctx, args...) | cmd := NewZSliceCmd(ctx, args...) | ||||
cmd.setFirstKeyPos(2) | |||||
cmd.SetFirstKeyPos(2) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -2710,7 +2756,7 @@ func (c cmdable) ZUnion(ctx context.Context, store ZStore) *StringSliceCmd { | |||||
args = append(args, "zunion", len(store.Keys)) | args = append(args, "zunion", len(store.Keys)) | ||||
args = store.appendArgs(args) | args = store.appendArgs(args) | ||||
cmd := NewStringSliceCmd(ctx, args...) | cmd := NewStringSliceCmd(ctx, args...) | ||||
cmd.setFirstKeyPos(2) | |||||
cmd.SetFirstKeyPos(2) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -2721,7 +2767,7 @@ func (c cmdable) ZUnionWithScores(ctx context.Context, store ZStore) *ZSliceCmd | |||||
args = store.appendArgs(args) | args = store.appendArgs(args) | ||||
args = append(args, "withscores") | args = append(args, "withscores") | ||||
cmd := NewZSliceCmd(ctx, args...) | cmd := NewZSliceCmd(ctx, args...) | ||||
cmd.setFirstKeyPos(2) | |||||
cmd.SetFirstKeyPos(2) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -2731,7 +2777,7 @@ func (c cmdable) ZUnionStore(ctx context.Context, dest string, store *ZStore) *I | |||||
args = append(args, "zunionstore", dest, len(store.Keys)) | args = append(args, "zunionstore", dest, len(store.Keys)) | ||||
args = store.appendArgs(args) | args = store.appendArgs(args) | ||||
cmd := NewIntCmd(ctx, args...) | cmd := NewIntCmd(ctx, args...) | ||||
cmd.setFirstKeyPos(3) | |||||
cmd.SetFirstKeyPos(3) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -2761,7 +2807,7 @@ func (c cmdable) ZDiff(ctx context.Context, keys ...string) *StringSliceCmd { | |||||
} | } | ||||
cmd := NewStringSliceCmd(ctx, args...) | cmd := NewStringSliceCmd(ctx, args...) | ||||
cmd.setFirstKeyPos(2) | |||||
cmd.SetFirstKeyPos(2) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -2777,7 +2823,7 @@ func (c cmdable) ZDiffWithScores(ctx context.Context, keys ...string) *ZSliceCmd | |||||
args[len(keys)+2] = "withscores" | args[len(keys)+2] = "withscores" | ||||
cmd := NewZSliceCmd(ctx, args...) | cmd := NewZSliceCmd(ctx, args...) | ||||
cmd.setFirstKeyPos(2) | |||||
cmd.SetFirstKeyPos(2) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -3053,7 +3099,7 @@ func (c cmdable) MemoryUsage(ctx context.Context, key string, samples ...int) *I | |||||
args = append(args, "SAMPLES", samples[0]) | args = append(args, "SAMPLES", samples[0]) | ||||
} | } | ||||
cmd := NewIntCmd(ctx, args...) | cmd := NewIntCmd(ctx, args...) | ||||
cmd.setFirstKeyPos(2) | |||||
cmd.SetFirstKeyPos(2) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -3070,7 +3116,7 @@ func (c cmdable) Eval(ctx context.Context, script string, keys []string, args .. | |||||
} | } | ||||
cmdArgs = appendArgs(cmdArgs, args) | cmdArgs = appendArgs(cmdArgs, args) | ||||
cmd := NewCmd(ctx, cmdArgs...) | cmd := NewCmd(ctx, cmdArgs...) | ||||
cmd.setFirstKeyPos(3) | |||||
cmd.SetFirstKeyPos(3) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -3085,7 +3131,7 @@ func (c cmdable) EvalSha(ctx context.Context, sha1 string, keys []string, args . | |||||
} | } | ||||
cmdArgs = appendArgs(cmdArgs, args) | cmdArgs = appendArgs(cmdArgs, args) | ||||
cmd := NewCmd(ctx, cmdArgs...) | cmd := NewCmd(ctx, cmdArgs...) | ||||
cmd.setFirstKeyPos(3) | |||||
cmd.SetFirstKeyPos(3) | |||||
_ = c(ctx, cmd) | _ = c(ctx, cmd) | ||||
return cmd | return cmd | ||||
} | } | ||||
@@ -134,7 +134,7 @@ func isMovedSameConnAddr(err error, addr string) bool { | |||||
if !strings.HasPrefix(redisError, "MOVED ") { | if !strings.HasPrefix(redisError, "MOVED ") { | ||||
return false | return false | ||||
} | } | ||||
return strings.HasSuffix(redisError, addr) | |||||
return strings.HasSuffix(redisError, " "+addr) | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
@@ -10,6 +10,7 @@ import ( | |||||
) | ) | ||||
// Scan parses bytes `b` to `v` with appropriate type. | // Scan parses bytes `b` to `v` with appropriate type. | ||||
//nolint:gocyclo | |||||
func Scan(b []byte, v interface{}) error { | func Scan(b []byte, v interface{}) error { | ||||
switch v := v.(type) { | switch v := v.(type) { | ||||
case nil: | case nil: | ||||
@@ -105,6 +106,13 @@ func Scan(b []byte, v interface{}) error { | |||||
var err error | var err error | ||||
*v, err = time.Parse(time.RFC3339Nano, util.BytesToString(b)) | *v, err = time.Parse(time.RFC3339Nano, util.BytesToString(b)) | ||||
return err | return err | ||||
case *time.Duration: | |||||
n, err := util.ParseInt(b, 10, 64) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
*v = time.Duration(n) | |||||
return nil | |||||
case encoding.BinaryUnmarshaler: | case encoding.BinaryUnmarshaler: | ||||
return v.UnmarshalBinary(b) | return v.UnmarshalBinary(b) | ||||
default: | default: | ||||
@@ -98,6 +98,8 @@ func (w *Writer) WriteArg(v interface{}) error { | |||||
case time.Time: | case time.Time: | ||||
w.numBuf = v.AppendFormat(w.numBuf[:0], time.RFC3339Nano) | w.numBuf = v.AppendFormat(w.numBuf[:0], time.RFC3339Nano) | ||||
return w.bytes(w.numBuf) | return w.bytes(w.numBuf) | ||||
case time.Duration: | |||||
return w.int(v.Nanoseconds()) | |||||
case encoding.BinaryMarshaler: | case encoding.BinaryMarshaler: | ||||
b, err := v.MarshalBinary() | b, err := v.MarshalBinary() | ||||
if err != nil { | if err != nil { | ||||
@@ -1,6 +1,6 @@ | |||||
{ | { | ||||
"name": "redis", | "name": "redis", | ||||
"version": "8.11.4", | |||||
"version": "8.11.5", | |||||
"main": "index.js", | "main": "index.js", | ||||
"repository": "git@github.com:go-redis/redis.git", | "repository": "git@github.com:go-redis/redis.git", | ||||
"author": "Vladimir Mihailenco <vladimir.webdev@gmail.com>", | "author": "Vladimir Mihailenco <vladimir.webdev@gmail.com>", | ||||
@@ -24,6 +24,7 @@ type pipelineExecer func(context.Context, []Cmder) error | |||||
// depends of your batch size and/or use TxPipeline. | // depends of your batch size and/or use TxPipeline. | ||||
type Pipeliner interface { | type Pipeliner interface { | ||||
StatefulCmdable | StatefulCmdable | ||||
Len() int | |||||
Do(ctx context.Context, args ...interface{}) *Cmd | Do(ctx context.Context, args ...interface{}) *Cmd | ||||
Process(ctx context.Context, cmd Cmder) error | Process(ctx context.Context, cmd Cmder) error | ||||
Close() error | Close() error | ||||
@@ -53,6 +54,15 @@ func (c *Pipeline) init() { | |||||
c.statefulCmdable = c.Process | c.statefulCmdable = c.Process | ||||
} | } | ||||
// Len returns the number of queued commands. | |||||
func (c *Pipeline) Len() int { | |||||
c.mu.Lock() | |||||
ln := len(c.cmds) | |||||
c.mu.Unlock() | |||||
return ln | |||||
} | |||||
// Do queues the custom command for later execution. | |||||
func (c *Pipeline) Do(ctx context.Context, args ...interface{}) *Cmd { | func (c *Pipeline) Do(ctx context.Context, args ...interface{}) *Cmd { | ||||
cmd := NewCmd(ctx, args...) | cmd := NewCmd(ctx, args...) | ||||
_ = c.Process(ctx, cmd) | _ = c.Process(ctx, cmd) | ||||
@@ -576,7 +576,7 @@ func (c *Ring) cmdInfo(ctx context.Context, name string) *CommandInfo { | |||||
} | } | ||||
info := cmdsInfo[name] | info := cmdsInfo[name] | ||||
if info == nil { | if info == nil { | ||||
internal.Logger.Printf(c.Context(), "info for cmd=%s not found", name) | |||||
internal.Logger.Printf(ctx, "info for cmd=%s not found", name) | |||||
} | } | ||||
return info | return info | ||||
} | } | ||||
@@ -25,6 +25,7 @@ type UniversalOptions struct { | |||||
Username string | Username string | ||||
Password string | Password string | ||||
SentinelUsername string | |||||
SentinelPassword string | SentinelPassword string | ||||
MaxRetries int | MaxRetries int | ||||
@@ -114,6 +115,7 @@ func (o *UniversalOptions) Failover() *FailoverOptions { | |||||
DB: o.DB, | DB: o.DB, | ||||
Username: o.Username, | Username: o.Username, | ||||
Password: o.Password, | Password: o.Password, | ||||
SentinelUsername: o.SentinelUsername, | |||||
SentinelPassword: o.SentinelPassword, | SentinelPassword: o.SentinelPassword, | ||||
MaxRetries: o.MaxRetries, | MaxRetries: o.MaxRetries, | ||||
@@ -2,5 +2,5 @@ package redis | |||||
// Version is the current release version. | // Version is the current release version. | ||||
func Version() string { | func Version() string { | ||||
return "8.11.4" | |||||
return "8.11.5" | |||||
} | } |
@@ -1,179 +0,0 @@ | |||||
// Copyright 2016 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package ptypes | |||||
import ( | |||||
"fmt" | |||||
"strings" | |||||
"github.com/golang/protobuf/proto" | |||||
"google.golang.org/protobuf/reflect/protoreflect" | |||||
"google.golang.org/protobuf/reflect/protoregistry" | |||||
anypb "github.com/golang/protobuf/ptypes/any" | |||||
) | |||||
const urlPrefix = "type.googleapis.com/" | |||||
// AnyMessageName returns the message name contained in an anypb.Any message. | |||||
// Most type assertions should use the Is function instead. | |||||
// | |||||
// Deprecated: Call the any.MessageName method instead. | |||||
func AnyMessageName(any *anypb.Any) (string, error) { | |||||
name, err := anyMessageName(any) | |||||
return string(name), err | |||||
} | |||||
func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) { | |||||
if any == nil { | |||||
return "", fmt.Errorf("message is nil") | |||||
} | |||||
name := protoreflect.FullName(any.TypeUrl) | |||||
if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 { | |||||
name = name[i+len("/"):] | |||||
} | |||||
if !name.IsValid() { | |||||
return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) | |||||
} | |||||
return name, nil | |||||
} | |||||
// MarshalAny marshals the given message m into an anypb.Any message. | |||||
// | |||||
// Deprecated: Call the anypb.New function instead. | |||||
func MarshalAny(m proto.Message) (*anypb.Any, error) { | |||||
switch dm := m.(type) { | |||||
case DynamicAny: | |||||
m = dm.Message | |||||
case *DynamicAny: | |||||
if dm == nil { | |||||
return nil, proto.ErrNil | |||||
} | |||||
m = dm.Message | |||||
} | |||||
b, err := proto.Marshal(m) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil | |||||
} | |||||
// Empty returns a new message of the type specified in an anypb.Any message. | |||||
// It returns protoregistry.NotFound if the corresponding message type could not | |||||
// be resolved in the global registry. | |||||
// | |||||
// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead | |||||
// to resolve the message name and create a new instance of it. | |||||
func Empty(any *anypb.Any) (proto.Message, error) { | |||||
name, err := anyMessageName(any) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
mt, err := protoregistry.GlobalTypes.FindMessageByName(name) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return proto.MessageV1(mt.New().Interface()), nil | |||||
} | |||||
// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message | |||||
// into the provided message m. It returns an error if the target message | |||||
// does not match the type in the Any message or if an unmarshal error occurs. | |||||
// | |||||
// The target message m may be a *DynamicAny message. If the underlying message | |||||
// type could not be resolved, then this returns protoregistry.NotFound. | |||||
// | |||||
// Deprecated: Call the any.UnmarshalTo method instead. | |||||
func UnmarshalAny(any *anypb.Any, m proto.Message) error { | |||||
if dm, ok := m.(*DynamicAny); ok { | |||||
if dm.Message == nil { | |||||
var err error | |||||
dm.Message, err = Empty(any) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
} | |||||
m = dm.Message | |||||
} | |||||
anyName, err := AnyMessageName(any) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
msgName := proto.MessageName(m) | |||||
if anyName != msgName { | |||||
return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName) | |||||
} | |||||
return proto.Unmarshal(any.Value, m) | |||||
} | |||||
// Is reports whether the Any message contains a message of the specified type. | |||||
// | |||||
// Deprecated: Call the any.MessageIs method instead. | |||||
func Is(any *anypb.Any, m proto.Message) bool { | |||||
if any == nil || m == nil { | |||||
return false | |||||
} | |||||
name := proto.MessageName(m) | |||||
if !strings.HasSuffix(any.TypeUrl, name) { | |||||
return false | |||||
} | |||||
return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/' | |||||
} | |||||
// DynamicAny is a value that can be passed to UnmarshalAny to automatically | |||||
// allocate a proto.Message for the type specified in an anypb.Any message. | |||||
// The allocated message is stored in the embedded proto.Message. | |||||
// | |||||
// Example: | |||||
// var x ptypes.DynamicAny | |||||
// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } | |||||
// fmt.Printf("unmarshaled message: %v", x.Message) | |||||
// | |||||
// Deprecated: Use the any.UnmarshalNew method instead to unmarshal | |||||
// the any message contents into a new instance of the underlying message. | |||||
type DynamicAny struct{ proto.Message } | |||||
func (m DynamicAny) String() string { | |||||
if m.Message == nil { | |||||
return "<nil>" | |||||
} | |||||
return m.Message.String() | |||||
} | |||||
func (m DynamicAny) Reset() { | |||||
if m.Message == nil { | |||||
return | |||||
} | |||||
m.Message.Reset() | |||||
} | |||||
func (m DynamicAny) ProtoMessage() { | |||||
return | |||||
} | |||||
func (m DynamicAny) ProtoReflect() protoreflect.Message { | |||||
if m.Message == nil { | |||||
return nil | |||||
} | |||||
return dynamicAny{proto.MessageReflect(m.Message)} | |||||
} | |||||
type dynamicAny struct{ protoreflect.Message } | |||||
func (m dynamicAny) Type() protoreflect.MessageType { | |||||
return dynamicAnyType{m.Message.Type()} | |||||
} | |||||
func (m dynamicAny) New() protoreflect.Message { | |||||
return dynamicAnyType{m.Message.Type()}.New() | |||||
} | |||||
func (m dynamicAny) Interface() protoreflect.ProtoMessage { | |||||
return DynamicAny{proto.MessageV1(m.Message.Interface())} | |||||
} | |||||
type dynamicAnyType struct{ protoreflect.MessageType } | |||||
func (t dynamicAnyType) New() protoreflect.Message { | |||||
return dynamicAny{t.MessageType.New()} | |||||
} | |||||
func (t dynamicAnyType) Zero() protoreflect.Message { | |||||
return dynamicAny{t.MessageType.Zero()} | |||||
} |
@@ -1,62 +0,0 @@ | |||||
// Code generated by protoc-gen-go. DO NOT EDIT. | |||||
// source: github.com/golang/protobuf/ptypes/any/any.proto | |||||
package any | |||||
import ( | |||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect" | |||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl" | |||||
anypb "google.golang.org/protobuf/types/known/anypb" | |||||
reflect "reflect" | |||||
) | |||||
// Symbols defined in public import of google/protobuf/any.proto. | |||||
type Any = anypb.Any | |||||
var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor | |||||
var file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{ | |||||
0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, | |||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, | |||||
0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, | |||||
0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, | |||||
0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29, | |||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, | |||||
0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, | |||||
0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, | |||||
0x74, 0x6f, 0x33, | |||||
} | |||||
var file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{} | |||||
var file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{ | |||||
0, // [0:0] is the sub-list for method output_type | |||||
0, // [0:0] is the sub-list for method input_type | |||||
0, // [0:0] is the sub-list for extension type_name | |||||
0, // [0:0] is the sub-list for extension extendee | |||||
0, // [0:0] is the sub-list for field type_name | |||||
} | |||||
func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() } | |||||
func file_github_com_golang_protobuf_ptypes_any_any_proto_init() { | |||||
if File_github_com_golang_protobuf_ptypes_any_any_proto != nil { | |||||
return | |||||
} | |||||
type x struct{} | |||||
out := protoimpl.TypeBuilder{ | |||||
File: protoimpl.DescBuilder{ | |||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | |||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc, | |||||
NumEnums: 0, | |||||
NumMessages: 0, | |||||
NumExtensions: 0, | |||||
NumServices: 0, | |||||
}, | |||||
GoTypes: file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes, | |||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs, | |||||
}.Build() | |||||
File_github_com_golang_protobuf_ptypes_any_any_proto = out.File | |||||
file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil | |||||
file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil | |||||
file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil | |||||
} |
@@ -1,10 +0,0 @@ | |||||
// Copyright 2016 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
// Package ptypes provides functionality for interacting with well-known types. | |||||
// | |||||
// Deprecated: Well-known types have specialized functionality directly | |||||
// injected into the generated packages for each message type. | |||||
// See the deprecation notice for each function for the suggested alternative. | |||||
package ptypes |
@@ -1,76 +0,0 @@ | |||||
// Copyright 2016 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package ptypes | |||||
import ( | |||||
"errors" | |||||
"fmt" | |||||
"time" | |||||
durationpb "github.com/golang/protobuf/ptypes/duration" | |||||
) | |||||
// Range of google.protobuf.Duration as specified in duration.proto. | |||||
// This is about 10,000 years in seconds. | |||||
const ( | |||||
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) | |||||
minSeconds = -maxSeconds | |||||
) | |||||
// Duration converts a durationpb.Duration to a time.Duration. | |||||
// Duration returns an error if dur is invalid or overflows a time.Duration. | |||||
// | |||||
// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead. | |||||
func Duration(dur *durationpb.Duration) (time.Duration, error) { | |||||
if err := validateDuration(dur); err != nil { | |||||
return 0, err | |||||
} | |||||
d := time.Duration(dur.Seconds) * time.Second | |||||
if int64(d/time.Second) != dur.Seconds { | |||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) | |||||
} | |||||
if dur.Nanos != 0 { | |||||
d += time.Duration(dur.Nanos) * time.Nanosecond | |||||
if (d < 0) != (dur.Nanos < 0) { | |||||
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) | |||||
} | |||||
} | |||||
return d, nil | |||||
} | |||||
// DurationProto converts a time.Duration to a durationpb.Duration. | |||||
// | |||||
// Deprecated: Call the durationpb.New function instead. | |||||
func DurationProto(d time.Duration) *durationpb.Duration { | |||||
nanos := d.Nanoseconds() | |||||
secs := nanos / 1e9 | |||||
nanos -= secs * 1e9 | |||||
return &durationpb.Duration{ | |||||
Seconds: int64(secs), | |||||
Nanos: int32(nanos), | |||||
} | |||||
} | |||||
// validateDuration determines whether the durationpb.Duration is valid | |||||
// according to the definition in google/protobuf/duration.proto. | |||||
// A valid durpb.Duration may still be too large to fit into a time.Duration | |||||
// Note that the range of durationpb.Duration is about 10,000 years, | |||||
// while the range of time.Duration is about 290 years. | |||||
func validateDuration(dur *durationpb.Duration) error { | |||||
if dur == nil { | |||||
return errors.New("duration: nil Duration") | |||||
} | |||||
if dur.Seconds < minSeconds || dur.Seconds > maxSeconds { | |||||
return fmt.Errorf("duration: %v: seconds out of range", dur) | |||||
} | |||||
if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 { | |||||
return fmt.Errorf("duration: %v: nanos out of range", dur) | |||||
} | |||||
// Seconds and Nanos must have the same sign, unless d.Nanos is zero. | |||||
if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) { | |||||
return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur) | |||||
} | |||||
return nil | |||||
} |
@@ -1,63 +0,0 @@ | |||||
// Code generated by protoc-gen-go. DO NOT EDIT. | |||||
// source: github.com/golang/protobuf/ptypes/duration/duration.proto | |||||
package duration | |||||
import ( | |||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect" | |||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl" | |||||
durationpb "google.golang.org/protobuf/types/known/durationpb" | |||||
reflect "reflect" | |||||
) | |||||
// Symbols defined in public import of google/protobuf/duration.proto. | |||||
type Duration = durationpb.Duration | |||||
var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor | |||||
var file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{ | |||||
0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, | |||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, | |||||
0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72, | |||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, | |||||
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, | |||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, | |||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, | |||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, | |||||
0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, | |||||
0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, | |||||
} | |||||
var file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{} | |||||
var file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{ | |||||
0, // [0:0] is the sub-list for method output_type | |||||
0, // [0:0] is the sub-list for method input_type | |||||
0, // [0:0] is the sub-list for extension type_name | |||||
0, // [0:0] is the sub-list for extension extendee | |||||
0, // [0:0] is the sub-list for field type_name | |||||
} | |||||
func init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() } | |||||
func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() { | |||||
if File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil { | |||||
return | |||||
} | |||||
type x struct{} | |||||
out := protoimpl.TypeBuilder{ | |||||
File: protoimpl.DescBuilder{ | |||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | |||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc, | |||||
NumEnums: 0, | |||||
NumMessages: 0, | |||||
NumExtensions: 0, | |||||
NumServices: 0, | |||||
}, | |||||
GoTypes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes, | |||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs, | |||||
}.Build() | |||||
File_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File | |||||
file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil | |||||
file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil | |||||
file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil | |||||
} |
@@ -1,112 +0,0 @@ | |||||
// Copyright 2016 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package ptypes | |||||
import ( | |||||
"errors" | |||||
"fmt" | |||||
"time" | |||||
timestamppb "github.com/golang/protobuf/ptypes/timestamp" | |||||
) | |||||
// Range of google.protobuf.Duration as specified in timestamp.proto. | |||||
const ( | |||||
// Seconds field of the earliest valid Timestamp. | |||||
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). | |||||
minValidSeconds = -62135596800 | |||||
// Seconds field just after the latest valid Timestamp. | |||||
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). | |||||
maxValidSeconds = 253402300800 | |||||
) | |||||
// Timestamp converts a timestamppb.Timestamp to a time.Time. | |||||
// It returns an error if the argument is invalid. | |||||
// | |||||
// Unlike most Go functions, if Timestamp returns an error, the first return | |||||
// value is not the zero time.Time. Instead, it is the value obtained from the | |||||
// time.Unix function when passed the contents of the Timestamp, in the UTC | |||||
// locale. This may or may not be a meaningful time; many invalid Timestamps | |||||
// do map to valid time.Times. | |||||
// | |||||
// A nil Timestamp returns an error. The first return value in that case is | |||||
// undefined. | |||||
// | |||||
// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead. | |||||
func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) { | |||||
// Don't return the zero value on error, because corresponds to a valid | |||||
// timestamp. Instead return whatever time.Unix gives us. | |||||
var t time.Time | |||||
if ts == nil { | |||||
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp | |||||
} else { | |||||
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() | |||||
} | |||||
return t, validateTimestamp(ts) | |||||
} | |||||
// TimestampNow returns a google.protobuf.Timestamp for the current time. | |||||
// | |||||
// Deprecated: Call the timestamppb.Now function instead. | |||||
func TimestampNow() *timestamppb.Timestamp { | |||||
ts, err := TimestampProto(time.Now()) | |||||
if err != nil { | |||||
panic("ptypes: time.Now() out of Timestamp range") | |||||
} | |||||
return ts | |||||
} | |||||
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. | |||||
// It returns an error if the resulting Timestamp is invalid. | |||||
// | |||||
// Deprecated: Call the timestamppb.New function instead. | |||||
func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) { | |||||
ts := ×tamppb.Timestamp{ | |||||
Seconds: t.Unix(), | |||||
Nanos: int32(t.Nanosecond()), | |||||
} | |||||
if err := validateTimestamp(ts); err != nil { | |||||
return nil, err | |||||
} | |||||
return ts, nil | |||||
} | |||||
// TimestampString returns the RFC 3339 string for valid Timestamps. | |||||
// For invalid Timestamps, it returns an error message in parentheses. | |||||
// | |||||
// Deprecated: Call the ts.AsTime method instead, | |||||
// followed by a call to the Format method on the time.Time value. | |||||
func TimestampString(ts *timestamppb.Timestamp) string { | |||||
t, err := Timestamp(ts) | |||||
if err != nil { | |||||
return fmt.Sprintf("(%v)", err) | |||||
} | |||||
return t.Format(time.RFC3339Nano) | |||||
} | |||||
// validateTimestamp determines whether a Timestamp is valid. | |||||
// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01) | |||||
// and has a Nanos field in the range [0, 1e9). | |||||
// | |||||
// If the Timestamp is valid, validateTimestamp returns nil. | |||||
// Otherwise, it returns an error that describes the problem. | |||||
// | |||||
// Every valid Timestamp can be represented by a time.Time, | |||||
// but the converse is not true. | |||||
func validateTimestamp(ts *timestamppb.Timestamp) error { | |||||
if ts == nil { | |||||
return errors.New("timestamp: nil Timestamp") | |||||
} | |||||
if ts.Seconds < minValidSeconds { | |||||
return fmt.Errorf("timestamp: %v before 0001-01-01", ts) | |||||
} | |||||
if ts.Seconds >= maxValidSeconds { | |||||
return fmt.Errorf("timestamp: %v after 10000-01-01", ts) | |||||
} | |||||
if ts.Nanos < 0 || ts.Nanos >= 1e9 { | |||||
return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) | |||||
} | |||||
return nil | |||||
} |
@@ -197,14 +197,6 @@ func goRuntimeMemStats() memStatsMetrics { | |||||
), | ), | ||||
eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) }, | eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) }, | ||||
valType: GaugeValue, | valType: GaugeValue, | ||||
}, { | |||||
desc: NewDesc( | |||||
memstatNamespace("gc_cpu_fraction"), | |||||
"The fraction of this program's available CPU time used by the GC since the program started.", | |||||
nil, nil, | |||||
), | |||||
eval: func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction }, | |||||
valType: GaugeValue, | |||||
}, | }, | ||||
} | } | ||||
} | } | ||||
@@ -268,7 +260,6 @@ func (c *baseGoCollector) Collect(ch chan<- Metric) { | |||||
quantiles[0.0] = stats.PauseQuantiles[0].Seconds() | quantiles[0.0] = stats.PauseQuantiles[0].Seconds() | ||||
ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), stats.PauseTotal.Seconds(), quantiles) | ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), stats.PauseTotal.Seconds(), quantiles) | ||||
ch <- MustNewConstMetric(c.gcLastTimeDesc, GaugeValue, float64(stats.LastGC.UnixNano())/1e9) | ch <- MustNewConstMetric(c.gcLastTimeDesc, GaugeValue, float64(stats.LastGC.UnixNano())/1e9) | ||||
ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1) | ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1) | ||||
} | } | ||||
@@ -278,6 +269,7 @@ func memstatNamespace(s string) string { | |||||
// memStatsMetrics provide description, evaluator, runtime/metrics name, and | // memStatsMetrics provide description, evaluator, runtime/metrics name, and | ||||
// value type for memstat metrics. | // value type for memstat metrics. | ||||
// TODO(bwplotka): Remove with end Go 1.16 EOL and replace with runtime/metrics.Description | |||||
type memStatsMetrics []struct { | type memStatsMetrics []struct { | ||||
desc *Desc | desc *Desc | ||||
eval func(*runtime.MemStats) float64 | eval func(*runtime.MemStats) float64 | ||||
@@ -40,13 +40,28 @@ type goCollector struct { | |||||
// | // | ||||
// Deprecated: Use collectors.NewGoCollector instead. | // Deprecated: Use collectors.NewGoCollector instead. | ||||
func NewGoCollector() Collector { | func NewGoCollector() Collector { | ||||
msMetrics := goRuntimeMemStats() | |||||
msMetrics = append(msMetrics, struct { | |||||
desc *Desc | |||||
eval func(*runtime.MemStats) float64 | |||||
valType ValueType | |||||
}{ | |||||
// This metric is omitted in Go1.17+, see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 | |||||
desc: NewDesc( | |||||
memstatNamespace("gc_cpu_fraction"), | |||||
"The fraction of this program's available CPU time used by the GC since the program started.", | |||||
nil, nil, | |||||
), | |||||
eval: func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction }, | |||||
valType: GaugeValue, | |||||
}) | |||||
return &goCollector{ | return &goCollector{ | ||||
base: newBaseGoCollector(), | base: newBaseGoCollector(), | ||||
msLast: &runtime.MemStats{}, | msLast: &runtime.MemStats{}, | ||||
msRead: runtime.ReadMemStats, | msRead: runtime.ReadMemStats, | ||||
msMaxWait: time.Second, | msMaxWait: time.Second, | ||||
msMaxAge: 5 * time.Minute, | msMaxAge: 5 * time.Minute, | ||||
msMetrics: goRuntimeMemStats(), | |||||
msMetrics: msMetrics, | |||||
} | } | ||||
} | } | ||||
@@ -25,11 +25,71 @@ import ( | |||||
//nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. | //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. | ||||
"github.com/golang/protobuf/proto" | "github.com/golang/protobuf/proto" | ||||
"github.com/prometheus/client_golang/prometheus/internal" | |||||
dto "github.com/prometheus/client_model/go" | dto "github.com/prometheus/client_model/go" | ||||
"github.com/prometheus/client_golang/prometheus/internal" | |||||
) | |||||
const ( | |||||
goGCHeapTinyAllocsObjects = "/gc/heap/tiny/allocs:objects" | |||||
goGCHeapAllocsObjects = "/gc/heap/allocs:objects" | |||||
goGCHeapFreesObjects = "/gc/heap/frees:objects" | |||||
goGCHeapAllocsBytes = "/gc/heap/allocs:bytes" | |||||
goGCHeapObjects = "/gc/heap/objects:objects" | |||||
goGCHeapGoalBytes = "/gc/heap/goal:bytes" | |||||
goMemoryClassesTotalBytes = "/memory/classes/total:bytes" | |||||
goMemoryClassesHeapObjectsBytes = "/memory/classes/heap/objects:bytes" | |||||
goMemoryClassesHeapUnusedBytes = "/memory/classes/heap/unused:bytes" | |||||
goMemoryClassesHeapReleasedBytes = "/memory/classes/heap/released:bytes" | |||||
goMemoryClassesHeapFreeBytes = "/memory/classes/heap/free:bytes" | |||||
goMemoryClassesHeapStacksBytes = "/memory/classes/heap/stacks:bytes" | |||||
goMemoryClassesOSStacksBytes = "/memory/classes/os-stacks:bytes" | |||||
goMemoryClassesMetadataMSpanInuseBytes = "/memory/classes/metadata/mspan/inuse:bytes" | |||||
goMemoryClassesMetadataMSPanFreeBytes = "/memory/classes/metadata/mspan/free:bytes" | |||||
goMemoryClassesMetadataMCacheInuseBytes = "/memory/classes/metadata/mcache/inuse:bytes" | |||||
goMemoryClassesMetadataMCacheFreeBytes = "/memory/classes/metadata/mcache/free:bytes" | |||||
goMemoryClassesProfilingBucketsBytes = "/memory/classes/profiling/buckets:bytes" | |||||
goMemoryClassesMetadataOtherBytes = "/memory/classes/metadata/other:bytes" | |||||
goMemoryClassesOtherBytes = "/memory/classes/other:bytes" | |||||
) | ) | ||||
// runtime/metrics names required for runtimeMemStats like logic. | |||||
var rmForMemStats = []string{goGCHeapTinyAllocsObjects, | |||||
goGCHeapAllocsObjects, | |||||
goGCHeapFreesObjects, | |||||
goGCHeapAllocsBytes, | |||||
goGCHeapObjects, | |||||
goGCHeapGoalBytes, | |||||
goMemoryClassesTotalBytes, | |||||
goMemoryClassesHeapObjectsBytes, | |||||
goMemoryClassesHeapUnusedBytes, | |||||
goMemoryClassesHeapReleasedBytes, | |||||
goMemoryClassesHeapFreeBytes, | |||||
goMemoryClassesHeapStacksBytes, | |||||
goMemoryClassesOSStacksBytes, | |||||
goMemoryClassesMetadataMSpanInuseBytes, | |||||
goMemoryClassesMetadataMSPanFreeBytes, | |||||
goMemoryClassesMetadataMCacheInuseBytes, | |||||
goMemoryClassesMetadataMCacheFreeBytes, | |||||
goMemoryClassesProfilingBucketsBytes, | |||||
goMemoryClassesMetadataOtherBytes, | |||||
goMemoryClassesOtherBytes, | |||||
} | |||||
func bestEffortLookupRM(lookup []string) []metrics.Description { | |||||
ret := make([]metrics.Description, 0, len(lookup)) | |||||
for _, rm := range metrics.All() { | |||||
for _, m := range lookup { | |||||
if m == rm.Name { | |||||
ret = append(ret, rm) | |||||
} | |||||
} | |||||
} | |||||
return ret | |||||
} | |||||
type goCollector struct { | type goCollector struct { | ||||
opt GoCollectorOptions | |||||
base baseGoCollector | base baseGoCollector | ||||
// mu protects updates to all fields ensuring a consistent | // mu protects updates to all fields ensuring a consistent | ||||
@@ -51,12 +111,46 @@ type goCollector struct { | |||||
msMetrics memStatsMetrics | msMetrics memStatsMetrics | ||||
} | } | ||||
const ( | |||||
// Those are not exposed due to need to move Go collector to another package in v2. | |||||
// See issue https://github.com/prometheus/client_golang/issues/1030. | |||||
goRuntimeMemStatsCollection uint32 = 1 << iota | |||||
goRuntimeMetricsCollection | |||||
) | |||||
// GoCollectorOptions should not be used be directly by anything, except `collectors` package. | |||||
// Use it via collectors package instead. See issue | |||||
// https://github.com/prometheus/client_golang/issues/1030. | |||||
// | |||||
// Deprecated: Use collectors.WithGoCollections | |||||
type GoCollectorOptions struct { | |||||
// EnabledCollection sets what type of collections collector should expose on top of base collection. | |||||
// By default it's goMemStatsCollection | goRuntimeMetricsCollection. | |||||
EnabledCollections uint32 | |||||
} | |||||
func (c GoCollectorOptions) isEnabled(flag uint32) bool { | |||||
return c.EnabledCollections&flag != 0 | |||||
} | |||||
const defaultGoCollections = goRuntimeMemStatsCollection | |||||
// NewGoCollector is the obsolete version of collectors.NewGoCollector. | // NewGoCollector is the obsolete version of collectors.NewGoCollector. | ||||
// See there for documentation. | // See there for documentation. | ||||
// | // | ||||
// Deprecated: Use collectors.NewGoCollector instead. | // Deprecated: Use collectors.NewGoCollector instead. | ||||
func NewGoCollector() Collector { | |||||
descriptions := metrics.All() | |||||
func NewGoCollector(opts ...func(o *GoCollectorOptions)) Collector { | |||||
opt := GoCollectorOptions{EnabledCollections: defaultGoCollections} | |||||
for _, o := range opts { | |||||
o(&opt) | |||||
} | |||||
var descriptions []metrics.Description | |||||
if opt.isEnabled(goRuntimeMetricsCollection) { | |||||
descriptions = metrics.All() | |||||
} else if opt.isEnabled(goRuntimeMemStatsCollection) { | |||||
descriptions = bestEffortLookupRM(rmForMemStats) | |||||
} | |||||
// Collect all histogram samples so that we can get their buckets. | // Collect all histogram samples so that we can get their buckets. | ||||
// The API guarantees that the buckets are always fixed for the lifetime | // The API guarantees that the buckets are always fixed for the lifetime | ||||
@@ -67,7 +161,11 @@ func NewGoCollector() Collector { | |||||
histograms = append(histograms, metrics.Sample{Name: d.Name}) | histograms = append(histograms, metrics.Sample{Name: d.Name}) | ||||
} | } | ||||
} | } | ||||
metrics.Read(histograms) | |||||
if len(histograms) > 0 { | |||||
metrics.Read(histograms) | |||||
} | |||||
bucketsMap := make(map[string][]float64) | bucketsMap := make(map[string][]float64) | ||||
for i := range histograms { | for i := range histograms { | ||||
bucketsMap[histograms[i].Name] = histograms[i].Value.Float64Histogram().Buckets | bucketsMap[histograms[i].Name] = histograms[i].Value.Float64Histogram().Buckets | ||||
@@ -83,7 +181,7 @@ func NewGoCollector() Collector { | |||||
if !ok { | if !ok { | ||||
// Just ignore this metric; we can't do anything with it here. | // Just ignore this metric; we can't do anything with it here. | ||||
// If a user decides to use the latest version of Go, we don't want | // If a user decides to use the latest version of Go, we don't want | ||||
// to fail here. This condition is tested elsewhere. | |||||
// to fail here. This condition is tested in TestExpectedRuntimeMetrics. | |||||
continue | continue | ||||
} | } | ||||
@@ -123,12 +221,18 @@ func NewGoCollector() Collector { | |||||
} | } | ||||
metricSet = append(metricSet, m) | metricSet = append(metricSet, m) | ||||
} | } | ||||
var msMetrics memStatsMetrics | |||||
if opt.isEnabled(goRuntimeMemStatsCollection) { | |||||
msMetrics = goRuntimeMemStats() | |||||
} | |||||
return &goCollector{ | return &goCollector{ | ||||
opt: opt, | |||||
base: newBaseGoCollector(), | base: newBaseGoCollector(), | ||||
rmSampleBuf: sampleBuf, | rmSampleBuf: sampleBuf, | ||||
rmSampleMap: sampleMap, | rmSampleMap: sampleMap, | ||||
rmMetrics: metricSet, | rmMetrics: metricSet, | ||||
msMetrics: goRuntimeMemStats(), | |||||
msMetrics: msMetrics, | |||||
} | } | ||||
} | } | ||||
@@ -163,40 +267,47 @@ func (c *goCollector) Collect(ch chan<- Metric) { | |||||
c.mu.Lock() | c.mu.Lock() | ||||
defer c.mu.Unlock() | defer c.mu.Unlock() | ||||
// Populate runtime/metrics sample buffer. | |||||
metrics.Read(c.rmSampleBuf) | |||||
// Update all our metrics from rmSampleBuf. | |||||
for i, sample := range c.rmSampleBuf { | |||||
// N.B. switch on concrete type because it's significantly more efficient | |||||
// than checking for the Counter and Gauge interface implementations. In | |||||
// this case, we control all the types here. | |||||
switch m := c.rmMetrics[i].(type) { | |||||
case *counter: | |||||
// Guard against decreases. This should never happen, but a failure | |||||
// to do so will result in a panic, which is a harsh consequence for | |||||
// a metrics collection bug. | |||||
v0, v1 := m.get(), unwrapScalarRMValue(sample.Value) | |||||
if v1 > v0 { | |||||
m.Add(unwrapScalarRMValue(sample.Value) - m.get()) | |||||
if len(c.rmSampleBuf) > 0 { | |||||
// Populate runtime/metrics sample buffer. | |||||
metrics.Read(c.rmSampleBuf) | |||||
} | |||||
if c.opt.isEnabled(goRuntimeMetricsCollection) { | |||||
// Collect all our metrics from rmSampleBuf. | |||||
for i, sample := range c.rmSampleBuf { | |||||
// N.B. switch on concrete type because it's significantly more efficient | |||||
// than checking for the Counter and Gauge interface implementations. In | |||||
// this case, we control all the types here. | |||||
switch m := c.rmMetrics[i].(type) { | |||||
case *counter: | |||||
// Guard against decreases. This should never happen, but a failure | |||||
// to do so will result in a panic, which is a harsh consequence for | |||||
// a metrics collection bug. | |||||
v0, v1 := m.get(), unwrapScalarRMValue(sample.Value) | |||||
if v1 > v0 { | |||||
m.Add(unwrapScalarRMValue(sample.Value) - m.get()) | |||||
} | |||||
m.Collect(ch) | |||||
case *gauge: | |||||
m.Set(unwrapScalarRMValue(sample.Value)) | |||||
m.Collect(ch) | |||||
case *batchHistogram: | |||||
m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name)) | |||||
m.Collect(ch) | |||||
default: | |||||
panic("unexpected metric type") | |||||
} | } | ||||
m.Collect(ch) | |||||
case *gauge: | |||||
m.Set(unwrapScalarRMValue(sample.Value)) | |||||
m.Collect(ch) | |||||
case *batchHistogram: | |||||
m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name)) | |||||
m.Collect(ch) | |||||
default: | |||||
panic("unexpected metric type") | |||||
} | } | ||||
} | } | ||||
// ms is a dummy MemStats that we populate ourselves so that we can | // ms is a dummy MemStats that we populate ourselves so that we can | ||||
// populate the old metrics from it. | |||||
var ms runtime.MemStats | |||||
memStatsFromRM(&ms, c.rmSampleMap) | |||||
for _, i := range c.msMetrics { | |||||
ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms)) | |||||
// populate the old metrics from it if goMemStatsCollection is enabled. | |||||
if c.opt.isEnabled(goRuntimeMemStatsCollection) { | |||||
var ms runtime.MemStats | |||||
memStatsFromRM(&ms, c.rmSampleMap) | |||||
for _, i := range c.msMetrics { | |||||
ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms)) | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -261,35 +372,30 @@ func memStatsFromRM(ms *runtime.MemStats, rm map[string]*metrics.Sample) { | |||||
// while having Mallocs - Frees still represent a live object count. | // while having Mallocs - Frees still represent a live object count. | ||||
// Unfortunately, MemStats doesn't actually export a large allocation count, | // Unfortunately, MemStats doesn't actually export a large allocation count, | ||||
// so it's impossible to pull this number out directly. | // so it's impossible to pull this number out directly. | ||||
tinyAllocs := lookupOrZero("/gc/heap/tiny/allocs:objects") | |||||
ms.Mallocs = lookupOrZero("/gc/heap/allocs:objects") + tinyAllocs | |||||
ms.Frees = lookupOrZero("/gc/heap/frees:objects") + tinyAllocs | |||||
tinyAllocs := lookupOrZero(goGCHeapTinyAllocsObjects) | |||||
ms.Mallocs = lookupOrZero(goGCHeapAllocsObjects) + tinyAllocs | |||||
ms.Frees = lookupOrZero(goGCHeapFreesObjects) + tinyAllocs | |||||
ms.TotalAlloc = lookupOrZero("/gc/heap/allocs:bytes") | |||||
ms.Sys = lookupOrZero("/memory/classes/total:bytes") | |||||
ms.TotalAlloc = lookupOrZero(goGCHeapAllocsBytes) | |||||
ms.Sys = lookupOrZero(goMemoryClassesTotalBytes) | |||||
ms.Lookups = 0 // Already always zero. | ms.Lookups = 0 // Already always zero. | ||||
ms.HeapAlloc = lookupOrZero("/memory/classes/heap/objects:bytes") | |||||
ms.HeapAlloc = lookupOrZero(goMemoryClassesHeapObjectsBytes) | |||||
ms.Alloc = ms.HeapAlloc | ms.Alloc = ms.HeapAlloc | ||||
ms.HeapInuse = ms.HeapAlloc + lookupOrZero("/memory/classes/heap/unused:bytes") | |||||
ms.HeapReleased = lookupOrZero("/memory/classes/heap/released:bytes") | |||||
ms.HeapIdle = ms.HeapReleased + lookupOrZero("/memory/classes/heap/free:bytes") | |||||
ms.HeapInuse = ms.HeapAlloc + lookupOrZero(goMemoryClassesHeapUnusedBytes) | |||||
ms.HeapReleased = lookupOrZero(goMemoryClassesHeapReleasedBytes) | |||||
ms.HeapIdle = ms.HeapReleased + lookupOrZero(goMemoryClassesHeapFreeBytes) | |||||
ms.HeapSys = ms.HeapInuse + ms.HeapIdle | ms.HeapSys = ms.HeapInuse + ms.HeapIdle | ||||
ms.HeapObjects = lookupOrZero("/gc/heap/objects:objects") | |||||
ms.StackInuse = lookupOrZero("/memory/classes/heap/stacks:bytes") | |||||
ms.StackSys = ms.StackInuse + lookupOrZero("/memory/classes/os-stacks:bytes") | |||||
ms.MSpanInuse = lookupOrZero("/memory/classes/metadata/mspan/inuse:bytes") | |||||
ms.MSpanSys = ms.MSpanInuse + lookupOrZero("/memory/classes/metadata/mspan/free:bytes") | |||||
ms.MCacheInuse = lookupOrZero("/memory/classes/metadata/mcache/inuse:bytes") | |||||
ms.MCacheSys = ms.MCacheInuse + lookupOrZero("/memory/classes/metadata/mcache/free:bytes") | |||||
ms.BuckHashSys = lookupOrZero("/memory/classes/profiling/buckets:bytes") | |||||
ms.GCSys = lookupOrZero("/memory/classes/metadata/other:bytes") | |||||
ms.OtherSys = lookupOrZero("/memory/classes/other:bytes") | |||||
ms.NextGC = lookupOrZero("/gc/heap/goal:bytes") | |||||
// N.B. LastGC is omitted because runtime.GCStats already has this. | |||||
// See https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 | |||||
// for more details. | |||||
ms.LastGC = 0 | |||||
ms.HeapObjects = lookupOrZero(goGCHeapObjects) | |||||
ms.StackInuse = lookupOrZero(goMemoryClassesHeapStacksBytes) | |||||
ms.StackSys = ms.StackInuse + lookupOrZero(goMemoryClassesOSStacksBytes) | |||||
ms.MSpanInuse = lookupOrZero(goMemoryClassesMetadataMSpanInuseBytes) | |||||
ms.MSpanSys = ms.MSpanInuse + lookupOrZero(goMemoryClassesMetadataMSPanFreeBytes) | |||||
ms.MCacheInuse = lookupOrZero(goMemoryClassesMetadataMCacheInuseBytes) | |||||
ms.MCacheSys = ms.MCacheInuse + lookupOrZero(goMemoryClassesMetadataMCacheFreeBytes) | |||||
ms.BuckHashSys = lookupOrZero(goMemoryClassesProfilingBucketsBytes) | |||||
ms.GCSys = lookupOrZero(goMemoryClassesMetadataOtherBytes) | |||||
ms.OtherSys = lookupOrZero(goMemoryClassesOtherBytes) | |||||
ms.NextGC = lookupOrZero(goGCHeapGoalBytes) | |||||
// N.B. GCCPUFraction is intentionally omitted. This metric is not useful, | // N.B. GCCPUFraction is intentionally omitted. This metric is not useful, | ||||
// and often misleading due to the fact that it's an average over the lifetime | // and often misleading due to the fact that it's an average over the lifetime | ||||
@@ -324,6 +430,11 @@ type batchHistogram struct { | |||||
// buckets must always be from the runtime/metrics package, following | // buckets must always be from the runtime/metrics package, following | ||||
// the same conventions. | // the same conventions. | ||||
func newBatchHistogram(desc *Desc, buckets []float64, hasSum bool) *batchHistogram { | func newBatchHistogram(desc *Desc, buckets []float64, hasSum bool) *batchHistogram { | ||||
// We need to remove -Inf values. runtime/metrics keeps them around. | |||||
// But -Inf bucket should not be allowed for prometheus histograms. | |||||
if buckets[0] == math.Inf(-1) { | |||||
buckets = buckets[1:] | |||||
} | |||||
h := &batchHistogram{ | h := &batchHistogram{ | ||||
desc: desc, | desc: desc, | ||||
buckets: buckets, | buckets: buckets, | ||||
@@ -382,8 +493,10 @@ func (h *batchHistogram) Write(out *dto.Metric) error { | |||||
for i, count := range h.counts { | for i, count := range h.counts { | ||||
totalCount += count | totalCount += count | ||||
if !h.hasSum { | if !h.hasSum { | ||||
// N.B. This computed sum is an underestimate. | |||||
sum += h.buckets[i] * float64(count) | |||||
if count != 0 { | |||||
// N.B. This computed sum is an underestimate. | |||||
sum += h.buckets[i] * float64(count) | |||||
} | |||||
} | } | ||||
// Skip the +Inf bucket, but only for the bucket list. | // Skip the +Inf bucket, but only for the bucket list. |
@@ -62,7 +62,7 @@ func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) | |||||
// other data. | // other data. | ||||
name = strings.ReplaceAll(name, "-", "_") | name = strings.ReplaceAll(name, "-", "_") | ||||
name = name + "_" + unit | name = name + "_" + unit | ||||
if d.Cumulative { | |||||
if d.Cumulative && d.Kind != metrics.KindFloat64Histogram { | |||||
name = name + "_total" | name = name + "_total" | ||||
} | } | ||||
@@ -84,12 +84,12 @@ func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) | |||||
func RuntimeMetricsBucketsForUnit(buckets []float64, unit string) []float64 { | func RuntimeMetricsBucketsForUnit(buckets []float64, unit string) []float64 { | ||||
switch unit { | switch unit { | ||||
case "bytes": | case "bytes": | ||||
// Rebucket as powers of 2. | |||||
return rebucketExp(buckets, 2) | |||||
// Re-bucket as powers of 2. | |||||
return reBucketExp(buckets, 2) | |||||
case "seconds": | case "seconds": | ||||
// Rebucket as powers of 10 and then merge all buckets greater | |||||
// Re-bucket as powers of 10 and then merge all buckets greater | |||||
// than 1 second into the +Inf bucket. | // than 1 second into the +Inf bucket. | ||||
b := rebucketExp(buckets, 10) | |||||
b := reBucketExp(buckets, 10) | |||||
for i := range b { | for i := range b { | ||||
if b[i] <= 1 { | if b[i] <= 1 { | ||||
continue | continue | ||||
@@ -103,11 +103,11 @@ func RuntimeMetricsBucketsForUnit(buckets []float64, unit string) []float64 { | |||||
return buckets | return buckets | ||||
} | } | ||||
// rebucketExp takes a list of bucket boundaries (lower bound inclusive) and | |||||
// reBucketExp takes a list of bucket boundaries (lower bound inclusive) and | |||||
// downsamples the buckets to those a multiple of base apart. The end result | // downsamples the buckets to those a multiple of base apart. The end result | ||||
// is a roughly exponential (in many cases, perfectly exponential) bucketing | // is a roughly exponential (in many cases, perfectly exponential) bucketing | ||||
// scheme. | // scheme. | ||||
func rebucketExp(buckets []float64, base float64) []float64 { | |||||
func reBucketExp(buckets []float64, base float64) []float64 { | |||||
bucket := buckets[0] | bucket := buckets[0] | ||||
var newBuckets []float64 | var newBuckets []float64 | ||||
// We may see a -Inf here, in which case, add it and skip it | // We may see a -Inf here, in which case, add it and skip it | ||||
@@ -12,6 +12,7 @@ | |||||
// limitations under the License. | // limitations under the License. | ||||
// Build only when actually fuzzing | // Build only when actually fuzzing | ||||
//go:build gofuzz | |||||
// +build gofuzz | // +build gofuzz | ||||
package expfmt | package expfmt | ||||
@@ -22,7 +22,6 @@ import ( | |||||
"strconv" | "strconv" | ||||
"strings" | "strings" | ||||
"github.com/golang/protobuf/ptypes" | |||||
"github.com/prometheus/common/model" | "github.com/prometheus/common/model" | ||||
dto "github.com/prometheus/client_model/go" | dto "github.com/prometheus/client_model/go" | ||||
@@ -473,10 +472,11 @@ func writeExemplar(w enhancedWriter, e *dto.Exemplar) (int, error) { | |||||
if err != nil { | if err != nil { | ||||
return written, err | return written, err | ||||
} | } | ||||
ts, err := ptypes.Timestamp((*e).Timestamp) | |||||
err = (*e).Timestamp.CheckValid() | |||||
if err != nil { | if err != nil { | ||||
return written, err | return written, err | ||||
} | } | ||||
ts := (*e).Timestamp.AsTime() | |||||
// TODO(beorn7): Format this directly from components of ts to | // TODO(beorn7): Format this directly from components of ts to | ||||
// avoid overflow/underflow and precision issues of the float | // avoid overflow/underflow and precision issues of the float | ||||
// conversion. | // conversion. | ||||
@@ -193,7 +193,7 @@ func ParseDuration(durationStr string) (Duration, error) { | |||||
// Allow 0 without a unit. | // Allow 0 without a unit. | ||||
return 0, nil | return 0, nil | ||||
case "": | case "": | ||||
return 0, fmt.Errorf("empty duration string") | |||||
return 0, errors.New("empty duration string") | |||||
} | } | ||||
matches := durationRE.FindStringSubmatch(durationStr) | matches := durationRE.FindStringSubmatch(durationStr) | ||||
if matches == nil { | if matches == nil { | ||||
@@ -1 +1,2 @@ | |||||
/fixtures/ | |||||
/testdata/fixtures/ | |||||
/fixtures |
@@ -1,4 +1,12 @@ | |||||
--- | --- | ||||
linters: | linters: | ||||
enable: | enable: | ||||
- golint | |||||
- godot | |||||
- revive | |||||
linter-settings: | |||||
godot: | |||||
capital: true | |||||
exclude: | |||||
# Ignore "See: URL" | |||||
- 'See:' |
@@ -1,3 +1,3 @@ | |||||
## Prometheus Community Code of Conduct | |||||
# Prometheus Community Code of Conduct | |||||
Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). | |||||
Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). |
@@ -97,7 +97,7 @@ Many of the files are changing continuously and the data being read can in some | |||||
reads in the same file. Also, most of the files are relatively small (less than a few KBs), and system calls | reads in the same file. Also, most of the files are relatively small (less than a few KBs), and system calls | ||||
to the `stat` function will often return the wrong size. Therefore, for most files it's recommended to read the | to the `stat` function will often return the wrong size. Therefore, for most files it's recommended to read the | ||||
full file in a single operation using an internal utility function called `util.ReadFileNoStat`. | full file in a single operation using an internal utility function called `util.ReadFileNoStat`. | ||||
This function is similar to `ioutil.ReadFile`, but it avoids the system call to `stat` to get the current size of | |||||
This function is similar to `os.ReadFile`, but it avoids the system call to `stat` to get the current size of | |||||
the file. | the file. | ||||
Note that parsing the file's contents can still be performed one line at a time. This is done by first reading | Note that parsing the file's contents can still be performed one line at a time. This is done by first reading | ||||
@@ -113,7 +113,7 @@ the full file, and then using a scanner on the `[]byte` or `string` containing t | |||||
``` | ``` | ||||
The `/sys` filesystem contains many very small files which contain only a single numeric or text value. These files | The `/sys` filesystem contains many very small files which contain only a single numeric or text value. These files | ||||
can be read using an internal function called `util.SysReadFile` which is similar to `ioutil.ReadFile` but does | |||||
can be read using an internal function called `util.SysReadFile` which is similar to `os.ReadFile` but does | |||||
not bother to check the size of the file before reading. | not bother to check the size of the file before reading. | ||||
``` | ``` | ||||
data, err := util.SysReadFile("/sys/class/power_supply/BAT0/capacity") | data, err := util.SysReadFile("/sys/class/power_supply/BAT0/capacity") | ||||
@@ -14,18 +14,18 @@ | |||||
include Makefile.common | include Makefile.common | ||||
%/.unpacked: %.ttar | %/.unpacked: %.ttar | ||||
@echo ">> extracting fixtures" | |||||
@echo ">> extracting fixtures $*" | |||||
./ttar -C $(dir $*) -x -f $*.ttar | ./ttar -C $(dir $*) -x -f $*.ttar | ||||
touch $@ | touch $@ | ||||
fixtures: fixtures/.unpacked | |||||
fixtures: testdata/fixtures/.unpacked | |||||
update_fixtures: | update_fixtures: | ||||
rm -vf fixtures/.unpacked | |||||
./ttar -c -f fixtures.ttar fixtures/ | |||||
rm -vf testdata/fixtures/.unpacked | |||||
./ttar -c -f testdata/fixtures.ttar -C testdata/ fixtures/ | |||||
.PHONY: build | .PHONY: build | ||||
build: | build: | ||||
.PHONY: test | .PHONY: test | ||||
test: fixtures/.unpacked common-test | |||||
test: testdata/fixtures/.unpacked common-test |
@@ -36,29 +36,6 @@ GO_VERSION ?= $(shell $(GO) version) | |||||
GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) | GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) | ||||
PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') | PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') | ||||
GOVENDOR := | |||||
GO111MODULE := | |||||
ifeq (, $(PRE_GO_111)) | |||||
ifneq (,$(wildcard go.mod)) | |||||
# Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI). | |||||
GO111MODULE := on | |||||
ifneq (,$(wildcard vendor)) | |||||
# Always use the local vendor/ directory to satisfy the dependencies. | |||||
GOOPTS := $(GOOPTS) -mod=vendor | |||||
endif | |||||
endif | |||||
else | |||||
ifneq (,$(wildcard go.mod)) | |||||
ifneq (,$(wildcard vendor)) | |||||
$(warning This repository requires Go >= 1.11 because of Go modules) | |||||
$(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)') | |||||
endif | |||||
else | |||||
# This repository isn't using Go modules (yet). | |||||
GOVENDOR := $(FIRST_GOPATH)/bin/govendor | |||||
endif | |||||
endif | |||||
PROMU := $(FIRST_GOPATH)/bin/promu | PROMU := $(FIRST_GOPATH)/bin/promu | ||||
pkgs = ./... | pkgs = ./... | ||||
@@ -78,17 +55,23 @@ ifneq ($(shell which gotestsum),) | |||||
endif | endif | ||||
endif | endif | ||||
PROMU_VERSION ?= 0.12.0 | |||||
PROMU_VERSION ?= 0.13.0 | |||||
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz | PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz | ||||
GOLANGCI_LINT := | GOLANGCI_LINT := | ||||
GOLANGCI_LINT_OPTS ?= | GOLANGCI_LINT_OPTS ?= | ||||
GOLANGCI_LINT_VERSION ?= v1.39.0 | |||||
GOLANGCI_LINT_VERSION ?= v1.45.2 | |||||
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64. | # golangci-lint only supports linux, darwin and windows platforms on i386/amd64. | ||||
# windows isn't included here because of the path separator being different. | # windows isn't included here because of the path separator being different. | ||||
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) | ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) | ||||
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386)) | ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386)) | ||||
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint | |||||
# If we're in CI and there is an Actions file, that means the linter | |||||
# is being run in Actions, so we don't need to run it here. | |||||
ifeq (,$(CIRCLE_JOB)) | |||||
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint | |||||
else ifeq (,$(wildcard .github/workflows/golangci-lint.yml)) | |||||
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint | |||||
endif | |||||
endif | endif | ||||
endif | endif | ||||
@@ -144,32 +127,25 @@ common-check_license: | |||||
.PHONY: common-deps | .PHONY: common-deps | ||||
common-deps: | common-deps: | ||||
@echo ">> getting dependencies" | @echo ">> getting dependencies" | ||||
ifdef GO111MODULE | |||||
GO111MODULE=$(GO111MODULE) $(GO) mod download | |||||
else | |||||
$(GO) get $(GOOPTS) -t ./... | |||||
endif | |||||
$(GO) mod download | |||||
.PHONY: update-go-deps | .PHONY: update-go-deps | ||||
update-go-deps: | update-go-deps: | ||||
@echo ">> updating Go dependencies" | @echo ">> updating Go dependencies" | ||||
@for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ | @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ | ||||
$(GO) get $$m; \ | |||||
$(GO) get -d $$m; \ | |||||
done | done | ||||
GO111MODULE=$(GO111MODULE) $(GO) mod tidy | |||||
ifneq (,$(wildcard vendor)) | |||||
GO111MODULE=$(GO111MODULE) $(GO) mod vendor | |||||
endif | |||||
$(GO) mod tidy | |||||
.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" | ||||
GO111MODULE=$(GO111MODULE) $(GOTEST) -short $(GOOPTS) $(pkgs) | |||||
$(GOTEST) -short $(GOOPTS) $(pkgs) | |||||
.PHONY: common-test | .PHONY: common-test | ||||
common-test: $(GOTEST_DIR) | common-test: $(GOTEST_DIR) | ||||
@echo ">> running all tests" | @echo ">> running all tests" | ||||
GO111MODULE=$(GO111MODULE) $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) | |||||
$(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) | |||||
$(GOTEST_DIR): | $(GOTEST_DIR): | ||||
@mkdir -p $@ | @mkdir -p $@ | ||||
@@ -177,25 +153,21 @@ $(GOTEST_DIR): | |||||
.PHONY: common-format | .PHONY: common-format | ||||
common-format: | common-format: | ||||
@echo ">> formatting code" | @echo ">> formatting code" | ||||
GO111MODULE=$(GO111MODULE) $(GO) fmt $(pkgs) | |||||
$(GO) fmt $(pkgs) | |||||
.PHONY: common-vet | .PHONY: common-vet | ||||
common-vet: | common-vet: | ||||
@echo ">> vetting code" | @echo ">> vetting code" | ||||
GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs) | |||||
$(GO) vet $(GOOPTS) $(pkgs) | |||||
.PHONY: common-lint | .PHONY: common-lint | ||||
common-lint: $(GOLANGCI_LINT) | common-lint: $(GOLANGCI_LINT) | ||||
ifdef GOLANGCI_LINT | ifdef GOLANGCI_LINT | ||||
@echo ">> running golangci-lint" | @echo ">> running golangci-lint" | ||||
ifdef GO111MODULE | |||||
# 'go list' needs to be executed before staticcheck to prepopulate the modules cache. | # 'go list' needs to be executed before staticcheck to prepopulate the modules cache. | ||||
# Otherwise staticcheck might fail randomly for some reason not yet explained. | # Otherwise staticcheck might fail randomly for some reason not yet explained. | ||||
GO111MODULE=$(GO111MODULE) $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null | |||||
GO111MODULE=$(GO111MODULE) $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) | |||||
else | |||||
$(GOLANGCI_LINT) run $(pkgs) | |||||
endif | |||||
$(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null | |||||
$(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) | |||||
endif | endif | ||||
.PHONY: common-yamllint | .PHONY: common-yamllint | ||||
@@ -212,28 +184,15 @@ endif | |||||
common-staticcheck: lint | common-staticcheck: lint | ||||
.PHONY: common-unused | .PHONY: common-unused | ||||
common-unused: $(GOVENDOR) | |||||
ifdef GOVENDOR | |||||
@echo ">> running check for unused packages" | |||||
@$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages' | |||||
else | |||||
ifdef GO111MODULE | |||||
common-unused: | |||||
@echo ">> running check for unused/missing packages in go.mod" | @echo ">> running check for unused/missing packages in go.mod" | ||||
GO111MODULE=$(GO111MODULE) $(GO) mod tidy | |||||
ifeq (,$(wildcard vendor)) | |||||
$(GO) mod tidy | |||||
@git diff --exit-code -- go.sum go.mod | @git diff --exit-code -- go.sum go.mod | ||||
else | |||||
@echo ">> running check for unused packages in vendor/" | |||||
GO111MODULE=$(GO111MODULE) $(GO) mod vendor | |||||
@git diff --exit-code -- go.sum go.mod vendor/ | |||||
endif | |||||
endif | |||||
endif | |||||
.PHONY: common-build | .PHONY: common-build | ||||
common-build: promu | common-build: promu | ||||
@echo ">> building binaries" | @echo ">> building binaries" | ||||
GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) | |||||
$(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) | |||||
.PHONY: common-tarball | .PHONY: common-tarball | ||||
common-tarball: promu | common-tarball: promu | ||||
@@ -289,12 +248,6 @@ $(GOLANGCI_LINT): | |||||
| sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) | | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) | ||||
endif | endif | ||||
ifdef GOVENDOR | |||||
.PHONY: $(GOVENDOR) | |||||
$(GOVENDOR): | |||||
GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor | |||||
endif | |||||
.PHONY: precheck | .PHONY: precheck | ||||
precheck:: | precheck:: | ||||
@@ -3,4 +3,4 @@ | |||||
The Prometheus security policy, including how to report vulnerabilities, can be | The Prometheus security policy, including how to report vulnerabilities, can be | ||||
found here: | found here: | ||||
https://prometheus.io/docs/operating/security/ | |||||
<https://prometheus.io/docs/operating/security/> |
@@ -15,11 +15,28 @@ package procfs | |||||
import ( | import ( | ||||
"fmt" | "fmt" | ||||
"io/ioutil" | |||||
"net" | "net" | ||||
"os" | |||||
"strconv" | |||||
"strings" | "strings" | ||||
) | ) | ||||
// Learned from include/uapi/linux/if_arp.h. | |||||
const ( | |||||
// completed entry (ha valid). | |||||
ATFComplete = 0x02 | |||||
// permanent entry. | |||||
ATFPermanent = 0x04 | |||||
// Publish entry. | |||||
ATFPublish = 0x08 | |||||
// Has requested trailers. | |||||
ATFUseTrailers = 0x10 | |||||
// Obsoleted: Want to use a netmask (only for proxy entries). | |||||
ATFNetmask = 0x20 | |||||
// Don't answer this addresses. | |||||
ATFDontPublish = 0x40 | |||||
) | |||||
// ARPEntry contains a single row of the columnar data represented in | // ARPEntry contains a single row of the columnar data represented in | ||||
// /proc/net/arp. | // /proc/net/arp. | ||||
type ARPEntry struct { | type ARPEntry struct { | ||||
@@ -29,12 +46,14 @@ type ARPEntry struct { | |||||
HWAddr net.HardwareAddr | HWAddr net.HardwareAddr | ||||
// Name of the device | // Name of the device | ||||
Device string | Device string | ||||
// Flags | |||||
Flags byte | |||||
} | } | ||||
// GatherARPEntries retrieves all the ARP entries, parse the relevant columns, | // GatherARPEntries retrieves all the ARP entries, parse the relevant columns, | ||||
// and then return a slice of ARPEntry's. | // and then return a slice of ARPEntry's. | ||||
func (fs FS) GatherARPEntries() ([]ARPEntry, error) { | func (fs FS) GatherARPEntries() ([]ARPEntry, error) { | ||||
data, err := ioutil.ReadFile(fs.proc.Path("net/arp")) | |||||
data, err := os.ReadFile(fs.proc.Path("net/arp")) | |||||
if err != nil { | if err != nil { | ||||
return nil, fmt.Errorf("error reading arp %q: %w", fs.proc.Path("net/arp"), err) | return nil, fmt.Errorf("error reading arp %q: %w", fs.proc.Path("net/arp"), err) | ||||
} | } | ||||
@@ -72,14 +91,26 @@ func parseARPEntries(data []byte) ([]ARPEntry, error) { | |||||
} | } | ||||
func parseARPEntry(columns []string) (ARPEntry, error) { | func parseARPEntry(columns []string) (ARPEntry, error) { | ||||
entry := ARPEntry{Device: columns[5]} | |||||
ip := net.ParseIP(columns[0]) | ip := net.ParseIP(columns[0]) | ||||
mac := net.HardwareAddr(columns[3]) | |||||
entry.IPAddr = ip | |||||
if mac, err := net.ParseMAC(columns[3]); err == nil { | |||||
entry.HWAddr = mac | |||||
} else { | |||||
return ARPEntry{}, err | |||||
} | |||||
entry := ARPEntry{ | |||||
IPAddr: ip, | |||||
HWAddr: mac, | |||||
Device: columns[5], | |||||
if flags, err := strconv.ParseUint(columns[2], 0, 8); err == nil { | |||||
entry.Flags = byte(flags) | |||||
} else { | |||||
return ARPEntry{}, err | |||||
} | } | ||||
return entry, nil | return entry, nil | ||||
} | } | ||||
// IsComplete returns true if ARP entry is marked with complete flag. | |||||
func (entry *ARPEntry) IsComplete() bool { | |||||
return entry.Flags&ATFComplete != 0 | |||||
} |
@@ -11,6 +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. | ||||
//go:build linux | |||||
// +build linux | // +build linux | ||||
package procfs | package procfs | ||||
@@ -27,7 +28,7 @@ import ( | |||||
"github.com/prometheus/procfs/internal/util" | "github.com/prometheus/procfs/internal/util" | ||||
) | ) | ||||
// CPUInfo contains general information about a system CPU found in /proc/cpuinfo | |||||
// CPUInfo contains general information about a system CPU found in /proc/cpuinfo. | |||||
type CPUInfo struct { | type CPUInfo struct { | ||||
Processor uint | Processor uint | ||||
VendorID string | VendorID string | ||||
@@ -469,7 +470,7 @@ func parseCPUInfoDummy(_ []byte) ([]CPUInfo, error) { // nolint:unused,deadcode | |||||
} | } | ||||
// firstNonEmptyLine advances the scanner to the first non-empty line | // firstNonEmptyLine advances the scanner to the first non-empty line | ||||
// and returns the contents of that line | |||||
// and returns the contents of that line. | |||||
func firstNonEmptyLine(scanner *bufio.Scanner) string { | func firstNonEmptyLine(scanner *bufio.Scanner) string { | ||||
for scanner.Scan() { | for scanner.Scan() { | ||||
line := scanner.Text() | line := scanner.Text() | ||||
@@ -11,6 +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. | ||||
//go:build linux && (arm || arm64) | |||||
// +build linux | // +build linux | ||||
// +build arm arm64 | // +build arm arm64 | ||||
@@ -11,6 +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. | ||||
//go:build linux && (mips || mipsle || mips64 || mips64le) | |||||
// +build linux | // +build linux | ||||
// +build mips mipsle mips64 mips64le | // +build mips mipsle mips64 mips64le | ||||
@@ -11,8 +11,8 @@ | |||||
// 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 | |||||
// +build !386,!amd64,!arm,!arm64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x | |||||
//go:build linux && !386 && !amd64 && !arm && !arm64 && !mips && !mips64 && !mips64le && !mipsle && !ppc64 && !ppc64le && !riscv64 && !s390x | |||||
// +build linux,!386,!amd64,!arm,!arm64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x | |||||
package procfs | package procfs | ||||
@@ -11,6 +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. | ||||
//go:build linux && (ppc64 || ppc64le) | |||||
// +build linux | // +build linux | ||||
// +build ppc64 ppc64le | // +build ppc64 ppc64le | ||||
@@ -11,6 +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. | ||||
//go:build linux && (riscv || riscv64) | |||||
// +build linux | // +build linux | ||||
// +build riscv riscv64 | // +build riscv riscv64 | ||||
@@ -11,6 +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. | ||||
//go:build linux | |||||
// +build linux | // +build linux | ||||
package procfs | package procfs | ||||
@@ -11,6 +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. | ||||
//go:build linux && (386 || amd64) | |||||
// +build linux | // +build linux | ||||
// +build 386 amd64 | // +build 386 amd64 | ||||
@@ -26,7 +26,7 @@ const ( | |||||
// DefaultSysMountPoint is the common mount point of the sys filesystem. | // DefaultSysMountPoint is the common mount point of the sys filesystem. | ||||
DefaultSysMountPoint = "/sys" | DefaultSysMountPoint = "/sys" | ||||
// DefaultConfigfsMountPoint is the common mount point of the configfs | |||||
// DefaultConfigfsMountPoint is the common mount point of the configfs. | |||||
DefaultConfigfsMountPoint = "/sys/kernel/config" | DefaultConfigfsMountPoint = "/sys/kernel/config" | ||||
) | ) | ||||
@@ -14,7 +14,7 @@ | |||||
package util | package util | ||||
import ( | import ( | ||||
"io/ioutil" | |||||
"os" | |||||
"strconv" | "strconv" | ||||
"strings" | "strings" | ||||
) | ) | ||||
@@ -66,7 +66,7 @@ func ParsePInt64s(ss []string) ([]*int64, error) { | |||||
// ReadUintFromFile reads a file and attempts to parse a uint64 from it. | // ReadUintFromFile reads a file and attempts to parse a uint64 from it. | ||||
func ReadUintFromFile(path string) (uint64, error) { | func ReadUintFromFile(path string) (uint64, error) { | ||||
data, err := ioutil.ReadFile(path) | |||||
data, err := os.ReadFile(path) | |||||
if err != nil { | if err != nil { | ||||
return 0, err | return 0, err | ||||
} | } | ||||
@@ -75,7 +75,7 @@ func ReadUintFromFile(path string) (uint64, error) { | |||||
// ReadIntFromFile reads a file and attempts to parse a int64 from it. | // ReadIntFromFile reads a file and attempts to parse a int64 from it. | ||||
func ReadIntFromFile(path string) (int64, error) { | func ReadIntFromFile(path string) (int64, error) { | ||||
data, err := ioutil.ReadFile(path) | |||||
data, err := os.ReadFile(path) | |||||
if err != nil { | if err != nil { | ||||
return 0, err | return 0, err | ||||
} | } | ||||
@@ -15,17 +15,16 @@ package util | |||||
import ( | import ( | ||||
"io" | "io" | ||||
"io/ioutil" | |||||
"os" | "os" | ||||
) | ) | ||||
// ReadFileNoStat uses ioutil.ReadAll to read contents of entire file. | |||||
// This is similar to ioutil.ReadFile but without the call to os.Stat, because | |||||
// ReadFileNoStat uses io.ReadAll to read contents of entire file. | |||||
// This is similar to os.ReadFile but without the call to os.Stat, because | |||||
// many files in /proc and /sys report incorrect file sizes (either 0 or 4096). | // many files in /proc and /sys report incorrect file sizes (either 0 or 4096). | ||||
// Reads a max file size of 512kB. For files larger than this, a scanner | |||||
// Reads a max file size of 1024kB. For files larger than this, a scanner | |||||
// should be used. | // should be used. | ||||
func ReadFileNoStat(filename string) ([]byte, error) { | func ReadFileNoStat(filename string) ([]byte, error) { | ||||
const maxBufferSize = 1024 * 512 | |||||
const maxBufferSize = 1024 * 1024 | |||||
f, err := os.Open(filename) | f, err := os.Open(filename) | ||||
if err != nil { | if err != nil { | ||||
@@ -34,5 +33,5 @@ func ReadFileNoStat(filename string) ([]byte, error) { | |||||
defer f.Close() | defer f.Close() | ||||
reader := io.LimitReader(f, maxBufferSize) | reader := io.LimitReader(f, maxBufferSize) | ||||
return ioutil.ReadAll(reader) | |||||
return io.ReadAll(reader) | |||||
} | } |
@@ -11,7 +11,9 @@ | |||||
// 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,!appengine | |||||
//go:build (linux || darwin) && !appengine | |||||
// +build linux darwin | |||||
// +build !appengine | |||||
package util | package util | ||||
@@ -21,7 +23,7 @@ import ( | |||||
"syscall" | "syscall" | ||||
) | ) | ||||
// SysReadFile is a simplified ioutil.ReadFile that invokes syscall.Read directly. | |||||
// SysReadFile is a simplified os.ReadFile that invokes syscall.Read directly. | |||||
// https://github.com/prometheus/node_exporter/pull/728/files | // https://github.com/prometheus/node_exporter/pull/728/files | ||||
// | // | ||||
// Note that this function will not read files larger than 128 bytes. | // Note that this function will not read files larger than 128 bytes. | ||||
@@ -33,7 +35,7 @@ func SysReadFile(file string) (string, error) { | |||||
defer f.Close() | defer f.Close() | ||||
// On some machines, hwmon drivers are broken and return EAGAIN. This causes | // On some machines, hwmon drivers are broken and return EAGAIN. This causes | ||||
// Go's ioutil.ReadFile implementation to poll forever. | |||||
// Go's os.ReadFile implementation to poll forever. | |||||
// | // | ||||
// Since we either want to read data or bail immediately, do the simplest | // Since we either want to read data or bail immediately, do the simplest | ||||
// possible read using syscall directly. | // possible read using syscall directly. | ||||
@@ -11,7 +11,8 @@ | |||||
// 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,appengine !linux | |||||
//go:build (linux && appengine) || (!linux && !darwin) | |||||
// +build linux,appengine !linux,!darwin | |||||
package util | package util | ||||
@@ -20,7 +20,6 @@ import ( | |||||
"errors" | "errors" | ||||
"fmt" | "fmt" | ||||
"io" | "io" | ||||
"io/ioutil" | |||||
"net" | "net" | ||||
"os" | "os" | ||||
"strconv" | "strconv" | ||||
@@ -84,7 +83,7 @@ func parseIPVSStats(r io.Reader) (IPVSStats, error) { | |||||
stats IPVSStats | stats IPVSStats | ||||
) | ) | ||||
statContent, err := ioutil.ReadAll(r) | |||||
statContent, err := io.ReadAll(r) | |||||
if err != nil { | if err != nil { | ||||
return IPVSStats{}, err | return IPVSStats{}, err | ||||
} | } | ||||
@@ -11,6 +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. | ||||
//go:build !windows | |||||
// +build !windows | // +build !windows | ||||
package procfs | package procfs | ||||
@@ -21,7 +21,7 @@ import ( | |||||
"github.com/prometheus/procfs/internal/util" | "github.com/prometheus/procfs/internal/util" | ||||
) | ) | ||||
// LoadAvg represents an entry in /proc/loadavg | |||||
// LoadAvg represents an entry in /proc/loadavg. | |||||
type LoadAvg struct { | type LoadAvg struct { | ||||
Load1 float64 | Load1 float64 | ||||
Load5 float64 | Load5 float64 | ||||
@@ -15,7 +15,7 @@ package procfs | |||||
import ( | import ( | ||||
"fmt" | "fmt" | ||||
"io/ioutil" | |||||
"os" | |||||
"regexp" | "regexp" | ||||
"strconv" | "strconv" | ||||
"strings" | "strings" | ||||
@@ -64,7 +64,7 @@ type MDStat struct { | |||||
// structs containing the relevant info. More information available here: | // structs containing the relevant info. More information available here: | ||||
// https://raid.wiki.kernel.org/index.php/Mdstat | // https://raid.wiki.kernel.org/index.php/Mdstat | ||||
func (fs FS) MDStat() ([]MDStat, error) { | func (fs FS) MDStat() ([]MDStat, error) { | ||||
data, err := ioutil.ReadFile(fs.proc.Path("mdstat")) | |||||
data, err := os.ReadFile(fs.proc.Path("mdstat")) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
@@ -166,8 +166,12 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { | |||||
} | } | ||||
func evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) { | func evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) { | ||||
statusFields := strings.Fields(statusLine) | |||||
if len(statusFields) < 1 { | |||||
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q", statusLine) | |||||
} | |||||
sizeStr := strings.Fields(statusLine)[0] | |||||
sizeStr := statusFields[0] | |||||
size, err = strconv.ParseInt(sizeStr, 10, 64) | size, err = strconv.ParseInt(sizeStr, 10, 64) | ||||
if err != nil { | if err != nil { | ||||
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) | return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) | ||||
@@ -25,7 +25,7 @@ import ( | |||||
) | ) | ||||
// A ConntrackStatEntry represents one line from net/stat/nf_conntrack | // A ConntrackStatEntry represents one line from net/stat/nf_conntrack | ||||
// and contains netfilter conntrack statistics at one CPU core | |||||
// and contains netfilter conntrack statistics at one CPU core. | |||||
type ConntrackStatEntry struct { | type ConntrackStatEntry struct { | ||||
Entries uint64 | Entries uint64 | ||||
Found uint64 | Found uint64 | ||||
@@ -38,12 +38,12 @@ type ConntrackStatEntry struct { | |||||
SearchRestart uint64 | SearchRestart uint64 | ||||
} | } | ||||
// ConntrackStat 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")) | ||||
} | } | ||||
// Parses a slice of ConntrackStatEntries from the given filepath | |||||
// Parses a slice of ConntrackStatEntries from the given filepath. | |||||
func readConntrackStat(path string) ([]ConntrackStatEntry, error) { | func readConntrackStat(path string) ([]ConntrackStatEntry, error) { | ||||
// This file is small and can be read with one syscall. | // This file is small and can be read with one syscall. | ||||
b, err := util.ReadFileNoStat(path) | b, err := util.ReadFileNoStat(path) | ||||
@@ -61,7 +61,7 @@ func readConntrackStat(path string) ([]ConntrackStatEntry, error) { | |||||
return stat, nil | return stat, nil | ||||
} | } | ||||
// Reads the contents of a conntrack statistics file and parses a slice of ConntrackStatEntries | |||||
// Reads the contents of a conntrack statistics file and parses a slice of ConntrackStatEntries. | |||||
func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) { | func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) { | ||||
var entries []ConntrackStatEntry | var entries []ConntrackStatEntry | ||||
@@ -79,7 +79,7 @@ func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) { | |||||
return entries, nil | return entries, nil | ||||
} | } | ||||
// Parses a ConntrackStatEntry from given array of fields | |||||
// Parses a ConntrackStatEntry from given array of fields. | |||||
func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) { | func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) { | ||||
if len(fields) != 17 { | if len(fields) != 17 { | ||||
return nil, fmt.Errorf("invalid conntrackstat entry, missing fields") | return nil, fmt.Errorf("invalid conntrackstat entry, missing fields") | ||||
@@ -143,7 +143,7 @@ func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) { | |||||
return entry, nil | return entry, nil | ||||
} | } | ||||
// Parses a uint64 from given hex in string | |||||
// Parses a uint64 from given hex in string. | |||||
func parseConntrackStatField(field string) (uint64, error) { | func parseConntrackStatField(field string) (uint64, error) { | ||||
val, err := strconv.ParseUint(field, 16, 64) | val, err := strconv.ParseUint(field, 16, 64) | ||||
if err != nil { | if err != nil { | ||||
@@ -87,17 +87,17 @@ func newNetDev(file string) (NetDev, error) { | |||||
// parseLine parses a single line from the /proc/net/dev file. Header lines | // parseLine parses a single line from the /proc/net/dev file. Header lines | ||||
// must be filtered prior to calling this method. | // must be filtered prior to calling this method. | ||||
func (netDev NetDev) parseLine(rawLine string) (*NetDevLine, error) { | func (netDev NetDev) parseLine(rawLine string) (*NetDevLine, error) { | ||||
parts := strings.SplitN(rawLine, ":", 2) | |||||
if len(parts) != 2 { | |||||
idx := strings.LastIndex(rawLine, ":") | |||||
if idx == -1 { | |||||
return nil, errors.New("invalid net/dev line, missing colon") | return nil, errors.New("invalid net/dev line, missing colon") | ||||
} | } | ||||
fields := strings.Fields(strings.TrimSpace(parts[1])) | |||||
fields := strings.Fields(strings.TrimSpace(rawLine[idx+1:])) | |||||
var err error | var err error | ||||
line := &NetDevLine{} | line := &NetDevLine{} | ||||
// Interface Name | // Interface Name | ||||
line.Name = strings.TrimSpace(parts[0]) | |||||
line.Name = strings.TrimSpace(rawLine[:idx]) | |||||
if line.Name == "" { | if line.Name == "" { | ||||
return nil, errors.New("invalid net/dev line, empty interface name") | return nil, errors.New("invalid net/dev line, empty interface name") | ||||
} | } | ||||
@@ -34,7 +34,7 @@ const ( | |||||
readLimit = 4294967296 // Byte -> 4 GiB | readLimit = 4294967296 // Byte -> 4 GiB | ||||
) | ) | ||||
// this contains generic data structures for both udp and tcp sockets | |||||
// This contains generic data structures for both udp and tcp sockets. | |||||
type ( | type ( | ||||
// NetIPSocket represents the contents of /proc/net/{t,u}dp{,6} file without the header. | // NetIPSocket represents the contents of /proc/net/{t,u}dp{,6} file without the header. | ||||
NetIPSocket []*netIPSocketLine | NetIPSocket []*netIPSocketLine | ||||
@@ -23,7 +23,7 @@ import ( | |||||
"github.com/prometheus/procfs/internal/util" | "github.com/prometheus/procfs/internal/util" | ||||
) | ) | ||||
// NetProtocolStats stores the contents from /proc/net/protocols | |||||
// NetProtocolStats stores the contents from /proc/net/protocols. | |||||
type NetProtocolStats map[string]NetProtocolStatLine | type NetProtocolStats map[string]NetProtocolStatLine | ||||
// NetProtocolStatLine contains a single line parsed from /proc/net/protocols. We | // NetProtocolStatLine contains a single line parsed from /proc/net/protocols. We | ||||
@@ -41,7 +41,7 @@ type NetProtocolStatLine struct { | |||||
Capabilities NetProtocolCapabilities | Capabilities NetProtocolCapabilities | ||||
} | } | ||||
// NetProtocolCapabilities contains a list of capabilities for each protocol | |||||
// NetProtocolCapabilities contains a list of capabilities for each protocol. | |||||
type NetProtocolCapabilities struct { | type NetProtocolCapabilities struct { | ||||
Close bool // 8 | Close bool // 8 | ||||
Connect bool // 9 | Connect bool // 9 | ||||
@@ -30,13 +30,13 @@ import ( | |||||
// * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162 | // * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162 | ||||
// and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810. | // and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810. | ||||
// SoftnetStat contains a single row of data from /proc/net/softnet_stat | |||||
// SoftnetStat contains a single row of data from /proc/net/softnet_stat. | |||||
type SoftnetStat struct { | type SoftnetStat struct { | ||||
// Number of processed packets | |||||
// Number of processed packets. | |||||
Processed uint32 | Processed uint32 | ||||
// Number of dropped packets | |||||
// Number of dropped packets. | |||||
Dropped uint32 | Dropped uint32 | ||||
// Number of times processing packets ran out of quota | |||||
// Number of times processing packets ran out of quota. | |||||
TimeSqueezed uint32 | TimeSqueezed uint32 | ||||
} | } | ||||
@@ -79,10 +79,13 @@ type XfrmStat struct { | |||||
// Policy is dead | // Policy is dead | ||||
XfrmOutPolDead int | XfrmOutPolDead int | ||||
// Policy Error | // Policy Error | ||||
XfrmOutPolError int | |||||
XfrmFwdHdrError int | |||||
XfrmOutPolError int | |||||
// Forward routing of a packet is not allowed | |||||
XfrmFwdHdrError int | |||||
// State is invalid, perhaps expired | |||||
XfrmOutStateInvalid int | XfrmOutStateInvalid int | ||||
XfrmAcquireError int | |||||
// State hasn’t been fully acquired before use | |||||
XfrmAcquireError int | |||||
} | } | ||||
// NewXfrmStat reads the xfrm_stat statistics. | // NewXfrmStat reads the xfrm_stat statistics. |
@@ -21,13 +21,13 @@ import ( | |||||
"strings" | "strings" | ||||
) | ) | ||||
// NetStat contains statistics for all the counters from one file | |||||
// NetStat contains statistics for all the counters from one file. | |||||
type NetStat struct { | type NetStat struct { | ||||
Filename string | |||||
Stats map[string][]uint64 | Stats map[string][]uint64 | ||||
Filename string | |||||
} | } | ||||
// NetStat retrieves stats from /proc/net/stat/ | |||||
// NetStat retrieves stats from `/proc/net/stat/`. | |||||
func (fs FS) NetStat() ([]NetStat, error) { | func (fs FS) NetStat() ([]NetStat, error) { | ||||
statFiles, err := filepath.Glob(fs.proc.Path("net/stat/*")) | statFiles, err := filepath.Glob(fs.proc.Path("net/stat/*")) | ||||
if err != nil { | if err != nil { | ||||
@@ -55,7 +55,7 @@ func (fs FS) NetStat() ([]NetStat, error) { | |||||
// Other strings represent per-CPU counters | // Other strings represent per-CPU counters | ||||
for scanner.Scan() { | for scanner.Scan() { | ||||
for num, counter := range strings.Fields(scanner.Text()) { | for num, counter := range strings.Fields(scanner.Text()) { | ||||
value, err := strconv.ParseUint(counter, 16, 32) | |||||
value, err := strconv.ParseUint(counter, 16, 64) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
@@ -16,7 +16,7 @@ package procfs | |||||
import ( | import ( | ||||
"bytes" | "bytes" | ||||
"fmt" | "fmt" | ||||
"io/ioutil" | |||||
"io" | |||||
"os" | "os" | ||||
"strconv" | "strconv" | ||||
"strings" | "strings" | ||||
@@ -82,7 +82,7 @@ func (fs FS) Self() (Proc, error) { | |||||
// NewProc returns a process for the given pid. | // NewProc returns a process for the given pid. | ||||
// | // | ||||
// Deprecated: use fs.Proc() instead | |||||
// Deprecated: Use fs.Proc() instead. | |||||
func (fs FS) NewProc(pid int) (Proc, error) { | func (fs FS) NewProc(pid int) (Proc, error) { | ||||
return fs.Proc(pid) | return fs.Proc(pid) | ||||
} | } | ||||
@@ -142,7 +142,7 @@ func (p Proc) Wchan() (string, error) { | |||||
} | } | ||||
defer f.Close() | defer f.Close() | ||||
data, err := ioutil.ReadAll(f) | |||||
data, err := io.ReadAll(f) | |||||
if err != nil { | if err != nil { | ||||
return "", err | return "", err | ||||
} | } | ||||
@@ -185,7 +185,7 @@ func (p Proc) Cwd() (string, error) { | |||||
return wd, err | return wd, err | ||||
} | } | ||||
// RootDir returns the absolute path to the process's root directory (as set by chroot) | |||||
// RootDir returns the absolute path to the process's root directory (as set by chroot). | |||||
func (p Proc) RootDir() (string, error) { | func (p Proc) RootDir() (string, error) { | ||||
rdir, err := os.Readlink(p.path("root")) | rdir, err := os.Readlink(p.path("root")) | ||||
if os.IsNotExist(err) { | if os.IsNotExist(err) { | ||||
@@ -311,7 +311,7 @@ func (p Proc) FileDescriptorsInfo() (ProcFDInfos, error) { | |||||
// Schedstat returns task scheduling information for the process. | // Schedstat returns task scheduling information for the process. | ||||
func (p Proc) Schedstat() (ProcSchedstat, error) { | func (p Proc) Schedstat() (ProcSchedstat, error) { | ||||
contents, err := ioutil.ReadFile(p.path("schedstat")) | |||||
contents, err := os.ReadFile(p.path("schedstat")) | |||||
if err != nil { | if err != nil { | ||||
return ProcSchedstat{}, err | return ProcSchedstat{}, err | ||||
} | } | ||||
@@ -45,7 +45,7 @@ type Cgroup struct { | |||||
} | } | ||||
// parseCgroupString parses each line of the /proc/[pid]/cgroup file | // parseCgroupString parses each line of the /proc/[pid]/cgroup file | ||||
// Line format is hierarchyID:[controller1,controller2]:path | |||||
// Line format is hierarchyID:[controller1,controller2]:path. | |||||
func parseCgroupString(cgroupStr string) (*Cgroup, error) { | func parseCgroupString(cgroupStr string) (*Cgroup, error) { | ||||
var err error | var err error | ||||
@@ -69,7 +69,7 @@ func parseCgroupString(cgroupStr string) (*Cgroup, error) { | |||||
return cgroup, nil | return cgroup, nil | ||||
} | } | ||||
// parseCgroups reads each line of the /proc/[pid]/cgroup file | |||||
// parseCgroups reads each line of the /proc/[pid]/cgroup file. | |||||
func parseCgroups(data []byte) ([]Cgroup, error) { | func parseCgroups(data []byte) ([]Cgroup, error) { | ||||
var cgroups []Cgroup | var cgroups []Cgroup | ||||
scanner := bufio.NewScanner(bytes.NewReader(data)) | scanner := bufio.NewScanner(bytes.NewReader(data)) | ||||
@@ -88,7 +88,7 @@ func parseCgroups(data []byte) ([]Cgroup, error) { | |||||
// Cgroups reads from /proc/<pid>/cgroups and returns a []*Cgroup struct locating this PID in each process | // 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, | // 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 | |||||
// so the len of the returned struct is equal to the number of active hierarchies on this system. | |||||
func (p Proc) Cgroups() ([]Cgroup, error) { | func (p Proc) Cgroups() ([]Cgroup, error) { | ||||
data, err := util.ReadFileNoStat(p.path("cgroup")) | data, err := util.ReadFileNoStat(p.path("cgroup")) | ||||
if err != nil { | if err != nil { | ||||
@@ -0,0 +1,98 @@ | |||||
// Copyright 2021 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" | |||||
) | |||||
// CgroupSummary models one line from /proc/cgroups. | |||||
// This file contains information about the controllers that are compiled into the kernel. | |||||
// | |||||
// Also see http://man7.org/linux/man-pages/man7/cgroups.7.html | |||||
type CgroupSummary struct { | |||||
// The name of the controller. controller is also known as subsystem. | |||||
SubsysName string | |||||
// The unique ID of the cgroup hierarchy on which this controller is mounted. | |||||
Hierarchy int | |||||
// The number of control groups in this hierarchy using this controller. | |||||
Cgroups int | |||||
// This field contains the value 1 if this controller is enabled, or 0 if it has been disabled | |||||
Enabled int | |||||
} | |||||
// parseCgroupSummary parses each line of the /proc/cgroup file | |||||
// Line format is `subsys_name hierarchy num_cgroups enabled`. | |||||
func parseCgroupSummaryString(CgroupSummaryStr string) (*CgroupSummary, error) { | |||||
var err error | |||||
fields := strings.Fields(CgroupSummaryStr) | |||||
// require at least 4 fields | |||||
if len(fields) < 4 { | |||||
return nil, fmt.Errorf("at least 4 fields required, found %d fields in cgroup info string: %s", len(fields), CgroupSummaryStr) | |||||
} | |||||
CgroupSummary := &CgroupSummary{ | |||||
SubsysName: fields[0], | |||||
} | |||||
CgroupSummary.Hierarchy, err = strconv.Atoi(fields[1]) | |||||
if err != nil { | |||||
return nil, fmt.Errorf("failed to parse hierarchy ID") | |||||
} | |||||
CgroupSummary.Cgroups, err = strconv.Atoi(fields[2]) | |||||
if err != nil { | |||||
return nil, fmt.Errorf("failed to parse Cgroup Num") | |||||
} | |||||
CgroupSummary.Enabled, err = strconv.Atoi(fields[3]) | |||||
if err != nil { | |||||
return nil, fmt.Errorf("failed to parse Enabled") | |||||
} | |||||
return CgroupSummary, nil | |||||
} | |||||
// parseCgroupSummary reads each line of the /proc/cgroup file. | |||||
func parseCgroupSummary(data []byte) ([]CgroupSummary, error) { | |||||
var CgroupSummarys []CgroupSummary | |||||
scanner := bufio.NewScanner(bytes.NewReader(data)) | |||||
for scanner.Scan() { | |||||
CgroupSummaryString := scanner.Text() | |||||
// ignore comment lines | |||||
if strings.HasPrefix(CgroupSummaryString, "#") { | |||||
continue | |||||
} | |||||
CgroupSummary, err := parseCgroupSummaryString(CgroupSummaryString) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
CgroupSummarys = append(CgroupSummarys, *CgroupSummary) | |||||
} | |||||
err := scanner.Err() | |||||
return CgroupSummarys, err | |||||
} | |||||
// CgroupSummarys returns information about current /proc/cgroups. | |||||
func (fs FS) CgroupSummarys() ([]CgroupSummary, error) { | |||||
data, err := util.ReadFileNoStat(fs.proc.Path("cgroups")) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return parseCgroupSummary(data) | |||||
} |
@@ -19,7 +19,7 @@ import ( | |||||
"github.com/prometheus/procfs/internal/util" | "github.com/prometheus/procfs/internal/util" | ||||
) | ) | ||||
// Environ reads process environments from /proc/<pid>/environ | |||||
// Environ reads process environments from `/proc/<pid>/environ`. | |||||
func (p Proc) Environ() ([]string, error) { | func (p Proc) Environ() ([]string, error) { | ||||
environments := make([]string, 0) | environments := make([]string, 0) | ||||
@@ -22,7 +22,6 @@ import ( | |||||
"github.com/prometheus/procfs/internal/util" | "github.com/prometheus/procfs/internal/util" | ||||
) | ) | ||||
// Regexp variables | |||||
var ( | var ( | ||||
rPos = regexp.MustCompile(`^pos:\s+(\d+)$`) | rPos = regexp.MustCompile(`^pos:\s+(\d+)$`) | ||||
rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`) | rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`) | ||||
@@ -122,7 +121,7 @@ func (p ProcFDInfos) Len() int { return len(p) } | |||||
func (p ProcFDInfos) Swap(i, j int) { p[i], p[j] = p[j], p[i] } | func (p ProcFDInfos) Swap(i, j int) { p[i], p[j] = p[j], p[i] } | ||||
func (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD } | func (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD } | ||||
// InotifyWatchLen returns the total number of inotify watches | |||||
// InotifyWatchLen returns the total number of inotify watches. | |||||
func (p ProcFDInfos) InotifyWatchLen() (int, error) { | func (p ProcFDInfos) InotifyWatchLen() (int, error) { | ||||
length := 0 | length := 0 | ||||
for _, f := range p { | for _, f := range p { | ||||
@@ -79,7 +79,7 @@ var ( | |||||
// NewLimits returns the current soft limits of the process. | // NewLimits returns the current soft limits of the process. | ||||
// | // | ||||
// Deprecated: use p.Limits() instead | |||||
// Deprecated: Use p.Limits() instead. | |||||
func (p Proc) NewLimits() (ProcLimits, error) { | func (p Proc) NewLimits() (ProcLimits, error) { | ||||
return p.Limits() | return p.Limits() | ||||
} | } | ||||
@@ -11,7 +11,9 @@ | |||||
// 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. | ||||
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && !js | |||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | ||||
// +build !js | |||||
package procfs | package procfs | ||||
@@ -25,7 +27,7 @@ import ( | |||||
"golang.org/x/sys/unix" | "golang.org/x/sys/unix" | ||||
) | ) | ||||
// ProcMapPermissions contains permission settings read from /proc/[pid]/maps | |||||
// 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 | ||||
@@ -39,8 +41,8 @@ type ProcMapPermissions struct { | |||||
Private bool | Private bool | ||||
} | } | ||||
// ProcMap contains the process memory-mappings of the process, | |||||
// read from /proc/[pid]/maps | |||||
// ProcMap contains the process memory-mappings of the process | |||||
// read from `/proc/[pid]/maps`. | |||||
type ProcMap struct { | type ProcMap struct { | ||||
// The start address of current mapping. | // The start address of current mapping. | ||||
StartAddr uintptr | StartAddr uintptr | ||||
@@ -79,7 +81,7 @@ func parseDevice(s string) (uint64, error) { | |||||
return unix.Mkdev(uint32(major), uint32(minor)), nil | return unix.Mkdev(uint32(major), uint32(minor)), nil | ||||
} | } | ||||
// parseAddress just converts a hex-string to a uintptr | |||||
// parseAddress converts a hex-string to a uintptr. | |||||
func parseAddress(s string) (uintptr, error) { | func parseAddress(s string) (uintptr, error) { | ||||
a, err := strconv.ParseUint(s, 16, 0) | a, err := strconv.ParseUint(s, 16, 0) | ||||
if err != nil { | if err != nil { | ||||
@@ -89,7 +91,7 @@ func parseAddress(s string) (uintptr, error) { | |||||
return uintptr(a), nil | return uintptr(a), nil | ||||
} | } | ||||
// parseAddresses parses the start-end address | |||||
// parseAddresses parses the start-end address. | |||||
func parseAddresses(s string) (uintptr, uintptr, error) { | func parseAddresses(s string) (uintptr, uintptr, error) { | ||||
toks := strings.Split(s, "-") | toks := strings.Split(s, "-") | ||||
if len(toks) < 2 { | if len(toks) < 2 { | ||||
@@ -0,0 +1,440 @@ | |||||
// Copyright 2022 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" | |||||
) | |||||
// ProcNetstat models the content of /proc/<pid>/net/netstat. | |||||
type ProcNetstat struct { | |||||
// The process ID. | |||||
PID int | |||||
TcpExt | |||||
IpExt | |||||
} | |||||
type TcpExt struct { // nolint:revive | |||||
SyncookiesSent float64 | |||||
SyncookiesRecv float64 | |||||
SyncookiesFailed float64 | |||||
EmbryonicRsts float64 | |||||
PruneCalled float64 | |||||
RcvPruned float64 | |||||
OfoPruned float64 | |||||
OutOfWindowIcmps float64 | |||||
LockDroppedIcmps float64 | |||||
ArpFilter float64 | |||||
TW float64 | |||||
TWRecycled float64 | |||||
TWKilled float64 | |||||
PAWSActive float64 | |||||
PAWSEstab float64 | |||||
DelayedACKs float64 | |||||
DelayedACKLocked float64 | |||||
DelayedACKLost float64 | |||||
ListenOverflows float64 | |||||
ListenDrops float64 | |||||
TCPHPHits float64 | |||||
TCPPureAcks float64 | |||||
TCPHPAcks float64 | |||||
TCPRenoRecovery float64 | |||||
TCPSackRecovery float64 | |||||
TCPSACKReneging float64 | |||||
TCPSACKReorder float64 | |||||
TCPRenoReorder float64 | |||||
TCPTSReorder float64 | |||||
TCPFullUndo float64 | |||||
TCPPartialUndo float64 | |||||
TCPDSACKUndo float64 | |||||
TCPLossUndo float64 | |||||
TCPLostRetransmit float64 | |||||
TCPRenoFailures float64 | |||||
TCPSackFailures float64 | |||||
TCPLossFailures float64 | |||||
TCPFastRetrans float64 | |||||
TCPSlowStartRetrans float64 | |||||
TCPTimeouts float64 | |||||
TCPLossProbes float64 | |||||
TCPLossProbeRecovery float64 | |||||
TCPRenoRecoveryFail float64 | |||||
TCPSackRecoveryFail float64 | |||||
TCPRcvCollapsed float64 | |||||
TCPDSACKOldSent float64 | |||||
TCPDSACKOfoSent float64 | |||||
TCPDSACKRecv float64 | |||||
TCPDSACKOfoRecv float64 | |||||
TCPAbortOnData float64 | |||||
TCPAbortOnClose float64 | |||||
TCPAbortOnMemory float64 | |||||
TCPAbortOnTimeout float64 | |||||
TCPAbortOnLinger float64 | |||||
TCPAbortFailed float64 | |||||
TCPMemoryPressures float64 | |||||
TCPMemoryPressuresChrono float64 | |||||
TCPSACKDiscard float64 | |||||
TCPDSACKIgnoredOld float64 | |||||
TCPDSACKIgnoredNoUndo float64 | |||||
TCPSpuriousRTOs float64 | |||||
TCPMD5NotFound float64 | |||||
TCPMD5Unexpected float64 | |||||
TCPMD5Failure float64 | |||||
TCPSackShifted float64 | |||||
TCPSackMerged float64 | |||||
TCPSackShiftFallback float64 | |||||
TCPBacklogDrop float64 | |||||
PFMemallocDrop float64 | |||||
TCPMinTTLDrop float64 | |||||
TCPDeferAcceptDrop float64 | |||||
IPReversePathFilter float64 | |||||
TCPTimeWaitOverflow float64 | |||||
TCPReqQFullDoCookies float64 | |||||
TCPReqQFullDrop float64 | |||||
TCPRetransFail float64 | |||||
TCPRcvCoalesce float64 | |||||
TCPOFOQueue float64 | |||||
TCPOFODrop float64 | |||||
TCPOFOMerge float64 | |||||
TCPChallengeACK float64 | |||||
TCPSYNChallenge float64 | |||||
TCPFastOpenActive float64 | |||||
TCPFastOpenActiveFail float64 | |||||
TCPFastOpenPassive float64 | |||||
TCPFastOpenPassiveFail float64 | |||||
TCPFastOpenListenOverflow float64 | |||||
TCPFastOpenCookieReqd float64 | |||||
TCPFastOpenBlackhole float64 | |||||
TCPSpuriousRtxHostQueues float64 | |||||
BusyPollRxPackets float64 | |||||
TCPAutoCorking float64 | |||||
TCPFromZeroWindowAdv float64 | |||||
TCPToZeroWindowAdv float64 | |||||
TCPWantZeroWindowAdv float64 | |||||
TCPSynRetrans float64 | |||||
TCPOrigDataSent float64 | |||||
TCPHystartTrainDetect float64 | |||||
TCPHystartTrainCwnd float64 | |||||
TCPHystartDelayDetect float64 | |||||
TCPHystartDelayCwnd float64 | |||||
TCPACKSkippedSynRecv float64 | |||||
TCPACKSkippedPAWS float64 | |||||
TCPACKSkippedSeq float64 | |||||
TCPACKSkippedFinWait2 float64 | |||||
TCPACKSkippedTimeWait float64 | |||||
TCPACKSkippedChallenge float64 | |||||
TCPWinProbe float64 | |||||
TCPKeepAlive float64 | |||||
TCPMTUPFail float64 | |||||
TCPMTUPSuccess float64 | |||||
TCPWqueueTooBig float64 | |||||
} | |||||
type IpExt struct { // nolint:revive | |||||
InNoRoutes float64 | |||||
InTruncatedPkts float64 | |||||
InMcastPkts float64 | |||||
OutMcastPkts float64 | |||||
InBcastPkts float64 | |||||
OutBcastPkts float64 | |||||
InOctets float64 | |||||
OutOctets float64 | |||||
InMcastOctets float64 | |||||
OutMcastOctets float64 | |||||
InBcastOctets float64 | |||||
OutBcastOctets float64 | |||||
InCsumErrors float64 | |||||
InNoECTPkts float64 | |||||
InECT1Pkts float64 | |||||
InECT0Pkts float64 | |||||
InCEPkts float64 | |||||
ReasmOverlaps float64 | |||||
} | |||||
func (p Proc) Netstat() (ProcNetstat, error) { | |||||
filename := p.path("net/netstat") | |||||
data, err := util.ReadFileNoStat(filename) | |||||
if err != nil { | |||||
return ProcNetstat{PID: p.PID}, err | |||||
} | |||||
procNetstat, err := parseNetstat(bytes.NewReader(data), filename) | |||||
procNetstat.PID = p.PID | |||||
return procNetstat, err | |||||
} | |||||
// parseNetstat parses the metrics from proc/<pid>/net/netstat file | |||||
// and returns a ProcNetstat structure. | |||||
func parseNetstat(r io.Reader, fileName string) (ProcNetstat, error) { | |||||
var ( | |||||
scanner = bufio.NewScanner(r) | |||||
procNetstat = ProcNetstat{} | |||||
) | |||||
for scanner.Scan() { | |||||
nameParts := strings.Split(scanner.Text(), " ") | |||||
scanner.Scan() | |||||
valueParts := strings.Split(scanner.Text(), " ") | |||||
// Remove trailing :. | |||||
protocol := strings.TrimSuffix(nameParts[0], ":") | |||||
if len(nameParts) != len(valueParts) { | |||||
return procNetstat, fmt.Errorf("mismatch field count mismatch in %s: %s", | |||||
fileName, protocol) | |||||
} | |||||
for i := 1; i < len(nameParts); i++ { | |||||
value, err := strconv.ParseFloat(valueParts[i], 64) | |||||
if err != nil { | |||||
return procNetstat, err | |||||
} | |||||
key := nameParts[i] | |||||
switch protocol { | |||||
case "TcpExt": | |||||
switch key { | |||||
case "SyncookiesSent": | |||||
procNetstat.TcpExt.SyncookiesSent = value | |||||
case "SyncookiesRecv": | |||||
procNetstat.TcpExt.SyncookiesRecv = value | |||||
case "SyncookiesFailed": | |||||
procNetstat.TcpExt.SyncookiesFailed = value | |||||
case "EmbryonicRsts": | |||||
procNetstat.TcpExt.EmbryonicRsts = value | |||||
case "PruneCalled": | |||||
procNetstat.TcpExt.PruneCalled = value | |||||
case "RcvPruned": | |||||
procNetstat.TcpExt.RcvPruned = value | |||||
case "OfoPruned": | |||||
procNetstat.TcpExt.OfoPruned = value | |||||
case "OutOfWindowIcmps": | |||||
procNetstat.TcpExt.OutOfWindowIcmps = value | |||||
case "LockDroppedIcmps": | |||||
procNetstat.TcpExt.LockDroppedIcmps = value | |||||
case "ArpFilter": | |||||
procNetstat.TcpExt.ArpFilter = value | |||||
case "TW": | |||||
procNetstat.TcpExt.TW = value | |||||
case "TWRecycled": | |||||
procNetstat.TcpExt.TWRecycled = value | |||||
case "TWKilled": | |||||
procNetstat.TcpExt.TWKilled = value | |||||
case "PAWSActive": | |||||
procNetstat.TcpExt.PAWSActive = value | |||||
case "PAWSEstab": | |||||
procNetstat.TcpExt.PAWSEstab = value | |||||
case "DelayedACKs": | |||||
procNetstat.TcpExt.DelayedACKs = value | |||||
case "DelayedACKLocked": | |||||
procNetstat.TcpExt.DelayedACKLocked = value | |||||
case "DelayedACKLost": | |||||
procNetstat.TcpExt.DelayedACKLost = value | |||||
case "ListenOverflows": | |||||
procNetstat.TcpExt.ListenOverflows = value | |||||
case "ListenDrops": | |||||
procNetstat.TcpExt.ListenDrops = value | |||||
case "TCPHPHits": | |||||
procNetstat.TcpExt.TCPHPHits = value | |||||
case "TCPPureAcks": | |||||
procNetstat.TcpExt.TCPPureAcks = value | |||||
case "TCPHPAcks": | |||||
procNetstat.TcpExt.TCPHPAcks = value | |||||
case "TCPRenoRecovery": | |||||
procNetstat.TcpExt.TCPRenoRecovery = value | |||||
case "TCPSackRecovery": | |||||
procNetstat.TcpExt.TCPSackRecovery = value | |||||
case "TCPSACKReneging": | |||||
procNetstat.TcpExt.TCPSACKReneging = value | |||||
case "TCPSACKReorder": | |||||
procNetstat.TcpExt.TCPSACKReorder = value | |||||
case "TCPRenoReorder": | |||||
procNetstat.TcpExt.TCPRenoReorder = value | |||||
case "TCPTSReorder": | |||||
procNetstat.TcpExt.TCPTSReorder = value | |||||
case "TCPFullUndo": | |||||
procNetstat.TcpExt.TCPFullUndo = value | |||||
case "TCPPartialUndo": | |||||
procNetstat.TcpExt.TCPPartialUndo = value | |||||
case "TCPDSACKUndo": | |||||
procNetstat.TcpExt.TCPDSACKUndo = value | |||||
case "TCPLossUndo": | |||||
procNetstat.TcpExt.TCPLossUndo = value | |||||
case "TCPLostRetransmit": | |||||
procNetstat.TcpExt.TCPLostRetransmit = value | |||||
case "TCPRenoFailures": | |||||
procNetstat.TcpExt.TCPRenoFailures = value | |||||
case "TCPSackFailures": | |||||
procNetstat.TcpExt.TCPSackFailures = value | |||||
case "TCPLossFailures": | |||||
procNetstat.TcpExt.TCPLossFailures = value | |||||
case "TCPFastRetrans": | |||||
procNetstat.TcpExt.TCPFastRetrans = value | |||||
case "TCPSlowStartRetrans": | |||||
procNetstat.TcpExt.TCPSlowStartRetrans = value | |||||
case "TCPTimeouts": | |||||
procNetstat.TcpExt.TCPTimeouts = value | |||||
case "TCPLossProbes": | |||||
procNetstat.TcpExt.TCPLossProbes = value | |||||
case "TCPLossProbeRecovery": | |||||
procNetstat.TcpExt.TCPLossProbeRecovery = value | |||||
case "TCPRenoRecoveryFail": | |||||
procNetstat.TcpExt.TCPRenoRecoveryFail = value | |||||
case "TCPSackRecoveryFail": | |||||
procNetstat.TcpExt.TCPSackRecoveryFail = value | |||||
case "TCPRcvCollapsed": | |||||
procNetstat.TcpExt.TCPRcvCollapsed = value | |||||
case "TCPDSACKOldSent": | |||||
procNetstat.TcpExt.TCPDSACKOldSent = value | |||||
case "TCPDSACKOfoSent": | |||||
procNetstat.TcpExt.TCPDSACKOfoSent = value | |||||
case "TCPDSACKRecv": | |||||
procNetstat.TcpExt.TCPDSACKRecv = value | |||||
case "TCPDSACKOfoRecv": | |||||
procNetstat.TcpExt.TCPDSACKOfoRecv = value | |||||
case "TCPAbortOnData": | |||||
procNetstat.TcpExt.TCPAbortOnData = value | |||||
case "TCPAbortOnClose": | |||||
procNetstat.TcpExt.TCPAbortOnClose = value | |||||
case "TCPDeferAcceptDrop": | |||||
procNetstat.TcpExt.TCPDeferAcceptDrop = value | |||||
case "IPReversePathFilter": | |||||
procNetstat.TcpExt.IPReversePathFilter = value | |||||
case "TCPTimeWaitOverflow": | |||||
procNetstat.TcpExt.TCPTimeWaitOverflow = value | |||||
case "TCPReqQFullDoCookies": | |||||
procNetstat.TcpExt.TCPReqQFullDoCookies = value | |||||
case "TCPReqQFullDrop": | |||||
procNetstat.TcpExt.TCPReqQFullDrop = value | |||||
case "TCPRetransFail": | |||||
procNetstat.TcpExt.TCPRetransFail = value | |||||
case "TCPRcvCoalesce": | |||||
procNetstat.TcpExt.TCPRcvCoalesce = value | |||||
case "TCPOFOQueue": | |||||
procNetstat.TcpExt.TCPOFOQueue = value | |||||
case "TCPOFODrop": | |||||
procNetstat.TcpExt.TCPOFODrop = value | |||||
case "TCPOFOMerge": | |||||
procNetstat.TcpExt.TCPOFOMerge = value | |||||
case "TCPChallengeACK": | |||||
procNetstat.TcpExt.TCPChallengeACK = value | |||||
case "TCPSYNChallenge": | |||||
procNetstat.TcpExt.TCPSYNChallenge = value | |||||
case "TCPFastOpenActive": | |||||
procNetstat.TcpExt.TCPFastOpenActive = value | |||||
case "TCPFastOpenActiveFail": | |||||
procNetstat.TcpExt.TCPFastOpenActiveFail = value | |||||
case "TCPFastOpenPassive": | |||||
procNetstat.TcpExt.TCPFastOpenPassive = value | |||||
case "TCPFastOpenPassiveFail": | |||||
procNetstat.TcpExt.TCPFastOpenPassiveFail = value | |||||
case "TCPFastOpenListenOverflow": | |||||
procNetstat.TcpExt.TCPFastOpenListenOverflow = value | |||||
case "TCPFastOpenCookieReqd": | |||||
procNetstat.TcpExt.TCPFastOpenCookieReqd = value | |||||
case "TCPFastOpenBlackhole": | |||||
procNetstat.TcpExt.TCPFastOpenBlackhole = value | |||||
case "TCPSpuriousRtxHostQueues": | |||||
procNetstat.TcpExt.TCPSpuriousRtxHostQueues = value | |||||
case "BusyPollRxPackets": | |||||
procNetstat.TcpExt.BusyPollRxPackets = value | |||||
case "TCPAutoCorking": | |||||
procNetstat.TcpExt.TCPAutoCorking = value | |||||
case "TCPFromZeroWindowAdv": | |||||
procNetstat.TcpExt.TCPFromZeroWindowAdv = value | |||||
case "TCPToZeroWindowAdv": | |||||
procNetstat.TcpExt.TCPToZeroWindowAdv = value | |||||
case "TCPWantZeroWindowAdv": | |||||
procNetstat.TcpExt.TCPWantZeroWindowAdv = value | |||||
case "TCPSynRetrans": | |||||
procNetstat.TcpExt.TCPSynRetrans = value | |||||
case "TCPOrigDataSent": | |||||
procNetstat.TcpExt.TCPOrigDataSent = value | |||||
case "TCPHystartTrainDetect": | |||||
procNetstat.TcpExt.TCPHystartTrainDetect = value | |||||
case "TCPHystartTrainCwnd": | |||||
procNetstat.TcpExt.TCPHystartTrainCwnd = value | |||||
case "TCPHystartDelayDetect": | |||||
procNetstat.TcpExt.TCPHystartDelayDetect = value | |||||
case "TCPHystartDelayCwnd": | |||||
procNetstat.TcpExt.TCPHystartDelayCwnd = value | |||||
case "TCPACKSkippedSynRecv": | |||||
procNetstat.TcpExt.TCPACKSkippedSynRecv = value | |||||
case "TCPACKSkippedPAWS": | |||||
procNetstat.TcpExt.TCPACKSkippedPAWS = value | |||||
case "TCPACKSkippedSeq": | |||||
procNetstat.TcpExt.TCPACKSkippedSeq = value | |||||
case "TCPACKSkippedFinWait2": | |||||
procNetstat.TcpExt.TCPACKSkippedFinWait2 = value | |||||
case "TCPACKSkippedTimeWait": | |||||
procNetstat.TcpExt.TCPACKSkippedTimeWait = value | |||||
case "TCPACKSkippedChallenge": | |||||
procNetstat.TcpExt.TCPACKSkippedChallenge = value | |||||
case "TCPWinProbe": | |||||
procNetstat.TcpExt.TCPWinProbe = value | |||||
case "TCPKeepAlive": | |||||
procNetstat.TcpExt.TCPKeepAlive = value | |||||
case "TCPMTUPFail": | |||||
procNetstat.TcpExt.TCPMTUPFail = value | |||||
case "TCPMTUPSuccess": | |||||
procNetstat.TcpExt.TCPMTUPSuccess = value | |||||
case "TCPWqueueTooBig": | |||||
procNetstat.TcpExt.TCPWqueueTooBig = value | |||||
} | |||||
case "IpExt": | |||||
switch key { | |||||
case "InNoRoutes": | |||||
procNetstat.IpExt.InNoRoutes = value | |||||
case "InTruncatedPkts": | |||||
procNetstat.IpExt.InTruncatedPkts = value | |||||
case "InMcastPkts": | |||||
procNetstat.IpExt.InMcastPkts = value | |||||
case "OutMcastPkts": | |||||
procNetstat.IpExt.OutMcastPkts = value | |||||
case "InBcastPkts": | |||||
procNetstat.IpExt.InBcastPkts = value | |||||
case "OutBcastPkts": | |||||
procNetstat.IpExt.OutBcastPkts = value | |||||
case "InOctets": | |||||
procNetstat.IpExt.InOctets = value | |||||
case "OutOctets": | |||||
procNetstat.IpExt.OutOctets = value | |||||
case "InMcastOctets": | |||||
procNetstat.IpExt.InMcastOctets = value | |||||
case "OutMcastOctets": | |||||
procNetstat.IpExt.OutMcastOctets = value | |||||
case "InBcastOctets": | |||||
procNetstat.IpExt.InBcastOctets = value | |||||
case "OutBcastOctets": | |||||
procNetstat.IpExt.OutBcastOctets = value | |||||
case "InCsumErrors": | |||||
procNetstat.IpExt.InCsumErrors = value | |||||
case "InNoECTPkts": | |||||
procNetstat.IpExt.InNoECTPkts = value | |||||
case "InECT1Pkts": | |||||
procNetstat.IpExt.InECT1Pkts = value | |||||
case "InECT0Pkts": | |||||
procNetstat.IpExt.InECT0Pkts = value | |||||
case "InCEPkts": | |||||
procNetstat.IpExt.InCEPkts = value | |||||
case "ReasmOverlaps": | |||||
procNetstat.IpExt.ReasmOverlaps = value | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return procNetstat, scanner.Err() | |||||
} |
@@ -35,9 +35,10 @@ import ( | |||||
const lineFormat = "avg10=%f avg60=%f avg300=%f total=%d" | const lineFormat = "avg10=%f avg60=%f avg300=%f total=%d" | ||||
// PSILine is a single line of values as returned by /proc/pressure/* | |||||
// The Avg entries are averages over n seconds, as a percentage | |||||
// The Total line is in microseconds | |||||
// PSILine is a single line of values as returned by `/proc/pressure/*`. | |||||
// | |||||
// The Avg entries are averages over n seconds, as a percentage. | |||||
// The Total line is in microseconds. | |||||
type PSILine struct { | type PSILine struct { | ||||
Avg10 float64 | Avg10 float64 | ||||
Avg60 float64 | Avg60 float64 | ||||
@@ -46,8 +47,9 @@ type PSILine struct { | |||||
} | } | ||||
// PSIStats represent pressure stall information from /proc/pressure/* | // PSIStats represent pressure stall information from /proc/pressure/* | ||||
// Some indicates the share of time in which at least some tasks are stalled | |||||
// Full indicates the share of time in which all non-idle tasks are stalled simultaneously | |||||
// | |||||
// "Some" indicates the share of time in which at least some tasks are stalled. | |||||
// "Full" indicates the share of time in which all non-idle tasks are stalled simultaneously. | |||||
type PSIStats struct { | type PSIStats struct { | ||||
Some *PSILine | Some *PSILine | ||||
Full *PSILine | Full *PSILine | ||||
@@ -65,7 +67,7 @@ func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) { | |||||
return parsePSIStats(resource, bytes.NewReader(data)) | return parsePSIStats(resource, bytes.NewReader(data)) | ||||
} | } | ||||
// parsePSIStats parses the specified file for pressure stall information | |||||
// parsePSIStats parses the specified file for pressure stall information. | |||||
func parsePSIStats(resource string, r io.Reader) (PSIStats, error) { | func parsePSIStats(resource string, r io.Reader) (PSIStats, error) { | ||||
psiStats := PSIStats{} | psiStats := PSIStats{} | ||||
@@ -11,6 +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. | ||||
//go:build !windows | |||||
// +build !windows | // +build !windows | ||||
package procfs | package procfs | ||||
@@ -28,30 +29,30 @@ import ( | |||||
) | ) | ||||
var ( | var ( | ||||
// match the header line before each mapped zone in /proc/pid/smaps | |||||
// match the header line before each mapped zone in `/proc/pid/smaps`. | |||||
procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`) | procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`) | ||||
) | ) | ||||
type ProcSMapsRollup struct { | type ProcSMapsRollup struct { | ||||
// Amount of the mapping that is currently resident in RAM | |||||
// Amount of the mapping that is currently resident in RAM. | |||||
Rss uint64 | Rss uint64 | ||||
// Process's proportional share of this mapping | |||||
// Process's proportional share of this mapping. | |||||
Pss uint64 | Pss uint64 | ||||
// Size in bytes of clean shared pages | |||||
// Size in bytes of clean shared pages. | |||||
SharedClean uint64 | SharedClean uint64 | ||||
// Size in bytes of dirty shared pages | |||||
// Size in bytes of dirty shared pages. | |||||
SharedDirty uint64 | SharedDirty uint64 | ||||
// Size in bytes of clean private pages | |||||
// Size in bytes of clean private pages. | |||||
PrivateClean uint64 | PrivateClean uint64 | ||||
// Size in bytes of dirty private pages | |||||
// Size in bytes of dirty private pages. | |||||
PrivateDirty uint64 | PrivateDirty uint64 | ||||
// Amount of memory currently marked as referenced or accessed | |||||
// Amount of memory currently marked as referenced or accessed. | |||||
Referenced uint64 | Referenced uint64 | ||||
// Amount of memory that does not belong to any file | |||||
// Amount of memory that does not belong to any file. | |||||
Anonymous uint64 | Anonymous uint64 | ||||
// Amount would-be-anonymous memory currently on swap | |||||
// Amount would-be-anonymous memory currently on swap. | |||||
Swap uint64 | Swap uint64 | ||||
// Process's proportional memory on swap | |||||
// Process's proportional memory on swap. | |||||
SwapPss uint64 | SwapPss uint64 | ||||
} | } | ||||
@@ -0,0 +1,353 @@ | |||||
// Copyright 2022 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" | |||||
) | |||||
// ProcSnmp models the content of /proc/<pid>/net/snmp. | |||||
type ProcSnmp struct { | |||||
// The process ID. | |||||
PID int | |||||
Ip | |||||
Icmp | |||||
IcmpMsg | |||||
Tcp | |||||
Udp | |||||
UdpLite | |||||
} | |||||
type Ip struct { // nolint:revive | |||||
Forwarding float64 | |||||
DefaultTTL float64 | |||||
InReceives float64 | |||||
InHdrErrors float64 | |||||
InAddrErrors float64 | |||||
ForwDatagrams float64 | |||||
InUnknownProtos float64 | |||||
InDiscards float64 | |||||
InDelivers float64 | |||||
OutRequests float64 | |||||
OutDiscards float64 | |||||
OutNoRoutes float64 | |||||
ReasmTimeout float64 | |||||
ReasmReqds float64 | |||||
ReasmOKs float64 | |||||
ReasmFails float64 | |||||
FragOKs float64 | |||||
FragFails float64 | |||||
FragCreates float64 | |||||
} | |||||
type Icmp struct { | |||||
InMsgs float64 | |||||
InErrors float64 | |||||
InCsumErrors float64 | |||||
InDestUnreachs float64 | |||||
InTimeExcds float64 | |||||
InParmProbs float64 | |||||
InSrcQuenchs float64 | |||||
InRedirects float64 | |||||
InEchos float64 | |||||
InEchoReps float64 | |||||
InTimestamps float64 | |||||
InTimestampReps float64 | |||||
InAddrMasks float64 | |||||
InAddrMaskReps float64 | |||||
OutMsgs float64 | |||||
OutErrors float64 | |||||
OutDestUnreachs float64 | |||||
OutTimeExcds float64 | |||||
OutParmProbs float64 | |||||
OutSrcQuenchs float64 | |||||
OutRedirects float64 | |||||
OutEchos float64 | |||||
OutEchoReps float64 | |||||
OutTimestamps float64 | |||||
OutTimestampReps float64 | |||||
OutAddrMasks float64 | |||||
OutAddrMaskReps float64 | |||||
} | |||||
type IcmpMsg struct { | |||||
InType3 float64 | |||||
OutType3 float64 | |||||
} | |||||
type Tcp struct { // nolint:revive | |||||
RtoAlgorithm float64 | |||||
RtoMin float64 | |||||
RtoMax float64 | |||||
MaxConn float64 | |||||
ActiveOpens float64 | |||||
PassiveOpens float64 | |||||
AttemptFails float64 | |||||
EstabResets float64 | |||||
CurrEstab float64 | |||||
InSegs float64 | |||||
OutSegs float64 | |||||
RetransSegs float64 | |||||
InErrs float64 | |||||
OutRsts float64 | |||||
InCsumErrors float64 | |||||
} | |||||
type Udp struct { // nolint:revive | |||||
InDatagrams float64 | |||||
NoPorts float64 | |||||
InErrors float64 | |||||
OutDatagrams float64 | |||||
RcvbufErrors float64 | |||||
SndbufErrors float64 | |||||
InCsumErrors float64 | |||||
IgnoredMulti float64 | |||||
} | |||||
type UdpLite struct { // nolint:revive | |||||
InDatagrams float64 | |||||
NoPorts float64 | |||||
InErrors float64 | |||||
OutDatagrams float64 | |||||
RcvbufErrors float64 | |||||
SndbufErrors float64 | |||||
InCsumErrors float64 | |||||
IgnoredMulti float64 | |||||
} | |||||
func (p Proc) Snmp() (ProcSnmp, error) { | |||||
filename := p.path("net/snmp") | |||||
data, err := util.ReadFileNoStat(filename) | |||||
if err != nil { | |||||
return ProcSnmp{PID: p.PID}, err | |||||
} | |||||
procSnmp, err := parseSnmp(bytes.NewReader(data), filename) | |||||
procSnmp.PID = p.PID | |||||
return procSnmp, err | |||||
} | |||||
// parseSnmp parses the metrics from proc/<pid>/net/snmp file | |||||
// and returns a map contains those metrics (e.g. {"Ip": {"Forwarding": 2}}). | |||||
func parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) { | |||||
var ( | |||||
scanner = bufio.NewScanner(r) | |||||
procSnmp = ProcSnmp{} | |||||
) | |||||
for scanner.Scan() { | |||||
nameParts := strings.Split(scanner.Text(), " ") | |||||
scanner.Scan() | |||||
valueParts := strings.Split(scanner.Text(), " ") | |||||
// Remove trailing :. | |||||
protocol := strings.TrimSuffix(nameParts[0], ":") | |||||
if len(nameParts) != len(valueParts) { | |||||
return procSnmp, fmt.Errorf("mismatch field count mismatch in %s: %s", | |||||
fileName, protocol) | |||||
} | |||||
for i := 1; i < len(nameParts); i++ { | |||||
value, err := strconv.ParseFloat(valueParts[i], 64) | |||||
if err != nil { | |||||
return procSnmp, err | |||||
} | |||||
key := nameParts[i] | |||||
switch protocol { | |||||
case "Ip": | |||||
switch key { | |||||
case "Forwarding": | |||||
procSnmp.Ip.Forwarding = value | |||||
case "DefaultTTL": | |||||
procSnmp.Ip.DefaultTTL = value | |||||
case "InReceives": | |||||
procSnmp.Ip.InReceives = value | |||||
case "InHdrErrors": | |||||
procSnmp.Ip.InHdrErrors = value | |||||
case "InAddrErrors": | |||||
procSnmp.Ip.InAddrErrors = value | |||||
case "ForwDatagrams": | |||||
procSnmp.Ip.ForwDatagrams = value | |||||
case "InUnknownProtos": | |||||
procSnmp.Ip.InUnknownProtos = value | |||||
case "InDiscards": | |||||
procSnmp.Ip.InDiscards = value | |||||
case "InDelivers": | |||||
procSnmp.Ip.InDelivers = value | |||||
case "OutRequests": | |||||
procSnmp.Ip.OutRequests = value | |||||
case "OutDiscards": | |||||
procSnmp.Ip.OutDiscards = value | |||||
case "OutNoRoutes": | |||||
procSnmp.Ip.OutNoRoutes = value | |||||
case "ReasmTimeout": | |||||
procSnmp.Ip.ReasmTimeout = value | |||||
case "ReasmReqds": | |||||
procSnmp.Ip.ReasmReqds = value | |||||
case "ReasmOKs": | |||||
procSnmp.Ip.ReasmOKs = value | |||||
case "ReasmFails": | |||||
procSnmp.Ip.ReasmFails = value | |||||
case "FragOKs": | |||||
procSnmp.Ip.FragOKs = value | |||||
case "FragFails": | |||||
procSnmp.Ip.FragFails = value | |||||
case "FragCreates": | |||||
procSnmp.Ip.FragCreates = value | |||||
} | |||||
case "Icmp": | |||||
switch key { | |||||
case "InMsgs": | |||||
procSnmp.Icmp.InMsgs = value | |||||
case "InErrors": | |||||
procSnmp.Icmp.InErrors = value | |||||
case "InCsumErrors": | |||||
procSnmp.Icmp.InCsumErrors = value | |||||
case "InDestUnreachs": | |||||
procSnmp.Icmp.InDestUnreachs = value | |||||
case "InTimeExcds": | |||||
procSnmp.Icmp.InTimeExcds = value | |||||
case "InParmProbs": | |||||
procSnmp.Icmp.InParmProbs = value | |||||
case "InSrcQuenchs": | |||||
procSnmp.Icmp.InSrcQuenchs = value | |||||
case "InRedirects": | |||||
procSnmp.Icmp.InRedirects = value | |||||
case "InEchos": | |||||
procSnmp.Icmp.InEchos = value | |||||
case "InEchoReps": | |||||
procSnmp.Icmp.InEchoReps = value | |||||
case "InTimestamps": | |||||
procSnmp.Icmp.InTimestamps = value | |||||
case "InTimestampReps": | |||||
procSnmp.Icmp.InTimestampReps = value | |||||
case "InAddrMasks": | |||||
procSnmp.Icmp.InAddrMasks = value | |||||
case "InAddrMaskReps": | |||||
procSnmp.Icmp.InAddrMaskReps = value | |||||
case "OutMsgs": | |||||
procSnmp.Icmp.OutMsgs = value | |||||
case "OutErrors": | |||||
procSnmp.Icmp.OutErrors = value | |||||
case "OutDestUnreachs": | |||||
procSnmp.Icmp.OutDestUnreachs = value | |||||
case "OutTimeExcds": | |||||
procSnmp.Icmp.OutTimeExcds = value | |||||
case "OutParmProbs": | |||||
procSnmp.Icmp.OutParmProbs = value | |||||
case "OutSrcQuenchs": | |||||
procSnmp.Icmp.OutSrcQuenchs = value | |||||
case "OutRedirects": | |||||
procSnmp.Icmp.OutRedirects = value | |||||
case "OutEchos": | |||||
procSnmp.Icmp.OutEchos = value | |||||
case "OutEchoReps": | |||||
procSnmp.Icmp.OutEchoReps = value | |||||
case "OutTimestamps": | |||||
procSnmp.Icmp.OutTimestamps = value | |||||
case "OutTimestampReps": | |||||
procSnmp.Icmp.OutTimestampReps = value | |||||
case "OutAddrMasks": | |||||
procSnmp.Icmp.OutAddrMasks = value | |||||
case "OutAddrMaskReps": | |||||
procSnmp.Icmp.OutAddrMaskReps = value | |||||
} | |||||
case "IcmpMsg": | |||||
switch key { | |||||
case "InType3": | |||||
procSnmp.IcmpMsg.InType3 = value | |||||
case "OutType3": | |||||
procSnmp.IcmpMsg.OutType3 = value | |||||
} | |||||
case "Tcp": | |||||
switch key { | |||||
case "RtoAlgorithm": | |||||
procSnmp.Tcp.RtoAlgorithm = value | |||||
case "RtoMin": | |||||
procSnmp.Tcp.RtoMin = value | |||||
case "RtoMax": | |||||
procSnmp.Tcp.RtoMax = value | |||||
case "MaxConn": | |||||
procSnmp.Tcp.MaxConn = value | |||||
case "ActiveOpens": | |||||
procSnmp.Tcp.ActiveOpens = value | |||||
case "PassiveOpens": | |||||
procSnmp.Tcp.PassiveOpens = value | |||||
case "AttemptFails": | |||||
procSnmp.Tcp.AttemptFails = value | |||||
case "EstabResets": | |||||
procSnmp.Tcp.EstabResets = value | |||||
case "CurrEstab": | |||||
procSnmp.Tcp.CurrEstab = value | |||||
case "InSegs": | |||||
procSnmp.Tcp.InSegs = value | |||||
case "OutSegs": | |||||
procSnmp.Tcp.OutSegs = value | |||||
case "RetransSegs": | |||||
procSnmp.Tcp.RetransSegs = value | |||||
case "InErrs": | |||||
procSnmp.Tcp.InErrs = value | |||||
case "OutRsts": | |||||
procSnmp.Tcp.OutRsts = value | |||||
case "InCsumErrors": | |||||
procSnmp.Tcp.InCsumErrors = value | |||||
} | |||||
case "Udp": | |||||
switch key { | |||||
case "InDatagrams": | |||||
procSnmp.Udp.InDatagrams = value | |||||
case "NoPorts": | |||||
procSnmp.Udp.NoPorts = value | |||||
case "InErrors": | |||||
procSnmp.Udp.InErrors = value | |||||
case "OutDatagrams": | |||||
procSnmp.Udp.OutDatagrams = value | |||||
case "RcvbufErrors": | |||||
procSnmp.Udp.RcvbufErrors = value | |||||
case "SndbufErrors": | |||||
procSnmp.Udp.SndbufErrors = value | |||||
case "InCsumErrors": | |||||
procSnmp.Udp.InCsumErrors = value | |||||
case "IgnoredMulti": | |||||
procSnmp.Udp.IgnoredMulti = value | |||||
} | |||||
case "UdpLite": | |||||
switch key { | |||||
case "InDatagrams": | |||||
procSnmp.UdpLite.InDatagrams = value | |||||
case "NoPorts": | |||||
procSnmp.UdpLite.NoPorts = value | |||||
case "InErrors": | |||||
procSnmp.UdpLite.InErrors = value | |||||
case "OutDatagrams": | |||||
procSnmp.UdpLite.OutDatagrams = value | |||||
case "RcvbufErrors": | |||||
procSnmp.UdpLite.RcvbufErrors = value | |||||
case "SndbufErrors": | |||||
procSnmp.UdpLite.SndbufErrors = value | |||||
case "InCsumErrors": | |||||
procSnmp.UdpLite.InCsumErrors = value | |||||
case "IgnoredMulti": | |||||
procSnmp.UdpLite.IgnoredMulti = value | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return procSnmp, scanner.Err() | |||||
} |
@@ -0,0 +1,381 @@ | |||||
// Copyright 2022 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" | |||||
"errors" | |||||
"io" | |||||
"os" | |||||
"strconv" | |||||
"strings" | |||||
"github.com/prometheus/procfs/internal/util" | |||||
) | |||||
// ProcSnmp6 models the content of /proc/<pid>/net/snmp6. | |||||
type ProcSnmp6 struct { | |||||
// The process ID. | |||||
PID int | |||||
Ip6 | |||||
Icmp6 | |||||
Udp6 | |||||
UdpLite6 | |||||
} | |||||
type Ip6 struct { // nolint:revive | |||||
InReceives float64 | |||||
InHdrErrors float64 | |||||
InTooBigErrors float64 | |||||
InNoRoutes float64 | |||||
InAddrErrors float64 | |||||
InUnknownProtos float64 | |||||
InTruncatedPkts float64 | |||||
InDiscards float64 | |||||
InDelivers float64 | |||||
OutForwDatagrams float64 | |||||
OutRequests float64 | |||||
OutDiscards float64 | |||||
OutNoRoutes float64 | |||||
ReasmTimeout float64 | |||||
ReasmReqds float64 | |||||
ReasmOKs float64 | |||||
ReasmFails float64 | |||||
FragOKs float64 | |||||
FragFails float64 | |||||
FragCreates float64 | |||||
InMcastPkts float64 | |||||
OutMcastPkts float64 | |||||
InOctets float64 | |||||
OutOctets float64 | |||||
InMcastOctets float64 | |||||
OutMcastOctets float64 | |||||
InBcastOctets float64 | |||||
OutBcastOctets float64 | |||||
InNoECTPkts float64 | |||||
InECT1Pkts float64 | |||||
InECT0Pkts float64 | |||||
InCEPkts float64 | |||||
} | |||||
type Icmp6 struct { | |||||
InMsgs float64 | |||||
InErrors float64 | |||||
OutMsgs float64 | |||||
OutErrors float64 | |||||
InCsumErrors float64 | |||||
InDestUnreachs float64 | |||||
InPktTooBigs float64 | |||||
InTimeExcds float64 | |||||
InParmProblems float64 | |||||
InEchos float64 | |||||
InEchoReplies float64 | |||||
InGroupMembQueries float64 | |||||
InGroupMembResponses float64 | |||||
InGroupMembReductions float64 | |||||
InRouterSolicits float64 | |||||
InRouterAdvertisements float64 | |||||
InNeighborSolicits float64 | |||||
InNeighborAdvertisements float64 | |||||
InRedirects float64 | |||||
InMLDv2Reports float64 | |||||
OutDestUnreachs float64 | |||||
OutPktTooBigs float64 | |||||
OutTimeExcds float64 | |||||
OutParmProblems float64 | |||||
OutEchos float64 | |||||
OutEchoReplies float64 | |||||
OutGroupMembQueries float64 | |||||
OutGroupMembResponses float64 | |||||
OutGroupMembReductions float64 | |||||
OutRouterSolicits float64 | |||||
OutRouterAdvertisements float64 | |||||
OutNeighborSolicits float64 | |||||
OutNeighborAdvertisements float64 | |||||
OutRedirects float64 | |||||
OutMLDv2Reports float64 | |||||
InType1 float64 | |||||
InType134 float64 | |||||
InType135 float64 | |||||
InType136 float64 | |||||
InType143 float64 | |||||
OutType133 float64 | |||||
OutType135 float64 | |||||
OutType136 float64 | |||||
OutType143 float64 | |||||
} | |||||
type Udp6 struct { // nolint:revive | |||||
InDatagrams float64 | |||||
NoPorts float64 | |||||
InErrors float64 | |||||
OutDatagrams float64 | |||||
RcvbufErrors float64 | |||||
SndbufErrors float64 | |||||
InCsumErrors float64 | |||||
IgnoredMulti float64 | |||||
} | |||||
type UdpLite6 struct { // nolint:revive | |||||
InDatagrams float64 | |||||
NoPorts float64 | |||||
InErrors float64 | |||||
OutDatagrams float64 | |||||
RcvbufErrors float64 | |||||
SndbufErrors float64 | |||||
InCsumErrors float64 | |||||
} | |||||
func (p Proc) Snmp6() (ProcSnmp6, error) { | |||||
filename := p.path("net/snmp6") | |||||
data, err := util.ReadFileNoStat(filename) | |||||
if err != nil { | |||||
// On systems with IPv6 disabled, this file won't exist. | |||||
// Do nothing. | |||||
if errors.Is(err, os.ErrNotExist) { | |||||
return ProcSnmp6{PID: p.PID}, nil | |||||
} | |||||
return ProcSnmp6{PID: p.PID}, err | |||||
} | |||||
procSnmp6, err := parseSNMP6Stats(bytes.NewReader(data)) | |||||
procSnmp6.PID = p.PID | |||||
return procSnmp6, err | |||||
} | |||||
// parseSnmp6 parses the metrics from proc/<pid>/net/snmp6 file | |||||
// and returns a map contains those metrics. | |||||
func parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) { | |||||
var ( | |||||
scanner = bufio.NewScanner(r) | |||||
procSnmp6 = ProcSnmp6{} | |||||
) | |||||
for scanner.Scan() { | |||||
stat := strings.Fields(scanner.Text()) | |||||
if len(stat) < 2 { | |||||
continue | |||||
} | |||||
// Expect to have "6" in metric name, skip line otherwise | |||||
if sixIndex := strings.Index(stat[0], "6"); sixIndex != -1 { | |||||
protocol := stat[0][:sixIndex+1] | |||||
key := stat[0][sixIndex+1:] | |||||
value, err := strconv.ParseFloat(stat[1], 64) | |||||
if err != nil { | |||||
return procSnmp6, err | |||||
} | |||||
switch protocol { | |||||
case "Ip6": | |||||
switch key { | |||||
case "InReceives": | |||||
procSnmp6.Ip6.InReceives = value | |||||
case "InHdrErrors": | |||||
procSnmp6.Ip6.InHdrErrors = value | |||||
case "InTooBigErrors": | |||||
procSnmp6.Ip6.InTooBigErrors = value | |||||
case "InNoRoutes": | |||||
procSnmp6.Ip6.InNoRoutes = value | |||||
case "InAddrErrors": | |||||
procSnmp6.Ip6.InAddrErrors = value | |||||
case "InUnknownProtos": | |||||
procSnmp6.Ip6.InUnknownProtos = value | |||||
case "InTruncatedPkts": | |||||
procSnmp6.Ip6.InTruncatedPkts = value | |||||
case "InDiscards": | |||||
procSnmp6.Ip6.InDiscards = value | |||||
case "InDelivers": | |||||
procSnmp6.Ip6.InDelivers = value | |||||
case "OutForwDatagrams": | |||||
procSnmp6.Ip6.OutForwDatagrams = value | |||||
case "OutRequests": | |||||
procSnmp6.Ip6.OutRequests = value | |||||
case "OutDiscards": | |||||
procSnmp6.Ip6.OutDiscards = value | |||||
case "OutNoRoutes": | |||||
procSnmp6.Ip6.OutNoRoutes = value | |||||
case "ReasmTimeout": | |||||
procSnmp6.Ip6.ReasmTimeout = value | |||||
case "ReasmReqds": | |||||
procSnmp6.Ip6.ReasmReqds = value | |||||
case "ReasmOKs": | |||||
procSnmp6.Ip6.ReasmOKs = value | |||||
case "ReasmFails": | |||||
procSnmp6.Ip6.ReasmFails = value | |||||
case "FragOKs": | |||||
procSnmp6.Ip6.FragOKs = value | |||||
case "FragFails": | |||||
procSnmp6.Ip6.FragFails = value | |||||
case "FragCreates": | |||||
procSnmp6.Ip6.FragCreates = value | |||||
case "InMcastPkts": | |||||
procSnmp6.Ip6.InMcastPkts = value | |||||
case "OutMcastPkts": | |||||
procSnmp6.Ip6.OutMcastPkts = value | |||||
case "InOctets": | |||||
procSnmp6.Ip6.InOctets = value | |||||
case "OutOctets": | |||||
procSnmp6.Ip6.OutOctets = value | |||||
case "InMcastOctets": | |||||
procSnmp6.Ip6.InMcastOctets = value | |||||
case "OutMcastOctets": | |||||
procSnmp6.Ip6.OutMcastOctets = value | |||||
case "InBcastOctets": | |||||
procSnmp6.Ip6.InBcastOctets = value | |||||
case "OutBcastOctets": | |||||
procSnmp6.Ip6.OutBcastOctets = value | |||||
case "InNoECTPkts": | |||||
procSnmp6.Ip6.InNoECTPkts = value | |||||
case "InECT1Pkts": | |||||
procSnmp6.Ip6.InECT1Pkts = value | |||||
case "InECT0Pkts": | |||||
procSnmp6.Ip6.InECT0Pkts = value | |||||
case "InCEPkts": | |||||
procSnmp6.Ip6.InCEPkts = value | |||||
} | |||||
case "Icmp6": | |||||
switch key { | |||||
case "InMsgs": | |||||
procSnmp6.Icmp6.InMsgs = value | |||||
case "InErrors": | |||||
procSnmp6.Icmp6.InErrors = value | |||||
case "OutMsgs": | |||||
procSnmp6.Icmp6.OutMsgs = value | |||||
case "OutErrors": | |||||
procSnmp6.Icmp6.OutErrors = value | |||||
case "InCsumErrors": | |||||
procSnmp6.Icmp6.InCsumErrors = value | |||||
case "InDestUnreachs": | |||||
procSnmp6.Icmp6.InDestUnreachs = value | |||||
case "InPktTooBigs": | |||||
procSnmp6.Icmp6.InPktTooBigs = value | |||||
case "InTimeExcds": | |||||
procSnmp6.Icmp6.InTimeExcds = value | |||||
case "InParmProblems": | |||||
procSnmp6.Icmp6.InParmProblems = value | |||||
case "InEchos": | |||||
procSnmp6.Icmp6.InEchos = value | |||||
case "InEchoReplies": | |||||
procSnmp6.Icmp6.InEchoReplies = value | |||||
case "InGroupMembQueries": | |||||
procSnmp6.Icmp6.InGroupMembQueries = value | |||||
case "InGroupMembResponses": | |||||
procSnmp6.Icmp6.InGroupMembResponses = value | |||||
case "InGroupMembReductions": | |||||
procSnmp6.Icmp6.InGroupMembReductions = value | |||||
case "InRouterSolicits": | |||||
procSnmp6.Icmp6.InRouterSolicits = value | |||||
case "InRouterAdvertisements": | |||||
procSnmp6.Icmp6.InRouterAdvertisements = value | |||||
case "InNeighborSolicits": | |||||
procSnmp6.Icmp6.InNeighborSolicits = value | |||||
case "InNeighborAdvertisements": | |||||
procSnmp6.Icmp6.InNeighborAdvertisements = value | |||||
case "InRedirects": | |||||
procSnmp6.Icmp6.InRedirects = value | |||||
case "InMLDv2Reports": | |||||
procSnmp6.Icmp6.InMLDv2Reports = value | |||||
case "OutDestUnreachs": | |||||
procSnmp6.Icmp6.OutDestUnreachs = value | |||||
case "OutPktTooBigs": | |||||
procSnmp6.Icmp6.OutPktTooBigs = value | |||||
case "OutTimeExcds": | |||||
procSnmp6.Icmp6.OutTimeExcds = value | |||||
case "OutParmProblems": | |||||
procSnmp6.Icmp6.OutParmProblems = value | |||||
case "OutEchos": | |||||
procSnmp6.Icmp6.OutEchos = value | |||||
case "OutEchoReplies": | |||||
procSnmp6.Icmp6.OutEchoReplies = value | |||||
case "OutGroupMembQueries": | |||||
procSnmp6.Icmp6.OutGroupMembQueries = value | |||||
case "OutGroupMembResponses": | |||||
procSnmp6.Icmp6.OutGroupMembResponses = value | |||||
case "OutGroupMembReductions": | |||||
procSnmp6.Icmp6.OutGroupMembReductions = value | |||||
case "OutRouterSolicits": | |||||
procSnmp6.Icmp6.OutRouterSolicits = value | |||||
case "OutRouterAdvertisements": | |||||
procSnmp6.Icmp6.OutRouterAdvertisements = value | |||||
case "OutNeighborSolicits": | |||||
procSnmp6.Icmp6.OutNeighborSolicits = value | |||||
case "OutNeighborAdvertisements": | |||||
procSnmp6.Icmp6.OutNeighborAdvertisements = value | |||||
case "OutRedirects": | |||||
procSnmp6.Icmp6.OutRedirects = value | |||||
case "OutMLDv2Reports": | |||||
procSnmp6.Icmp6.OutMLDv2Reports = value | |||||
case "InType1": | |||||
procSnmp6.Icmp6.InType1 = value | |||||
case "InType134": | |||||
procSnmp6.Icmp6.InType134 = value | |||||
case "InType135": | |||||
procSnmp6.Icmp6.InType135 = value | |||||
case "InType136": | |||||
procSnmp6.Icmp6.InType136 = value | |||||
case "InType143": | |||||
procSnmp6.Icmp6.InType143 = value | |||||
case "OutType133": | |||||
procSnmp6.Icmp6.OutType133 = value | |||||
case "OutType135": | |||||
procSnmp6.Icmp6.OutType135 = value | |||||
case "OutType136": | |||||
procSnmp6.Icmp6.OutType136 = value | |||||
case "OutType143": | |||||
procSnmp6.Icmp6.OutType143 = value | |||||
} | |||||
case "Udp6": | |||||
switch key { | |||||
case "InDatagrams": | |||||
procSnmp6.Udp6.InDatagrams = value | |||||
case "NoPorts": | |||||
procSnmp6.Udp6.NoPorts = value | |||||
case "InErrors": | |||||
procSnmp6.Udp6.InErrors = value | |||||
case "OutDatagrams": | |||||
procSnmp6.Udp6.OutDatagrams = value | |||||
case "RcvbufErrors": | |||||
procSnmp6.Udp6.RcvbufErrors = value | |||||
case "SndbufErrors": | |||||
procSnmp6.Udp6.SndbufErrors = value | |||||
case "InCsumErrors": | |||||
procSnmp6.Udp6.InCsumErrors = value | |||||
case "IgnoredMulti": | |||||
procSnmp6.Udp6.IgnoredMulti = value | |||||
} | |||||
case "UdpLite6": | |||||
switch key { | |||||
case "InDatagrams": | |||||
procSnmp6.UdpLite6.InDatagrams = value | |||||
case "NoPorts": | |||||
procSnmp6.UdpLite6.NoPorts = value | |||||
case "InErrors": | |||||
procSnmp6.UdpLite6.InErrors = value | |||||
case "OutDatagrams": | |||||
procSnmp6.UdpLite6.OutDatagrams = value | |||||
case "RcvbufErrors": | |||||
procSnmp6.UdpLite6.RcvbufErrors = value | |||||
case "SndbufErrors": | |||||
procSnmp6.UdpLite6.SndbufErrors = value | |||||
case "InCsumErrors": | |||||
procSnmp6.UdpLite6.InCsumErrors = value | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return procSnmp6, scanner.Err() | |||||
} |
@@ -81,10 +81,10 @@ type ProcStat struct { | |||||
STime uint | STime uint | ||||
// Amount of time that this process's waited-for children have been | // Amount of time that this process's waited-for children have been | ||||
// scheduled in user mode, measured in clock ticks. | // scheduled in user mode, measured in clock ticks. | ||||
CUTime uint | |||||
CUTime int | |||||
// Amount of time that this process's waited-for children have been | // Amount of time that this process's waited-for children have been | ||||
// scheduled in kernel mode, measured in clock ticks. | // scheduled in kernel mode, measured in clock ticks. | ||||
CSTime uint | |||||
CSTime int | |||||
// For processes running a real-time scheduling policy, this is the negated | // For processes running a real-time scheduling policy, this is the negated | ||||
// scheduling priority, minus one. | // scheduling priority, minus one. | ||||
Priority int | Priority int | ||||
@@ -115,7 +115,7 @@ type ProcStat struct { | |||||
// NewStat returns the current status information of the process. | // NewStat returns the current status information of the process. | ||||
// | // | ||||
// Deprecated: use p.Stat() instead | |||||
// Deprecated: Use p.Stat() instead. | |||||
func (p Proc) NewStat() (ProcStat, error) { | func (p Proc) NewStat() (ProcStat, error) { | ||||
return p.Stat() | return p.Stat() | ||||
} | } | ||||
@@ -141,6 +141,11 @@ func (p Proc) Stat() (ProcStat, error) { | |||||
} | } | ||||
s.Comm = string(data[l+1 : r]) | s.Comm = string(data[l+1 : r]) | ||||
// Check the following resources for the details about the particular stat | |||||
// fields and their data types: | |||||
// * https://man7.org/linux/man-pages/man5/proc.5.html | |||||
// * https://man7.org/linux/man-pages/man3/scanf.3.html | |||||
_, err = fmt.Fscan( | _, err = fmt.Fscan( | ||||
bytes.NewBuffer(data[r+2:]), | bytes.NewBuffer(data[r+2:]), | ||||
&s.State, | &s.State, | ||||
@@ -33,37 +33,37 @@ type ProcStatus struct { | |||||
TGID int | TGID int | ||||
// Peak virtual memory size. | // Peak virtual memory size. | ||||
VmPeak uint64 // nolint:golint | |||||
VmPeak uint64 // nolint:revive | |||||
// Virtual memory size. | // Virtual memory size. | ||||
VmSize uint64 // nolint:golint | |||||
VmSize uint64 // nolint:revive | |||||
// Locked memory size. | // Locked memory size. | ||||
VmLck uint64 // nolint:golint | |||||
VmLck uint64 // nolint:revive | |||||
// Pinned memory size. | // Pinned memory size. | ||||
VmPin uint64 // nolint:golint | |||||
VmPin uint64 // nolint:revive | |||||
// Peak resident set size. | // Peak resident set size. | ||||
VmHWM uint64 // nolint:golint | |||||
VmHWM uint64 // nolint:revive | |||||
// Resident set size (sum of RssAnnon RssFile and RssShmem). | // Resident set size (sum of RssAnnon RssFile and RssShmem). | ||||
VmRSS uint64 // nolint:golint | |||||
VmRSS uint64 // nolint:revive | |||||
// Size of resident anonymous memory. | // Size of resident anonymous memory. | ||||
RssAnon uint64 // nolint:golint | |||||
RssAnon uint64 // nolint:revive | |||||
// Size of resident file mappings. | // Size of resident file mappings. | ||||
RssFile uint64 // nolint:golint | |||||
RssFile uint64 // nolint:revive | |||||
// Size of resident shared memory. | // Size of resident shared memory. | ||||
RssShmem uint64 // nolint:golint | |||||
RssShmem uint64 // nolint:revive | |||||
// Size of data segments. | // Size of data segments. | ||||
VmData uint64 // nolint:golint | |||||
VmData uint64 // nolint:revive | |||||
// Size of stack segments. | // Size of stack segments. | ||||
VmStk uint64 // nolint:golint | |||||
VmStk uint64 // nolint:revive | |||||
// Size of text segments. | // Size of text segments. | ||||
VmExe uint64 // nolint:golint | |||||
VmExe uint64 // nolint:revive | |||||
// Shared library code size. | // Shared library code size. | ||||
VmLib uint64 // nolint:golint | |||||
VmLib uint64 // nolint:revive | |||||
// Page table entries size. | // Page table entries size. | ||||
VmPTE uint64 // nolint:golint | |||||
VmPTE uint64 // nolint:revive | |||||
// Size of second-level page tables. | // Size of second-level page tables. | ||||
VmPMD uint64 // nolint:golint | |||||
VmPMD uint64 // nolint:revive | |||||
// Swapped-out virtual memory size by anonymous private. | // Swapped-out virtual memory size by anonymous private. | ||||
VmSwap uint64 // nolint:golint | |||||
VmSwap uint64 // nolint:revive | |||||
// Size of hugetlb memory portions | // Size of hugetlb memory portions | ||||
HugetlbPages uint64 | HugetlbPages uint64 | ||||
@@ -0,0 +1,51 @@ | |||||
// Copyright 2022 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 ( | |||||
"fmt" | |||||
"strings" | |||||
"github.com/prometheus/procfs/internal/util" | |||||
) | |||||
func sysctlToPath(sysctl string) string { | |||||
return strings.Replace(sysctl, ".", "/", -1) | |||||
} | |||||
func (fs FS) SysctlStrings(sysctl string) ([]string, error) { | |||||
value, err := util.SysReadFile(fs.proc.Path("sys", sysctlToPath(sysctl))) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return strings.Fields(value), nil | |||||
} | |||||
func (fs FS) SysctlInts(sysctl string) ([]int, error) { | |||||
fields, err := fs.SysctlStrings(sysctl) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
values := make([]int, len(fields)) | |||||
for i, f := range fields { | |||||
vp := util.NewValueParser(f) | |||||
values[i] = vp.Int() | |||||
if err := vp.Err(); err != nil { | |||||
return nil, fmt.Errorf("field %d in sysctl %s is not a valid int: %w", i, sysctl, err) | |||||
} | |||||
} | |||||
return values, nil | |||||
} |
@@ -40,7 +40,7 @@ type Schedstat struct { | |||||
CPUs []*SchedstatCPU | CPUs []*SchedstatCPU | ||||
} | } | ||||
// SchedstatCPU contains the values from one "cpu<N>" line | |||||
// SchedstatCPU contains the values from one "cpu<N>" line. | |||||
type SchedstatCPU struct { | type SchedstatCPU struct { | ||||
CPUNum string | CPUNum string | ||||
@@ -49,14 +49,14 @@ type SchedstatCPU struct { | |||||
RunTimeslices uint64 | RunTimeslices uint64 | ||||
} | } | ||||
// ProcSchedstat contains the values from /proc/<pid>/schedstat | |||||
// ProcSchedstat contains the values from `/proc/<pid>/schedstat`. | |||||
type ProcSchedstat struct { | type ProcSchedstat struct { | ||||
RunningNanoseconds uint64 | RunningNanoseconds uint64 | ||||
WaitingNanoseconds uint64 | WaitingNanoseconds uint64 | ||||
RunTimeslices uint64 | RunTimeslices uint64 | ||||
} | } | ||||
// Schedstat reads data from /proc/schedstat | |||||
// Schedstat reads data from `/proc/schedstat`. | |||||
func (fs FS) Schedstat() (*Schedstat, error) { | func (fs FS) Schedstat() (*Schedstat, error) { | ||||
file, err := os.Open(fs.proc.Path("schedstat")) | file, err := os.Open(fs.proc.Path("schedstat")) | ||||
if err != nil { | if err != nil { | ||||
@@ -137,7 +137,7 @@ func parseSlabInfo21(r *bytes.Reader) (SlabInfo, error) { | |||||
return s, nil | return s, nil | ||||
} | } | ||||
// SlabInfo reads data from /proc/slabinfo | |||||
// SlabInfo reads data from `/proc/slabinfo`. | |||||
func (fs FS) SlabInfo() (SlabInfo, error) { | func (fs FS) SlabInfo() (SlabInfo, error) { | ||||
// TODO: Consider passing options to allow for parsing different | // TODO: Consider passing options to allow for parsing different | ||||
// slabinfo versions. However, slabinfo 2.1 has been stable since | // slabinfo versions. However, slabinfo 2.1 has been stable since | ||||
@@ -0,0 +1,160 @@ | |||||
// Copyright 2022 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" | |||||
) | |||||
// Softirqs represents the softirq statistics. | |||||
type Softirqs struct { | |||||
Hi []uint64 | |||||
Timer []uint64 | |||||
NetTx []uint64 | |||||
NetRx []uint64 | |||||
Block []uint64 | |||||
IRQPoll []uint64 | |||||
Tasklet []uint64 | |||||
Sched []uint64 | |||||
HRTimer []uint64 | |||||
RCU []uint64 | |||||
} | |||||
func (fs FS) Softirqs() (Softirqs, error) { | |||||
fileName := fs.proc.Path("softirqs") | |||||
data, err := util.ReadFileNoStat(fileName) | |||||
if err != nil { | |||||
return Softirqs{}, err | |||||
} | |||||
reader := bytes.NewReader(data) | |||||
return parseSoftirqs(reader) | |||||
} | |||||
func parseSoftirqs(r io.Reader) (Softirqs, error) { | |||||
var ( | |||||
softirqs = Softirqs{} | |||||
scanner = bufio.NewScanner(r) | |||||
) | |||||
if !scanner.Scan() { | |||||
return Softirqs{}, fmt.Errorf("softirqs empty") | |||||
} | |||||
for scanner.Scan() { | |||||
parts := strings.Fields(scanner.Text()) | |||||
var err error | |||||
// require at least one cpu | |||||
if len(parts) < 2 { | |||||
continue | |||||
} | |||||
switch { | |||||
case parts[0] == "HI:": | |||||
perCPU := parts[1:] | |||||
softirqs.Hi = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.Hi[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (HI%d): %w", count, i, err) | |||||
} | |||||
} | |||||
case parts[0] == "TIMER:": | |||||
perCPU := parts[1:] | |||||
softirqs.Timer = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.Timer[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (TIMER%d): %w", count, i, err) | |||||
} | |||||
} | |||||
case parts[0] == "NET_TX:": | |||||
perCPU := parts[1:] | |||||
softirqs.NetTx = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.NetTx[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_TX%d): %w", count, i, err) | |||||
} | |||||
} | |||||
case parts[0] == "NET_RX:": | |||||
perCPU := parts[1:] | |||||
softirqs.NetRx = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.NetRx[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_RX%d): %w", count, i, err) | |||||
} | |||||
} | |||||
case parts[0] == "BLOCK:": | |||||
perCPU := parts[1:] | |||||
softirqs.Block = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.Block[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (BLOCK%d): %w", count, i, err) | |||||
} | |||||
} | |||||
case parts[0] == "IRQ_POLL:": | |||||
perCPU := parts[1:] | |||||
softirqs.IRQPoll = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.IRQPoll[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (IRQ_POLL%d): %w", count, i, err) | |||||
} | |||||
} | |||||
case parts[0] == "TASKLET:": | |||||
perCPU := parts[1:] | |||||
softirqs.Tasklet = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.Tasklet[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (TASKLET%d): %w", count, i, err) | |||||
} | |||||
} | |||||
case parts[0] == "SCHED:": | |||||
perCPU := parts[1:] | |||||
softirqs.Sched = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.Sched[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (SCHED%d): %w", count, i, err) | |||||
} | |||||
} | |||||
case parts[0] == "HRTIMER:": | |||||
perCPU := parts[1:] | |||||
softirqs.HRTimer = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.HRTimer[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (HRTIMER%d): %w", count, i, err) | |||||
} | |||||
} | |||||
case parts[0] == "RCU:": | |||||
perCPU := parts[1:] | |||||
softirqs.RCU = make([]uint64, len(perCPU)) | |||||
for i, count := range perCPU { | |||||
if softirqs.RCU[i], err = strconv.ParseUint(count, 10, 64); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (RCU%d): %w", count, i, err) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
if err := scanner.Err(); err != nil { | |||||
return Softirqs{}, fmt.Errorf("couldn't parse softirqs: %w", err) | |||||
} | |||||
return softirqs, scanner.Err() | |||||
} |
@@ -41,7 +41,7 @@ type CPUStat struct { | |||||
// SoftIRQStat represent the softirq statistics as exported in the procfs stat file. | // SoftIRQStat represent the softirq statistics as exported in the procfs stat file. | ||||
// A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html | // A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html | ||||
// It is possible to get per-cpu stats by reading /proc/softirqs | |||||
// It is possible to get per-cpu stats by reading `/proc/softirqs`. | |||||
type SoftIRQStat struct { | type SoftIRQStat struct { | ||||
Hi uint64 | Hi uint64 | ||||
Timer uint64 | Timer uint64 | ||||
@@ -145,7 +145,7 @@ func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) { | |||||
// NewStat returns information about current cpu/process statistics. | // NewStat returns information about current cpu/process statistics. | ||||
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt | // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt | ||||
// | // | ||||
// Deprecated: use fs.Stat() instead | |||||
// Deprecated: Use fs.Stat() instead. | |||||
func NewStat() (Stat, error) { | func NewStat() (Stat, error) { | ||||
fs, err := NewFS(fs.DefaultProcMountPoint) | fs, err := NewFS(fs.DefaultProcMountPoint) | ||||
if err != nil { | if err != nil { | ||||
@@ -155,15 +155,15 @@ func NewStat() (Stat, error) { | |||||
} | } | ||||
// NewStat returns information about current cpu/process statistics. | // NewStat returns information about current cpu/process statistics. | ||||
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt | |||||
// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt | |||||
// | // | ||||
// Deprecated: use fs.Stat() instead | |||||
// Deprecated: Use fs.Stat() instead. | |||||
func (fs FS) NewStat() (Stat, error) { | func (fs FS) NewStat() (Stat, error) { | ||||
return fs.Stat() | return fs.Stat() | ||||
} | } | ||||
// Stat returns information about current cpu/process statistics. | // Stat returns information about current cpu/process statistics. | ||||
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt | |||||
// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt | |||||
func (fs FS) Stat() (Stat, error) { | func (fs FS) Stat() (Stat, error) { | ||||
fileName := fs.proc.Path("stat") | fileName := fs.proc.Path("stat") | ||||
data, err := util.ReadFileNoStat(fileName) | data, err := util.ReadFileNoStat(fileName) | ||||
@@ -11,13 +11,13 @@ | |||||
// 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. | ||||
//go:build !windows | |||||
// +build !windows | // +build !windows | ||||
package procfs | package procfs | ||||
import ( | import ( | ||||
"fmt" | "fmt" | ||||
"io/ioutil" | |||||
"os" | "os" | ||||
"path/filepath" | "path/filepath" | ||||
"strings" | "strings" | ||||
@@ -29,7 +29,7 @@ import ( | |||||
// https://www.kernel.org/doc/Documentation/sysctl/vm.txt | // https://www.kernel.org/doc/Documentation/sysctl/vm.txt | ||||
// Each setting is exposed as a single file. | // Each setting is exposed as a single file. | ||||
// Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array | // Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array | ||||
// and numa_zonelist_order (deprecated) which is a string | |||||
// and numa_zonelist_order (deprecated) which is a string. | |||||
type VM struct { | type VM struct { | ||||
AdminReserveKbytes *int64 // /proc/sys/vm/admin_reserve_kbytes | AdminReserveKbytes *int64 // /proc/sys/vm/admin_reserve_kbytes | ||||
BlockDump *int64 // /proc/sys/vm/block_dump | BlockDump *int64 // /proc/sys/vm/block_dump | ||||
@@ -87,7 +87,7 @@ func (fs FS) VM() (*VM, error) { | |||||
return nil, fmt.Errorf("%s is not a directory", path) | return nil, fmt.Errorf("%s is not a directory", path) | ||||
} | } | ||||
files, err := ioutil.ReadDir(path) | |||||
files, err := os.ReadDir(path) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
@@ -11,6 +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. | ||||
//go:build !windows | |||||
// +build !windows | // +build !windows | ||||
package procfs | package procfs | ||||
@@ -18,7 +19,7 @@ package procfs | |||||
import ( | import ( | ||||
"bytes" | "bytes" | ||||
"fmt" | "fmt" | ||||
"io/ioutil" | |||||
"os" | |||||
"regexp" | "regexp" | ||||
"strings" | "strings" | ||||
@@ -72,7 +73,7 @@ var nodeZoneRE = regexp.MustCompile(`(\d+), zone\s+(\w+)`) | |||||
// structs containing the relevant info. More information available here: | // structs containing the relevant info. More information available here: | ||||
// https://www.kernel.org/doc/Documentation/sysctl/vm.txt | // https://www.kernel.org/doc/Documentation/sysctl/vm.txt | ||||
func (fs FS) Zoneinfo() ([]Zoneinfo, error) { | func (fs FS) Zoneinfo() ([]Zoneinfo, error) { | ||||
data, err := ioutil.ReadFile(fs.proc.Path("zoneinfo")) | |||||
data, err := os.ReadFile(fs.proc.Path("zoneinfo")) | |||||
if err != nil { | if err != nil { | ||||
return nil, fmt.Errorf("error reading zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err) | return nil, fmt.Errorf("error reading zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err) | ||||
} | } | ||||
@@ -1,3 +0,0 @@ | |||||
# This source code refers to The Go Authors for copyright purposes. | |||||
# The master list of authors is in the main Go distribution, | |||||
# visible at http://tip.golang.org/AUTHORS. |
@@ -1,3 +0,0 @@ | |||||
# This source code was written by the Go contributors. | |||||
# The master list of contributors is in the main Go distribution, | |||||
# visible at http://tip.golang.org/CONTRIBUTORS. |
@@ -0,0 +1,29 @@ | |||||
// Copyright 2021 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc | |||||
// +build darwin freebsd netbsd openbsd | |||||
// +build gc | |||||
#include "textflag.h" | |||||
// System call support for RISCV64 BSD | |||||
// Just jump to package syscall's implementation for all these functions. | |||||
// The runtime may know about them. | |||||
TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||||
JMP syscall·Syscall(SB) | |||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||||
JMP syscall·Syscall6(SB) | |||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 | |||||
JMP syscall·Syscall9(SB) | |||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||||
JMP syscall·RawSyscall(SB) | |||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||||
JMP syscall·RawSyscall6(SB) |
@@ -0,0 +1,54 @@ | |||||
// Copyright 2022 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
//go:build linux && loong64 && gc | |||||
// +build linux | |||||
// +build loong64 | |||||
// +build gc | |||||
#include "textflag.h" | |||||
// Just jump to package syscall's implementation for all these functions. | |||||
// The runtime may know about them. | |||||
TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||||
JMP syscall·Syscall(SB) | |||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||||
JMP syscall·Syscall6(SB) | |||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 | |||||
JAL runtime·entersyscall(SB) | |||||
MOVV a1+8(FP), R4 | |||||
MOVV a2+16(FP), R5 | |||||
MOVV a3+24(FP), R6 | |||||
MOVV R0, R7 | |||||
MOVV R0, R8 | |||||
MOVV R0, R9 | |||||
MOVV trap+0(FP), R11 // syscall entry | |||||
SYSCALL | |||||
MOVV R4, r1+32(FP) | |||||
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0 | |||||
JAL runtime·exitsyscall(SB) | |||||
RET | |||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||||
JMP syscall·RawSyscall(SB) | |||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||||
JMP syscall·RawSyscall6(SB) | |||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 | |||||
MOVV a1+8(FP), R4 | |||||
MOVV a2+16(FP), R5 | |||||
MOVV a3+24(FP), R6 | |||||
MOVV R0, R7 | |||||
MOVV R0, R8 | |||||
MOVV R0, R9 | |||||
MOVV trap+0(FP), R11 // syscall entry | |||||
SYSCALL | |||||
MOVV R4, r1+32(FP) | |||||
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0 | |||||
RET |
@@ -2,8 +2,8 @@ | |||||
// Use of this source code is governed by a BSD-style | // Use of this source code is governed by a BSD-style | ||||
// license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
// | // | ||||
//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh | |||||
// +build 386 amd64 amd64p32 alpha arm arm64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh | |||||
//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh | |||||
// +build 386 amd64 amd64p32 alpha arm arm64 loong64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh | |||||
package unix | package unix | ||||
@@ -1,233 +0,0 @@ | |||||
// Copyright 2017 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep | |||||
// them here for backwards compatibility. | |||||
package unix | |||||
const ( | |||||
DLT_HHDLC = 0x79 | |||||
IFF_SMART = 0x20 | |||||
IFT_1822 = 0x2 | |||||
IFT_A12MPPSWITCH = 0x82 | |||||
IFT_AAL2 = 0xbb | |||||
IFT_AAL5 = 0x31 | |||||
IFT_ADSL = 0x5e | |||||
IFT_AFLANE8023 = 0x3b | |||||
IFT_AFLANE8025 = 0x3c | |||||
IFT_ARAP = 0x58 | |||||
IFT_ARCNET = 0x23 | |||||
IFT_ARCNETPLUS = 0x24 | |||||
IFT_ASYNC = 0x54 | |||||
IFT_ATM = 0x25 | |||||
IFT_ATMDXI = 0x69 | |||||
IFT_ATMFUNI = 0x6a | |||||
IFT_ATMIMA = 0x6b | |||||
IFT_ATMLOGICAL = 0x50 | |||||
IFT_ATMRADIO = 0xbd | |||||
IFT_ATMSUBINTERFACE = 0x86 | |||||
IFT_ATMVCIENDPT = 0xc2 | |||||
IFT_ATMVIRTUAL = 0x95 | |||||
IFT_BGPPOLICYACCOUNTING = 0xa2 | |||||
IFT_BSC = 0x53 | |||||
IFT_CCTEMUL = 0x3d | |||||
IFT_CEPT = 0x13 | |||||
IFT_CES = 0x85 | |||||
IFT_CHANNEL = 0x46 | |||||
IFT_CNR = 0x55 | |||||
IFT_COFFEE = 0x84 | |||||
IFT_COMPOSITELINK = 0x9b | |||||
IFT_DCN = 0x8d | |||||
IFT_DIGITALPOWERLINE = 0x8a | |||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba | |||||
IFT_DLSW = 0x4a | |||||
IFT_DOCSCABLEDOWNSTREAM = 0x80 | |||||
IFT_DOCSCABLEMACLAYER = 0x7f | |||||
IFT_DOCSCABLEUPSTREAM = 0x81 | |||||
IFT_DS0 = 0x51 | |||||
IFT_DS0BUNDLE = 0x52 | |||||
IFT_DS1FDL = 0xaa | |||||
IFT_DS3 = 0x1e | |||||
IFT_DTM = 0x8c | |||||
IFT_DVBASILN = 0xac | |||||
IFT_DVBASIOUT = 0xad | |||||
IFT_DVBRCCDOWNSTREAM = 0x93 | |||||
IFT_DVBRCCMACLAYER = 0x92 | |||||
IFT_DVBRCCUPSTREAM = 0x94 | |||||
IFT_ENC = 0xf4 | |||||
IFT_EON = 0x19 | |||||
IFT_EPLRS = 0x57 | |||||
IFT_ESCON = 0x49 | |||||
IFT_ETHER = 0x6 | |||||
IFT_FAITH = 0xf2 | |||||
IFT_FAST = 0x7d | |||||
IFT_FASTETHER = 0x3e | |||||
IFT_FASTETHERFX = 0x45 | |||||
IFT_FDDI = 0xf | |||||
IFT_FIBRECHANNEL = 0x38 | |||||
IFT_FRAMERELAYINTERCONNECT = 0x3a | |||||
IFT_FRAMERELAYMPI = 0x5c | |||||
IFT_FRDLCIENDPT = 0xc1 | |||||
IFT_FRELAY = 0x20 | |||||
IFT_FRELAYDCE = 0x2c | |||||
IFT_FRF16MFRBUNDLE = 0xa3 | |||||
IFT_FRFORWARD = 0x9e | |||||
IFT_G703AT2MB = 0x43 | |||||
IFT_G703AT64K = 0x42 | |||||
IFT_GIF = 0xf0 | |||||
IFT_GIGABITETHERNET = 0x75 | |||||
IFT_GR303IDT = 0xb2 | |||||
IFT_GR303RDT = 0xb1 | |||||
IFT_H323GATEKEEPER = 0xa4 | |||||
IFT_H323PROXY = 0xa5 | |||||
IFT_HDH1822 = 0x3 | |||||
IFT_HDLC = 0x76 | |||||
IFT_HDSL2 = 0xa8 | |||||
IFT_HIPERLAN2 = 0xb7 | |||||
IFT_HIPPI = 0x2f | |||||
IFT_HIPPIINTERFACE = 0x39 | |||||
IFT_HOSTPAD = 0x5a | |||||
IFT_HSSI = 0x2e | |||||
IFT_HY = 0xe | |||||
IFT_IBM370PARCHAN = 0x48 | |||||
IFT_IDSL = 0x9a | |||||
IFT_IEEE80211 = 0x47 | |||||
IFT_IEEE80212 = 0x37 | |||||
IFT_IEEE8023ADLAG = 0xa1 | |||||
IFT_IFGSN = 0x91 | |||||
IFT_IMT = 0xbe | |||||
IFT_INTERLEAVE = 0x7c | |||||
IFT_IP = 0x7e | |||||
IFT_IPFORWARD = 0x8e | |||||
IFT_IPOVERATM = 0x72 | |||||
IFT_IPOVERCDLC = 0x6d | |||||
IFT_IPOVERCLAW = 0x6e | |||||
IFT_IPSWITCH = 0x4e | |||||
IFT_IPXIP = 0xf9 | |||||
IFT_ISDN = 0x3f | |||||
IFT_ISDNBASIC = 0x14 | |||||
IFT_ISDNPRIMARY = 0x15 | |||||
IFT_ISDNS = 0x4b | |||||
IFT_ISDNU = 0x4c | |||||
IFT_ISO88022LLC = 0x29 | |||||
IFT_ISO88023 = 0x7 | |||||
IFT_ISO88024 = 0x8 | |||||
IFT_ISO88025 = 0x9 | |||||
IFT_ISO88025CRFPINT = 0x62 | |||||
IFT_ISO88025DTR = 0x56 | |||||
IFT_ISO88025FIBER = 0x73 | |||||
IFT_ISO88026 = 0xa | |||||
IFT_ISUP = 0xb3 | |||||
IFT_L3IPXVLAN = 0x89 | |||||
IFT_LAPB = 0x10 | |||||
IFT_LAPD = 0x4d | |||||
IFT_LAPF = 0x77 | |||||
IFT_LOCALTALK = 0x2a | |||||
IFT_LOOP = 0x18 | |||||
IFT_MEDIAMAILOVERIP = 0x8b | |||||
IFT_MFSIGLINK = 0xa7 | |||||
IFT_MIOX25 = 0x26 | |||||
IFT_MODEM = 0x30 | |||||
IFT_MPC = 0x71 | |||||
IFT_MPLS = 0xa6 | |||||
IFT_MPLSTUNNEL = 0x96 | |||||
IFT_MSDSL = 0x8f | |||||
IFT_MVL = 0xbf | |||||
IFT_MYRINET = 0x63 | |||||
IFT_NFAS = 0xaf | |||||
IFT_NSIP = 0x1b | |||||
IFT_OPTICALCHANNEL = 0xc3 | |||||
IFT_OPTICALTRANSPORT = 0xc4 | |||||
IFT_OTHER = 0x1 | |||||
IFT_P10 = 0xc | |||||
IFT_P80 = 0xd | |||||
IFT_PARA = 0x22 | |||||
IFT_PFLOG = 0xf6 | |||||
IFT_PFSYNC = 0xf7 | |||||
IFT_PLC = 0xae | |||||
IFT_POS = 0xab | |||||
IFT_PPPMULTILINKBUNDLE = 0x6c | |||||
IFT_PROPBWAP2MP = 0xb8 | |||||
IFT_PROPCNLS = 0x59 | |||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 | |||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 | |||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 | |||||
IFT_PROPMUX = 0x36 | |||||
IFT_PROPWIRELESSP2P = 0x9d | |||||
IFT_PTPSERIAL = 0x16 | |||||
IFT_PVC = 0xf1 | |||||
IFT_QLLC = 0x44 | |||||
IFT_RADIOMAC = 0xbc | |||||
IFT_RADSL = 0x5f | |||||
IFT_REACHDSL = 0xc0 | |||||
IFT_RFC1483 = 0x9f | |||||
IFT_RS232 = 0x21 | |||||
IFT_RSRB = 0x4f | |||||
IFT_SDLC = 0x11 | |||||
IFT_SDSL = 0x60 | |||||
IFT_SHDSL = 0xa9 | |||||
IFT_SIP = 0x1f | |||||
IFT_SLIP = 0x1c | |||||
IFT_SMDSDXI = 0x2b | |||||
IFT_SMDSICIP = 0x34 | |||||
IFT_SONET = 0x27 | |||||
IFT_SONETOVERHEADCHANNEL = 0xb9 | |||||
IFT_SONETPATH = 0x32 | |||||
IFT_SONETVT = 0x33 | |||||
IFT_SRP = 0x97 | |||||
IFT_SS7SIGLINK = 0x9c | |||||
IFT_STACKTOSTACK = 0x6f | |||||
IFT_STARLAN = 0xb | |||||
IFT_STF = 0xd7 | |||||
IFT_T1 = 0x12 | |||||
IFT_TDLC = 0x74 | |||||
IFT_TERMPAD = 0x5b | |||||
IFT_TR008 = 0xb0 | |||||
IFT_TRANSPHDLC = 0x7b | |||||
IFT_TUNNEL = 0x83 | |||||
IFT_ULTRA = 0x1d | |||||
IFT_USB = 0xa0 | |||||
IFT_V11 = 0x40 | |||||
IFT_V35 = 0x2d | |||||
IFT_V36 = 0x41 | |||||
IFT_V37 = 0x78 | |||||
IFT_VDSL = 0x61 | |||||
IFT_VIRTUALIPADDRESS = 0x70 | |||||
IFT_VOICEEM = 0x64 | |||||
IFT_VOICEENCAP = 0x67 | |||||
IFT_VOICEFXO = 0x65 | |||||
IFT_VOICEFXS = 0x66 | |||||
IFT_VOICEOVERATM = 0x98 | |||||
IFT_VOICEOVERFRAMERELAY = 0x99 | |||||
IFT_VOICEOVERIP = 0x68 | |||||
IFT_X213 = 0x5d | |||||
IFT_X25 = 0x5 | |||||
IFT_X25DDN = 0x4 | |||||
IFT_X25HUNTGROUP = 0x7a | |||||
IFT_X25MLP = 0x79 | |||||
IFT_X25PLE = 0x28 | |||||
IFT_XETHER = 0x1a | |||||
IPPROTO_MAXID = 0x34 | |||||
IPV6_FAITH = 0x1d | |||||
IPV6_MIN_MEMBERSHIPS = 0x1f | |||||
IP_FAITH = 0x16 | |||||
IP_MAX_SOURCE_FILTER = 0x400 | |||||
IP_MIN_MEMBERSHIPS = 0x1f | |||||
MAP_NORESERVE = 0x40 | |||||
MAP_RENAME = 0x20 | |||||
NET_RT_MAXID = 0x6 | |||||
RTF_PRCLONING = 0x10000 | |||||
RTM_OLDADD = 0x9 | |||||
RTM_OLDDEL = 0xa | |||||
RT_CACHING_CONTEXT = 0x1 | |||||
RT_NORTREF = 0x2 | |||||
SIOCADDRT = 0x8030720a | |||||
SIOCALIFADDR = 0x8118691b | |||||
SIOCDELRT = 0x8030720b | |||||
SIOCDLIFADDR = 0x8118691d | |||||
SIOCGLIFADDR = 0xc118691c | |||||
SIOCGLIFPHYADDR = 0xc118694b | |||||
SIOCSLIFPHYADDR = 0x8118694a | |||||
) |
@@ -1,233 +0,0 @@ | |||||
// Copyright 2017 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep | |||||
// them here for backwards compatibility. | |||||
package unix | |||||
const ( | |||||
DLT_HHDLC = 0x79 | |||||
IFF_SMART = 0x20 | |||||
IFT_1822 = 0x2 | |||||
IFT_A12MPPSWITCH = 0x82 | |||||
IFT_AAL2 = 0xbb | |||||
IFT_AAL5 = 0x31 | |||||
IFT_ADSL = 0x5e | |||||
IFT_AFLANE8023 = 0x3b | |||||
IFT_AFLANE8025 = 0x3c | |||||
IFT_ARAP = 0x58 | |||||
IFT_ARCNET = 0x23 | |||||
IFT_ARCNETPLUS = 0x24 | |||||
IFT_ASYNC = 0x54 | |||||
IFT_ATM = 0x25 | |||||
IFT_ATMDXI = 0x69 | |||||
IFT_ATMFUNI = 0x6a | |||||
IFT_ATMIMA = 0x6b | |||||
IFT_ATMLOGICAL = 0x50 | |||||
IFT_ATMRADIO = 0xbd | |||||
IFT_ATMSUBINTERFACE = 0x86 | |||||
IFT_ATMVCIENDPT = 0xc2 | |||||
IFT_ATMVIRTUAL = 0x95 | |||||
IFT_BGPPOLICYACCOUNTING = 0xa2 | |||||
IFT_BSC = 0x53 | |||||
IFT_CCTEMUL = 0x3d | |||||
IFT_CEPT = 0x13 | |||||
IFT_CES = 0x85 | |||||
IFT_CHANNEL = 0x46 | |||||
IFT_CNR = 0x55 | |||||
IFT_COFFEE = 0x84 | |||||
IFT_COMPOSITELINK = 0x9b | |||||
IFT_DCN = 0x8d | |||||
IFT_DIGITALPOWERLINE = 0x8a | |||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba | |||||
IFT_DLSW = 0x4a | |||||
IFT_DOCSCABLEDOWNSTREAM = 0x80 | |||||
IFT_DOCSCABLEMACLAYER = 0x7f | |||||
IFT_DOCSCABLEUPSTREAM = 0x81 | |||||
IFT_DS0 = 0x51 | |||||
IFT_DS0BUNDLE = 0x52 | |||||
IFT_DS1FDL = 0xaa | |||||
IFT_DS3 = 0x1e | |||||
IFT_DTM = 0x8c | |||||
IFT_DVBASILN = 0xac | |||||
IFT_DVBASIOUT = 0xad | |||||
IFT_DVBRCCDOWNSTREAM = 0x93 | |||||
IFT_DVBRCCMACLAYER = 0x92 | |||||
IFT_DVBRCCUPSTREAM = 0x94 | |||||
IFT_ENC = 0xf4 | |||||
IFT_EON = 0x19 | |||||
IFT_EPLRS = 0x57 | |||||
IFT_ESCON = 0x49 | |||||
IFT_ETHER = 0x6 | |||||
IFT_FAITH = 0xf2 | |||||
IFT_FAST = 0x7d | |||||
IFT_FASTETHER = 0x3e | |||||
IFT_FASTETHERFX = 0x45 | |||||
IFT_FDDI = 0xf | |||||
IFT_FIBRECHANNEL = 0x38 | |||||
IFT_FRAMERELAYINTERCONNECT = 0x3a | |||||
IFT_FRAMERELAYMPI = 0x5c | |||||
IFT_FRDLCIENDPT = 0xc1 | |||||
IFT_FRELAY = 0x20 | |||||
IFT_FRELAYDCE = 0x2c | |||||
IFT_FRF16MFRBUNDLE = 0xa3 | |||||
IFT_FRFORWARD = 0x9e | |||||
IFT_G703AT2MB = 0x43 | |||||
IFT_G703AT64K = 0x42 | |||||
IFT_GIF = 0xf0 | |||||
IFT_GIGABITETHERNET = 0x75 | |||||
IFT_GR303IDT = 0xb2 | |||||
IFT_GR303RDT = 0xb1 | |||||
IFT_H323GATEKEEPER = 0xa4 | |||||
IFT_H323PROXY = 0xa5 | |||||
IFT_HDH1822 = 0x3 | |||||
IFT_HDLC = 0x76 | |||||
IFT_HDSL2 = 0xa8 | |||||
IFT_HIPERLAN2 = 0xb7 | |||||
IFT_HIPPI = 0x2f | |||||
IFT_HIPPIINTERFACE = 0x39 | |||||
IFT_HOSTPAD = 0x5a | |||||
IFT_HSSI = 0x2e | |||||
IFT_HY = 0xe | |||||
IFT_IBM370PARCHAN = 0x48 | |||||
IFT_IDSL = 0x9a | |||||
IFT_IEEE80211 = 0x47 | |||||
IFT_IEEE80212 = 0x37 | |||||
IFT_IEEE8023ADLAG = 0xa1 | |||||
IFT_IFGSN = 0x91 | |||||
IFT_IMT = 0xbe | |||||
IFT_INTERLEAVE = 0x7c | |||||
IFT_IP = 0x7e | |||||
IFT_IPFORWARD = 0x8e | |||||
IFT_IPOVERATM = 0x72 | |||||
IFT_IPOVERCDLC = 0x6d | |||||
IFT_IPOVERCLAW = 0x6e | |||||
IFT_IPSWITCH = 0x4e | |||||
IFT_IPXIP = 0xf9 | |||||
IFT_ISDN = 0x3f | |||||
IFT_ISDNBASIC = 0x14 | |||||
IFT_ISDNPRIMARY = 0x15 | |||||
IFT_ISDNS = 0x4b | |||||
IFT_ISDNU = 0x4c | |||||
IFT_ISO88022LLC = 0x29 | |||||
IFT_ISO88023 = 0x7 | |||||
IFT_ISO88024 = 0x8 | |||||
IFT_ISO88025 = 0x9 | |||||
IFT_ISO88025CRFPINT = 0x62 | |||||
IFT_ISO88025DTR = 0x56 | |||||
IFT_ISO88025FIBER = 0x73 | |||||
IFT_ISO88026 = 0xa | |||||
IFT_ISUP = 0xb3 | |||||
IFT_L3IPXVLAN = 0x89 | |||||
IFT_LAPB = 0x10 | |||||
IFT_LAPD = 0x4d | |||||
IFT_LAPF = 0x77 | |||||
IFT_LOCALTALK = 0x2a | |||||
IFT_LOOP = 0x18 | |||||
IFT_MEDIAMAILOVERIP = 0x8b | |||||
IFT_MFSIGLINK = 0xa7 | |||||
IFT_MIOX25 = 0x26 | |||||
IFT_MODEM = 0x30 | |||||
IFT_MPC = 0x71 | |||||
IFT_MPLS = 0xa6 | |||||
IFT_MPLSTUNNEL = 0x96 | |||||
IFT_MSDSL = 0x8f | |||||
IFT_MVL = 0xbf | |||||
IFT_MYRINET = 0x63 | |||||
IFT_NFAS = 0xaf | |||||
IFT_NSIP = 0x1b | |||||
IFT_OPTICALCHANNEL = 0xc3 | |||||
IFT_OPTICALTRANSPORT = 0xc4 | |||||
IFT_OTHER = 0x1 | |||||
IFT_P10 = 0xc | |||||
IFT_P80 = 0xd | |||||
IFT_PARA = 0x22 | |||||
IFT_PFLOG = 0xf6 | |||||
IFT_PFSYNC = 0xf7 | |||||
IFT_PLC = 0xae | |||||
IFT_POS = 0xab | |||||
IFT_PPPMULTILINKBUNDLE = 0x6c | |||||
IFT_PROPBWAP2MP = 0xb8 | |||||
IFT_PROPCNLS = 0x59 | |||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 | |||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 | |||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 | |||||
IFT_PROPMUX = 0x36 | |||||
IFT_PROPWIRELESSP2P = 0x9d | |||||
IFT_PTPSERIAL = 0x16 | |||||
IFT_PVC = 0xf1 | |||||
IFT_QLLC = 0x44 | |||||
IFT_RADIOMAC = 0xbc | |||||
IFT_RADSL = 0x5f | |||||
IFT_REACHDSL = 0xc0 | |||||
IFT_RFC1483 = 0x9f | |||||
IFT_RS232 = 0x21 | |||||
IFT_RSRB = 0x4f | |||||
IFT_SDLC = 0x11 | |||||
IFT_SDSL = 0x60 | |||||
IFT_SHDSL = 0xa9 | |||||
IFT_SIP = 0x1f | |||||
IFT_SLIP = 0x1c | |||||
IFT_SMDSDXI = 0x2b | |||||
IFT_SMDSICIP = 0x34 | |||||
IFT_SONET = 0x27 | |||||
IFT_SONETOVERHEADCHANNEL = 0xb9 | |||||
IFT_SONETPATH = 0x32 | |||||
IFT_SONETVT = 0x33 | |||||
IFT_SRP = 0x97 | |||||
IFT_SS7SIGLINK = 0x9c | |||||
IFT_STACKTOSTACK = 0x6f | |||||
IFT_STARLAN = 0xb | |||||
IFT_STF = 0xd7 | |||||
IFT_T1 = 0x12 | |||||
IFT_TDLC = 0x74 | |||||
IFT_TERMPAD = 0x5b | |||||
IFT_TR008 = 0xb0 | |||||
IFT_TRANSPHDLC = 0x7b | |||||
IFT_TUNNEL = 0x83 | |||||
IFT_ULTRA = 0x1d | |||||
IFT_USB = 0xa0 | |||||
IFT_V11 = 0x40 | |||||
IFT_V35 = 0x2d | |||||
IFT_V36 = 0x41 | |||||
IFT_V37 = 0x78 | |||||
IFT_VDSL = 0x61 | |||||
IFT_VIRTUALIPADDRESS = 0x70 | |||||
IFT_VOICEEM = 0x64 | |||||
IFT_VOICEENCAP = 0x67 | |||||
IFT_VOICEFXO = 0x65 | |||||
IFT_VOICEFXS = 0x66 | |||||
IFT_VOICEOVERATM = 0x98 | |||||
IFT_VOICEOVERFRAMERELAY = 0x99 | |||||
IFT_VOICEOVERIP = 0x68 | |||||
IFT_X213 = 0x5d | |||||
IFT_X25 = 0x5 | |||||
IFT_X25DDN = 0x4 | |||||
IFT_X25HUNTGROUP = 0x7a | |||||
IFT_X25MLP = 0x79 | |||||
IFT_X25PLE = 0x28 | |||||
IFT_XETHER = 0x1a | |||||
IPPROTO_MAXID = 0x34 | |||||
IPV6_FAITH = 0x1d | |||||
IPV6_MIN_MEMBERSHIPS = 0x1f | |||||
IP_FAITH = 0x16 | |||||
IP_MAX_SOURCE_FILTER = 0x400 | |||||
IP_MIN_MEMBERSHIPS = 0x1f | |||||
MAP_NORESERVE = 0x40 | |||||
MAP_RENAME = 0x20 | |||||
NET_RT_MAXID = 0x6 | |||||
RTF_PRCLONING = 0x10000 | |||||
RTM_OLDADD = 0x9 | |||||
RTM_OLDDEL = 0xa | |||||
RT_CACHING_CONTEXT = 0x1 | |||||
RT_NORTREF = 0x2 | |||||
SIOCADDRT = 0x8040720a | |||||
SIOCALIFADDR = 0x8118691b | |||||
SIOCDELRT = 0x8040720b | |||||
SIOCDLIFADDR = 0x8118691d | |||||
SIOCGLIFADDR = 0xc118691c | |||||
SIOCGLIFPHYADDR = 0xc118694b | |||||
SIOCSLIFPHYADDR = 0x8118694a | |||||
) |
@@ -1,226 +0,0 @@ | |||||
// Copyright 2017 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package unix | |||||
const ( | |||||
IFT_1822 = 0x2 | |||||
IFT_A12MPPSWITCH = 0x82 | |||||
IFT_AAL2 = 0xbb | |||||
IFT_AAL5 = 0x31 | |||||
IFT_ADSL = 0x5e | |||||
IFT_AFLANE8023 = 0x3b | |||||
IFT_AFLANE8025 = 0x3c | |||||
IFT_ARAP = 0x58 | |||||
IFT_ARCNET = 0x23 | |||||
IFT_ARCNETPLUS = 0x24 | |||||
IFT_ASYNC = 0x54 | |||||
IFT_ATM = 0x25 | |||||
IFT_ATMDXI = 0x69 | |||||
IFT_ATMFUNI = 0x6a | |||||
IFT_ATMIMA = 0x6b | |||||
IFT_ATMLOGICAL = 0x50 | |||||
IFT_ATMRADIO = 0xbd | |||||
IFT_ATMSUBINTERFACE = 0x86 | |||||
IFT_ATMVCIENDPT = 0xc2 | |||||
IFT_ATMVIRTUAL = 0x95 | |||||
IFT_BGPPOLICYACCOUNTING = 0xa2 | |||||
IFT_BSC = 0x53 | |||||
IFT_CCTEMUL = 0x3d | |||||
IFT_CEPT = 0x13 | |||||
IFT_CES = 0x85 | |||||
IFT_CHANNEL = 0x46 | |||||
IFT_CNR = 0x55 | |||||
IFT_COFFEE = 0x84 | |||||
IFT_COMPOSITELINK = 0x9b | |||||
IFT_DCN = 0x8d | |||||
IFT_DIGITALPOWERLINE = 0x8a | |||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba | |||||
IFT_DLSW = 0x4a | |||||
IFT_DOCSCABLEDOWNSTREAM = 0x80 | |||||
IFT_DOCSCABLEMACLAYER = 0x7f | |||||
IFT_DOCSCABLEUPSTREAM = 0x81 | |||||
IFT_DS0 = 0x51 | |||||
IFT_DS0BUNDLE = 0x52 | |||||
IFT_DS1FDL = 0xaa | |||||
IFT_DS3 = 0x1e | |||||
IFT_DTM = 0x8c | |||||
IFT_DVBASILN = 0xac | |||||
IFT_DVBASIOUT = 0xad | |||||
IFT_DVBRCCDOWNSTREAM = 0x93 | |||||
IFT_DVBRCCMACLAYER = 0x92 | |||||
IFT_DVBRCCUPSTREAM = 0x94 | |||||
IFT_ENC = 0xf4 | |||||
IFT_EON = 0x19 | |||||
IFT_EPLRS = 0x57 | |||||
IFT_ESCON = 0x49 | |||||
IFT_ETHER = 0x6 | |||||
IFT_FAST = 0x7d | |||||
IFT_FASTETHER = 0x3e | |||||
IFT_FASTETHERFX = 0x45 | |||||
IFT_FDDI = 0xf | |||||
IFT_FIBRECHANNEL = 0x38 | |||||
IFT_FRAMERELAYINTERCONNECT = 0x3a | |||||
IFT_FRAMERELAYMPI = 0x5c | |||||
IFT_FRDLCIENDPT = 0xc1 | |||||
IFT_FRELAY = 0x20 | |||||
IFT_FRELAYDCE = 0x2c | |||||
IFT_FRF16MFRBUNDLE = 0xa3 | |||||
IFT_FRFORWARD = 0x9e | |||||
IFT_G703AT2MB = 0x43 | |||||
IFT_G703AT64K = 0x42 | |||||
IFT_GIF = 0xf0 | |||||
IFT_GIGABITETHERNET = 0x75 | |||||
IFT_GR303IDT = 0xb2 | |||||
IFT_GR303RDT = 0xb1 | |||||
IFT_H323GATEKEEPER = 0xa4 | |||||
IFT_H323PROXY = 0xa5 | |||||
IFT_HDH1822 = 0x3 | |||||
IFT_HDLC = 0x76 | |||||
IFT_HDSL2 = 0xa8 | |||||
IFT_HIPERLAN2 = 0xb7 | |||||
IFT_HIPPI = 0x2f | |||||
IFT_HIPPIINTERFACE = 0x39 | |||||
IFT_HOSTPAD = 0x5a | |||||
IFT_HSSI = 0x2e | |||||
IFT_HY = 0xe | |||||
IFT_IBM370PARCHAN = 0x48 | |||||
IFT_IDSL = 0x9a | |||||
IFT_IEEE80211 = 0x47 | |||||
IFT_IEEE80212 = 0x37 | |||||
IFT_IEEE8023ADLAG = 0xa1 | |||||
IFT_IFGSN = 0x91 | |||||
IFT_IMT = 0xbe | |||||
IFT_INTERLEAVE = 0x7c | |||||
IFT_IP = 0x7e | |||||
IFT_IPFORWARD = 0x8e | |||||
IFT_IPOVERATM = 0x72 | |||||
IFT_IPOVERCDLC = 0x6d | |||||
IFT_IPOVERCLAW = 0x6e | |||||
IFT_IPSWITCH = 0x4e | |||||
IFT_ISDN = 0x3f | |||||
IFT_ISDNBASIC = 0x14 | |||||
IFT_ISDNPRIMARY = 0x15 | |||||
IFT_ISDNS = 0x4b | |||||
IFT_ISDNU = 0x4c | |||||
IFT_ISO88022LLC = 0x29 | |||||
IFT_ISO88023 = 0x7 | |||||
IFT_ISO88024 = 0x8 | |||||
IFT_ISO88025 = 0x9 | |||||
IFT_ISO88025CRFPINT = 0x62 | |||||
IFT_ISO88025DTR = 0x56 | |||||
IFT_ISO88025FIBER = 0x73 | |||||
IFT_ISO88026 = 0xa | |||||
IFT_ISUP = 0xb3 | |||||
IFT_L3IPXVLAN = 0x89 | |||||
IFT_LAPB = 0x10 | |||||
IFT_LAPD = 0x4d | |||||
IFT_LAPF = 0x77 | |||||
IFT_LOCALTALK = 0x2a | |||||
IFT_LOOP = 0x18 | |||||
IFT_MEDIAMAILOVERIP = 0x8b | |||||
IFT_MFSIGLINK = 0xa7 | |||||
IFT_MIOX25 = 0x26 | |||||
IFT_MODEM = 0x30 | |||||
IFT_MPC = 0x71 | |||||
IFT_MPLS = 0xa6 | |||||
IFT_MPLSTUNNEL = 0x96 | |||||
IFT_MSDSL = 0x8f | |||||
IFT_MVL = 0xbf | |||||
IFT_MYRINET = 0x63 | |||||
IFT_NFAS = 0xaf | |||||
IFT_NSIP = 0x1b | |||||
IFT_OPTICALCHANNEL = 0xc3 | |||||
IFT_OPTICALTRANSPORT = 0xc4 | |||||
IFT_OTHER = 0x1 | |||||
IFT_P10 = 0xc | |||||
IFT_P80 = 0xd | |||||
IFT_PARA = 0x22 | |||||
IFT_PFLOG = 0xf6 | |||||
IFT_PFSYNC = 0xf7 | |||||
IFT_PLC = 0xae | |||||
IFT_POS = 0xab | |||||
IFT_PPPMULTILINKBUNDLE = 0x6c | |||||
IFT_PROPBWAP2MP = 0xb8 | |||||
IFT_PROPCNLS = 0x59 | |||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 | |||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 | |||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 | |||||
IFT_PROPMUX = 0x36 | |||||
IFT_PROPWIRELESSP2P = 0x9d | |||||
IFT_PTPSERIAL = 0x16 | |||||
IFT_PVC = 0xf1 | |||||
IFT_QLLC = 0x44 | |||||
IFT_RADIOMAC = 0xbc | |||||
IFT_RADSL = 0x5f | |||||
IFT_REACHDSL = 0xc0 | |||||
IFT_RFC1483 = 0x9f | |||||
IFT_RS232 = 0x21 | |||||
IFT_RSRB = 0x4f | |||||
IFT_SDLC = 0x11 | |||||
IFT_SDSL = 0x60 | |||||
IFT_SHDSL = 0xa9 | |||||
IFT_SIP = 0x1f | |||||
IFT_SLIP = 0x1c | |||||
IFT_SMDSDXI = 0x2b | |||||
IFT_SMDSICIP = 0x34 | |||||
IFT_SONET = 0x27 | |||||
IFT_SONETOVERHEADCHANNEL = 0xb9 | |||||
IFT_SONETPATH = 0x32 | |||||
IFT_SONETVT = 0x33 | |||||
IFT_SRP = 0x97 | |||||
IFT_SS7SIGLINK = 0x9c | |||||
IFT_STACKTOSTACK = 0x6f | |||||
IFT_STARLAN = 0xb | |||||
IFT_STF = 0xd7 | |||||
IFT_T1 = 0x12 | |||||
IFT_TDLC = 0x74 | |||||
IFT_TERMPAD = 0x5b | |||||
IFT_TR008 = 0xb0 | |||||
IFT_TRANSPHDLC = 0x7b | |||||
IFT_TUNNEL = 0x83 | |||||
IFT_ULTRA = 0x1d | |||||
IFT_USB = 0xa0 | |||||
IFT_V11 = 0x40 | |||||
IFT_V35 = 0x2d | |||||
IFT_V36 = 0x41 | |||||
IFT_V37 = 0x78 | |||||
IFT_VDSL = 0x61 | |||||
IFT_VIRTUALIPADDRESS = 0x70 | |||||
IFT_VOICEEM = 0x64 | |||||
IFT_VOICEENCAP = 0x67 | |||||
IFT_VOICEFXO = 0x65 | |||||
IFT_VOICEFXS = 0x66 | |||||
IFT_VOICEOVERATM = 0x98 | |||||
IFT_VOICEOVERFRAMERELAY = 0x99 | |||||
IFT_VOICEOVERIP = 0x68 | |||||
IFT_X213 = 0x5d | |||||
IFT_X25 = 0x5 | |||||
IFT_X25DDN = 0x4 | |||||
IFT_X25HUNTGROUP = 0x7a | |||||
IFT_X25MLP = 0x79 | |||||
IFT_X25PLE = 0x28 | |||||
IFT_XETHER = 0x1a | |||||
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go | |||||
IFF_SMART = 0x20 | |||||
IFT_FAITH = 0xf2 | |||||
IFT_IPXIP = 0xf9 | |||||
IPPROTO_MAXID = 0x34 | |||||
IPV6_FAITH = 0x1d | |||||
IP_FAITH = 0x16 | |||||
MAP_NORESERVE = 0x40 | |||||
MAP_RENAME = 0x20 | |||||
NET_RT_MAXID = 0x6 | |||||
RTF_PRCLONING = 0x10000 | |||||
RTM_OLDADD = 0x9 | |||||
RTM_OLDDEL = 0xa | |||||
SIOCADDRT = 0x8030720a | |||||
SIOCALIFADDR = 0x8118691b | |||||
SIOCDELRT = 0x8030720b | |||||
SIOCDLIFADDR = 0x8118691d | |||||
SIOCGLIFADDR = 0xc118691c | |||||
SIOCGLIFPHYADDR = 0xc118694b | |||||
SIOCSLIFPHYADDR = 0x8118694a | |||||
) |
@@ -1,17 +0,0 @@ | |||||
// Copyright 2020 The Go Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep | |||||
// them here for backwards compatibility. | |||||
package unix | |||||
const ( | |||||
DLT_HHDLC = 0x79 | |||||
IPV6_MIN_MEMBERSHIPS = 0x1f | |||||
IP_MAX_SOURCE_FILTER = 0x400 | |||||
IP_MIN_MEMBERSHIPS = 0x1f | |||||
RT_CACHING_CONTEXT = 0x1 | |||||
RT_NORTREF = 0x2 | |||||
) |
@@ -8,7 +8,6 @@ | |||||
package unix | package unix | ||||
import ( | import ( | ||||
"bytes" | |||||
"unsafe" | "unsafe" | ||||
) | ) | ||||
@@ -45,13 +44,7 @@ func NewIfreq(name string) (*Ifreq, error) { | |||||
// Name returns the interface name associated with the Ifreq. | // Name returns the interface name associated with the Ifreq. | ||||
func (ifr *Ifreq) Name() string { | func (ifr *Ifreq) Name() string { | ||||
// BytePtrToString requires a NULL terminator or the program may crash. If | |||||
// one is not present, just return the empty string. | |||||
if !bytes.Contains(ifr.raw.Ifrn[:], []byte{0x00}) { | |||||
return "" | |||||
} | |||||
return BytePtrToString(&ifr.raw.Ifrn[0]) | |||||
return ByteSliceToString(ifr.raw.Ifrn[:]) | |||||
} | } | ||||
// According to netdevice(7), only AF_INET addresses are returned for numerous | // According to netdevice(7), only AF_INET addresses are returned for numerous | ||||
@@ -194,3 +194,26 @@ func ioctlIfreqData(fd int, req uint, value *ifreqData) error { | |||||
// identical so pass *IfreqData directly. | // identical so pass *IfreqData directly. | ||||
return ioctlPtr(fd, req, unsafe.Pointer(value)) | return ioctlPtr(fd, req, unsafe.Pointer(value)) | ||||
} | } | ||||
// IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an | |||||
// existing KCM socket, returning a structure containing the file descriptor of | |||||
// the new socket. | |||||
func IoctlKCMClone(fd int) (*KCMClone, error) { | |||||
var info KCMClone | |||||
if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil { | |||||
return nil, err | |||||
} | |||||
return &info, nil | |||||
} | |||||
// IoctlKCMAttach attaches a TCP socket and associated BPF program file | |||||
// descriptor to a multiplexor. | |||||
func IoctlKCMAttach(fd int, info KCMAttach) error { | |||||
return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info)) | |||||
} | |||||
// IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor. | |||||
func IoctlKCMUnattach(fd int, info KCMUnattach) error { | |||||
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info)) | |||||
} |
@@ -89,25 +89,30 @@ dragonfly_amd64) | |||||
freebsd_386) | freebsd_386) | ||||
mkerrors="$mkerrors -m32" | mkerrors="$mkerrors -m32" | ||||
mksyscall="go run mksyscall.go -l32" | mksyscall="go run mksyscall.go -l32" | ||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'" | |||||
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | mktypes="GOARCH=$GOARCH go tool cgo -godefs" | ||||
;; | ;; | ||||
freebsd_amd64) | freebsd_amd64) | ||||
mkerrors="$mkerrors -m64" | mkerrors="$mkerrors -m64" | ||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'" | |||||
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | mktypes="GOARCH=$GOARCH go tool cgo -godefs" | ||||
;; | ;; | ||||
freebsd_arm) | freebsd_arm) | ||||
mkerrors="$mkerrors" | mkerrors="$mkerrors" | ||||
mksyscall="go run mksyscall.go -l32 -arm" | mksyscall="go run mksyscall.go -l32 -arm" | ||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'" | |||||
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||||
# Let the type of C char be signed for making the bare syscall | # Let the type of C char be signed for making the bare syscall | ||||
# API consistent across platforms. | # API consistent across platforms. | ||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | ||||
;; | ;; | ||||
freebsd_arm64) | freebsd_arm64) | ||||
mkerrors="$mkerrors -m64" | mkerrors="$mkerrors -m64" | ||||
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'" | |||||
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||||
;; | |||||
freebsd_riscv64) | |||||
mkerrors="$mkerrors -m64" | |||||
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | ||||
;; | ;; | ||||
netbsd_386) | netbsd_386) | ||||
@@ -128,6 +128,7 @@ includes_FreeBSD=' | |||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||
#include <sys/ptrace.h> | |||||
#include <net/bpf.h> | #include <net/bpf.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_types.h> | #include <net/if_types.h> | ||||
@@ -202,9 +203,11 @@ struct ltchars { | |||||
#include <sys/timerfd.h> | #include <sys/timerfd.h> | ||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <sys/xattr.h> | #include <sys/xattr.h> | ||||
#include <linux/audit.h> | |||||
#include <linux/bpf.h> | #include <linux/bpf.h> | ||||
#include <linux/can.h> | #include <linux/can.h> | ||||
#include <linux/can/error.h> | #include <linux/can/error.h> | ||||
#include <linux/can/netlink.h> | |||||
#include <linux/can/raw.h> | #include <linux/can/raw.h> | ||||
#include <linux/capability.h> | #include <linux/capability.h> | ||||
#include <linux/cryptouser.h> | #include <linux/cryptouser.h> | ||||
@@ -214,6 +217,7 @@ struct ltchars { | |||||
#include <linux/ethtool_netlink.h> | #include <linux/ethtool_netlink.h> | ||||
#include <linux/falloc.h> | #include <linux/falloc.h> | ||||
#include <linux/fanotify.h> | #include <linux/fanotify.h> | ||||
#include <linux/fib_rules.h> | |||||
#include <linux/filter.h> | #include <linux/filter.h> | ||||
#include <linux/fs.h> | #include <linux/fs.h> | ||||
#include <linux/fscrypt.h> | #include <linux/fscrypt.h> | ||||
@@ -231,6 +235,7 @@ struct ltchars { | |||||
#include <linux/if_packet.h> | #include <linux/if_packet.h> | ||||
#include <linux/if_xdp.h> | #include <linux/if_xdp.h> | ||||
#include <linux/input.h> | #include <linux/input.h> | ||||
#include <linux/kcm.h> | |||||
#include <linux/kexec.h> | #include <linux/kexec.h> | ||||
#include <linux/keyctl.h> | #include <linux/keyctl.h> | ||||
#include <linux/landlock.h> | #include <linux/landlock.h> | ||||
@@ -292,6 +297,10 @@ struct ltchars { | |||||
#define SOL_NETLINK 270 | #define SOL_NETLINK 270 | ||||
#endif | #endif | ||||
#ifndef SOL_SMC | |||||
#define SOL_SMC 286 | |||||
#endif | |||||
#ifdef SOL_BLUETOOTH | #ifdef SOL_BLUETOOTH | ||||
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h | // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h | ||||
// but it is already in bluetooth_linux.go | // but it is already in bluetooth_linux.go | ||||
@@ -503,6 +512,7 @@ ccflags="$@" | |||||
$2 ~ /^O?XTABS$/ || | $2 ~ /^O?XTABS$/ || | ||||
$2 ~ /^TC[IO](ON|OFF)$/ || | $2 ~ /^TC[IO](ON|OFF)$/ || | ||||
$2 ~ /^IN_/ || | $2 ~ /^IN_/ || | ||||
$2 ~ /^KCM/ || | |||||
$2 ~ /^LANDLOCK_/ || | $2 ~ /^LANDLOCK_/ || | ||||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ || | $2 ~ /^LOCK_(SH|EX|NB|UN)$/ || | ||||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ || | $2 ~ /^LO_(KEY|NAME)_SIZE$/ || | ||||
@@ -525,7 +535,7 @@ ccflags="$@" | |||||
$2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ || | $2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ || | ||||
$2 ~ /^NS_GET_/ || | $2 ~ /^NS_GET_/ || | ||||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || | $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || | ||||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ || | |||||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|PIOD|TFD)_/ || | |||||
$2 ~ /^KEXEC_/ || | $2 ~ /^KEXEC_/ || | ||||
$2 ~ /^LINUX_REBOOT_CMD_/ || | $2 ~ /^LINUX_REBOOT_CMD_/ || | ||||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || | $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || | ||||
@@ -549,6 +559,7 @@ ccflags="$@" | |||||
$2 ~ /^CLONE_[A-Z_]+/ || | $2 ~ /^CLONE_[A-Z_]+/ || | ||||
$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ && | $2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ && | ||||
$2 ~ /^(BPF|DLT)_/ || | $2 ~ /^(BPF|DLT)_/ || | ||||
$2 ~ /^AUDIT_/ || | |||||
$2 ~ /^(CLOCK|TIMER)_/ || | $2 ~ /^(CLOCK|TIMER)_/ || | ||||
$2 ~ /^CAN_/ || | $2 ~ /^CAN_/ || | ||||
$2 ~ /^CAP_/ || | $2 ~ /^CAP_/ || | ||||
@@ -571,7 +582,6 @@ ccflags="$@" | |||||
$2 ~ /^SEEK_/ || | $2 ~ /^SEEK_/ || | ||||
$2 ~ /^SPLICE_/ || | $2 ~ /^SPLICE_/ || | ||||
$2 ~ /^SYNC_FILE_RANGE_/ || | $2 ~ /^SYNC_FILE_RANGE_/ || | ||||
$2 !~ /^AUDIT_RECORD_MAGIC/ && | |||||
$2 !~ /IOC_MAGIC/ && | $2 !~ /IOC_MAGIC/ && | ||||
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ || | $2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ || | ||||
$2 ~ /^(VM|VMADDR)_/ || | $2 ~ /^(VM|VMADDR)_/ || | ||||
@@ -597,8 +607,10 @@ ccflags="$@" | |||||
$2 ~ /^DEVLINK_/ || | $2 ~ /^DEVLINK_/ || | ||||
$2 ~ /^ETHTOOL_/ || | $2 ~ /^ETHTOOL_/ || | ||||
$2 ~ /^LWTUNNEL_IP/ || | $2 ~ /^LWTUNNEL_IP/ || | ||||
$2 ~ /^ITIMER_/ || | |||||
$2 !~ "WMESGLEN" && | $2 !~ "WMESGLEN" && | ||||
$2 ~ /^W[A-Z0-9]+$/ || | $2 ~ /^W[A-Z0-9]+$/ || | ||||
$2 ~ /^P_/ || | |||||
$2 ~/^PPPIOC/ || | $2 ~/^PPPIOC/ || | ||||
$2 ~ /^FAN_|FANOTIFY_/ || | $2 ~ /^FAN_|FANOTIFY_/ || | ||||
$2 == "HID_MAX_DESCRIPTOR_SIZE" || | $2 == "HID_MAX_DESCRIPTOR_SIZE" || | ||||
@@ -608,6 +620,7 @@ ccflags="$@" | |||||
$2 ~ /^OTP/ || | $2 ~ /^OTP/ || | ||||
$2 ~ /^MEM/ || | $2 ~ /^MEM/ || | ||||
$2 ~ /^WG/ || | $2 ~ /^WG/ || | ||||
$2 ~ /^FIB_RULE_/ || | |||||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} | $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} | ||||
$2 ~ /^__WCOREFLAG$/ {next} | $2 ~ /^__WCOREFLAG$/ {next} | ||||
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} | $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} | ||||
@@ -37,6 +37,7 @@ func Creat(path string, mode uint32) (fd int, err error) { | |||||
} | } | ||||
//sys utimes(path string, times *[2]Timeval) (err error) | //sys utimes(path string, times *[2]Timeval) (err error) | ||||
func Utimes(path string, tv []Timeval) error { | func Utimes(path string, tv []Timeval) error { | ||||
if len(tv) != 2 { | if len(tv) != 2 { | ||||
return EINVAL | return EINVAL | ||||
@@ -45,6 +46,7 @@ func Utimes(path string, tv []Timeval) error { | |||||
} | } | ||||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) | //sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) | ||||
func UtimesNano(path string, ts []Timespec) error { | func UtimesNano(path string, ts []Timespec) error { | ||||
if len(ts) != 2 { | if len(ts) != 2 { | ||||
return EINVAL | return EINVAL | ||||
@@ -215,20 +217,63 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { | |||||
return | return | ||||
} | } | ||||
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { | |||||
// Recvmsg not implemented on AIX | |||||
sa := new(SockaddrUnix) | |||||
return -1, -1, -1, sa, ENOSYS | |||||
} | |||||
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { | |||||
_, err = SendmsgN(fd, p, oob, to, flags) | |||||
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { | |||||
var msg Msghdr | |||||
msg.Name = (*byte)(unsafe.Pointer(rsa)) | |||||
msg.Namelen = uint32(SizeofSockaddrAny) | |||||
var dummy byte | |||||
if len(oob) > 0 { | |||||
// receive at least one normal byte | |||||
if emptyIovecs(iov) { | |||||
var iova [1]Iovec | |||||
iova[0].Base = &dummy | |||||
iova[0].SetLen(1) | |||||
iov = iova[:] | |||||
} | |||||
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | |||||
msg.SetControllen(len(oob)) | |||||
} | |||||
if len(iov) > 0 { | |||||
msg.Iov = &iov[0] | |||||
msg.SetIovlen(len(iov)) | |||||
} | |||||
if n, err = recvmsg(fd, &msg, flags); n == -1 { | |||||
return | |||||
} | |||||
oobn = int(msg.Controllen) | |||||
recvflags = int(msg.Flags) | |||||
return | return | ||||
} | } | ||||
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { | |||||
// SendmsgN not implemented on AIX | |||||
return -1, ENOSYS | |||||
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { | |||||
var msg Msghdr | |||||
msg.Name = (*byte)(unsafe.Pointer(ptr)) | |||||
msg.Namelen = uint32(salen) | |||||
var dummy byte | |||||
var empty bool | |||||
if len(oob) > 0 { | |||||
// send at least one normal byte | |||||
empty = emptyIovecs(iov) | |||||
if empty { | |||||
var iova [1]Iovec | |||||
iova[0].Base = &dummy | |||||
iova[0].SetLen(1) | |||||
iov = iova[:] | |||||
} | |||||
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | |||||
msg.SetControllen(len(oob)) | |||||
} | |||||
if len(iov) > 0 { | |||||
msg.Iov = &iov[0] | |||||
msg.SetIovlen(len(iov)) | |||||
} | |||||
if n, err = sendmsg(fd, &msg, flags); err != nil { | |||||
return 0, err | |||||
} | |||||
if len(oob) > 0 && empty { | |||||
n = 0 | |||||
} | |||||
return n, nil | |||||
} | } | ||||
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | ||||
@@ -306,11 +351,13 @@ func direntNamlen(buf []byte) (uint64, bool) { | |||||
} | } | ||||
//sys getdirent(fd int, buf []byte) (n int, err error) | //sys getdirent(fd int, buf []byte) (n int, err error) | ||||
func Getdents(fd int, buf []byte) (n int, err error) { | func Getdents(fd int, buf []byte) (n int, err error) { | ||||
return getdirent(fd, buf) | return getdirent(fd, buf) | ||||
} | } | ||||
//sys wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error) | //sys wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error) | ||||
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { | func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { | ||||
var status _C_int | var status _C_int | ||||
var r Pid_t | var r Pid_t | ||||
@@ -378,6 +425,7 @@ func (w WaitStatus) TrapCause() int { return -1 } | |||||
//sys fcntl(fd int, cmd int, arg int) (val int, err error) | //sys fcntl(fd int, cmd int, arg int) (val int, err error) | ||||
//sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range | //sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range | ||||
func Fsync(fd int) error { | func Fsync(fd int) error { | ||||
return fsyncRange(fd, O_SYNC, 0, 0) | return fsyncRange(fd, O_SYNC, 0, 0) | ||||
} | } | ||||
@@ -458,8 +506,8 @@ func Fsync(fd int) error { | |||||
//sys Listen(s int, n int) (err error) | //sys Listen(s int, n int) (err error) | ||||
//sys lstat(path string, stat *Stat_t) (err error) | //sys lstat(path string, stat *Stat_t) (err error) | ||||
//sys Pause() (err error) | //sys Pause() (err error) | ||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = pread64 | |||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64 | |||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = pread64 | |||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64 | |||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) | //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) | ||||
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) | //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) | ||||
//sysnb Setregid(rgid int, egid int) (err error) | //sysnb Setregid(rgid int, egid int) (err error) | ||||
@@ -542,6 +590,7 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { | |||||
//sys Getsystemcfg(label int) (n uint64) | //sys Getsystemcfg(label int) (n uint64) | ||||
//sys umount(target string) (err error) | //sys umount(target string) (err error) | ||||
func Unmount(target string, flags int) (err error) { | func Unmount(target string, flags int) (err error) { | ||||
if flags != 0 { | if flags != 0 { | ||||
// AIX doesn't have any flags for umount. | // AIX doesn't have any flags for umount. | ||||
@@ -325,80 +325,62 @@ func GetsockoptString(fd, level, opt int) (string, error) { | |||||
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) | //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) | ||||
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) | //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) | ||||
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { | |||||
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { | |||||
var msg Msghdr | var msg Msghdr | ||||
var rsa RawSockaddrAny | |||||
msg.Name = (*byte)(unsafe.Pointer(&rsa)) | |||||
msg.Name = (*byte)(unsafe.Pointer(rsa)) | |||||
msg.Namelen = uint32(SizeofSockaddrAny) | msg.Namelen = uint32(SizeofSockaddrAny) | ||||
var iov Iovec | |||||
if len(p) > 0 { | |||||
iov.Base = (*byte)(unsafe.Pointer(&p[0])) | |||||
iov.SetLen(len(p)) | |||||
} | |||||
var dummy byte | var dummy byte | ||||
if len(oob) > 0 { | if len(oob) > 0 { | ||||
// receive at least one normal byte | // receive at least one normal byte | ||||
if len(p) == 0 { | |||||
iov.Base = &dummy | |||||
iov.SetLen(1) | |||||
if emptyIovecs(iov) { | |||||
var iova [1]Iovec | |||||
iova[0].Base = &dummy | |||||
iova[0].SetLen(1) | |||||
iov = iova[:] | |||||
} | } | ||||
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | ||||
msg.SetControllen(len(oob)) | msg.SetControllen(len(oob)) | ||||
} | } | ||||
msg.Iov = &iov | |||||
msg.Iovlen = 1 | |||||
if len(iov) > 0 { | |||||
msg.Iov = &iov[0] | |||||
msg.SetIovlen(len(iov)) | |||||
} | |||||
if n, err = recvmsg(fd, &msg, flags); err != nil { | if n, err = recvmsg(fd, &msg, flags); err != nil { | ||||
return | return | ||||
} | } | ||||
oobn = int(msg.Controllen) | oobn = int(msg.Controllen) | ||||
recvflags = int(msg.Flags) | recvflags = int(msg.Flags) | ||||
// source address is only specified if the socket is unconnected | |||||
if rsa.Addr.Family != AF_UNSPEC { | |||||
from, err = anyToSockaddr(fd, &rsa) | |||||
} | |||||
return | return | ||||
} | } | ||||
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) | //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) | ||||
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { | |||||
_, err = SendmsgN(fd, p, oob, to, flags) | |||||
return | |||||
} | |||||
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { | |||||
var ptr unsafe.Pointer | |||||
var salen _Socklen | |||||
if to != nil { | |||||
ptr, salen, err = to.sockaddr() | |||||
if err != nil { | |||||
return 0, err | |||||
} | |||||
} | |||||
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { | |||||
var msg Msghdr | var msg Msghdr | ||||
msg.Name = (*byte)(unsafe.Pointer(ptr)) | msg.Name = (*byte)(unsafe.Pointer(ptr)) | ||||
msg.Namelen = uint32(salen) | msg.Namelen = uint32(salen) | ||||
var iov Iovec | |||||
if len(p) > 0 { | |||||
iov.Base = (*byte)(unsafe.Pointer(&p[0])) | |||||
iov.SetLen(len(p)) | |||||
} | |||||
var dummy byte | var dummy byte | ||||
var empty bool | |||||
if len(oob) > 0 { | if len(oob) > 0 { | ||||
// send at least one normal byte | // send at least one normal byte | ||||
if len(p) == 0 { | |||||
iov.Base = &dummy | |||||
iov.SetLen(1) | |||||
empty = emptyIovecs(iov) | |||||
if empty { | |||||
var iova [1]Iovec | |||||
iova[0].Base = &dummy | |||||
iova[0].SetLen(1) | |||||
iov = iova[:] | |||||
} | } | ||||
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | ||||
msg.SetControllen(len(oob)) | msg.SetControllen(len(oob)) | ||||
} | } | ||||
msg.Iov = &iov | |||||
msg.Iovlen = 1 | |||||
if len(iov) > 0 { | |||||
msg.Iov = &iov[0] | |||||
msg.SetIovlen(len(iov)) | |||||
} | |||||
if n, err = sendmsg(fd, &msg, flags); err != nil { | if n, err = sendmsg(fd, &msg, flags); err != nil { | ||||
return 0, err | return 0, err | ||||
} | } | ||||
if len(oob) > 0 && len(p) == 0 { | |||||
if len(oob) > 0 && empty { | |||||
n = 0 | n = 0 | ||||
} | } | ||||
return n, nil | return n, nil | ||||
@@ -571,12 +553,7 @@ func UtimesNano(path string, ts []Timespec) error { | |||||
if len(ts) != 2 { | if len(ts) != 2 { | ||||
return EINVAL | return EINVAL | ||||
} | } | ||||
// Darwin setattrlist can set nanosecond timestamps | |||||
err := setattrlistTimes(path, ts, 0) | |||||
if err != ENOSYS { | |||||
return err | |||||
} | |||||
err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) | |||||
err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) | |||||
if err != ENOSYS { | if err != ENOSYS { | ||||
return err | return err | ||||
} | } | ||||
@@ -596,10 +573,6 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { | |||||
if len(ts) != 2 { | if len(ts) != 2 { | ||||
return EINVAL | return EINVAL | ||||
} | } | ||||
err := setattrlistTimes(path, ts, flags) | |||||
if err != ENOSYS { | |||||
return err | |||||
} | |||||
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) | return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) | ||||
} | } | ||||
@@ -141,16 +141,6 @@ func direntNamlen(buf []byte) (uint64, bool) { | |||||
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } | func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } | ||||
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } | func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } | ||||
type attrList struct { | |||||
bitmapCount uint16 | |||||
_ uint16 | |||||
CommonAttr uint32 | |||||
VolAttr uint32 | |||||
DirAttr uint32 | |||||
FileAttr uint32 | |||||
Forkattr uint32 | |||||
} | |||||
//sysnb pipe(p *[2]int32) (err error) | //sysnb pipe(p *[2]int32) (err error) | ||||
func Pipe(p []int) (err error) { | func Pipe(p []int) (err error) { | ||||
@@ -282,36 +272,7 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) { | |||||
return flistxattr(fd, xattrPointer(dest), len(dest), 0) | return flistxattr(fd, xattrPointer(dest), len(dest), 0) | ||||
} | } | ||||
func setattrlistTimes(path string, times []Timespec, flags int) error { | |||||
_p0, err := BytePtrFromString(path) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
var attrList attrList | |||||
attrList.bitmapCount = ATTR_BIT_MAP_COUNT | |||||
attrList.CommonAttr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME | |||||
// order is mtime, atime: the opposite of Chtimes | |||||
attributes := [2]Timespec{times[1], times[0]} | |||||
options := 0 | |||||
if flags&AT_SYMLINK_NOFOLLOW != 0 { | |||||
options |= FSOPT_NOFOLLOW | |||||
} | |||||
return setattrlist( | |||||
_p0, | |||||
unsafe.Pointer(&attrList), | |||||
unsafe.Pointer(&attributes), | |||||
unsafe.Sizeof(attributes), | |||||
options) | |||||
} | |||||
//sys setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) | |||||
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error { | |||||
// Darwin doesn't support SYS_UTIMENSAT | |||||
return ENOSYS | |||||
} | |||||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) | |||||
/* | /* | ||||
* Wrapped | * Wrapped | ||||
@@ -432,6 +393,13 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) { | |||||
return x, err | return x, err | ||||
} | } | ||||
func GetsockoptTCPConnectionInfo(fd, level, opt int) (*TCPConnectionInfo, error) { | |||||
var value TCPConnectionInfo | |||||
vallen := _Socklen(SizeofTCPConnectionInfo) | |||||
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) | |||||
return &value, err | |||||
} | |||||
func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) { | func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) { | ||||
mib, err := sysctlmib(name, args...) | mib, err := sysctlmib(name, args...) | ||||
if err != nil { | if err != nil { | ||||
@@ -543,11 +511,12 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { | |||||
//sys Mkdirat(dirfd int, path string, mode uint32) (err error) | //sys Mkdirat(dirfd int, path string, mode uint32) (err error) | ||||
//sys Mkfifo(path string, mode uint32) (err error) | //sys Mkfifo(path string, mode uint32) (err error) | ||||
//sys Mknod(path string, mode uint32, dev int) (err error) | //sys Mknod(path string, mode uint32, dev int) (err error) | ||||
//sys Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error) | |||||
//sys Open(path string, mode int, perm uint32) (fd int, err error) | //sys Open(path string, mode int, perm uint32) (fd int, err error) | ||||
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) | //sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) | ||||
//sys Pathconf(path string, name int) (val int, err error) | //sys Pathconf(path string, name int) (val int, err error) | ||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) | |||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) | |||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) | |||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) | |||||
//sys read(fd int, p []byte) (n int, err error) | //sys read(fd int, p []byte) (n int, err error) | ||||
//sys Readlink(path string, buf []byte) (n int, err error) | //sys Readlink(path string, buf []byte) (n int, err error) | ||||
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) | //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) | ||||
@@ -611,7 +580,6 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { | |||||
// Nfssvc | // Nfssvc | ||||
// Getfh | // Getfh | ||||
// Quotactl | // Quotactl | ||||
// Mount | |||||
// Csops | // Csops | ||||
// Waitid | // Waitid | ||||
// Add_profil | // Add_profil | ||||
@@ -125,12 +125,14 @@ func Pipe2(p []int, flags int) (err error) { | |||||
} | } | ||||
//sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error) | //sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error) | ||||
func Pread(fd int, p []byte, offset int64) (n int, err error) { | |||||
func pread(fd int, p []byte, offset int64) (n int, err error) { | |||||
return extpread(fd, p, 0, offset) | return extpread(fd, p, 0, offset) | ||||
} | } | ||||
//sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) | //sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) | ||||
func Pwrite(fd int, p []byte, offset int64) (n int, err error) { | |||||
func pwrite(fd int, p []byte, offset int64) (n int, err error) { | |||||
return extpwrite(fd, p, 0, offset) | return extpwrite(fd, p, 0, offset) | ||||
} | } | ||||
@@ -169,11 +171,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||||
return | return | ||||
} | } | ||||
func setattrlistTimes(path string, times []Timespec, flags int) error { | |||||
// used on Darwin for UtimesNano | |||||
return ENOSYS | |||||
} | |||||
//sys ioctl(fd int, req uint, arg uintptr) (err error) | //sys ioctl(fd int, req uint, arg uintptr) (err error) | ||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL | //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL | ||||