Skip to content

Commit 6ac1349

Browse files
committed
perf: 记录会话生命周期日志
1 parent f8fe7c4 commit 6ac1349

File tree

11 files changed

+875
-277
lines changed

11 files changed

+875
-277
lines changed

cmd/common/uploader_service.go

+22-2
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ func (u *UploaderService) UploadReplay(sid, replayPath string) error {
155155
logger.Errorf("Retrieve session %s detail failed: %s", sid, err)
156156
return err
157157
}
158+
u.recordingSessionLifecycleReplay(sid, model.ReplayUploadStart, "")
158159
today := sess.DateStart.UTC().Format(dateTimeFormat)
159160
absGzFile := replayPath
160161
if !isGzipFile(absGzFile) {
@@ -169,20 +170,29 @@ func (u *UploaderService) UploadReplay(sid, replayPath string) error {
169170
replayBackend := u.getReplayBackend()
170171
gzFilename := filepath.Base(absGzFile)
171172
target := strings.Join([]string{today, gzFilename}, "/")
172-
err = replayBackend.Upload(absGzFile, target)
173173
replayBackendName := replayBackend.TypeName()
174+
if replayBackendName == "null" {
175+
reason := string(model.ReasonErrNullStorage)
176+
u.recordingSessionLifecycleReplay(sid, model.ReplayUploadFailure, reason)
177+
_ = os.Remove(absGzFile)
178+
return nil
179+
}
180+
181+
err = replayBackend.Upload(absGzFile, target)
174182
if err != nil && replayBackendName != "server" {
183+
u.recordingSessionLifecycleReplay(sid, model.ReplayUploadFailure, err.Error())
175184
logger.Errorf("Uploader service replay backend %s error %s", replayBackendName, err)
176185
logger.Error("Switch default server to upload replay %s.", absGzFile)
177186
replayBackendName = "server"
187+
u.recordingSessionLifecycleReplay(sid, model.ReplayUploadStart, "")
178188
err = u.apiClient.Upload(sid, absGzFile)
179189
}
180190
if err != nil {
191+
u.recordingSessionLifecycleReplay(sid, model.ReplayUploadFailure, err.Error())
181192
logger.Errorf("Uploader service replay %s uploaded error: %s", absGzFile, err)
182193
return err
183194
}
184195
logger.Infof("Uploader service replay file %s upload to %s", absGzFile, replayBackendName)
185-
186196
if _, err = u.apiClient.FinishReply(sid); err != nil {
187197
logger.Errorf("Finish %s replay api failed: %s", sid, err)
188198
return err
@@ -208,13 +218,16 @@ func (u *UploaderService) UploadRemainReplays(replayDir string) (ret RemainRepla
208218
logger.Debugf("Upload Remain %d replay files", len(allRemainReplays))
209219
for replayPath := range allRemainReplays {
210220
remainReplay := allRemainReplays[replayPath]
221+
u.recordingSessionLifecycleReplay(remainReplay.Id, model.ReplayUploadStart, "")
211222
if err := u.uploadRemainReplay(&remainReplay); err != nil {
212223
logger.Errorf("Uploader service clean remain replay %s failed: %s",
213224
replayPath, err)
214225
failureFiles = append(failureFiles, replayPath)
215226
failureErrs = append(failureErrs, err.Error())
227+
u.recordingSessionLifecycleReplay(remainReplay.Id, model.ReplayUploadFailure, err.Error())
216228
continue
217229
}
230+
u.recordingSessionLifecycleReplay(remainReplay.Id, model.ReplayUploadSuccess, "")
218231
successFiles = append(successFiles, replayPath)
219232
// 上传完成 删除原录像文件
220233
if err := os.Remove(replayPath); err != nil {
@@ -232,6 +245,13 @@ func (u *UploaderService) UploadRemainReplays(replayDir string) (ret RemainRepla
232245
return
233246
}
234247

248+
func (u *UploaderService) recordingSessionLifecycleReplay(sid string, event model.LifecycleEvent, msgErr string) {
249+
logObj := model.SessionLifecycleLog{Reason: msgErr}
250+
if err := u.apiClient.RecordSessionLifecycleLog(sid, event, logObj); err != nil {
251+
logger.Errorf("Record session %s activity %s failed: %s", sid, event, err)
252+
}
253+
}
254+
235255
func (u *UploaderService) uploadRemainReplay(replay *RemainReplay) error {
236256
replayAbsGzPath := replay.AbsFilePath
237257
if !isGzipFile(replayAbsGzPath) {

cmd/impl/convert_model.go

+16
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,19 @@ func ConvertToReqInfo(req *pb.ReqInfo) model.ReqInfo {
7979
URL: req.GetUrl(),
8080
}
8181
}
82+
83+
var LifecycleEventMap = map[pb.SessionLifecycleLogRequest_EventType]model.LifecycleEvent{
84+
pb.SessionLifecycleLogRequest_AssetConnectSuccess: model.AssetConnectSuccess,
85+
pb.SessionLifecycleLogRequest_AssetConnectFinished: model.AssetConnectFinished,
86+
pb.SessionLifecycleLogRequest_CreateShareLink: model.CreateShareLink,
87+
pb.SessionLifecycleLogRequest_UserJoinSession: model.UserJoinSession,
88+
pb.SessionLifecycleLogRequest_UserLeaveSession: model.UserLeaveSession,
89+
pb.SessionLifecycleLogRequest_AdminJoinMonitor: model.AdminJoinMonitor,
90+
pb.SessionLifecycleLogRequest_AdminExitMonitor: model.AdminExitMonitor,
91+
pb.SessionLifecycleLogRequest_ReplayConvertStart: model.ReplayConvertStart,
92+
pb.SessionLifecycleLogRequest_ReplayConvertSuccess: model.ReplayUploadStart,
93+
pb.SessionLifecycleLogRequest_ReplayConvertFailure: model.ReplayConvertFailure,
94+
pb.SessionLifecycleLogRequest_ReplayUploadStart: model.ReplayConvertStart,
95+
pb.SessionLifecycleLogRequest_ReplayUploadSuccess: model.ReplayUploadSuccess,
96+
pb.SessionLifecycleLogRequest_ReplayUploadFailure: model.ReplayUploadFailure,
97+
}

cmd/impl/jms_record_session.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package impl
2+
3+
import (
4+
"context"
5+
6+
"github.com/jumpserver/wisp/pkg/jms-sdk-go/model"
7+
"github.com/jumpserver/wisp/pkg/logger"
8+
pb "github.com/jumpserver/wisp/protobuf-go/protobuf"
9+
)
10+
11+
func (j *JMServer) RecordSessionLifecycleLog(ctx context.Context, req *pb.SessionLifecycleLogRequest) (*pb.StatusResponse, error) {
12+
var (
13+
status pb.Status
14+
)
15+
sessionId := req.GetSessionId()
16+
event := req.GetEvent()
17+
reason := req.GetReason()
18+
user := req.GetUser()
19+
logObj := model.SessionLifecycleLog{Reason: reason, User: user}
20+
lifecycleEvent := LifecycleEventMap[event]
21+
logger.Infof("Request record session %s lifecyle %s : %s", sessionId, event, logObj)
22+
if err := j.apiClient.RecordSessionLifecycleLog(sessionId, lifecycleEvent, logObj); err != nil {
23+
logger.Errorf("Record session %s lifecyle failed: %s", sessionId, err)
24+
status.Err = err.Error()
25+
return &pb.StatusResponse{Status: &status}, nil
26+
}
27+
status.Ok = true
28+
return &pb.StatusResponse{Status: &status}, nil
29+
}

pkg/jms-sdk-go/model/session.go

+38
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,41 @@ const (
8888
LoginFromRT LabelFiled = "RT"
8989
LoginFromDT LabelFiled = "DT"
9090
)
91+
92+
type LifecycleEvent string
93+
94+
const (
95+
AssetConnectSuccess LifecycleEvent = "asset_connect_success"
96+
AssetConnectFinished LifecycleEvent = "asset_connect_finished"
97+
CreateShareLink LifecycleEvent = "create_share_link"
98+
UserJoinSession LifecycleEvent = "user_join_session"
99+
UserLeaveSession LifecycleEvent = "user_leave_session"
100+
AdminJoinMonitor LifecycleEvent = "admin_join_monitor"
101+
AdminExitMonitor LifecycleEvent = "admin_exit_monitor"
102+
ReplayConvertStart LifecycleEvent = "replay_convert_start"
103+
ReplayConvertSuccess LifecycleEvent = "replay_convert_success"
104+
ReplayConvertFailure LifecycleEvent = "replay_convert_failure"
105+
ReplayUploadStart LifecycleEvent = "replay_upload_start"
106+
ReplayUploadSuccess LifecycleEvent = "replay_upload_success"
107+
ReplayUploadFailure LifecycleEvent = "replay_upload_failure"
108+
)
109+
110+
type SessionLifecycleLog struct {
111+
Reason string `json:"reason"`
112+
User string `json:"user"`
113+
}
114+
115+
var EmptyLifecycleLog = SessionLifecycleLog{}
116+
117+
type SessionLifecycleReasonErr string
118+
119+
const (
120+
ReasonErrConnectFailed SessionLifecycleReasonErr = "connect_failed"
121+
ReasonErrConnectDisconnect SessionLifecycleReasonErr = "connect_disconnect"
122+
ReasonErrUserClose SessionLifecycleReasonErr = "user_close"
123+
ReasonErrIdleDisconnect SessionLifecycleReasonErr = "idle_disconnect"
124+
ReasonErrAdminTerminate SessionLifecycleReasonErr = "admin_terminate"
125+
ReasonErrMaxSessionTimeout SessionLifecycleReasonErr = "max_session_timeout"
126+
ReasonErrPermissionExpired SessionLifecycleReasonErr = "permission_expired"
127+
ReasonErrNullStorage SessionLifecycleReasonErr = "null_storage"
128+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package service
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/jumpserver/wisp/pkg/jms-sdk-go/model"
7+
)
8+
9+
func (s *JMService) RecordSessionLifecycleLog(sid string, event model.LifecycleEvent, logObj model.SessionLifecycleLog) (err error) {
10+
data := map[string]interface{}{
11+
"event": event,
12+
}
13+
if logObj.Reason != "" {
14+
data["reason"] = logObj.Reason
15+
}
16+
if logObj.User != "" {
17+
data["user"] = logObj.User
18+
}
19+
20+
reqURL := fmt.Sprintf(SessionLifecycleLogURL, sid)
21+
var resp map[string]interface{}
22+
_, err = s.authClient.Post(reqURL, data, &resp)
23+
return
24+
}

pkg/jms-sdk-go/service/url.go

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const (
2626
FinishTaskURL = "/api/v1/terminal/tasks/%s/"
2727
JoinRoomValidateURL = "/api/v1/terminal/sessions/join/validate/"
2828
FTPLogListURL = "/api/v1/audits/ftp-logs/" // 上传 ftp日志
29+
30+
SessionLifecycleLogURL = "/api/v1/terminal/sessions/%s/lifecycle_log/"
2931
)
3032

3133
// 授权相关API

0 commit comments

Comments
 (0)