<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #44652 Docs: https://github.com/fleetdm/fleet/pull/46631 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Database migrations - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). ## New Fleet configuration settings - [x] Setting(s) is/are explicitly excluded from GitOps <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Route-aware OpenTelemetry trace sampling with tiered default ratios (very low for select high-volume routes, reduced rate for admin reads, full sampling otherwise). * Admin-only GET/PATCH /debug/trace_sampler to view and update sampling ratios and a runtime "force full" toggle. * Liveness probe endpoints (/healthz, /version, /metrics) are excluded from tracing; settings propagate to replicas at runtime without restart. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
74 lines
2.9 KiB
Go
74 lines
2.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/fleetdm/fleet/v4/server/activity/api"
|
|
api_http "github.com/fleetdm/fleet/v4/server/activity/api/http"
|
|
eu "github.com/fleetdm/fleet/v4/server/platform/endpointer"
|
|
platform_http "github.com/fleetdm/fleet/v4/server/platform/http"
|
|
"github.com/fleetdm/fleet/v4/server/platform/tracing"
|
|
"github.com/go-kit/kit/endpoint"
|
|
kithttp "github.com/go-kit/kit/transport/http"
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
// GetRoutes returns a function that registers activity routes on the router.
|
|
func GetRoutes(svc api.Service, authMiddleware endpoint.Middleware) eu.HandlerRoutesFunc {
|
|
return func(r *mux.Router, opts []kithttp.ServerOption) {
|
|
attachFleetAPIRoutes(r, svc, authMiddleware, opts)
|
|
}
|
|
}
|
|
|
|
func attachFleetAPIRoutes(r *mux.Router, svc api.Service, authMiddleware endpoint.Middleware, opts []kithttp.ServerOption) {
|
|
// User-authenticated endpoints
|
|
ue := newUserAuthenticatedEndpointer(svc, authMiddleware, opts, r, apiVersions()...)
|
|
|
|
ue.GET("/api/_version_/fleet/activities", listActivitiesEndpoint, api_http.ListActivitiesRequest{})
|
|
ue.GET("/api/_version_/fleet/hosts/{id:[0-9]+}/activities", listHostPastActivitiesEndpoint, api_http.ListHostPastActivitiesRequest{})
|
|
}
|
|
|
|
// RegisterTracingTiers classifies this context's routes for trace sampling. Both activity list endpoints are admin reads, so
|
|
// they belong in the standard tier (default 2%). Kept next to the route registrations above so the two stay in sync. The
|
|
// sampler's version normalizer collapses the {fleetversion:...} segment, so the "_version_" placeholder matches the rendered
|
|
// span name regardless of the configured API versions.
|
|
func RegisterTracingTiers(registry *tracing.Registry) {
|
|
registry.Register(http.MethodGet, "/api/_version_/fleet/activities", tracing.TierStandard)
|
|
registry.Register(http.MethodGet, "/api/_version_/fleet/hosts/{id}/activities", tracing.TierStandard)
|
|
}
|
|
|
|
func apiVersions() []string {
|
|
return []string{"v1", "latest"}
|
|
}
|
|
|
|
// listActivitiesEndpoint handles GET /api/_version_/fleet/activities
|
|
func listActivitiesEndpoint(ctx context.Context, request any, svc api.Service) platform_http.Errorer {
|
|
req := request.(*api_http.ListActivitiesRequest)
|
|
|
|
activities, meta, err := svc.ListActivities(ctx, req.ListOptions)
|
|
if err != nil {
|
|
return api_http.ListActivitiesResponse{Err: err}
|
|
}
|
|
|
|
return api_http.ListActivitiesResponse{
|
|
Meta: meta,
|
|
Activities: activities,
|
|
}
|
|
}
|
|
|
|
// listHostPastActivitiesEndpoint handles GET /api/_version_/fleet/hosts/{id}/activities
|
|
func listHostPastActivitiesEndpoint(ctx context.Context, request any, svc api.Service) platform_http.Errorer {
|
|
req := request.(*api_http.ListHostPastActivitiesRequest)
|
|
|
|
activities, meta, err := svc.ListHostPastActivities(ctx, req.HostID, req.ListOptions)
|
|
if err != nil {
|
|
return api_http.ListHostPastActivitiesResponse{Err: err}
|
|
}
|
|
|
|
return api_http.ListHostPastActivitiesResponse{
|
|
Meta: meta,
|
|
Activities: activities,
|
|
}
|
|
}
|