2021-10-01 12:37:27 +00:00
|
|
|
package proxy
|
2020-10-21 08:10:27 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-02-19 17:08:08 +00:00
|
|
|
"fmt"
|
2020-10-21 08:10:27 +00:00
|
|
|
"reflect"
|
|
|
|
|
2024-02-19 17:08:08 +00:00
|
|
|
logging "github.com/ipfs/go-log/v2"
|
2020-10-21 08:10:27 +00:00
|
|
|
"go.opencensus.io/tag"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/api"
|
2021-10-01 12:37:27 +00:00
|
|
|
"github.com/filecoin-project/lotus/metrics"
|
2020-10-21 08:10:27 +00:00
|
|
|
)
|
|
|
|
|
2023-12-04 13:15:52 +00:00
|
|
|
func MetricedAPI[T, P any](a T) *P {
|
2023-12-04 13:10:24 +00:00
|
|
|
var out P
|
2023-12-03 06:40:01 +00:00
|
|
|
proxy(a, &out)
|
2023-12-04 13:15:52 +00:00
|
|
|
return &out
|
2023-12-03 06:40:01 +00:00
|
|
|
}
|
|
|
|
|
2020-10-21 08:10:27 +00:00
|
|
|
func MetricedStorMinerAPI(a api.StorageMiner) api.StorageMiner {
|
2021-03-25 14:09:50 +00:00
|
|
|
var out api.StorageMinerStruct
|
2021-06-29 12:07:00 +00:00
|
|
|
proxy(a, &out)
|
2020-10-21 08:10:27 +00:00
|
|
|
return &out
|
|
|
|
}
|
|
|
|
|
|
|
|
func MetricedFullAPI(a api.FullNode) api.FullNode {
|
2021-03-25 14:09:50 +00:00
|
|
|
var out api.FullNodeStruct
|
2021-06-29 12:07:00 +00:00
|
|
|
proxy(a, &out)
|
2020-10-21 08:10:27 +00:00
|
|
|
return &out
|
|
|
|
}
|
|
|
|
|
2021-03-23 12:42:56 +00:00
|
|
|
func MetricedWorkerAPI(a api.Worker) api.Worker {
|
2021-03-25 14:09:50 +00:00
|
|
|
var out api.WorkerStruct
|
2021-06-29 12:07:00 +00:00
|
|
|
proxy(a, &out)
|
2020-10-21 08:10:27 +00:00
|
|
|
return &out
|
|
|
|
}
|
|
|
|
|
2021-03-23 12:42:56 +00:00
|
|
|
func MetricedWalletAPI(a api.Wallet) api.Wallet {
|
2021-03-25 14:09:50 +00:00
|
|
|
var out api.WalletStruct
|
2021-06-29 12:07:00 +00:00
|
|
|
proxy(a, &out)
|
2020-10-21 08:10:27 +00:00
|
|
|
return &out
|
|
|
|
}
|
|
|
|
|
2021-03-23 12:42:56 +00:00
|
|
|
func MetricedGatewayAPI(a api.Gateway) api.Gateway {
|
2021-03-25 14:09:50 +00:00
|
|
|
var out api.GatewayStruct
|
2021-06-29 12:07:00 +00:00
|
|
|
proxy(a, &out)
|
2020-10-21 08:10:27 +00:00
|
|
|
return &out
|
|
|
|
}
|
|
|
|
|
2021-06-29 12:07:00 +00:00
|
|
|
func proxy(in interface{}, outstr interface{}) {
|
|
|
|
outs := api.GetInternalStructs(outstr)
|
|
|
|
for _, out := range outs {
|
|
|
|
rint := reflect.ValueOf(out).Elem()
|
|
|
|
ra := reflect.ValueOf(in)
|
2020-10-21 08:10:27 +00:00
|
|
|
|
2021-06-29 12:07:00 +00:00
|
|
|
for f := 0; f < rint.NumField(); f++ {
|
|
|
|
field := rint.Type().Field(f)
|
|
|
|
fn := ra.MethodByName(field.Name)
|
2020-10-21 08:10:27 +00:00
|
|
|
|
2021-06-29 12:07:00 +00:00
|
|
|
rint.Field(f).Set(reflect.MakeFunc(field.Type, func(args []reflect.Value) (results []reflect.Value) {
|
|
|
|
ctx := args[0].Interface().(context.Context)
|
|
|
|
// upsert function name into context
|
2021-10-01 12:37:27 +00:00
|
|
|
ctx, _ = tag.New(ctx, tag.Upsert(metrics.Endpoint, field.Name))
|
|
|
|
stop := metrics.Timer(ctx, metrics.APIRequestDuration)
|
2021-06-29 12:07:00 +00:00
|
|
|
defer stop()
|
|
|
|
// pass tagged ctx back into function call
|
|
|
|
args[0] = reflect.ValueOf(ctx)
|
|
|
|
return fn.Call(args)
|
|
|
|
}))
|
|
|
|
}
|
2020-10-21 08:10:27 +00:00
|
|
|
}
|
2020-10-21 08:39:57 +00:00
|
|
|
}
|
2024-02-19 17:08:08 +00:00
|
|
|
|
|
|
|
var log = logging.Logger("api_proxy")
|
|
|
|
|
|
|
|
func LoggingAPI[T, P any](a T) *P {
|
|
|
|
var out P
|
|
|
|
logProxy(a, &out)
|
|
|
|
return &out
|
|
|
|
}
|
|
|
|
|
|
|
|
func logProxy(in interface{}, outstr interface{}) {
|
|
|
|
outs := api.GetInternalStructs(outstr)
|
|
|
|
for _, out := range outs {
|
|
|
|
rint := reflect.ValueOf(out).Elem()
|
|
|
|
ra := reflect.ValueOf(in)
|
|
|
|
|
|
|
|
for f := 0; f < rint.NumField(); f++ {
|
|
|
|
field := rint.Type().Field(f)
|
|
|
|
fn := ra.MethodByName(field.Name)
|
|
|
|
|
|
|
|
rint.Field(f).Set(reflect.MakeFunc(field.Type, func(args []reflect.Value) (results []reflect.Value) {
|
|
|
|
var wargs []interface{}
|
|
|
|
wargs = append(wargs, "method", field.Name)
|
|
|
|
|
|
|
|
for i := 1; i < len(args); i++ {
|
|
|
|
wargs = append(wargs, fmt.Sprintf("arg%d", i), args[i].Interface())
|
|
|
|
}
|
|
|
|
|
|
|
|
res := fn.Call(args)
|
|
|
|
for i, r := range res {
|
|
|
|
wargs = append(wargs, fmt.Sprintf("ret%d", i), r.Interface())
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Debugw("APICALL", wargs...)
|
|
|
|
return res
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|