Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 11 additions & 242 deletions cmd/osquery-perf/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"time"

"github.com/fleetdm/fleet/v4/cmd/osquery-perf/installer_cache"
"github.com/fleetdm/fleet/v4/cmd/osquery-perf/osquery_perf"
"github.com/fleetdm/fleet/v4/pkg/file"
"github.com/fleetdm/fleet/v4/pkg/mdm/mdmtest"
"github.com/fleetdm/fleet/v4/server/fleet"
Expand Down Expand Up @@ -141,240 +142,6 @@ func init() {
ubuntuSoftware = loadSoftwareItems(ubuntuSoftwareFS, "ubuntu_2204-software.json.bz2")
}

type Stats struct {
startTime time.Time
errors int
osqueryEnrollments int
orbitEnrollments int
mdmEnrollments int
mdmSessions int
distributedWrites int
mdmCommandsReceived int
distributedReads int
configRequests int
configErrors int
resultLogRequests int
orbitErrors int
mdmErrors int
ddmDeclarationItemsErrors int
ddmConfigurationErrors int
ddmActivationErrors int
ddmStatusErrors int
ddmDeclarationItemsSuccess int
ddmConfigurationSuccess int
ddmActivationSuccess int
ddmStatusSuccess int
desktopErrors int
distributedReadErrors int
distributedWriteErrors int
resultLogErrors int
bufferedLogs int

l sync.Mutex
}

func (s *Stats) IncrementErrors(errors int) {
s.l.Lock()
defer s.l.Unlock()
s.errors += errors
}

func (s *Stats) IncrementEnrollments() {
s.l.Lock()
defer s.l.Unlock()
s.osqueryEnrollments++
}

func (s *Stats) IncrementOrbitEnrollments() {
s.l.Lock()
defer s.l.Unlock()
s.orbitEnrollments++
}

func (s *Stats) IncrementMDMEnrollments() {
s.l.Lock()
defer s.l.Unlock()
s.mdmEnrollments++
}

func (s *Stats) IncrementMDMSessions() {
s.l.Lock()
defer s.l.Unlock()
s.mdmSessions++
}

func (s *Stats) IncrementDistributedWrites() {
s.l.Lock()
defer s.l.Unlock()
s.distributedWrites++
}

func (s *Stats) IncrementMDMCommandsReceived() {
s.l.Lock()
defer s.l.Unlock()
s.mdmCommandsReceived++
}

func (s *Stats) IncrementDistributedReads() {
s.l.Lock()
defer s.l.Unlock()
s.distributedReads++
}

func (s *Stats) IncrementConfigRequests() {
s.l.Lock()
defer s.l.Unlock()
s.configRequests++
}

func (s *Stats) IncrementConfigErrors() {
s.l.Lock()
defer s.l.Unlock()
s.configErrors++
}

func (s *Stats) IncrementResultLogRequests() {
s.l.Lock()
defer s.l.Unlock()
s.resultLogRequests++
}

func (s *Stats) IncrementOrbitErrors() {
s.l.Lock()
defer s.l.Unlock()
s.orbitErrors++
}

func (s *Stats) IncrementMDMErrors() {
s.l.Lock()
defer s.l.Unlock()
s.mdmErrors++
}

func (s *Stats) IncrementDDMDeclarationItemsErrors() {
s.l.Lock()
defer s.l.Unlock()
s.ddmDeclarationItemsErrors++
}

func (s *Stats) IncrementDDMConfigurationErrors() {
s.l.Lock()
defer s.l.Unlock()
s.ddmConfigurationErrors++
}

func (s *Stats) IncrementDDMActivationErrors() {
s.l.Lock()
defer s.l.Unlock()
s.ddmActivationErrors++
}

func (s *Stats) IncrementDDMStatusErrors() {
s.l.Lock()
defer s.l.Unlock()
s.ddmStatusErrors++
}

func (s *Stats) IncrementDDMDeclarationItemsSuccess() {
s.l.Lock()
defer s.l.Unlock()
s.ddmDeclarationItemsSuccess++
}

func (s *Stats) IncrementDDMConfigurationSuccess() {
s.l.Lock()
defer s.l.Unlock()
s.ddmConfigurationSuccess++
}

