Redis-to-HTTP proxy https://rpjios.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

146 lines
2.9 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.1"
  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. for _, toDec := range list {
  68. var newVal [2]float64
  69. err = json.Unmarshal([]byte(toDec), &newVal)
  70. if err != nil {
  71. log.Printf("bad rpjiosListVal! %v\n", err)
  72. stillGoing = false
  73. break
  74. }
  75. if int64(newVal[0]) >= limUnix {
  76. retList = append(retList, newVal)
  77. } else {
  78. stillGoing = false
  79. }
  80. }
  81. if stillGoing {
  82. start = end
  83. end = end + end
  84. }
  85. }
  86. log.Printf("1 RETLIST LEN: %v (%v)\n", len(retList), cap(retList))
  87. if cadSpec, ok := query["cad"]; ok {
  88. cad, err := strconv.ParseInt(cadSpec[0], 10, 64)
  89. if err == nil && cad < (back*60) {
  90. newList := make([][2]float64, 0, int64(cap(retList))/cad)
  91. lastMark := int64(-1)
  92. // TODO: detect natural cadence and then jump over N elements
  93. // in retList as optimization
  94. for _, chkVal := range retList {
  95. curMark := int64(chkVal[0])
  96. if lastMark == int64(-1) || lastMark-curMark > cad {
  97. newList = append(newList, chkVal)
  98. lastMark = curMark
  99. }
  100. }
  101. retList = newList
  102. log.Printf("2 RETLIST LEN: %v (%v)\n", len(retList), cap(retList))
  103. }
  104. }
  105. rlStr, err := json.Marshal(retList)
  106. if err == nil {
  107. return string(rlStr), nil
  108. }
  109. }
  110. }
  111. return "", nil
  112. }