提交 11653125 编写于 作者: K kongfei

replace json with easyjson for router

上级 8a145d5b
......@@ -16,6 +16,7 @@ require (
github.com/google/uuid v1.3.0
github.com/json-iterator/go v1.1.12
github.com/koding/multiconfig v0.0.0-20171124222453-69c27309b2d7
github.com/mailru/easyjson v0.7.7
github.com/mattn/go-isatty v0.0.12
github.com/orcaman/concurrent-map v0.0.0-20210501183033-44dafcb38ecc
github.com/pkg/errors v0.9.1
......@@ -58,6 +59,7 @@ require (
github.com/jackc/pgx/v4 v4.13.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.2 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
......
......@@ -245,6 +245,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
......@@ -277,6 +279,8 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
......
......@@ -16,11 +16,8 @@ import (
"github.com/didi/nightingale/v5/src/server/naming"
promstat "github.com/didi/nightingale/v5/src/server/stat"
jsoniter "github.com/json-iterator/go"
)
var json = jsoniter.ConfigCompatibleWithStandardLibrary
func New(version string, reloadFunc func()) *gin.Engine {
gin.SetMode(config.C.RunMode)
......
......@@ -16,14 +16,17 @@ import (
promstat "github.com/didi/nightingale/v5/src/server/stat"
"github.com/didi/nightingale/v5/src/server/writer"
"github.com/gin-gonic/gin"
"github.com/mailru/easyjson"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/prompb"
)
//easyjson:json
type TimeSeries struct {
Series []*DatadogMetric `json:"series"`
}
//easyjson:json
type DatadogMetric struct {
Metric string `json:"metric"`
Points []DatadogPoint `json:"points"`
......@@ -31,6 +34,7 @@ type DatadogMetric struct {
Tags []string `json:"tags,omitempty"`
}
//easyjson:json
type DatadogPoint [2]float64
func (m *DatadogMetric) Clean() error {
......@@ -213,7 +217,7 @@ func datadogSeries(c *gin.Context) {
}
var series TimeSeries
err = json.Unmarshal(bs, &series)
err = easyjson.Unmarshal(bs, &series)
if err != nil {
c.String(400, err.Error())
return
......
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
package router
import (
json "encoding/json"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
)
// suppress unused package warning
var (
_ *json.RawMessage
_ *jlexer.Lexer
_ *jwriter.Writer
_ easyjson.Marshaler
)
func easyjsonF301f710DecodeGithubComDidiNightingaleV5SrcServerRouter(in *jlexer.Lexer, out *TimeSeries) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "series":
if in.IsNull() {
in.Skip()
out.Series = nil
} else {
in.Delim('[')
if out.Series == nil {
if !in.IsDelim(']') {
out.Series = make([]*DatadogMetric, 0, 8)
} else {
out.Series = []*DatadogMetric{}
}
} else {
out.Series = (out.Series)[:0]
}
for !in.IsDelim(']') {
var v1 *DatadogMetric
if in.IsNull() {
in.Skip()
v1 = nil
} else {
if v1 == nil {
v1 = new(DatadogMetric)
}
(*v1).UnmarshalEasyJSON(in)
}
out.Series = append(out.Series, v1)
in.WantComma()
}
in.Delim(']')
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonF301f710EncodeGithubComDidiNightingaleV5SrcServerRouter(out *jwriter.Writer, in TimeSeries) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"series\":"
out.RawString(prefix[1:])
if in.Series == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v2, v3 := range in.Series {
if v2 > 0 {
out.RawByte(',')
}
if v3 == nil {
out.RawString("null")
} else {
(*v3).MarshalEasyJSON(out)
}
}
out.RawByte(']')
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v TimeSeries) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonF301f710EncodeGithubComDidiNightingaleV5SrcServerRouter(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v TimeSeries) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonF301f710EncodeGithubComDidiNightingaleV5SrcServerRouter(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *TimeSeries) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonF301f710DecodeGithubComDidiNightingaleV5SrcServerRouter(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *TimeSeries) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonF301f710DecodeGithubComDidiNightingaleV5SrcServerRouter(l, v)
}
func easyjsonF301f710DecodeGithubComDidiNightingaleV5SrcServerRouter1(in *jlexer.Lexer, out *DatadogPoint) {
isTopLevel := in.IsStart()
if in.IsNull() {
in.Skip()
} else {
in.Delim('[')
v4 := 0
for !in.IsDelim(']') {
if v4 < 2 {
(*out)[v4] = float64(in.Float64())
v4++
} else {
in.SkipRecursive()
}
in.WantComma()
}
in.Delim(']')
}
if isTopLevel {
in.Consumed()
}
}
func easyjsonF301f710EncodeGithubComDidiNightingaleV5SrcServerRouter1(out *jwriter.Writer, in DatadogPoint) {
out.RawByte('[')
for v5 := range in {
if v5 > 0 {
out.RawByte(',')
}
out.Float64(float64((in)[v5]))
}
out.RawByte(']')
}
// MarshalJSON supports json.Marshaler interface
func (v DatadogPoint) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonF301f710EncodeGithubComDidiNightingaleV5SrcServerRouter1(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v DatadogPoint) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonF301f710EncodeGithubComDidiNightingaleV5SrcServerRouter1(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *DatadogPoint) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonF301f710DecodeGithubComDidiNightingaleV5SrcServerRouter1(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *DatadogPoint) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonF301f710DecodeGithubComDidiNightingaleV5SrcServerRouter1(l, v)
}
func easyjsonF301f710DecodeGithubComDidiNightingaleV5SrcServerRouter2(in *jlexer.Lexer, out *DatadogMetric) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "metric":
out.Metric = string(in.String())
case "points":
if in.IsNull() {
in.Skip()
out.Points = nil
} else {
in.Delim('[')
if out.Points == nil {
if !in.IsDelim(']') {
out.Points = make([]DatadogPoint, 0, 4)
} else {
out.Points = []DatadogPoint{}
}
} else {
out.Points = (out.Points)[:0]
}
for !in.IsDelim(']') {
var v6 DatadogPoint
(v6).UnmarshalEasyJSON(in)
out.Points = append(out.Points, v6)
in.WantComma()
}
in.Delim(']')
}
case "host":
out.Host = string(in.String())
case "tags":
if in.IsNull() {
in.Skip()
out.Tags = nil
} else {
in.Delim('[')
if out.Tags == nil {
if !in.IsDelim(']') {
out.Tags = make([]string, 0, 4)
} else {
out.Tags = []string{}
}
} else {
out.Tags = (out.Tags)[:0]
}
for !in.IsDelim(']') {
var v7 string
v7 = string(in.String())
out.Tags = append(out.Tags, v7)
in.WantComma()
}
in.Delim(']')
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonF301f710EncodeGithubComDidiNightingaleV5SrcServerRouter2(out *jwriter.Writer, in DatadogMetric) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"metric\":"
out.RawString(prefix[1:])
out.String(string(in.Metric))
}
{
const prefix string = ",\"points\":"
out.RawString(prefix)
if in.Points == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v8, v9 := range in.Points {
if v8 > 0 {
out.RawByte(',')
}
(v9).MarshalEasyJSON(out)
}
out.RawByte(']')
}
}
{
const prefix string = ",\"host\":"
out.RawString(prefix)
out.String(string(in.Host))
}
if len(in.Tags) != 0 {
const prefix string = ",\"tags\":"
out.RawString(prefix)
{
out.RawByte('[')
for v10, v11 := range in.Tags {
if v10 > 0 {
out.RawByte(',')
}
out.String(string(v11))
}
out.RawByte(']')
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v DatadogMetric) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonF301f710EncodeGithubComDidiNightingaleV5SrcServerRouter2(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v DatadogMetric) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonF301f710EncodeGithubComDidiNightingaleV5SrcServerRouter2(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *DatadogMetric) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonF301f710DecodeGithubComDidiNightingaleV5SrcServerRouter2(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *DatadogMetric) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonF301f710DecodeGithubComDidiNightingaleV5SrcServerRouter2(l, v)
}
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
package router
import (
json "encoding/json"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
)
// suppress unused package warning
var (
_ *json.RawMessage
_ *jlexer.Lexer
_ *jwriter.Writer
_ easyjson.Marshaler
)
......@@ -15,10 +15,12 @@ import (
promstat "github.com/didi/nightingale/v5/src/server/stat"
"github.com/didi/nightingale/v5/src/server/writer"
"github.com/gin-gonic/gin"
"github.com/mailru/easyjson"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/prompb"
)
//easyjson:json
type FalconMetric struct {
Metric string `json:"metric"`
Endpoint string `json:"endpoint"`
......@@ -28,6 +30,9 @@ type FalconMetric struct {
Tags string `json:"tags"`
}
//easyjson:json
type FalconMetricArr []FalconMetric
func (m *FalconMetric) Clean(ts int64) error {
if m.Metric == "" {
return fmt.Errorf("metric is blank")
......@@ -162,13 +167,13 @@ func falconPush(c *gin.Context) {
return
}
var arr []FalconMetric
var arr FalconMetricArr
if bs[0] == '[' {
err = json.Unmarshal(bs, &arr)
err = easyjson.Unmarshal(bs, &arr)
} else {
var one FalconMetric
err = json.Unmarshal(bs, &one)
err = easyjson.Unmarshal(bs, &one)
arr = []FalconMetric{one}
}
......
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
package router
import (
json "encoding/json"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
)
// suppress unused package warning
var (
_ *json.RawMessage
_ *jlexer.Lexer
_ *jwriter.Writer
_ easyjson.Marshaler
)
func easyjson61ba9b47DecodeGithubComDidiNightingaleV5SrcServerRouter(in *jlexer.Lexer, out *FalconMetricArr) {
isTopLevel := in.IsStart()
if in.IsNull() {
in.Skip()
*out = nil
} else {
in.Delim('[')
if *out == nil {
if !in.IsDelim(']') {
*out = make(FalconMetricArr, 0, 0)
} else {
*out = FalconMetricArr{}
}
} else {
*out = (*out)[:0]
}
for !in.IsDelim(']') {
var v1 FalconMetric
(v1).UnmarshalEasyJSON(in)
*out = append(*out, v1)
in.WantComma()
}
in.Delim(']')
}
if isTopLevel {
in.Consumed()
}
}
func easyjson61ba9b47EncodeGithubComDidiNightingaleV5SrcServerRouter(out *jwriter.Writer, in FalconMetricArr) {
if in == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v2, v3 := range in {
if v2 > 0 {
out.RawByte(',')
}
(v3).MarshalEasyJSON(out)
}
out.RawByte(']')
}
}
// MarshalJSON supports json.Marshaler interface
func (v FalconMetricArr) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjson61ba9b47EncodeGithubComDidiNightingaleV5SrcServerRouter(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v FalconMetricArr) MarshalEasyJSON(w *jwriter.Writer) {
easyjson61ba9b47EncodeGithubComDidiNightingaleV5SrcServerRouter(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *FalconMetricArr) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjson61ba9b47DecodeGithubComDidiNightingaleV5SrcServerRouter(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *FalconMetricArr) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjson61ba9b47DecodeGithubComDidiNightingaleV5SrcServerRouter(l, v)
}
func easyjson61ba9b47DecodeGithubComDidiNightingaleV5SrcServerRouter1(in *jlexer.Lexer, out *FalconMetric) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "metric":
out.Metric = string(in.String())
case "endpoint":
out.Endpoint = string(in.String())
case "timestamp":
out.Timestamp = int64(in.Int64())
case "value":
if m, ok := out.ValueUnTyped.(easyjson.Unmarshaler); ok {
m.UnmarshalEasyJSON(in)
} else if m, ok := out.ValueUnTyped.(json.Unmarshaler); ok {
_ = m.UnmarshalJSON(in.Raw())
} else {
out.ValueUnTyped = in.Interface()
}
case "tags":
out.Tags = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjson61ba9b47EncodeGithubComDidiNightingaleV5SrcServerRouter1(out *jwriter.Writer, in FalconMetric) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"metric\":"
out.RawString(prefix[1:])
out.String(string(in.Metric))
}
{
const prefix string = ",\"endpoint\":"
out.RawString(prefix)
out.String(string(in.Endpoint))
}
{
const prefix string = ",\"timestamp\":"
out.RawString(prefix)
out.Int64(int64(in.Timestamp))
}
{
const prefix string = ",\"value\":"
out.RawString(prefix)
if m, ok := in.ValueUnTyped.(easyjson.Marshaler); ok {
m.MarshalEasyJSON(out)
} else if m, ok := in.ValueUnTyped.(json.Marshaler); ok {
out.Raw(m.MarshalJSON())
} else {
out.Raw(json.Marshal(in.ValueUnTyped))
}
}
{
const prefix string = ",\"tags\":"
out.RawString(prefix)
out.String(string(in.Tags))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v FalconMetric) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjson61ba9b47EncodeGithubComDidiNightingaleV5SrcServerRouter1(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v FalconMetric) MarshalEasyJSON(w *jwriter.Writer) {
easyjson61ba9b47EncodeGithubComDidiNightingaleV5SrcServerRouter1(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *FalconMetric) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjson61ba9b47DecodeGithubComDidiNightingaleV5SrcServerRouter1(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *FalconMetric) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjson61ba9b47DecodeGithubComDidiNightingaleV5SrcServerRouter1(l, v)
}
......@@ -19,8 +19,11 @@ import (
"github.com/didi/nightingale/v5/src/server/memsto"
promstat "github.com/didi/nightingale/v5/src/server/stat"
"github.com/didi/nightingale/v5/src/server/writer"
"github.com/mailru/easyjson"
_ "github.com/mailru/easyjson/gen"
)
// easyjson:json
type HTTPMetric struct {
Metric string `json:"metric"`
Timestamp int64 `json:"timestamp"`
......@@ -29,6 +32,9 @@ type HTTPMetric struct {
Tags map[string]string `json:"tags"`
}
//easyjson:json
type HTTPMetricArr []HTTPMetric
func (m *HTTPMetric) Clean(ts int64) error {
if m.Metric == "" {
return fmt.Errorf("metric is blank")
......@@ -145,13 +151,13 @@ func handleOpenTSDB(c *gin.Context) {
return
}
var arr []HTTPMetric
var arr HTTPMetricArr
if bs[0] == '[' {
err = json.Unmarshal(bs, &arr)
err = easyjson.Unmarshal(bs, &arr)
} else {
var one HTTPMetric
err = json.Unmarshal(bs, &one)
err = easyjson.Unmarshal(bs, &one)
arr = []HTTPMetric{one}
}
......
// TEMPORARY AUTOGENERATED FILE: easyjson stub code to make the package
// compilable during generation.
package router
import (
"github.com/mailru/easyjson/jwriter"
"github.com/mailru/easyjson/jlexer"
)
func ( HTTPMetric ) MarshalJSON() ([]byte, error) { return nil, nil }
func (* HTTPMetric ) UnmarshalJSON([]byte) error { return nil }
func ( HTTPMetric ) MarshalEasyJSON(w *jwriter.Writer) {}
func (* HTTPMetric ) UnmarshalEasyJSON(l *jlexer.Lexer) {}
type EasyJSON_exporter_HTTPMetric *HTTPMetric
func ( HTTPMetricArr ) MarshalJSON() ([]byte, error) { return nil, nil }
func (* HTTPMetricArr ) UnmarshalJSON([]byte) error { return nil }
func ( HTTPMetricArr ) MarshalEasyJSON(w *jwriter.Writer) {}
func (* HTTPMetricArr ) UnmarshalEasyJSON(l *jlexer.Lexer) {}
type EasyJSON_exporter_HTTPMetricArr *HTTPMetricArr
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册