Redis-to-HTTP proxy https://rpjios.com
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

151 righe
3.0 KiB

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "net/url"
  7. "os"
  8. "strconv"
  9. "time"
  10. )
  11. var hostname string
  12. func Version() string {
  13. return "0.0.2"
  14. }
  15. func HandleMsg(payload interface{}) (interface{}, error) {
  16. rxTime := float64(time.Now().UnixNano()) / 1e9
  17. if len(hostname) == 0 {
  18. hn, err := os.Hostname()
  19. if err != nil {
  20. log.Panic("can't get hostname!")
  21. }
  22. hostname = fmt.Sprintf("rhp://%s", hn)
  23. }
  24. var parsed map[string]interface{}
  25. err := json.Unmarshal([]byte(payload.(string)), &parsed)
  26. if err != nil {
  27. return payload, fmt.Errorf("unmarshal")
  28. }
  29. if ds, ok := parsed["__ds"]; ok {
  30. parsed["__ds"] = map[string]interface{}{
  31. "host": hostname,
  32. "prev": ds,
  33. "rate": 1,
  34. "tsDelta": rxTime - ds.(map[string]interface{})["ts"].(float64),
  35. "ts": rxTime,
  36. }
  37. newPayload, err := json.Marshal(parsed)
  38. if err != nil {
  39. return payload, fmt.Errorf("marshal")
  40. }
  41. return string(newPayload), nil
  42. }
  43. return payload, nil
  44. }
  45. func HandleListReq(dir string, file string, query url.Values, listLookup RhpHandleListReqLookupFunc) (string, error) {
  46. if dir != "/list/" || file == "" {
  47. return "", nil
  48. }
  49. if timeSpec, ok := query["back"]; ok {
  50. back, err := strconv.ParseInt(timeSpec[0], 10, 64)
  51. if err == nil {
  52. start := int64(0)
  53. end := int64(100)
  54. _ux := time.Now()
  55. limUnix := _ux.Unix() - (back * 60)
  56. log.Printf("NOW %v (%d)\n", _ux.String(), _ux.Unix())
  57. log.Printf("LIM %v (%d)\n", time.Unix(limUnix, 0), limUnix)
  58. retList := make([][2]float64, 0, end-start)
  59. stillGoing := true
  60. for stillGoing {
  61. list, err := listLookup(start, end)
  62. if err != nil {
  63. stillGoing = false
  64. log.Printf("broke! %v", err)
  65. break
  66. }
  67. if len(list) == 0 {
  68. stillGoing = false
  69. break
  70. }
  71. for _, toDec := range list {
  72. var newVal [2]float64
  73. err = json.Unmarshal([]byte(toDec), &newVal)
  74. if err != nil {
  75. log.Printf("bad rpjiosListVal! %v\n", err)
  76. stillGoing = false
  77. break
  78. }
  79. if int64(newVal[0]) >= limUnix {
  80. retList = append(retList, newVal)
  81. } else {
  82. stillGoing = false
  83. }
  84. }
  85. if stillGoing {
  86. start = end
  87. end = end + end
  88. }
  89. }
  90. log.Printf("1 RETLIST LEN: %v (%v)\n", len(retList), cap(retList))
  91. if cadSpec, ok := query["cad"]; ok {
  92. cad, err := strconv.ParseInt(cadSpec[0], 10, 64)
  93. if err == nil && cad < (back*60) {
  94. newList := make([][2]float64, 0, int64(cap(retList))/cad)
  95. lastMark := int64(-1)
  96. // TODO: detect natural cadence and then jump over N elements
  97. // in retList as optimization
  98. for _, chkVal := range retList {
  99. curMark := int64(chkVal[0])
  100. if lastMark == int64(-1) || lastMark-curMark > cad {
  101. newList = append(newList, chkVal)
  102. lastMark = curMark
  103. }
  104. }
  105. retList = newList
  106. log.Printf("2 RETLIST LEN: %v (%v)\n", len(retList), cap(retList))
  107. }
  108. }
  109. rlStr, err := json.Marshal(retList)
  110. if err == nil {
  111. return string(rlStr), nil
  112. }
  113. }
  114. }
  115. return "", nil
  116. }