Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd773056

Browse files
committed
chore: add usage tracking package
1 parentd7bdb3c commitd773056

22 files changed

+1867
-16
lines changed

‎CODEOWNERS‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ tailnet/proto/ @spikecurtis @johnstcn
77
vpn/vpn.proto@spikecurtis@johnstcn
88
vpn/version.go@spikecurtis@johnstcn
99

10-
1110
# This caching code is particularly tricky, and one must be very careful when
1211
# altering it.
1312
coderd/files/@aslilac
@@ -34,3 +33,8 @@ site/CLAUDE.md
3433
# requires elite ball knowledge of most of the scheduling code to make changes
3534
# without inadvertently affecting other parts of the codebase.
3635
coderd/schedule/autostop.go@deansheather@DanielleMaywood
36+
37+
# Usage tracking code requires intimate knowledge of Tallyman and Metronome, as
38+
# well as guidance from revenue.
39+
coderd/usage/@deansheather
40+
enterprise/coderd/usage/@deansheather

‎coderd/database/dbauthz/dbauthz.go‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3951,6 +3951,13 @@ func (q *querier) InsertTemplateVersionWorkspaceTag(ctx context.Context, arg dat
39513951
returnq.db.InsertTemplateVersionWorkspaceTag(ctx,arg)
39523952
}
39533953

3954+
func (q*querier)InsertUsageEvent(ctx context.Context,arg database.InsertUsageEventParams)error {
3955+
iferr:=q.authorizeContext(ctx,policy.ActionCreate,rbac.ResourceSystem);err!=nil {
3956+
returnerr
3957+
}
3958+
returnq.db.InsertUsageEvent(ctx,arg)
3959+
}
3960+
39543961
func (q*querier)InsertUser(ctx context.Context,arg database.InsertUserParams) (database.User,error) {
39553962
// Always check if the assigned roles can actually be assigned by this actor.
39563963
impliedRoles:=append([]rbac.RoleIdentifier{rbac.RoleMember()},q.convertToDeploymentRoles(arg.RBACRoles)...)
@@ -4306,6 +4313,14 @@ func (q *querier) RevokeDBCryptKey(ctx context.Context, activeKeyDigest string)
43064313
returnq.db.RevokeDBCryptKey(ctx,activeKeyDigest)
43074314
}
43084315

4316+
func (q*querier)SelectUsageEventsForPublishing(ctx context.Context,arg time.Time) ([]database.UsageEvent,error) {
4317+
// ActionUpdate because we're updating the publish_started_at column.
4318+
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,rbac.ResourceSystem);err!=nil {
4319+
returnnil,err
4320+
}
4321+
returnq.db.SelectUsageEventsForPublishing(ctx,arg)
4322+
}
4323+
43094324
func (q*querier)TryAcquireLock(ctx context.Context,idint64) (bool,error) {
43104325
returnq.db.TryAcquireLock(ctx,id)
43114326
}
@@ -4787,6 +4802,13 @@ func (q *querier) UpdateTemplateWorkspacesLastUsedAt(ctx context.Context, arg da
47874802
returnfetchAndExec(q.log,q.auth,policy.ActionUpdate,fetch,q.db.UpdateTemplateWorkspacesLastUsedAt)(ctx,arg)
47884803
}
47894804

4805+
func (q*querier)UpdateUsageEventsPostPublish(ctx context.Context,arg database.UpdateUsageEventsPostPublishParams)error {
4806+
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,rbac.ResourceSystem);err!=nil {
4807+
returnerr
4808+
}
4809+
returnq.db.UpdateUsageEventsPostPublish(ctx,arg)
4810+
}
4811+
47904812
func (q*querier)UpdateUserDeletedByID(ctx context.Context,id uuid.UUID)error {
47914813
returndeleteQ(q.log,q.auth,q.db.GetUserByID,q.db.UpdateUserDeletedByID)(ctx,id)
47924814
}

