Add logging HTTP requests as single session

This commit is contained in:
Ingo Oppermann
2023-06-21 16:46:35 +02:00
parent 6826a0b22d
commit b8a975b7c7
4 changed files with 96 additions and 15 deletions

View File

@@ -94,6 +94,8 @@ func NewHLSWithConfig(config HLSConfig) echo.MiddlewareFunc {
func (h *hls) handleIngress(c echo.Context, next echo.HandlerFunc) error {
req := c.Request()
ctxuser := util.DefaultContext(c, "user", "")
path := req.URL.Path
if strings.HasSuffix(path, ".m3u8") {
@@ -113,10 +115,15 @@ func (h *hls) handleIngress(c echo.Context, next echo.HandlerFunc) error {
}
if !h.ingressCollector.IsKnownSession(path) {
ip, _ := net.AnonymizeIPString(c.RealIP())
// Register a new session
reference := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
h.ingressCollector.RegisterAndActivate(path, reference, path, "")
h.ingressCollector.RegisterAndActivate(path, reference, path, ip)
h.ingressCollector.Extra(path, map[string]interface{}{
"name": ctxuser,
"ip": ip,
"user_agent": req.Header.Get("User-Agent"),
})
}

View File

@@ -4,8 +4,13 @@ import (
"io"
"net"
"net/http"
"net/url"
"github.com/datarhei/core/v16/glob"
"github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/v16/session"
"github.com/lithammer/shortuuid/v4"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
@@ -43,6 +48,8 @@ func NewHTTPWithConfig(config HTTPConfig) echo.MiddlewareFunc {
return next(c)
}
ctxuser := util.DefaultContext(c, "user", "")
req := c.Request()
res := c.Response()
@@ -51,32 +58,91 @@ func NewHTTPWithConfig(config HTTPConfig) echo.MiddlewareFunc {
host = ""
}
path := req.URL.Path
location := path + req.URL.RawQuery
remote := req.RemoteAddr
id := shortuuid.New()
data := map[string]interface{}{}
e := util.DefaultContext[interface{}](c, "session", nil)
if e != nil {
var ok bool
data, ok = e.(map[string]interface{})
if !ok {
return api.Err(http.StatusForbidden, "", "invalid session data, cast")
}
if match, ok := data["match"].(string); ok {
if ok, err := glob.Match(match, path, '/'); !ok {
if err != nil {
return api.Err(http.StatusForbidden, "", "no match for '%s' in %s: %s", match, path, err.Error())
}
return api.Err(http.StatusForbidden, "", "no match for '%s' in %s", match, path)
}
}
referrer := req.Header.Get("Referer")
if u, err := url.Parse(referrer); err == nil {
referrer = u.Host
}
if remote, ok := data["remote"].([]string); ok && len(remote) != 0 {
match := false
for _, r := range remote {
if referrer == r {
match = true
break
}
}
if !match {
return api.Err(http.StatusForbidden, "", "remote not allowed")
}
}
}
data["name"] = ctxuser
data["method"] = req.Method
data["code"] = 0
reader := req.Body
r := &fakeReader{
reader: req.Body,
}
req.Body = r
defer func() {
req.Body = reader
if config.Collector.IsCollectableIP(host) {
config.Collector.RegisterAndActivate("HTTP", "", "any", "any")
config.Collector.Ingress("HTTP", r.size+headerSize(req.Header))
}
}()
writer := res.Writer
w := &fakeWriter{
ResponseWriter: res.Writer,
}
res.Writer = w
if config.Collector.IsCollectableIP(host) {
config.Collector.RegisterAndActivate(id, "", location, remote)
config.Collector.Extra(id, data)
}
defer config.Collector.Close(id)
defer func() {
req.Body = reader
if config.Collector.IsCollectableIP(host) {
config.Collector.Ingress(id, r.size+headerSize(req.Header))
}
}()
defer func() {
res.Writer = writer
if config.Collector.IsCollectableIP(host) {
config.Collector.Egress("HTTP", w.size+headerSize(res.Header()))
config.Collector.Egress(id, w.size+headerSize(res.Header()))
data["code"] = res.Status
config.Collector.Extra(id, data)
}
}()
@@ -104,6 +170,13 @@ func (r *fakeReader) Close() error {
type fakeWriter struct {
http.ResponseWriter
size int64
code int
}
func (w *fakeWriter) WriteHeader(statusCode int) {
w.ResponseWriter.WriteHeader(statusCode)
w.code = statusCode
}
func (w *fakeWriter) Write(body []byte) (int, error) {

View File

@@ -371,9 +371,6 @@ func NewServer(config Config) (Server, error) {
return nil
},
}))
s.router.Use(mwsession.NewHTTPWithConfig(mwsession.HTTPConfig{
Collector: config.Sessions.Collector("http"),
}))
s.router.HideBanner = true
s.router.HidePort = true
@@ -386,6 +383,10 @@ func NewServer(config Config) (Server, error) {
s.router.Use(s.middleware.iam)
s.router.Use(mwsession.NewHTTPWithConfig(mwsession.HTTPConfig{
Collector: config.Sessions.Collector("http"),
}))
// Add static routes
if path, target := config.Router.StaticRoute(); len(target) != 0 {
group := s.router.Group(path)

View File

@@ -314,7 +314,7 @@ func (r *registry) Register(id string, conf CollectorConfig) (Collector, error)
return nil, fmt.Errorf("a collector with the ID '%s' already exists", id)
}
m, err := newCollector(id, r.persist.sessionsCh, r.logger.WithComponent(id), conf)
m, err := newCollector(id, r.persist.sessionsCh, r.logger, conf)
if err != nil {
return nil, err
}