mirror of https://github.com/grafana/grafana
parent
d7f6f11eb1
commit
6618bff806
@ -0,0 +1,63 @@ |
||||
#!/bin/bash |
||||
|
||||
# This script generates all GAPIC clients in this repo. |
||||
# One-time setup: |
||||
# cd path/to/googleapis # https://github.com/googleapis/googleapis |
||||
# virtualenv env |
||||
# . env/bin/activate |
||||
# pip install googleapis-artman |
||||
# deactivate |
||||
# |
||||
# Regenerate: |
||||
# cd path/to/googleapis |
||||
# . env/bin/activate |
||||
# $GOPATH/src/cloud.google.com/go/regen-gapic.sh |
||||
# deactivate |
||||
# |
||||
# Being in googleapis directory is important; |
||||
# that's where we find YAML files and where artman puts the "artman-genfiles" directory. |
||||
# |
||||
# NOTE: This script does not generate the "raw" gRPC client found in google.golang.org/genproto. |
||||
# To do that, use the regen.sh script in the genproto repo instead. |
||||
|
||||
set -ex |
||||
|
||||
APIS=( |
||||
google/cloud/bigquery/datatransfer/artman_bigquerydatatransfer.yaml |
||||
google/cloud/dataproc/artman_dataproc_v1.yaml |
||||
google/cloud/language/artman_language_v1.yaml |
||||
google/cloud/language/artman_language_v1beta2.yaml |
||||
google/cloud/oslogin/artman_oslogin_v1beta.yaml |
||||
google/cloud/speech/artman_speech_v1.yaml |
||||
google/cloud/speech/artman_speech_v1beta1.yaml |
||||
google/cloud/videointelligence/artman_videointelligence_v1beta1.yaml |
||||
google/cloud/videointelligence/artman_videointelligence_v1beta2.yaml |
||||
google/cloud/vision/artman_vision_v1.yaml |
||||
google/cloud/vision/artman_vision_v1p1beta1.yaml |
||||
google/container/artman_container.yaml |
||||
google/devtools/artman_clouddebugger.yaml |
||||
google/devtools/clouderrorreporting/artman_errorreporting.yaml |
||||
google/devtools/cloudtrace/artman_cloudtrace_v1.yaml |
||||
google/devtools/cloudtrace/artman_cloudtrace_v2.yaml |
||||
google/firestore/artman_firestore.yaml |
||||
google/logging/artman_logging.yaml |
||||
google/longrunning/artman_longrunning.yaml |
||||
google/monitoring/artman_monitoring.yaml |
||||
google/privacy/dlp/artman_dlp.yaml |
||||
google/pubsub/artman_pubsub.yaml |
||||
google/spanner/admin/database/artman_spanner_admin_database.yaml |
||||
google/spanner/admin/instance/artman_spanner_admin_instance.yaml |
||||
google/spanner/artman_spanner.yaml |
||||
) |
||||
|
||||
for api in "${APIS[@]}"; do |
||||
rm -rf artman-genfiles/* |
||||
artman2 --config "$api" generate go_gapic |
||||
cp -r artman-genfiles/gapi-*/cloud.google.com/go/* $GOPATH/src/cloud.google.com/go/ |
||||
done |
||||
|
||||
go list cloud.google.com/go/... | grep apiv | xargs go test |
||||
|
||||
go test -short cloud.google.com/go/... |
||||
|
||||
echo "googleapis version: $(git rev-parse HEAD)" |
@ -0,0 +1,202 @@ |
||||
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||
//
|
||||
// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
package mysql |
||||
|
||||
import ( |
||||
"context" |
||||
"database/sql" |
||||
"database/sql/driver" |
||||
) |
||||
|
||||
// Ping implements driver.Pinger interface
|
||||
func (mc *mysqlConn) Ping(ctx context.Context) error { |
||||
if mc.closed.IsSet() { |
||||
errLog.Print(ErrInvalidConn) |
||||
return driver.ErrBadConn |
||||
} |
||||
|
||||
if err := mc.watchCancel(ctx); err != nil { |
||||
return err |
||||
} |
||||
defer mc.finish() |
||||
|
||||
if err := mc.writeCommandPacket(comPing); err != nil { |
||||
return err |
||||
} |
||||
if _, err := mc.readResultOK(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
// BeginTx implements driver.ConnBeginTx interface
|
||||
func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { |
||||
if err := mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
defer mc.finish() |
||||
|
||||
if sql.IsolationLevel(opts.Isolation) != sql.LevelDefault { |
||||
level, err := mapIsolationLevel(opts.Isolation) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
err = mc.exec("SET TRANSACTION ISOLATION LEVEL " + level) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
return mc.begin(opts.ReadOnly) |
||||
} |
||||
|
||||
func (mc *mysqlConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { |
||||
dargs, err := namedValueToValue(args) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
rows, err := mc.query(query, dargs) |
||||
if err != nil { |
||||
mc.finish() |
||||
return nil, err |
||||
} |
||||
rows.finish = mc.finish |
||||
return rows, err |
||||
} |
||||
|
||||
func (mc *mysqlConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { |
||||
dargs, err := namedValueToValue(args) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
defer mc.finish() |
||||
|
||||
return mc.Exec(query, dargs) |
||||
} |
||||
|
||||
func (mc *mysqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) { |
||||
if err := mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
stmt, err := mc.Prepare(query) |
||||
mc.finish() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
select { |
||||
default: |
||||
case <-ctx.Done(): |
||||
stmt.Close() |
||||
return nil, ctx.Err() |
||||
} |
||||
return stmt, nil |
||||
} |
||||
|
||||
func (stmt *mysqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { |
||||
dargs, err := namedValueToValue(args) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := stmt.mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
rows, err := stmt.query(dargs) |
||||
if err != nil { |
||||
stmt.mc.finish() |
||||
return nil, err |
||||
} |
||||
rows.finish = stmt.mc.finish |
||||
return rows, err |
||||
} |
||||
|
||||
func (stmt *mysqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { |
||||
dargs, err := namedValueToValue(args) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := stmt.mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
defer stmt.mc.finish() |
||||
|
||||
return stmt.Exec(dargs) |
||||
} |
||||
|
||||
func (mc *mysqlConn) watchCancel(ctx context.Context) error { |
||||
if mc.watching { |
||||
// Reach here if canceled,
|
||||
// so the connection is already invalid
|
||||
mc.cleanup() |
||||
return nil |
||||
} |
||||
if ctx.Done() == nil { |
||||
return nil |
||||
} |
||||
|
||||
mc.watching = true |
||||
select { |
||||
default: |
||||
case <-ctx.Done(): |
||||
return ctx.Err() |
||||
} |
||||
if mc.watcher == nil { |
||||
return nil |
||||
} |
||||
|
||||
mc.watcher <- ctx |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func (mc *mysqlConn) startWatcher() { |
||||
watcher := make(chan mysqlContext, 1) |
||||
mc.watcher = watcher |
||||
finished := make(chan struct{}) |
||||
mc.finished = finished |
||||
go func() { |
||||
for { |
||||
var ctx mysqlContext |
||||
select { |
||||
case ctx = <-watcher: |
||||
case <-mc.closech: |
||||
return |
||||
} |
||||
|
||||
select { |
||||
case <-ctx.Done(): |
||||
mc.cancel(ctx.Err()) |
||||
case <-finished: |
||||
case <-mc.closech: |
||||
return |
||||
} |
||||
} |
||||
}() |
||||
} |
||||
|
||||
func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) { |
||||
nv.Value, err = converter{}.ConvertValue(nv.Value) |
||||
return |
||||
} |
@ -0,0 +1,194 @@ |
||||
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||
//
|
||||
// Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package mysql |
||||
|
||||
import ( |
||||
"database/sql" |
||||
"reflect" |
||||
) |
||||
|
||||
func (mf *mysqlField) typeDatabaseName() string { |
||||
switch mf.fieldType { |
||||
case fieldTypeBit: |
||||
return "BIT" |
||||
case fieldTypeBLOB: |
||||
if mf.charSet != collations[binaryCollation] { |
||||
return "TEXT" |
||||
} |
||||
return "BLOB" |
||||
case fieldTypeDate: |
||||
return "DATE" |
||||
case fieldTypeDateTime: |
||||
return "DATETIME" |
||||
case fieldTypeDecimal: |
||||
return "DECIMAL" |
||||
case fieldTypeDouble: |
||||
return "DOUBLE" |
||||
case fieldTypeEnum: |
||||
return "ENUM" |
||||
case fieldTypeFloat: |
||||
return "FLOAT" |
||||
case fieldTypeGeometry: |
||||
return "GEOMETRY" |
||||
case fieldTypeInt24: |
||||
return "MEDIUMINT" |
||||
case fieldTypeJSON: |
||||
return "JSON" |
||||
case fieldTypeLong: |
||||
return "INT" |
||||
case fieldTypeLongBLOB: |
||||
if mf.charSet != collations[binaryCollation] { |
||||
return "LONGTEXT" |
||||
} |
||||
return "LONGBLOB" |
||||
case fieldTypeLongLong: |
||||
return "BIGINT" |
||||
case fieldTypeMediumBLOB: |
||||
if mf.charSet != collations[binaryCollation] { |
||||
return "MEDIUMTEXT" |
||||
} |
||||
return "MEDIUMBLOB" |
||||
case fieldTypeNewDate: |
||||
return "DATE" |
||||
case fieldTypeNewDecimal: |
||||
return "DECIMAL" |
||||
case fieldTypeNULL: |
||||
return "NULL" |
||||
case fieldTypeSet: |
||||
return "SET" |
||||
case fieldTypeShort: |
||||
return "SMALLINT" |
||||
case fieldTypeString: |
||||
if mf.charSet == collations[binaryCollation] { |
||||
return "BINARY" |
||||
} |
||||
return "CHAR" |
||||
case fieldTypeTime: |
||||
return "TIME" |
||||
case fieldTypeTimestamp: |
||||
return "TIMESTAMP" |
||||
case fieldTypeTiny: |
||||
return "TINYINT" |
||||
case fieldTypeTinyBLOB: |
||||
if mf.charSet != collations[binaryCollation] { |
||||
return "TINYTEXT" |
||||
} |
||||
return "TINYBLOB" |
||||
case fieldTypeVarChar: |
||||
if mf.charSet == collations[binaryCollation] { |
||||
return "VARBINARY" |
||||
} |
||||
return "VARCHAR" |
||||
case fieldTypeVarString: |
||||
if mf.charSet == collations[binaryCollation] { |
||||
return "VARBINARY" |
||||
} |
||||
return "VARCHAR" |
||||
case fieldTypeYear: |
||||
return "YEAR" |
||||
default: |
||||
return "" |
||||
} |
||||
} |
||||
|
||||
var ( |
||||
scanTypeFloat32 = reflect.TypeOf(float32(0)) |
||||
scanTypeFloat64 = reflect.TypeOf(float64(0)) |
||||
scanTypeInt8 = reflect.TypeOf(int8(0)) |
||||
scanTypeInt16 = reflect.TypeOf(int16(0)) |
||||
scanTypeInt32 = reflect.TypeOf(int32(0)) |
||||
scanTypeInt64 = reflect.TypeOf(int64(0)) |
||||
scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{}) |
||||
scanTypeNullInt = reflect.TypeOf(sql.NullInt64{}) |
||||
scanTypeNullTime = reflect.TypeOf(NullTime{}) |
||||
scanTypeUint8 = reflect.TypeOf(uint8(0)) |
||||
scanTypeUint16 = reflect.TypeOf(uint16(0)) |
||||
scanTypeUint32 = reflect.TypeOf(uint32(0)) |
||||
scanTypeUint64 = reflect.TypeOf(uint64(0)) |
||||
scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{}) |
||||
scanTypeUnknown = reflect.TypeOf(new(interface{})) |
||||
) |
||||
|
||||
type mysqlField struct { |
||||
tableName string |
||||
name string |
||||
length uint32 |
||||
flags fieldFlag |
||||
fieldType fieldType |
||||
decimals byte |
||||
charSet uint8 |
||||
} |
||||
|
||||
func (mf *mysqlField) scanType() reflect.Type { |
||||
switch mf.fieldType { |
||||
case fieldTypeTiny: |
||||
if mf.flags&flagNotNULL != 0 { |
||||
if mf.flags&flagUnsigned != 0 { |
||||
return scanTypeUint8 |
||||
} |
||||
return scanTypeInt8 |
||||
} |
||||
return scanTypeNullInt |
||||
|
||||
case fieldTypeShort, fieldTypeYear: |
||||
if mf.flags&flagNotNULL != 0 { |
||||
if mf.flags&flagUnsigned != 0 { |
||||
return scanTypeUint16 |
||||
} |
||||
return scanTypeInt16 |
||||
} |
||||
return scanTypeNullInt |
||||
|
||||
case fieldTypeInt24, fieldTypeLong: |
||||
if mf.flags&flagNotNULL != 0 { |
||||
if mf.flags&flagUnsigned != 0 { |
||||
return scanTypeUint32 |
||||
} |
||||
return scanTypeInt32 |
||||
} |
||||
return scanTypeNullInt |
||||
|
||||
case fieldTypeLongLong: |
||||
if mf.flags&flagNotNULL != 0 { |
||||
if mf.flags&flagUnsigned != 0 { |
||||
return scanTypeUint64 |
||||
} |
||||
return scanTypeInt64 |
||||
} |
||||
return scanTypeNullInt |
||||
|
||||
case fieldTypeFloat: |
||||
if mf.flags&flagNotNULL != 0 { |
||||
return scanTypeFloat32 |
||||
} |
||||
return scanTypeNullFloat |
||||
|
||||
case fieldTypeDouble: |
||||
if mf.flags&flagNotNULL != 0 { |
||||
return scanTypeFloat64 |
||||
} |
||||
return scanTypeNullFloat |
||||
|
||||
case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar, |
||||
fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB, |
||||
fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB, |
||||
fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON, |
||||
fieldTypeTime: |
||||
return scanTypeRawBytes |
||||
|
||||
case fieldTypeDate, fieldTypeNewDate, |
||||
fieldTypeTimestamp, fieldTypeDateTime: |
||||
// NullTime is always returned for more consistent behavior as it can
|
||||
// handle both cases of parseTime regardless if the field is nullable.
|
||||
return scanTypeNullTime |
||||
|
||||
default: |
||||
return scanTypeUnknown |
||||
} |
||||
} |
@ -0,0 +1,40 @@ |
||||
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||
//
|
||||
// Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// +build go1.7
|
||||
// +build !go1.8
|
||||
|
||||
package mysql |
||||
|
||||
import "crypto/tls" |
||||
|
||||
func cloneTLSConfig(c *tls.Config) *tls.Config { |
||||
return &tls.Config{ |
||||
Rand: c.Rand, |
||||
Time: c.Time, |
||||
Certificates: c.Certificates, |
||||
NameToCertificate: c.NameToCertificate, |
||||
GetCertificate: c.GetCertificate, |
||||
RootCAs: c.RootCAs, |
||||
NextProtos: c.NextProtos, |
||||
ServerName: c.ServerName, |
||||
ClientAuth: c.ClientAuth, |
||||
ClientCAs: c.ClientCAs, |
||||
InsecureSkipVerify: c.InsecureSkipVerify, |
||||
CipherSuites: c.CipherSuites, |
||||
PreferServerCipherSuites: c.PreferServerCipherSuites, |
||||
SessionTicketsDisabled: c.SessionTicketsDisabled, |
||||
SessionTicketKey: c.SessionTicketKey, |
||||
ClientSessionCache: c.ClientSessionCache, |
||||
MinVersion: c.MinVersion, |
||||
MaxVersion: c.MaxVersion, |
||||
CurvePreferences: c.CurvePreferences, |
||||
DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, |
||||
Renegotiation: c.Renegotiation, |
||||
} |
||||
} |
@ -0,0 +1,49 @@ |
||||
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||
//
|
||||
// Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
package mysql |
||||
|
||||
import ( |
||||
"crypto/tls" |
||||
"database/sql" |
||||
"database/sql/driver" |
||||
"errors" |
||||
) |
||||
|
||||
func cloneTLSConfig(c *tls.Config) *tls.Config { |
||||
return c.Clone() |
||||
} |
||||
|
||||
func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) { |
||||
dargs := make([]driver.Value, len(named)) |
||||
for n, param := range named { |
||||
if len(param.Name) > 0 { |
||||
// TODO: support the use of Named Parameters #561
|
||||
return nil, errors.New("mysql: driver does not support the use of Named Parameters") |
||||
} |
||||
dargs[n] = param.Value |
||||
} |
||||
return dargs, nil |
||||
} |
||||
|
||||
func mapIsolationLevel(level driver.IsolationLevel) (string, error) { |
||||
switch sql.IsolationLevel(level) { |
||||
case sql.LevelRepeatableRead: |
||||
return "REPEATABLE READ", nil |
||||
case sql.LevelReadCommitted: |
||||
return "READ COMMITTED", nil |
||||
case sql.LevelReadUncommitted: |
||||
return "READ UNCOMMITTED", nil |
||||
case sql.LevelSerializable: |
||||
return "SERIALIZABLE", nil |
||||
default: |
||||
return "", errors.New("mysql: unsupported isolation level: " + string(level)) |
||||
} |
||||
} |
@ -0,0 +1,46 @@ |
||||
// Copyright 2018 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 util |
||||
|
||||
import "strconv" |
||||
|
||||
// ParseUint32s parses a slice of strings into a slice of uint32s.
|
||||
func ParseUint32s(ss []string) ([]uint32, error) { |
||||
us := make([]uint32, 0, len(ss)) |
||||
for _, s := range ss { |
||||
u, err := strconv.ParseUint(s, 10, 32) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
us = append(us, uint32(u)) |
||||
} |
||||
|
||||
return us, nil |
||||
} |
||||
|
||||
// ParseUint64s parses a slice of strings into a slice of uint64s.
|
||||
func ParseUint64s(ss []string) ([]uint64, error) { |
||||
us := make([]uint64, 0, len(ss)) |
||||
for _, s := range ss { |
||||
u, err := strconv.ParseUint(s, 10, 64) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
us = append(us, u) |
||||
} |
||||
|
||||
return us, nil |
||||
} |
@ -0,0 +1,184 @@ |
||||
// Copyright 2018 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 nfsd implements parsing of /proc/net/rpc/nfsd.
|
||||
// Fields are documented in https://www.svennd.be/nfsd-stats-explained-procnetrpcnfsd/
|
||||
package nfsd |
||||
|
||||
// ReplyCache models the "rc" line.
|
||||
type ReplyCache struct { |
||||
Hits uint64 |
||||
Misses uint64 |
||||
NoCache uint64 |
||||
} |
||||
|
||||
// FileHandles models the "fh" line.
|
||||
type FileHandles struct { |
||||
Stale uint64 |
||||
TotalLookups uint64 |
||||
AnonLookups uint64 |
||||
DirNoCache uint64 |
||||
NoDirNoCache uint64 |
||||
} |
||||
|
||||
// InputOutput models the "io" line.
|
||||
type InputOutput struct { |
||||
Read uint64 |
||||
Write uint64 |
||||
} |
||||
|
||||
// Threads models the "th" line.
|
||||
type Threads struct { |
||||
Threads uint64 |
||||
FullCnt uint64 |
||||
} |
||||
|
||||
// ReadAheadCache models the "ra" line.
|
||||
type ReadAheadCache struct { |
||||
CacheSize uint64 |
||||
CacheHistogram []uint64 |
||||
NotFound uint64 |
||||
} |
||||
|
||||
// Network models the "net" line.
|
||||
type Network struct { |
||||
NetCount uint64 |
||||
UDPCount uint64 |
||||
TCPCount uint64 |
||||
TCPConnect uint64 |
||||
} |
||||
|
||||
// RPC models the "rpc" line.
|
||||
type RPC struct { |
||||
RPCCount uint64 |
||||
BadCnt uint64 |
||||
BadFmt uint64 |
||||
BadAuth uint64 |
||||
BadcInt uint64 |
||||
} |
||||
|
||||
// V2Stats models the "proc2" line.
|
||||
type V2Stats struct { |
||||
Null uint64 |
||||
GetAttr uint64 |
||||
SetAttr uint64 |
||||
Root uint64 |
||||
Lookup uint64 |
||||
ReadLink uint64 |
||||
Read uint64 |
||||
WrCache uint64 |
||||
Write uint64 |
||||
Create uint64 |
||||
Remove uint64 |
||||
Rename uint64 |
||||
Link uint64 |
||||
SymLink uint64 |
||||
MkDir uint64 |
||||
RmDir uint64 |
||||
ReadDir uint64 |
||||
FsStat uint64 |
||||
} |
||||
|
||||
// V3Stats models the "proc3" line.
|
||||
type V3Stats struct { |
||||
Null uint64 |
||||
GetAttr uint64 |
||||
SetAttr uint64 |
||||
Lookup uint64 |
||||
Access uint64 |
||||
ReadLink uint64 |
||||
Read uint64 |
||||
Write uint64 |
||||
Create uint64 |
||||
MkDir uint64 |
||||
SymLink uint64 |
||||
MkNod uint64 |
||||
Remove uint64 |
||||
RmDir uint64 |
||||
Rename uint64 |
||||
Link uint64 |
||||
ReadDir uint64 |
||||
ReadDirPlus uint64 |
||||
FsStat uint64 |
||||
FsInfo uint64 |
||||
PathConf uint64 |
||||
Commit uint64 |
||||
} |
||||
|
||||
// V4Stats models the "proc4" line.
|
||||
type V4Stats struct { |
||||
Null uint64 |
||||
Compound uint64 |
||||
} |
||||
|
||||
// V4Ops models the "proc4ops" line: NFSv4 operations
|
||||
// Variable list, see:
|
||||
// v4.0 https://tools.ietf.org/html/rfc3010 (38 operations)
|
||||
// v4.1 https://tools.ietf.org/html/rfc5661 (58 operations)
|
||||
// v4.2 https://tools.ietf.org/html/draft-ietf-nfsv4-minorversion2-41 (71 operations)
|
||||
type V4Ops struct { |
||||
//Values uint64 // Variable depending on v4.x sub-version. TODO: Will this always at least include the fields in this struct?
|
||||
Op0Unused uint64 |
||||
Op1Unused uint64 |
||||
Op2Future uint64 |
||||
Access uint64 |
||||
Close uint64 |
||||
Commit uint64 |
||||
Create uint64 |
||||
DelegPurge uint64 |
||||
DelegReturn uint64 |
||||
GetAttr uint64 |
||||
GetFH uint64 |
||||
Link uint64 |
||||
Lock uint64 |
||||
Lockt uint64 |
||||
Locku uint64 |
||||
Lookup uint64 |
||||
LookupRoot uint64 |
||||
Nverify uint64 |
||||
Open uint64 |
||||
OpenAttr uint64 |
||||
OpenConfirm uint64 |
||||
OpenDgrd uint64 |
||||
PutFH uint64 |
||||
PutPubFH uint64 |
||||
PutRootFH uint64 |
||||
Read uint64 |
||||
ReadDir uint64 |
||||
ReadLink uint64 |
||||
Remove uint64 |
||||
Rename uint64 |
||||
Renew uint64 |
||||
RestoreFH uint64 |
||||
SaveFH uint64 |
||||
SecInfo uint64 |
||||
SetAttr uint64 |
||||
Verify uint64 |
||||
Write uint64 |
||||
RelLockOwner uint64 |
||||
} |
||||
|
||||
// RPCStats models all stats from /proc/net/rpc/nfsd.
|
||||
type RPCStats struct { |
||||
ReplyCache ReplyCache |
||||
FileHandles FileHandles |
||||
InputOutput InputOutput |
||||
Threads Threads |
||||
ReadAheadCache ReadAheadCache |
||||
Network Network |
||||
RPC RPC |
||||
V2Stats V2Stats |
||||
V3Stats V3Stats |
||||
V4Stats V4Stats |
||||
V4Ops V4Ops |
||||
} |
@ -0,0 +1,298 @@ |
||||
// Copyright 2018 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 nfsd |
||||
|
||||
import ( |
||||
"bufio" |
||||
"fmt" |
||||
"io" |
||||
"strings" |
||||
|
||||
"github.com/prometheus/procfs/internal/util" |
||||
) |
||||
|
||||
// ParseRPCStats returns stats read from /proc/net/rpc/nfsd
|
||||
func ParseRPCStats(r io.Reader) (*RPCStats, error) { |
||||
stats := &RPCStats{} |
||||
|
||||
scanner := bufio.NewScanner(r) |
||||
for scanner.Scan() { |
||||
line := scanner.Text() |
||||
parts := strings.Fields(scanner.Text()) |
||||
// require at least <key> <value>
|
||||
if len(parts) < 2 { |
||||
return nil, fmt.Errorf("invalid NFSd metric line %q", line) |
||||
} |
||||
label := parts[0] |
||||
|
||||
var values []uint64 |
||||
var err error |
||||
if label == "th" { |
||||
if len(parts) < 3 { |
||||
return nil, fmt.Errorf("invalid NFSd th metric line %q", line) |
||||
} |
||||
values, err = util.ParseUint64s(parts[1:3]) |
||||
} else { |
||||
values, err = util.ParseUint64s(parts[1:]) |
||||
} |
||||
if err != nil { |
||||
return nil, fmt.Errorf("error parsing NFSd metric line: %s", err) |
||||
} |
||||
|
||||
switch metricLine := parts[0]; metricLine { |
||||
case "rc": |
||||
stats.ReplyCache, err = parseReplyCache(values) |
||||
case "fh": |
||||
stats.FileHandles, err = parseFileHandles(values) |
||||
case "io": |
||||
stats.InputOutput, err = parseInputOutput(values) |
||||
case "th": |
||||
stats.Threads, err = parseThreads(values) |
||||
case "ra": |
||||
stats.ReadAheadCache, err = parseReadAheadCache(values) |
||||
case "net": |
||||
stats.Network, err = parseNetwork(values) |
||||
case "rpc": |
||||
stats.RPC, err = parseRPC(values) |
||||
case "proc2": |
||||
stats.V2Stats, err = parseV2Stats(values) |
||||
case "proc3": |
||||
stats.V3Stats, err = parseV3Stats(values) |
||||
case "proc4": |
||||
stats.V4Stats, err = parseV4Stats(values) |
||||
case "proc4ops": |
||||
stats.V4Ops, err = parseV4Ops(values) |
||||
default: |
||||
return nil, fmt.Errorf("unknown NFSd metric line %q", metricLine) |
||||
} |
||||
if err != nil { |
||||
return nil, fmt.Errorf("errors parsing NFSd metric line: %s", err) |
||||
} |
||||
} |
||||
|
||||
if err := scanner.Err(); err != nil { |
||||
return nil, fmt.Errorf("error scanning NFSd file: %s", err) |
||||
} |
||||
|
||||
return stats, nil |
||||
} |
||||
|
||||
func parseReplyCache(v []uint64) (ReplyCache, error) { |
||||
if len(v) != 3 { |
||||
return ReplyCache{}, fmt.Errorf("invalid ReplyCache line %q", v) |
||||
} |
||||
|
||||
return ReplyCache{ |
||||
Hits: v[0], |
||||
Misses: v[1], |
||||
NoCache: v[2], |
||||
}, nil |
||||
} |
||||
|
||||
func parseFileHandles(v []uint64) (FileHandles, error) { |
||||
if len(v) != 5 { |
||||
return FileHandles{}, fmt.Errorf("invalid FileHandles, line %q", v) |
||||
} |
||||
|
||||
return FileHandles{ |
||||
Stale: v[0], |
||||
TotalLookups: v[1], |
||||
AnonLookups: v[2], |
||||
DirNoCache: v[3], |
||||
NoDirNoCache: v[4], |
||||
}, nil |
||||
} |
||||
|
||||
func parseInputOutput(v []uint64) (InputOutput, error) { |
||||
if len(v) != 2 { |
||||
return InputOutput{}, fmt.Errorf("invalid InputOutput line %q", v) |
||||
} |
||||
|
||||
return InputOutput{ |
||||
Read: v[0], |
||||
Write: v[1], |
||||
}, nil |
||||
} |
||||
|
||||
func parseThreads(v []uint64) (Threads, error) { |
||||
if len(v) != 2 { |
||||
return Threads{}, fmt.Errorf("invalid Threads line %q", v) |
||||
} |
||||
|
||||
return Threads{ |
||||
Threads: v[0], |
||||
FullCnt: v[1], |
||||
}, nil |
||||
} |
||||
|
||||
func parseReadAheadCache(v []uint64) (ReadAheadCache, error) { |
||||
if len(v) != 12 { |
||||
return ReadAheadCache{}, fmt.Errorf("invalid ReadAheadCache line %q", v) |
||||
} |
||||
|
||||
return ReadAheadCache{ |
||||
CacheSize: v[0], |
||||
CacheHistogram: v[1:11], |
||||
NotFound: v[11], |
||||
}, nil |
||||
} |
||||
|
||||
func parseNetwork(v []uint64) (Network, error) { |
||||
if len(v) != 4 { |
||||
return Network{}, fmt.Errorf("invalid Network line %q", v) |
||||
} |
||||
|
||||
return Network{ |
||||
NetCount: v[0], |
||||
UDPCount: v[1], |
||||
TCPCount: v[2], |
||||
TCPConnect: v[3], |
||||
}, nil |
||||
} |
||||
|
||||
func parseRPC(v []uint64) (RPC, error) { |
||||
if len(v) != 5 { |
||||
return RPC{}, fmt.Errorf("invalid RPC line %q", v) |
||||
} |
||||
|
||||
return RPC{ |
||||
RPCCount: v[0], |
||||
BadCnt: v[1], |
||||
BadFmt: v[2], |
||||
BadAuth: v[3], |
||||
BadcInt: v[4], |
||||
}, nil |
||||
} |
||||
|
||||
func parseV2Stats(v []uint64) (V2Stats, error) { |
||||
values := int(v[0]) |
||||
if len(v[1:]) != values || values != 18 { |
||||
return V2Stats{}, fmt.Errorf("invalid V2Stats line %q", v) |
||||
} |
||||
|
||||
return V2Stats{ |
||||
Null: v[1], |
||||
GetAttr: v[2], |
||||
SetAttr: v[3], |
||||
Root: v[4], |
||||
Lookup: v[5], |
||||
ReadLink: v[6], |
||||
Read: v[7], |
||||
WrCache: v[8], |
||||
Write: v[9], |
||||
Create: v[10], |
||||
Remove: v[11], |
||||
Rename: v[12], |
||||
Link: v[13], |
||||
SymLink: v[14], |
||||
MkDir: v[15], |
||||
RmDir: v[16], |
||||
ReadDir: v[17], |
||||
FsStat: v[18], |
||||
}, nil |
||||
} |
||||
|
||||
func parseV3Stats(v []uint64) (V3Stats, error) { |
||||
values := int(v[0]) |
||||
if len(v[1:]) != values || values != 22 { |
||||
return V3Stats{}, fmt.Errorf("invalid V3Stats line %q", v) |
||||
} |
||||
|
||||
return V3Stats{ |
||||
Null: v[1], |
||||
GetAttr: v[2], |
||||
SetAttr: v[3], |
||||
Lookup: v[4], |
||||
Access: v[5], |
||||
ReadLink: v[6], |
||||
Read: v[7], |
||||
Write: v[8], |
||||
Create: v[9], |
||||
MkDir: v[10], |
||||
SymLink: v[11], |
||||
MkNod: v[12], |
||||
Remove: v[13], |
||||
RmDir: v[14], |
||||
Rename: v[15], |
||||
Link: v[16], |
||||
ReadDir: v[17], |
||||
ReadDirPlus: v[18], |
||||
FsStat: v[19], |
||||
FsInfo: v[20], |
||||
PathConf: v[21], |
||||
Commit: v[22], |
||||
}, nil |
||||
} |
||||
|
||||
func parseV4Stats(v []uint64) (V4Stats, error) { |
||||
values := int(v[0]) |
||||
if len(v[1:]) != values || values != 2 { |
||||
return V4Stats{}, fmt.Errorf("invalid V4Stats line %q", v) |
||||
} |
||||
|
||||
return V4Stats{ |
||||
Null: v[1], |
||||
Compound: v[2], |
||||
}, nil |
||||
} |
||||
|
||||
func parseV4Ops(v []uint64) (V4Ops, error) { |
||||
values := int(v[0]) |
||||
if len(v[1:]) != values || values < 39 { |
||||
return V4Ops{}, fmt.Errorf("invalid V4Ops line %q", v) |
||||
} |
||||
|
||||
stats := V4Ops{ |
||||
Op0Unused: v[1], |
||||
Op1Unused: v[2], |
||||
Op2Future: v[3], |
||||
Access: v[4], |
||||
Close: v[5], |
||||
Commit: v[6], |
||||
Create: v[7], |
||||
DelegPurge: v[8], |
||||
DelegReturn: v[9], |
||||
GetAttr: v[10], |
||||
GetFH: v[11], |
||||
Link: v[12], |
||||
Lock: v[13], |
||||
Lockt: v[14], |
||||
Locku: v[15], |
||||
Lookup: v[16], |
||||
LookupRoot: v[17], |
||||
Nverify: v[18], |
||||
Open: v[19], |
||||
OpenAttr: v[20], |
||||
OpenConfirm: v[21], |
||||
OpenDgrd: v[22], |
||||
PutFH: v[23], |
||||
PutPubFH: v[24], |
||||
PutRootFH: v[25], |
||||
Read: v[26], |
||||
ReadDir: v[27], |
||||
ReadLink: v[28], |
||||
Remove: v[29], |
||||
Rename: v[30], |
||||
Renew: v[31], |
||||
RestoreFH: v[32], |
||||
SaveFH: v[33], |
||||
SecInfo: v[34], |
||||
SetAttr: v[35], |
||||
Verify: v[36], |
||||
Write: v[37], |
||||
RelLockOwner: v[38], |
||||
} |
||||
|
||||
return stats, nil |
||||
} |
Loading…
Reference in new issue