‎coderd/database/dbauthz/dbauthz_test.go‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5666,3 +5666,27 @@ func (s *MethodTestSuite) TestUserSecrets() {
56665666
Asserts(userSecret,policy.ActionRead,userSecret,policy.ActionDelete)
56675667
}))
56685668
}
5669+
5670+
func (s*MethodTestSuite)TestUsageEvents() {
5671+
s.Run("InsertUsageEvent",s.Subtest(func(db database.Store,check*expects) {
5672+
check.Args(database.InsertUsageEventParams{
5673+
ID:"1",
5674+
EventType:database.UsageEventTypeDcManagedAgentsV1,
5675+
EventData: []byte("{}"),
5676+
CreatedAt:dbtime.Now(),
5677+
}).Asserts(rbac.ResourceSystem,policy.ActionCreate)
5678+
}))
5679+
5680+
s.Run("SelectUsageEventsForPublishing",s.Subtest(func(db database.Store,check*expects) {
5681+
check.Args(dbtime.Now()).Asserts(rbac.ResourceSystem,policy.ActionUpdate)
5682+
}))
5683+
5684+
s.Run("UpdateUsageEventsPostPublish",s.Subtest(func(db database.Store,check*expects) {
5685+
check.Args(database.UpdateUsageEventsPostPublishParams{
5686+
Now:dbtime.Now(),
5687+
IDs: []string{"1","2"},
5688+
FailureMessages: []string{"error","error"},
5689+
SetPublishedAts: []bool{false,false},
5690+
}).Asserts(rbac.ResourceSystem,policy.ActionUpdate)
5691+
}))
5692+
}

‎coderd/database/dbmetrics/querymetrics.go‎

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbmock/dbmock.go‎

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dump.sql‎

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
DROPTABLE usage_events;
2+
DROPTYPE usage_event_type;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
CREATETYPEusage_event_typeAS ENUM (
2+
'dc_managed_agents_v1'
3+
);
4+
5+
COMMENT ON TYPE usage_event_type IS'The usage event type with version. "dc" means "discrete" (e.g. a single event, for counters), "hb" means "heartbeat" (e.g. a recurring event that contains a total count of usage generated from the database, for gauges).';
6+
7+
CREATETABLEusage_events (
8+
idTEXTPRIMARY KEY,
9+
event_type usage_event_typeNOT NULL,
10+
event_data JSONBNOT NULL,
11+
created_atTIMESTAMP WITH TIME ZONENOT NULL,
12+
publish_started_atTIMESTAMP WITH TIME ZONE DEFAULTNULL,
13+
published_atTIMESTAMP WITH TIME ZONE DEFAULTNULL,
14+
failure_messageTEXT DEFAULTNULL
15+
);
16+
17+
COMMENT ON TABLE usage_events IS'usage_events contains usage data that is collected from the product and potentially shipped to the usage collector service.';
18+
COMMENT ON COLUMN usage_events.id IS'For "discrete" event types, this is a random UUID. For "heartbeat" event types, this is a combination of the event type and a truncated timestamp.';
19+
COMMENT ON COLUMN usage_events.event_data IS'Event payload. Determined by the matching usage struct for this event type.';
20+
COMMENT ON COLUMN usage_events.publish_started_at IS'Set to a timestamp while the event is being published by a Coder replica to the usage collector service. Used to avoid duplicate publishes by multiple replicas. Timestamps older than 1 hour are considered expired.';
21+
COMMENT ON COLUMN usage_events.published_at IS'Set to a timestamp when the event is successfully (or permanently unsuccessfully) published to the usage collector service. If set, the event should never be attempted to be published again.';
22+
COMMENT ON COLUMN usage_events.failure_message IS'Set to an error message when the event is temporarily or permanently unsuccessfully published to the usage collector service.';
23+
24+
CREATEINDEXidx_usage_events_created_atON usage_events (created_at);
25+
CREATEINDEXidx_usage_events_publish_started_atON usage_events (publish_started_at);
26+
CREATEINDEXidx_usage_events_published_atON usage_events (published_at);

‎coderd/database/modelmethods.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/hex"
55
"sort"
66
"strconv"
7+
"strings"
78
"time"
89

910
"github.com/google/uuid"
@@ -636,3 +637,11 @@ func (m WorkspaceAgentVolumeResourceMonitor) Debounce(
636637
func (sUserSecret)RBACObject() rbac.Object {
637638
returnrbac.ResourceUserSecret.WithID(s.ID).WithOwner(s.UserID.String())
638639
}
640+
641+
func (eUsageEventType)IsDiscrete()bool {
642+
returne.Valid()&&strings.HasPrefix(string(e),"dc_")
643+
}
644+
645+
func (eUsageEventType)IsHeartbeat()bool {
646+
returne.Valid()&&strings.HasPrefix(string(e),"hb_")
647+
}

‎coderd/database/models.go‎

Lines changed: 72 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp