Skip to content

Commit 5231bef

Browse files
committed
chore: route connection logs to new table
1 parent 9ab9c52 commit 5231bef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2231
-489
lines changed

coderd/agentapi/api.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
agentproto "github.com/coder/coder/v2/agent/proto"
2020
"github.com/coder/coder/v2/coderd/agentapi/resourcesmonitor"
2121
"github.com/coder/coder/v2/coderd/appearance"
22-
"github.com/coder/coder/v2/coderd/audit"
22+
"github.com/coder/coder/v2/coderd/connectionlog"
2323
"github.com/coder/coder/v2/coderd/database"
2424
"github.com/coder/coder/v2/coderd/database/pubsub"
2525
"github.com/coder/coder/v2/coderd/externalauth"
@@ -50,7 +50,7 @@ type API struct {
5050
*ResourcesMonitoringAPI
5151
*LogsAPI
5252
*ScriptsAPI
53-
*AuditAPI
53+
*ConnLogAPI
5454
*SubAgentAPI
5555
*tailnet.DRPCService
5656

@@ -71,7 +71,7 @@ type Options struct {
7171
Database database.Store
7272
NotificationsEnqueuer notifications.Enqueuer
7373
Pubsub pubsub.Pubsub
74-
Auditor *atomic.Pointer[audit.Auditor]
74+
ConnectionLogger *atomic.Pointer[connectionlog.ConnectionLogger]
7575
DerpMapFn func() *tailcfg.DERPMap
7676
TailnetCoordinator *atomic.Pointer[tailnet.Coordinator]
7777
StatsReporter *workspacestats.Reporter
@@ -180,11 +180,11 @@ func New(opts Options) *API {
180180
Database: opts.Database,
181181
}
182182

183-
api.AuditAPI = &AuditAPI{
184-
AgentFn: api.agent,
185-
Auditor: opts.Auditor,
186-
Database: opts.Database,
187-
Log: opts.Log,
183+
api.ConnLogAPI = &ConnLogAPI{
184+
AgentFn: api.agent,
185+
ConnectionLogger: opts.ConnectionLogger,
186+
Database: opts.Database,
187+
Log: opts.Log,
188188
}
189189

190190
api.DRPCService = &tailnet.DRPCService{

coderd/agentapi/audit.go

Lines changed: 0 additions & 105 deletions
This file was deleted.

coderd/agentapi/connectionlog.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package agentapi
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
"sync/atomic"
7+
8+
"github.com/google/uuid"
9+
"golang.org/x/xerrors"
10+
"google.golang.org/protobuf/types/known/emptypb"
11+
12+
"cdr.dev/slog"
13+
agentproto "github.com/coder/coder/v2/agent/proto"
14+
"github.com/coder/coder/v2/coderd/connectionlog"
15+
"github.com/coder/coder/v2/coderd/database"
16+
"github.com/coder/coder/v2/coderd/database/db2sdk"
17+
)
18+
19+
type ConnLogAPI struct {
20+
AgentFn func(context.Context) (database.WorkspaceAgent, error)
21+
ConnectionLogger *atomic.Pointer[connectionlog.ConnectionLogger]
22+
Database database.Store
23+
Log slog.Logger
24+
}
25+
26+
func (a *ConnLogAPI) ReportConnection(ctx context.Context, req *agentproto.ReportConnectionRequest) (*emptypb.Empty, error) {
27+
// We use the connection ID to identify which connection log event to mark
28+
// as closed, when we receive a close action for that ID.
29+
connectionID, err := uuid.FromBytes(req.GetConnection().GetId())
30+
if err != nil {
31+
return nil, xerrors.Errorf("connection id from bytes: %w", err)
32+
}
33+
34+
if connectionID == uuid.Nil {
35+
return nil, xerrors.New("connection ID cannot be nil")
36+
}
37+
action, err := db2sdk.ConnectionLogStatusFromAgentProtoConnectionAction(req.GetConnection().GetAction())
38+
if err != nil {
39+
return nil, err
40+
}
41+
connectionType, err := db2sdk.ConnectionLogConnectionTypeFromAgentProtoConnectionType(req.GetConnection().GetType())
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
var code sql.NullInt32
47+
if action == database.ConnectionStatusDisconnected {
48+
code = sql.NullInt32{
49+
Int32: req.GetConnection().GetStatusCode(),
50+
Valid: true,
51+
}
52+
}
53+
54+
// Fetch contextual data for this connection log event.
55+
workspaceAgent, err := a.AgentFn(ctx)
56+
if err != nil {
57+
return nil, xerrors.Errorf("get agent: %w", err)
58+
}
59+
workspace, err := a.Database.GetWorkspaceByAgentID(ctx, workspaceAgent.ID)
60+
if err != nil {
61+
return nil, xerrors.Errorf("get workspace by agent id: %w", err)
62+
}
63+
64+
reason := req.GetConnection().GetReason()
65+
connLogger := *a.ConnectionLogger.Load()
66+
err = connLogger.Upsert(ctx, database.UpsertConnectionLogParams{
67+
ID: uuid.New(),
68+
Time: req.GetConnection().GetTimestamp().AsTime(),
69+
OrganizationID: workspace.OrganizationID,
70+
WorkspaceOwnerID: workspace.OwnerID,
71+
WorkspaceID: workspace.ID,
72+
WorkspaceName: workspace.Name,
73+
AgentName: workspaceAgent.Name,
74+
Type: connectionType,
75+
Code: code,
76+
Ip: database.ParseIP(req.GetConnection().GetIp()),
77+
ConnectionID: uuid.NullUUID{
78+
UUID: connectionID,
79+
Valid: true,
80+
},
81+
CloseReason: sql.NullString{
82+
String: reason,
83+
Valid: reason != "",
84+
},
85+
// Used to populate whether the connection was established or closed
86+
// outside of the DB (slog).
87+
ConnectionStatus: action,
88+
89+
// It's not possible to tell which user connected. Once we have
90+
// the capability, this may be reported by the agent.
91+
UserID: uuid.NullUUID{
92+
Valid: false,
93+
},
94+
// N/A
95+
UserAgent: sql.NullString{},
96+
// N/A
97+
SlugOrPort: sql.NullString{},
98+
})
99+
if err != nil {
100+
return nil, xerrors.Errorf("export connection log: %w", err)
101+
}
102+
103+
return &emptypb.Empty{}, nil
104+
}

0 commit comments

Comments
 (0)