func (s *Stats) IncrementDDMActivationSuccess() {
s.l.Lock()
defer s.l.Unlock()
s.ddmActivationSuccess++
}

func (s *Stats) IncrementDDMStatusSuccess() {
s.l.Lock()
defer s.l.Unlock()
s.ddmStatusSuccess++
}

func (s *Stats) IncrementDesktopErrors() {
s.l.Lock()
defer s.l.Unlock()
s.desktopErrors++
}

func (s *Stats) IncrementDistributedReadErrors() {
s.l.Lock()
defer s.l.Unlock()
s.distributedReadErrors++
}

func (s *Stats) IncrementDistributedWriteErrors() {
s.l.Lock()
defer s.l.Unlock()
s.distributedWriteErrors++
}

func (s *Stats) IncrementResultLogErrors() {
s.l.Lock()
defer s.l.Unlock()
s.resultLogErrors++
}

func (s *Stats) UpdateBufferedLogs(v int) {
s.l.Lock()
defer s.l.Unlock()
s.bufferedLogs += v
if s.bufferedLogs < 0 {
s.bufferedLogs = 0
}
}

func (s *Stats) Log() {
s.l.Lock()
defer s.l.Unlock()

log.Printf(
"uptime: %s, error rate: %.2f, osquery enrolls: %d, orbit enrolls: %d, mdm enrolls: %d, distributed/reads: %d, distributed/writes: %d, config requests: %d, result log requests: %d, mdm sessions initiated: %d, mdm commands received: %d, config errors: %d, distributed/read errors: %d, distributed/write errors: %d, log result errors: %d, orbit errors: %d, desktop errors: %d, mdm errors: %d, ddm declaration items success: %d, ddm declaration items errors: %d, ddm activation success: %d, ddm activation errors: %d, ddm configuration success: %d, ddm configuration errors: %d, ddm status success: %d, ddm status errors: %d, buffered logs: %d",
time.Since(s.startTime).Round(time.Second),
float64(s.errors)/float64(s.osqueryEnrollments),
s.osqueryEnrollments,
s.orbitEnrollments,
s.mdmEnrollments,
s.distributedReads,
s.distributedWrites,
s.configRequests,
s.resultLogRequests,
s.mdmSessions,
s.mdmCommandsReceived,
s.configErrors,
s.distributedReadErrors,
s.distributedWriteErrors,
s.resultLogErrors,
s.orbitErrors,
s.desktopErrors,
s.mdmErrors,
s.ddmDeclarationItemsSuccess,
s.ddmDeclarationItemsErrors,
s.ddmActivationSuccess,
s.ddmActivationErrors,
s.ddmConfigurationSuccess,
s.ddmConfigurationErrors,
s.ddmStatusSuccess,
s.ddmStatusErrors,
s.bufferedLogs,
)
}

func (s *Stats) runLoop() {
ticker := time.Tick(10 * time.Second)
for range ticker {
s.Log()
}
}

