Skip to content

Commit

Permalink
Added /stats
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonLovesDoggo committed May 25, 2024
1 parent c1a7131 commit bc842ad
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 24 deletions.
21 changes: 17 additions & 4 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,8 @@ <h1 id="countapi">Abacus</h1>
</p>

<p>
So far, <code data-stat-id="keys_created">...</code> keys have been created and there have been <code
data-stat-id="requests">...</code> requests served being <code data-stat-id="keys_updated">...</code> key
updates.<br>
So far, <code data-stat-id="keys">...</code> keys have been created and there have been <code
data-stat-id="commands_processed">...</code> requests served. Abacus is currently on version <code data-stat-id="version">...</code>.<br>
This page has been visited <code id="visits">...</code> times.
</p>
<h1 id="tldr">TL;DR</h1>
Expand Down Expand Up @@ -547,7 +546,20 @@ <h3 class="endpoint">/update/:namespace/*key?value=:amount (Requires Admin Key)<
</pre>



<h3 class="endpoint">/stats</h3>
<p>Gives some info about the server and database.</p>
<pre class="success">
GET /stats
⇒ 200 {
"commands_processed": "14911", // total requests
"db_uptime": "527154", // db uptime in seconds
"db_version": "6.0.16", // Redis version
"expired_keys": "438", // N expired keys
"key_misses": "468", // Requests that returned 404 (key not found)
"keys": "75", // N active keys
"version": "1.0.0" // Abacus's current version
}
</pre>

<footer>
made by <a href="https://jasoncameron.dev">Jason Cameron</a> as a replacement for <a
Expand Down Expand Up @@ -580,6 +592,7 @@ <h3 class="endpoint">/update/:namespace/*key?value=:amount (Requires Admin Key)<
for (var i in els)
els[i].innerText = str;
}
document.querySelectorAll(`*[data-stat-id="keys"]`).innerText = obj["keys"] + obj["expired_keys"];
}
setTimeout(stats, 10000);
});
Expand Down
12 changes: 7 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const DocsUrl string = "https://jasoncameron.dev/abacus/"

var startTime time.Time

const Version string = "1.0.0"

func main() {
// only run the following if .env is present
utils.LoadEnv()
Expand All @@ -45,12 +47,12 @@ func main() {
context.JSON(http.StatusOK, gin.H{
"status": "ok", "uptime": time.Since(startTime).String()})
})
route.GET("/docs", func(context *gin.Context) {
context.Redirect(http.StatusPermanentRedirect, DocsUrl)
})

route.GET("/docs", func(context *gin.Context) {
context.Redirect(http.StatusPermanentRedirect, DocsUrl)
})
route.GET("/stats", StatsView)

route.GET("/get/:namespace/*key", GetView)
route.GET("/get/:namespace/*key", GetView)

route.GET("/hit/:namespace/*key", HitView)
route.GET("/stream/:namespace/*key", middleware.SSEMiddleware(), StreamValueView)
Expand Down
64 changes: 49 additions & 15 deletions routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"
"os"
"strconv"
"strings"
"sync"

"github.com/redis/go-redis/v9"
Expand All @@ -32,21 +33,23 @@ func SetStream(dbKey string, value int) {
}
}

var DB_NUM int = 0

func init() {
// Connect to Redis
utils.LoadEnv()
ADDR := os.Getenv("REDIS_HOST") + ":" + os.Getenv("REDIS_PORT")
fmt.Println("Listening to redis on: " + ADDR)
PASS, _ := strconv.Atoi(os.Getenv("REDIS_DB"))
DB_NUM, _ := strconv.Atoi(os.Getenv("REDIS_DB"))
Client = redis.NewClient(&redis.Options{
Addr: ADDR, // Redis server address
Username: os.Getenv("REDIS_USERNAME"),
Password: os.Getenv("REDIS_PASSWORD"),
DB: PASS,
DB: DB_NUM,
})
}

func StreamValueView(c *gin.Context) { // todo: fix hanging when key does not exist
func StreamValueView(c *gin.Context) { // todo: fix hanging when key does not exist
namespace, key := utils.GetNamespaceKey(c)
if namespace == "" || key == "" {
return
Expand Down Expand Up @@ -130,7 +133,6 @@ func HitView(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"value": val})
}


func GetView(c *gin.Context) {
namespace, key := utils.GetNamespaceKey(c)
if namespace == "" || key == "" {
Expand All @@ -143,24 +145,21 @@ func GetView(c *gin.Context) {
// Get data from Redis
val, err := Client.Get(context.Background(), dbKey).Result()


if err == redis.Nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Key not found"})
return
} else if err != nil { // Other Redis errors
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get data. Try again later."})
return
}
if err == redis.Nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Key not found"})
return
} else if err != nil { // Other Redis errors
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get data. Try again later."})
return
}

go func() {
Client.Expire(context.Background(), dbKey, utils.BaseTTLPeriod)
}()
intval, _ := strconv.Atoi(val)
intval, _ := strconv.Atoi(val)
c.JSON(http.StatusOK, gin.H{"value": intval})
}



func CreateRandomView(c *gin.Context) {
key, _ := utils.GenerateRandomString(16)
namespace, err := utils.GenerateRandomString(16)
Expand Down Expand Up @@ -345,3 +344,38 @@ func UpdateByView(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"value": int64(val)})
go SetStream(dbKey, int(val))
}

func StatsView(c *gin.Context) {
// get average ttl using INFO

ctx := context.Background()
infoStr, err := Client.Info(ctx).Result()
if err != nil {
panic(err)
}

infoDict := make(map[string]map[string]string)
sections := strings.Split(infoStr, "\r\n\r\n")

for _, section := range sections {
lines := strings.Split(section, "\r\n")
sectionName := lines[0][2:] // Remove "# " prefix

infoDict[sectionName] = make(map[string]string)
for _, line := range lines[1:] {
parts := strings.Split(line, ":")
if len(parts) == 2 {
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
infoDict[sectionName][key] = value
}
}
}

dbInfo := strings.Split(infoDict["Keyspace"]["db"+strconv.Itoa(DB_NUM)], ",")
keys := strings.Split(dbInfo[0], "=")
c.JSON(http.StatusOK, gin.H{"version": Version, "db_uptime": infoDict["Server"]["uptime_in_seconds"], "db_version": infoDict["Server"]["redis_version"], "expired_keys": infoDict["Stats"]["expired_keys"],
"key_misses": infoDict["Stats"]["keyspace_misses"],
"commands_processed": infoDict["Stats"]["total_commands_processed"], "keys": keys[1]})

}

0 comments on commit bc842ad

Please sign in to comment.