Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

additional stats #19078

Merged
merged 26 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5d6cb07
additional stats
sharon-fdm May 16, 2024
b3f20f7
fix test
sharon-fdm May 16, 2024
ffd85fd
Merge branch 'main' into additional_stats
sharon-fdm May 17, 2024
f486a85
Update cmd/fleet/serve_test.go
sharon-fdm May 23, 2024
7beef00
Update serve_test.go
sharon-fdm May 23, 2024
a7c8fd2
Update serve_test.go
sharon-fdm May 23, 2024
6a98f32
Update server/datastore/mysql/statistics.go
sharon-fdm May 23, 2024
0df924b
Update server/datastore/mysql/statistics.go
sharon-fdm May 23, 2024
9f08269
Update server/datastore/mysql/statistics.go
sharon-fdm May 23, 2024
8ff76bc
Update server/datastore/mysql/statistics.go
sharon-fdm May 23, 2024
c7b9f6b
Update server/datastore/mysql/statistics.go
sharon-fdm May 23, 2024
fbc3337
Update server/datastore/mysql/statistics.go
sharon-fdm May 23, 2024
1f544ca
Update server/fleet/statistics.go
sharon-fdm May 23, 2024
94c1d82
Apply suggestions from code review
sharon-fdm May 23, 2024
a39bd6d
PR review
sharon-fdm May 23, 2024
a52cf7a
change
sharon-fdm May 23, 2024
ad06f30
Merge branch 'main' into additional_stats
sharon-fdm May 23, 2024
bb5a97b
Merge branch 'main' into additional_stats
sharon-fdm May 24, 2024
23cc6ce
add tests
sharon-fdm May 24, 2024
279b9ac
add tests
sharon-fdm May 24, 2024
5ba4ba1
Merge branch 'main' into additional_stats
sharon-fdm May 24, 2024
ffcc1c1
refactor
sharon-fdm May 24, 2024
3327856
fix
sharon-fdm May 24, 2024
e5827e1
fix sql
sharon-fdm May 24, 2024
5be6c0a
fix test
sharon-fdm May 24, 2024
b04c256
Merge branch 'main' into additional_stats
sharon-fdm May 24, 2024
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
1 change: 1 addition & 0 deletions changes/19072-additional-stats
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added additional statistics items as part of our quality telemetry.
8 changes: 7 additions & 1 deletion cmd/fleet/serve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ func TestMaybeSendStatistics(t *testing.T) {
LicenseTier: "premium",
NumHostsEnrolled: 999,
NumUsers: 99,
NumSoftwareVersions: 100,
NumHostSoftwares: 101,
NumSoftwareTitles: 102,
NumHostSoftwareInstalledPaths: 103,
NumSoftwareCPEs: 104,
NumSoftwareCVEs: 105,
NumTeams: 9,
NumPolicies: 0,
NumLabels: 3,
Expand Down Expand Up @@ -128,7 +134,7 @@ func TestMaybeSendStatistics(t *testing.T) {
require.NoError(t, err)
assert.True(t, recorded)
require.True(t, cleanedup)
assert.Equal(t, `{"anonymousIdentifier":"ident","fleetVersion":"1.2.3","licenseTier":"premium","organization":"Fleet","numHostsEnrolled":999,"numUsers":99,"numTeams":9,"numPolicies":0,"numLabels":3,"softwareInventoryEnabled":true,"vulnDetectionEnabled":true,"systemUsersEnabled":true,"hostsStatusWebHookEnabled":true,"mdmMacOsEnabled":false,"hostExpiryEnabled":false,"mdmWindowsEnabled":false,"liveQueryDisabled":false,"numWeeklyActiveUsers":111,"numWeeklyPolicyViolationDaysActual":0,"numWeeklyPolicyViolationDaysPossible":0,"hostsEnrolledByOperatingSystem":{"linux":[{"version":"1.2.3","numEnrolled":22}]},"hostsEnrolledByOrbitVersion":[],"hostsEnrolledByOsqueryVersion":[],"storedErrors":[],"numHostsNotResponding":0}`, requestBody)
assert.Equal(t, `{"anonymousIdentifier":"ident","fleetVersion":"1.2.3","licenseTier":"premium","organization":"Fleet","numHostsEnrolled":999,"numUsers":99,"numSoftwareVersions":100,"numHostSoftwares":101,"numSoftwareTitles":102,"numHostSoftwareInstalledPaths":103,"numSoftwareCPEs":104,"numSoftwareCVEs":105,"numTeams":9,"numPolicies":0,"numLabels":3,"softwareInventoryEnabled":true,"vulnDetectionEnabled":true,"systemUsersEnabled":true,"hostsStatusWebHookEnabled":true,"mdmMacOsEnabled":false,"hostExpiryEnabled":false,"mdmWindowsEnabled":false,"liveQueryDisabled":false,"numWeeklyActiveUsers":111,"numWeeklyPolicyViolationDaysActual":0,"numWeeklyPolicyViolationDaysPossible":0,"hostsEnrolledByOperatingSystem":{"linux":[{"version":"1.2.3","numEnrolled":22}]},"hostsEnrolledByOrbitVersion":[],"hostsEnrolledByOsqueryVersion":[],"storedErrors":[],"numHostsNotResponding":0}`, requestBody)
}

func TestMaybeSendStatisticsSkipsSendingIfNotNeeded(t *testing.T) {
Expand Down
32 changes: 31 additions & 1 deletion server/datastore/mysql/statistics.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,34 @@ func (ds *Datastore) ShouldSendStatistics(ctx context.Context, frequency time.Du
if err != nil {
return ctxerr.Wrap(ctx, err, "amount enrolled hosts by os")
}
amountUsers, err := amountUsersDB(ctx, ds.writer(ctx))
amountUsers, err := tableRowsCount(ctx, ds.writer(ctx), "users")
if err != nil {
return ctxerr.Wrap(ctx, err, "amount users")
}
amountSoftwaresVersions, err := tableRowsCount(ctx, ds.writer(ctx), "software")
if err != nil {
return ctxerr.Wrap(ctx, err, "amount software")
}
amountHostSoftwares, err := tableRowsCount(ctx, ds.writer(ctx), "host_software")
if err != nil {
return ctxerr.Wrap(ctx, err, "amount host_software")
}
amountSoftwareTitles, err := tableRowsCount(ctx, ds.writer(ctx), "software_titles")
if err != nil {
return ctxerr.Wrap(ctx, err, "amount software_titles")
}
amountHostSoftwareInstalledPaths, err := tableRowsCount(ctx, ds.writer(ctx), "host_software_installed_paths")
if err != nil {
return ctxerr.Wrap(ctx, err, "amount host_software_installed_paths")
}
amountSoftwareCpes, err := tableRowsCount(ctx, ds.writer(ctx), "software_cpe")
if err != nil {
return ctxerr.Wrap(ctx, err, "amount software_cpe")
}
amountSoftwareCves, err := tableRowsCount(ctx, ds.writer(ctx), "software_cve")
if err != nil {
return ctxerr.Wrap(ctx, err, "amount software_cve")
}
amountTeams, err := amountTeamsDB(ctx, ds.writer(ctx))
if err != nil {
return ctxerr.Wrap(ctx, err, "amount teams")
Expand Down Expand Up @@ -77,6 +101,12 @@ func (ds *Datastore) ShouldSendStatistics(ctx context.Context, frequency time.Du

stats.NumHostsEnrolled = amountEnrolledHosts
stats.NumUsers = amountUsers
stats.NumSoftwareVersions = amountSoftwaresVersions
stats.NumHostSoftwares = amountHostSoftwares
stats.NumSoftwareTitles = amountSoftwareTitles
stats.NumHostSoftwareInstalledPaths = amountHostSoftwareInstalledPaths
stats.NumSoftwareCPEs = amountSoftwareCpes
stats.NumSoftwareCVEs = amountSoftwareCves
stats.NumTeams = amountTeams
stats.NumPolicies = amountPolicies
stats.NumLabels = amountLabels
Expand Down
24 changes: 24 additions & 0 deletions server/datastore/mysql/statistics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ func testStatisticsShouldSend(t *testing.T, ds *Datastore) {
assert.Equal(t, "Fleet", stats.Organization)
assert.Equal(t, 0, stats.NumHostsEnrolled)
assert.Equal(t, 0, stats.NumUsers)
assert.Equal(t, 0, stats.NumSoftwareVersions)
assert.Equal(t, 0, stats.NumHostSoftwares)
assert.Equal(t, 0, stats.NumSoftwareTitles)
assert.Equal(t, 0, stats.NumHostSoftwareInstalledPaths)
assert.Equal(t, 0, stats.NumSoftwareCPEs)
assert.Equal(t, 0, stats.NumSoftwareCVEs)
assert.Equal(t, 0, stats.NumTeams)
assert.Equal(t, 0, stats.NumPolicies)
assert.Equal(t, builtinLabels, stats.NumLabels)
Expand Down Expand Up @@ -202,6 +208,12 @@ func testStatisticsShouldSend(t *testing.T, ds *Datastore) {
assert.Equal(t, "Fleet", stats.Organization)
assert.Equal(t, 1, stats.NumHostsEnrolled)
assert.Equal(t, 2, stats.NumUsers)
assert.Equal(t, 0, stats.NumSoftwareVersions)
assert.Equal(t, 0, stats.NumHostSoftwares)
assert.Equal(t, 0, stats.NumSoftwareTitles)
assert.Equal(t, 0, stats.NumHostSoftwareInstalledPaths)
assert.Equal(t, 0, stats.NumSoftwareCPEs)
assert.Equal(t, 0, stats.NumSoftwareCVEs)
assert.Equal(t, 1, stats.NumTeams)
assert.Equal(t, 1, stats.NumPolicies)
assert.Equal(t, builtinLabels+1, stats.NumLabels)
Expand Down Expand Up @@ -300,6 +312,12 @@ func testStatisticsShouldSend(t *testing.T, ds *Datastore) {
assert.Equal(t, "Fleet", stats.Organization)
assert.Equal(t, 5, stats.NumHostsEnrolled)
assert.Equal(t, 2, stats.NumUsers)
assert.Equal(t, 0, stats.NumSoftwareVersions)
assert.Equal(t, 0, stats.NumHostSoftwares)
assert.Equal(t, 0, stats.NumSoftwareTitles)
assert.Equal(t, 0, stats.NumHostSoftwareInstalledPaths)
assert.Equal(t, 0, stats.NumSoftwareCPEs)
assert.Equal(t, 0, stats.NumSoftwareCVEs)
assert.Equal(t, 0, stats.NumWeeklyActiveUsers) // no active user since last stats were sent
require.Len(t, stats.HostsEnrolledByOperatingSystem, 3) // empty platform, rhel and macos
assert.Equal(t, 5, stats.NumWeeklyPolicyViolationDaysActual)
Expand Down Expand Up @@ -338,6 +356,12 @@ func testStatisticsShouldSend(t *testing.T, ds *Datastore) {
assert.Equal(t, "Fleet", stats.Organization)
assert.Equal(t, 5, stats.NumHostsEnrolled)
assert.Equal(t, 2, stats.NumUsers)
assert.Equal(t, 0, stats.NumSoftwareVersions)
assert.Equal(t, 0, stats.NumHostSoftwares)
assert.Equal(t, 0, stats.NumSoftwareTitles)
assert.Equal(t, 0, stats.NumHostSoftwareInstalledPaths)
assert.Equal(t, 0, stats.NumSoftwareCPEs)
assert.Equal(t, 0, stats.NumSoftwareCVEs)
assert.Equal(t, 1, stats.NumWeeklyActiveUsers)
assert.Equal(t, 0, stats.NumWeeklyPolicyViolationDaysActual)
assert.Equal(t, 0, stats.NumWeeklyPolicyViolationDaysPossible)
Expand Down
8 changes: 4 additions & 4 deletions server/datastore/mysql/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,13 @@ func (ds *Datastore) DeleteUser(ctx context.Context, id uint) error {
return ds.deleteEntity(ctx, usersTable, id)
}

func amountUsersDB(ctx context.Context, db sqlx.QueryerContext) (int, error) {
var amount int
err := sqlx.GetContext(ctx, db, &amount, `SELECT count(*) FROM users`)
func tableRowsCount(ctx context.Context, db sqlx.QueryerContext, tableName string) (int, error) {
var count int
err := sqlx.GetContext(ctx, db, &count, fmt.Sprintf(`SELECT count(*) FROM %s`, tableName))
if err != nil {
return 0, err
}
return amount, nil
return count, nil
}
sharon-fdm marked this conversation as resolved.
Show resolved Hide resolved

func amountActiveUsersSinceDB(ctx context.Context, db sqlx.QueryerContext, since time.Time) (int, error) {
Expand Down
42 changes: 24 additions & 18 deletions server/fleet/statistics.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,30 @@ import (
)

type StatisticsPayload struct {
AnonymousIdentifier string `json:"anonymousIdentifier"`
FleetVersion string `json:"fleetVersion"`
LicenseTier string `json:"licenseTier"`
Organization string `json:"organization"`
NumHostsEnrolled int `json:"numHostsEnrolled"`
NumUsers int `json:"numUsers"`
NumTeams int `json:"numTeams"`
NumPolicies int `json:"numPolicies"`
NumLabels int `json:"numLabels"`
SoftwareInventoryEnabled bool `json:"softwareInventoryEnabled"`
VulnDetectionEnabled bool `json:"vulnDetectionEnabled"`
SystemUsersEnabled bool `json:"systemUsersEnabled"`
HostsStatusWebHookEnabled bool `json:"hostsStatusWebHookEnabled"`
MDMMacOsEnabled bool `json:"mdmMacOsEnabled"`
HostExpiryEnabled bool `json:"hostExpiryEnabled"`
MDMWindowsEnabled bool `json:"mdmWindowsEnabled"`
LiveQueryDisabled bool `json:"liveQueryDisabled"`
NumWeeklyActiveUsers int `json:"numWeeklyActiveUsers"`
AnonymousIdentifier string `json:"anonymousIdentifier"`
FleetVersion string `json:"fleetVersion"`
LicenseTier string `json:"licenseTier"`
Organization string `json:"organization"`
NumHostsEnrolled int `json:"numHostsEnrolled"`
NumUsers int `json:"numUsers"`
NumSoftwareVersions int `json:"numSoftwareVersions"`
NumHostSoftwares int `json:"numHostSoftwares"`
NumSoftwareTitles int `json:"numSoftwareTitles"`
NumHostSoftwareInstalledPaths int `json:"numHostSoftwareInstalledPaths"`
NumSoftwareCPEs int `json:"numSoftwareCPEs"`
NumSoftwareCVEs int `json:"numSoftwareCVEs"`
NumTeams int `json:"numTeams"`
NumPolicies int `json:"numPolicies"`
NumLabels int `json:"numLabels"`
SoftwareInventoryEnabled bool `json:"softwareInventoryEnabled"`
VulnDetectionEnabled bool `json:"vulnDetectionEnabled"`
SystemUsersEnabled bool `json:"systemUsersEnabled"`
HostsStatusWebHookEnabled bool `json:"hostsStatusWebHookEnabled"`
MDMMacOsEnabled bool `json:"mdmMacOsEnabled"`
HostExpiryEnabled bool `json:"hostExpiryEnabled"`
MDMWindowsEnabled bool `json:"mdmWindowsEnabled"`
LiveQueryDisabled bool `json:"liveQueryDisabled"`
NumWeeklyActiveUsers int `json:"numWeeklyActiveUsers"`
// NumWeeklyPolicyViolationDaysActual is an aggregate count of actual policy violation days. One
// policy violation day is added for each policy that a host is failing as of the time the count
// is incremented. The count increments once per 24-hour interval and resets each week.
Expand Down
Loading