Stream live server logs over SSE
This commit is contained in:
@@ -202,6 +202,8 @@ type Core interface {
|
||||
GetLogStreamForSession(string, string) (domain.LogStream, error)
|
||||
ListLogStreamsForSession(string, domain.LogStreamFilter) ([]domain.LogStream, error)
|
||||
QueryLogStreamForSession(string, domain.LogStreamCursorQuery) (domain.LogStreamCursorResult, error)
|
||||
SubscribeLogEvents(string) (LogEventSubscription, error)
|
||||
SubscribeLogEventsForSession(string, string) (LogEventSubscription, error)
|
||||
IngestLogBatch(domain.LogBatchIngest) (domain.LogBatchIngestResult, error)
|
||||
QueryLogStream(domain.LogStreamCursorQuery) (domain.LogStreamCursorResult, error)
|
||||
ListGamePlayersForSession(string, domain.GamePlayerFilter) ([]domain.GamePlayer, error)
|
||||
@@ -236,6 +238,9 @@ type CoreService struct {
|
||||
bridgeMu sync.Mutex
|
||||
bridgeSeq uint64
|
||||
logStore LogBodyStore
|
||||
logEventMu sync.Mutex
|
||||
logEventSubscribers map[uint64]logEventSubscriber
|
||||
logEventSubscriberSeq uint64
|
||||
artifactStore ArtifactBodyStore
|
||||
artifactMu sync.Mutex
|
||||
artifactTransfers map[string]domain.ArtifactTransferSession
|
||||
@@ -279,6 +284,7 @@ func newCoreServiceWithLogStore(store repo.Store, logStore LogBodyStore, now fun
|
||||
authSessions: map[string]string{},
|
||||
runSessions: map[string]domain.RunControlSession{},
|
||||
logStore: logStore,
|
||||
logEventSubscribers: map[uint64]logEventSubscriber{},
|
||||
artifactStore: artifactStore,
|
||||
artifactTransfers: map[string]domain.ArtifactTransferSession{},
|
||||
artifactPayloads: map[string][]byte{},
|
||||
@@ -2329,21 +2335,36 @@ func (svc *CoreService) ensureJobLogStreams(job domain.Job, stamp time.Time) err
|
||||
streams := []struct {
|
||||
key string
|
||||
source domain.LogStreamSource
|
||||
}{
|
||||
{key: "stdout", source: domain.LogStreamSourceProcess},
|
||||
{key: "stderr", source: domain.LogStreamSourceProcess},
|
||||
}{}
|
||||
addStream := func(key string, source domain.LogStreamSource) {
|
||||
key = strings.TrimSpace(key)
|
||||
if key == "" {
|
||||
return
|
||||
}
|
||||
for _, stream := range streams {
|
||||
if stream.key == key {
|
||||
return
|
||||
}
|
||||
}
|
||||
streams = append(streams, struct {
|
||||
key string
|
||||
source domain.LogStreamSource
|
||||
}{key: key, source: source})
|
||||
}
|
||||
addStream("stdout", domain.LogStreamSourceProcess)
|
||||
addStream("stderr", domain.LogStreamSourceProcess)
|
||||
for _, source := range job.ExecutionInput.LogSources {
|
||||
if source.Kind != "process.stdout" && source.Kind != "process.stderr" {
|
||||
continue
|
||||
}
|
||||
addStream(source.StreamKey, domain.LogStreamSourceProcess)
|
||||
}
|
||||
if job.Capability == domain.JobCapabilityRemoteRunProgram {
|
||||
streams = append(streams,
|
||||
struct {
|
||||
key string
|
||||
source domain.LogStreamSource
|
||||
}{key: "management-program.stdout", source: domain.LogStreamSourceManagementProgram},
|
||||
struct {
|
||||
key string
|
||||
source domain.LogStreamSource
|
||||
}{key: "management-program.stderr", source: domain.LogStreamSourceManagementProgram},
|
||||
)
|
||||
addStream("management-program.stdout", domain.LogStreamSourceManagementProgram)
|
||||
addStream("management-program.stderr", domain.LogStreamSourceManagementProgram)
|
||||
}
|
||||
if job.Capability == domain.JobCapabilityLogsBackfill && job.ExecutionInput.LogSource != nil && strings.TrimSpace(job.ExecutionInput.LogSource.StreamKey) != "" {
|
||||
addStream(job.ExecutionInput.LogSource.StreamKey, domain.LogStreamSourceFile)
|
||||
}
|
||||
for _, item := range streams {
|
||||
stream := domain.LogStream{
|
||||
|
||||
Reference in New Issue
Block a user