go解析Prometheus的數據


訪問一個api, 返回如下數據:

{"status":"success","data":{"resultType":"matrix","result":[{"metric":{},"values":[[1473820558.361,"28765"],[1473820573.361,"28768"],[1473820588.361,"28772"],[1473820603.361,"28776"],[1473820618.361,"28780"],[1473820633.361,"28783"],[1473820648.361,"28786"],[1473820663.361,"28790"],[1473820678.361,"28793"],[1473820693.361,"28796"],[1473820708.361,"28799"],[1473820723.361,"28802"],[1473820738.361,"28806"],[1473820753.361,"28809"],[1473820768.361,"28817"],[1473820783.361,"28829"],[1473820798.361,"28832"],[1473820813.361,"28858"],[1473820828.361,"28862"],[1473820843.361,"28867"],[1473820858.361,"28873"]]}]}}


js, err := simplejson.NewJson(body)
    if err != nil {
        panic(err.Error())
    }
    //解析數組
    arr, _ := js.Get("data").Get("result").GetIndex(0).Get("values").Array()
    length := len(arr)
 
    for i := 0; i < length; i++ {
        x:= *js.Get("data").Get("result").GetIndex(0).Get("values").GetIndex(i).GetIndex(0))
        //fmt.Println(*js.Get("data").Get("result").GetIndex(0).Get("values").GetIndex(i).GetIndex(1))
    }

訪問一個api, 返回如下數據:

{
"data": {
"trend": {
"fields": [
"min_time",
"last_px",
"avg_px",
"business_amount"
]
,
"600570.SS": [
[
201501090930,
54.98,
54.98,
28327
],
[
201501090931,
54.63,
54.829486,
49700
]
]
}
}
}

需要解析 600570.SS 后的json數據,用了 simplejson包

js, err := simplejson.NewJson([]byte(str))
check(err)
arr, _ := js.Get("data").Get("trend").Get("600570.ss").Array()

可是對返回的arr數據,用了18般武藝都解析不了。 arr類型理論是一個interface{}類型,但是里面又包含了四組數據,對於這類json數據,網上文檔都沒有解析的方法。 反復嘗試后,用reflect.type 測試了下,發現系統把arr 認定為[]interface 類型,於是類型斷言后,遍歷。 這回可以把里面數據分拆開了,系統又把里面的數據判斷為 json.Number數據類型。 然后就沒有然后了.... 經過這一番摸索,對於空接口、類型斷言,json包內部的一些設定有了更深的理解:空接口就是因為它靈活,所以在使用時要經過一系列的判斷。

上代碼:

package main

import (
"encoding/json"
"fmt"
"github.com/bitly/go-simplejson"
"io/ioutil"
"net/http"
//"reflect"
"regexp"
"strconv"
"strings"
)

//const blkSize int = 10000

type trend struct {
date int64
last_px float32 //最新價
avg_px float32 //平均價
volumn float32 //成交量
}

var (
lines []string
blksLen []int
isGB bool
)

func check(err error) {
if err != nil {
panic(err.Error())
}
}

func Get(url string) ([]byte, error) {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
resp, err := http.Get(url)
check(err)
//Println(resp.StatusCode)
if resp.StatusCode != 200 {
panic("FUCK")
}
return ioutil.ReadAll(resp.Body)
}

func strip(src string) string {
src = strings.ToLower(src)
re, _ := regexp.Compile(`<!doctype.*?>`)
src = re.ReplaceAllString(src, "")

re, _ = regexp.Compile(`<!--.*?-->`)
src = re.ReplaceAllString(src, "")

re, _ = regexp.Compile(`<script[\S\s]+?</script>`)
src = re.ReplaceAllString(src, "")

re, _ = regexp.Compile(`<style[\S\s]+?</style>`)
src = re.ReplaceAllString(src, "")

re, _ = regexp.Compile(`<.*?>`)
src = re.ReplaceAllString(src, "")

re, _ = regexp.Compile(`&.{1,5};|&#.{1,5};`)
src = re.ReplaceAllString(src, "")

src = strings.Replace(src, "\r\n", "\n", -1)
src = strings.Replace(src, "\r", "\n", -1)
return src
}

func Do(url string) string {
body, err := Get(url)
check(err)
plainText := strip(string(body))
return plainText
}

func main() {

str := Do("http://xxx:8081/quote/v1/trend?prod_code=600570.SS&fields=last_px,business_amount,avg_px")
js, err := simplejson.NewJson([]byte(str))
check(err)
arr, _ := js.Get("data").Get("trend").Get("600570.ss").Array()
t := len(arr)
stockdata := trend{}
trends := make([]trend, 0, t)
for _, v := range arr {
//就在這里i進行類型判斷
value, _ := v.([]interface{})
for k, u := range value {

x, _ := u.(json.Number) //類型斷言
y, _ := strconv.ParseFloat(string(x), 64) //將字符型號轉化為float64
//v := reflect.ValueOf(k)
//fmt.Println("type:", v.Type())
switch k {
case 0:
stockdata.date = int64(y)
case 1:
stockdata.last_px = float32(y)
case 2:
stockdata.volumn = float32(y)
case 3:
stockdata.avg_px = float32(y)
default:
fmt.Println("結構體中不存在此元素")

}

}
trends = append(trends, stockdata)

}
fmt.Println(trends)
}

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com