From 867cfc55ee5b90ee2dc4b00dfef6bf43e1831ca7 Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Thu, 25 Sep 2025 11:28:02 +0200 Subject: [PATCH] feat: add endpoint for service specific transfer count stats --- web_serviceV2.go | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/web_serviceV2.go b/web_serviceV2.go index d03f7a0..f1f7e5c 100644 --- a/web_serviceV2.go +++ b/web_serviceV2.go @@ -39,6 +39,7 @@ func NewWebServiceV2(config *Config, storage StorageInterface) *WebServiceV2 { mux.HandleFunc("GET /logs", ws.handleLogs) mux.HandleFunc("GET /export", ws.handleExport) mux.HandleFunc("GET /stats", ws.handleStats) + mux.HandleFunc("GET /stats/{service}", ws.handleServiceStats) loggedMux := LoggingMiddleware(mux) @@ -228,6 +229,72 @@ func (ws *WebServiceV2) handleStats(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(stats) } +func (ws *WebServiceV2) handleServiceStats(w http.ResponseWriter, r *http.Request) { + service := r.PathValue("service") + if service == "" { + http.Error(w, "Service parameter is missing", http.StatusBadRequest) + return + } + + timeRangeStr := r.URL.Query().Get("time_range") + var startTime time.Time + if timeRangeStr == "" { + startTime = time.Now().Add(-24 * time.Hour) + } else { + duration, err := time.ParseDuration(timeRangeStr) + if err != nil { + http.Error(w, fmt.Sprintf("Invalid time_range: %v", err), http.StatusBadRequest) + return + } + startTime = time.Now().Add(-duration) + } + + query := StorageQuery{ + Service: service, + StartTime: startTime, + Limit: 0, + OrderDesc: false, + } + + ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second) + defer cancel() + + entries, err := ws.storage.Query(ctx, query) + if err != nil { + slog.Error("Failed to query service stats", "service", service, "error", err) + http.Error(w, fmt.Sprintf("Query error: %v", err), http.StatusInternalServerError) + return + } + + uniqueTransfers := make(map[string]struct{}) + for _, entry := range entries { + var identifier string + switch v := entry.ServiceInformation.(type) { + case models.TSTransferInfo: + identifier = v.TransferID + case models.TJMTransferInfo: + identifier = v.TransferID + default: + continue + } + + if identifier != "" { + uniqueTransfers[identifier] = struct{}{} + } + } + + stats := map[string]any{ + "service": service, + "start_time": startTime, + "end_time": time.Now(), + "unique_transfer_identifiers": len(uniqueTransfers), + "entry_count": len(entries), + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(stats) +} + func (ws *WebServiceV2) parseLogsQuery(r *http.Request) StorageQuery { query := StorageQuery{ Limit: 100,