type nodeKeyManager struct {
filepath string

Expand Down Expand Up @@ -436,7 +203,7 @@ type mdmAgent struct {
model string
serverAddress string
softwareCount softwareEntityCount
stats *Stats
stats *osquery_perf.Stats
strings map[string]string
}

Expand All @@ -463,7 +230,7 @@ type agent struct {
liveQueryNoResultsProb float64
strings map[string]string
serverAddress string
stats *Stats
stats *osquery_perf.Stats
nodeKeyManager *nodeKeyManager
nodeKey string
templates *template.Template
Expand Down Expand Up @@ -1314,13 +1081,14 @@ func (a *agent) installSoftwareItem(installerID string, orbitClient *service.Orb
if !failed {
var cacheMiss bool
// Download the file if needed to get its metadata
meta, cacheMiss, err = installerMetadataCache.Get(installer.InstallerID, orbitClient)
meta, cacheMiss, err = installerMetadataCache.Get(installer, orbitClient)
if err != nil {
return
}

if !cacheMiss {
// If we didn't download and analyze the file, we do a download and don't save the result
if !cacheMiss && installer.SoftwareInstallerURL == nil {
// If we didn't download and analyze the file, AND we did not use a CDN URL to get the file,
// we do a download now and don't save the result. Doing this download adds realistic load on the server.
err = orbitClient.DownloadAndDiscardSoftwareInstaller(installer.InstallerID)
if err != nil {
log.Println("download and discard software installer:", err)
Expand Down Expand Up @@ -2765,10 +2533,11 @@ func main() {
// Spread starts over the interval to prevent thundering herd
sleepTime := *startPeriod / time.Duration(*hostCount)

stats := &Stats{
startTime: time.Now(),
stats := &osquery_perf.Stats{
StartTime: time.Now(),
}
go stats.runLoop()
go stats.RunLoop()
installerMetadataCache.Stats = stats

nodeKeyManager := &nodeKeyManager{}
if nodeKeyFile != nil {
Expand Down
45 changes: 33 additions & 12 deletions cmd/osquery-perf/installer_cache/installer-cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"sync"

"github.com/fleetdm/fleet/v4/cmd/osquery-perf/osquery_perf"
"github.com/fleetdm/fleet/v4/pkg/file"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/service"
Expand All @@ -16,51 +17,71 @@ import (
type Metadata struct {
mu sync.Mutex
cache map[uint]*file.InstallerMetadata
Stats *osquery_perf.Stats
}

func (c *Metadata) Get(key uint, orbitClient *service.OrbitClient) (meta *file.InstallerMetadata,
func (c *Metadata) Get(installer *fleet.SoftwareInstallDetails, orbitClient *service.OrbitClient) (meta *file.InstallerMetadata,
cacheMiss bool, err error) {
c.mu.Lock()
defer c.mu.Unlock()
if c.cache == nil {
c.cache = make(map[uint]*file.InstallerMetadata, 1)
}

meta, ok := c.cache[key]
meta, ok := c.cache[installer.InstallerID]
if !ok {
var err error
meta, err = populateMetadata(orbitClient, key)
meta, err = c.populateMetadata(installer, orbitClient)
if err != nil {
return nil, false, err
}
c.cache[key] = meta
c.cache[installer.InstallerID] = meta
cacheMiss = true
}
return meta, cacheMiss, nil
}

func populateMetadata(orbitClient *service.OrbitClient, installerID uint) (*file.InstallerMetadata, error) {
func (c *Metadata) populateMetadata(installer *fleet.SoftwareInstallDetails, orbitClient *service.OrbitClient) (*file.InstallerMetadata,
error) {
tmpDir, err := os.MkdirTemp("", "")
if err != nil {
log.Println("create temp dir:", err)
c.Stats.IncrementOrbitErrors()
log.Println("level=error, create temp dir:", err)
return nil, err
}
defer os.RemoveAll(tmpDir)
path, err := orbitClient.DownloadSoftwareInstaller(installerID, tmpDir)
if err != nil {
log.Println("download software installer:", err)
return nil, err

var path string
if installer.SoftwareInstallerURL != nil {
path, err = orbitClient.DownloadSoftwareInstallerFromURL(installer.SoftwareInstallerURL.URL,
installer.SoftwareInstallerURL.Filename, tmpDir)
if err != nil {
log.Printf("level=error, msg=download software installer from URL; is CloudFront CDN configured correctly?, err=%s", err)
c.Stats.IncrementOrbitErrors()
return nil, err
}
}

if path == "" {
path, err = orbitClient.DownloadSoftwareInstaller(installer.InstallerID, tmpDir)
if err != nil {
log.Printf("level=error, msg=download software installer, err=%s", err)
c.Stats.IncrementOrbitErrors()
return nil, err
}
}
// Figure out what we're actually installing here and add it to software inventory
tfr, err := fleet.NewKeepFileReader(path)
if err != nil {
log.Println("open installer:", err)
c.Stats.IncrementOrbitErrors()
log.Println("level=error, open installer:", err)
return nil, err
}
defer tfr.Close()
item, err := file.ExtractInstallerMetadata(tfr)
if err != nil {
log.Println("extract installer metadata:", err)
c.Stats.IncrementOrbitErrors()
log.Println("level=error, extract installer metadata:", err)
return nil, err
}
return item, nil
Expand Down
Loading