mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-10 07:34:04 -08:00
Merge pull request #27 from matttproud/julius-api
Add REST API, expression browser, and text/JSON output formats.
This commit is contained in:
commit
f546548097
11
api/api.go
Normal file
11
api/api.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"code.google.com/p/gorest"
|
||||
)
|
||||
|
||||
type MetricsService struct {
|
||||
gorest.RestService `root:"/api/" consumes:"application/json" produces:"application/json"`
|
||||
|
||||
query gorest.EndPoint `method:"GET" path:"/query?{expr:string}&{json:string}&{start:string}&{end:string}" output:"string"`
|
||||
}
|
21
api/query.go
Normal file
21
api/query.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/matttproud/prometheus/rules"
|
||||
"github.com/matttproud/prometheus/rules/ast"
|
||||
"time"
|
||||
)
|
||||
func (serv MetricsService) Query(Expr string, Json string, Start string, End string) (result string) {
|
||||
exprNode, err := rules.LoadExprFromString(Expr)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
timestamp := time.Now()
|
||||
|
||||
format := ast.TEXT
|
||||
if Json != "" {
|
||||
format = ast.JSON
|
||||
}
|
||||
return ast.EvalToString(exprNode, ×tamp, format)
|
||||
}
|
10
main.go
10
main.go
|
@ -14,7 +14,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"code.google.com/p/gorest"
|
||||
"fmt"
|
||||
"github.com/matttproud/prometheus/api"
|
||||
"github.com/matttproud/golang_instrumentation"
|
||||
"github.com/matttproud/prometheus/config"
|
||||
"github.com/matttproud/prometheus/retrieval"
|
||||
|
@ -66,20 +68,24 @@ func main() {
|
|||
}
|
||||
|
||||
go func() {
|
||||
gorest.RegisterService(new(api.MetricsService))
|
||||
exporter := registry.DefaultRegistry.YieldExporter()
|
||||
|
||||
http.Handle("/", gorest.Handle())
|
||||
http.Handle("/metrics.json", exporter)
|
||||
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
||||
http.ListenAndServe(":9090", nil)
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case scrapeResult := <-scrapeResults:
|
||||
fmt.Printf("scrapeResult -> %s\n", scrapeResult)
|
||||
//fmt.Printf("scrapeResult -> %s\n", scrapeResult)
|
||||
for _, sample := range scrapeResult.Samples {
|
||||
persistence.AppendSample(&sample)
|
||||
}
|
||||
case ruleResult := <-ruleResults:
|
||||
fmt.Printf("ruleResult -> %s\n", ruleResult)
|
||||
//fmt.Printf("ruleResult -> %s\n", ruleResult)
|
||||
for _, sample := range ruleResult.Samples {
|
||||
persistence.AppendSample(sample)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,19 @@ package ast
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OutputFormat int
|
||||
|
||||
const (
|
||||
TEXT OutputFormat = iota
|
||||
JSON
|
||||
)
|
||||
|
||||
func binOpTypeToString(opType BinOpType) string {
|
||||
opTypeMap := map[BinOpType]string{
|
||||
ADD: "+",
|
||||
|
@ -34,6 +42,16 @@ func aggrTypeToString(aggrType AggrType) string {
|
|||
return aggrTypeMap[aggrType]
|
||||
}
|
||||
|
||||
func exprTypeToString(exprType ExprType) string {
|
||||
exprTypeMap := map[ExprType]string{
|
||||
SCALAR: "scalar",
|
||||
VECTOR: "vector",
|
||||
MATRIX: "matrix",
|
||||
STRING: "string",
|
||||
}
|
||||
return exprTypeMap[exprType]
|
||||
}
|
||||
|
||||
func durationToString(duration time.Duration) string {
|
||||
seconds := int64(duration / time.Second)
|
||||
factors := map[string]int64{
|
||||
|
@ -81,6 +99,96 @@ func (vector Vector) ToString() string {
|
|||
return strings.Join(metricStrings, "\n")
|
||||
}
|
||||
|
||||
func (matrix Matrix) ToString() string {
|
||||
metricStrings := []string{}
|
||||
for _, sampleSet := range matrix {
|
||||
metricName, ok := sampleSet.Metric["name"]
|
||||
if !ok {
|
||||
panic("Tried to print matrix without metric name")
|
||||
}
|
||||
labelStrings := []string{}
|
||||
for label, value := range sampleSet.Metric {
|
||||
if label != "name" {
|
||||
labelStrings = append(labelStrings, fmt.Sprintf("%v='%v'", label, value))
|
||||
}
|
||||
}
|
||||
sort.Strings(labelStrings)
|
||||
valueStrings := []string{}
|
||||
for _, value := range sampleSet.Values {
|
||||
valueStrings = append(valueStrings,
|
||||
fmt.Sprintf("\n%v @[%v]", value.Value, value.Timestamp))
|
||||
}
|
||||
metricStrings = append(metricStrings,
|
||||
fmt.Sprintf("%v{%v} => %v",
|
||||
metricName,
|
||||
strings.Join(labelStrings, ","),
|
||||
strings.Join(valueStrings, ", ")))
|
||||
}
|
||||
sort.Strings(metricStrings)
|
||||
return strings.Join(metricStrings, "\n")
|
||||
}
|
||||
|
||||
func errorToJSON(err error) string {
|
||||
errorStruct := struct {
|
||||
Type string
|
||||
Error string
|
||||
}{
|
||||
Type: "error",
|
||||
Error: err.Error(),
|
||||
}
|
||||
|
||||
errorJSON, err := json.MarshalIndent(errorStruct, "", "\t")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(errorJSON)
|
||||
}
|
||||
|
||||
func typedValueToJSON(data interface{}, typeStr string) string {
|
||||
dataStruct := struct {
|
||||
Type string
|
||||
Value interface{}
|
||||
}{
|
||||
Type: typeStr,
|
||||
Value: data,
|
||||
}
|
||||
dataJSON, err := json.MarshalIndent(dataStruct, "", "\t")
|
||||
if err != nil {
|
||||
return errorToJSON(err)
|
||||
}
|
||||
return string(dataJSON)
|
||||
}
|
||||
|
||||
func EvalToString(node Node, timestamp *time.Time, format OutputFormat) string {
|
||||
switch node.Type() {
|
||||
case SCALAR:
|
||||
scalar := node.(ScalarNode).Eval(timestamp)
|
||||
switch format {
|
||||
case TEXT: return fmt.Sprintf("scalar: %v", scalar)
|
||||
case JSON: return typedValueToJSON(scalar, "scalar")
|
||||
}
|
||||
case VECTOR:
|
||||
vector := node.(VectorNode).Eval(timestamp)
|
||||
switch format {
|
||||
case TEXT: return vector.ToString()
|
||||
case JSON: return typedValueToJSON(vector, "vector")
|
||||
}
|
||||
case MATRIX:
|
||||
matrix := node.(MatrixNode).Eval(timestamp)
|
||||
switch format {
|
||||
case TEXT: return matrix.ToString()
|
||||
case JSON: return typedValueToJSON(matrix, "matrix")
|
||||
}
|
||||
case STRING:
|
||||
str := node.(StringNode).Eval(timestamp)
|
||||
switch format {
|
||||
case TEXT: return str
|
||||
case JSON: return typedValueToJSON(str, "string")
|
||||
}
|
||||
}
|
||||
panic("Switch didn't cover all node types")
|
||||
}
|
||||
|
||||
func (node *VectorLiteral) ToString() string {
|
||||
metricName, ok := node.labels["name"]
|
||||
if !ok {
|
||||
|
|
Loading…
Reference in a new issue