KrakenD plugins are not only for response manipulation, but a much more powerful solution. There are 4 types of plugins in krakend, what you want to do I think that fits best as an HTTP SERVER plugin.
This type of plugin intercepts all incoming traffic and you can record it in a Redis database.
I have improvised a main.go
of the idea, but you should check the plugin guide in the documentation for more details.
Hope this helps illustrating the idea
package main
import (
"context"
"errors"
"fmt"
"html"
"net/http"
)
// HandlerRegisterer is the symbol the plugin loader will try to load. It must implement the Registerer interface
var HandlerRegisterer = registerer("krakend-api-monetization")
type registerer string
var logger Logger = nil
func (registerer) RegisterLogger(v interface{}) {
l, ok := v.(Logger)
if !ok {
return
}
logger = l
logger.Debug(fmt.Sprintf("[PLUGIN: %s] Logger loaded", HandlerRegisterer))
}
func (r registerer) RegisterHandlers(f func(
name string,
handler func(context.Context, map[string]interface{}, http.Handler) (http.Handler, error),
)) {
f(string(r), r.registerHandlers)
}
func (r registerer) registerHandlers(_ context.Context, extra map[string]interface{}, h http.Handler) (http.Handler, error) {
// check the passed configuration and initialize the plugin
name, ok := extra["name"].([]interface{})
if !ok {
return nil, errors.New("wrong config")
}
if v, ok := name[0].(string); !ok || v != string(r) {
return nil, fmt.Errorf("unknown register %s", name)
}
// check the cfg. If the modifier requires some configuration,
// it should be under the name of the plugin. E.g.:
/*
"extra_config":{
"plugin/http-server":{
"name":["krakend-api-monetization"],
"krakend-api-monetization":{
"redis_host": "localhost:6379"
}
}
}
*/
// The config variable contains all the keys you hace defined in the configuration:
config, _ := extra["krakend-api-monetization"].(map[string]interface{})
// The plugin will save activity in this host:
redis_host, _ := config["redis_host"].(string)
logger.Debug(fmt.Sprintf("The plugin is now storing on %s", redis_host))
// return the actual handler wrapping or your custom logic so it can be used as a replacement for the default http handler
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// TODO: Save in Redis the request
rdb := redis.NewClient(&redis.Options{
Addr: redis_host,
Password: "", // no password set
DB: 0, // use default DB
})
// etc...
logger.Debug("Request saved:", html.EscapeString(req.URL.Path))
}), nil
}
func main() {}
type Logger interface {
Debug(v ...interface{})
Info(v ...interface{})
Warning(v ...interface{})
Error(v ...interface{})
Critical(v ...interface{})
Fatal(v ...interface{})
}