feature: Logs table creates an entry as soon as the execution is started (#464)
This commit is contained in:
parent
964dc7b48a
commit
1bfb7c4b28
|
|
@ -199,6 +199,10 @@ message EventExecutionFinished {
|
|||
LogEntry log_entry = 1;
|
||||
}
|
||||
|
||||
message EventExecutionStarted {
|
||||
LogEntry log_entry = 1;
|
||||
}
|
||||
|
||||
message KillActionRequest {
|
||||
string execution_tracking_id = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ func DefaultExecutor(cfg *config.Config) *Executor {
|
|||
}
|
||||
|
||||
type listener interface {
|
||||
OnExecutionStarted(actionTitle string)
|
||||
OnExecutionStarted(logEntry *InternalLogEntry)
|
||||
OnExecutionFinished(logEntry *InternalLogEntry)
|
||||
OnOutputChunk(o []byte, executionTrackingId string)
|
||||
OnActionMapRebuilt()
|
||||
|
|
@ -233,7 +233,7 @@ func (e *Executor) execChain(req *ExecutionRequest) {
|
|||
|
||||
// This isn't a step, because we want to notify all listeners, irrespective
|
||||
// of how many steps were actually executed.
|
||||
notifyListeners(req)
|
||||
notifyListenersFinished(req)
|
||||
}
|
||||
|
||||
func getConcurrentCount(req *ExecutionRequest) int {
|
||||
|
|
@ -400,6 +400,8 @@ func stepRequestAction(req *ExecutionRequest) bool {
|
|||
"tags": req.Tags,
|
||||
}).Infof("Action requested")
|
||||
|
||||
notifyListenersStarted(req)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -425,12 +427,18 @@ func stepLogFinish(req *ExecutionRequest) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func notifyListeners(req *ExecutionRequest) {
|
||||
func notifyListenersFinished(req *ExecutionRequest) {
|
||||
for _, listener := range req.executor.listeners {
|
||||
listener.OnExecutionFinished(req.logEntry)
|
||||
}
|
||||
}
|
||||
|
||||
func notifyListenersStarted(req *ExecutionRequest) {
|
||||
for _, listener := range req.executor.listeners {
|
||||
listener.OnExecutionStarted(req.logEntry)
|
||||
}
|
||||
}
|
||||
|
||||
func appendErrorToStderr(err error, logEntry *InternalLogEntry) {
|
||||
if err != nil {
|
||||
logEntry.Output = err.Error() + "\n\n" + logEntry.Output
|
||||
|
|
|
|||
|
|
@ -35,13 +35,10 @@ var ExecutionListener WebsocketExecutionListener
|
|||
|
||||
type WebsocketExecutionListener struct{}
|
||||
|
||||
func (WebsocketExecutionListener) OnExecutionStarted(title string) {
|
||||
/*
|
||||
broadcast(ExecutionStarted{
|
||||
Type: "ExecutionStarted",
|
||||
Action: title,
|
||||
});
|
||||
*/
|
||||
func (WebsocketExecutionListener) OnExecutionStarted(ile *executor.InternalLogEntry) {
|
||||
broadcast(&pb.EventExecutionStarted{
|
||||
LogEntry: internalLogEntryToPb(ile),
|
||||
});
|
||||
}
|
||||
|
||||
func OnEntityChanged() {
|
||||
|
|
@ -82,22 +79,7 @@ func (WebsocketExecutionListener) OnOutputChunk(chunk []byte, executionTrackingI
|
|||
|
||||
func (WebsocketExecutionListener) OnExecutionFinished(logEntry *executor.InternalLogEntry) {
|
||||
evt := &pb.EventExecutionFinished{
|
||||
LogEntry: &pb.LogEntry{
|
||||
ActionTitle: logEntry.ActionTitle,
|
||||
ActionIcon: logEntry.ActionIcon,
|
||||
ActionId: logEntry.ActionId,
|
||||
DatetimeStarted: logEntry.DatetimeStarted.Format("2006-01-02 15:04:05"),
|
||||
DatetimeFinished: logEntry.DatetimeFinished.Format("2006-01-02 15:04:05"),
|
||||
Output: logEntry.Output,
|
||||
TimedOut: logEntry.TimedOut,
|
||||
Blocked: logEntry.Blocked,
|
||||
ExitCode: logEntry.ExitCode,
|
||||
Tags: logEntry.Tags,
|
||||
ExecutionTrackingId: logEntry.ExecutionTrackingID,
|
||||
ExecutionStarted: logEntry.ExecutionStarted,
|
||||
ExecutionFinished: logEntry.ExecutionFinished,
|
||||
User: logEntry.Username,
|
||||
},
|
||||
LogEntry: internalLogEntryToPb(logEntry),
|
||||
}
|
||||
|
||||
log.Infof("Execution finished: %v+v", evt.LogEntry)
|
||||
|
|
@ -178,3 +160,23 @@ func HandleWebsocket(w http.ResponseWriter, r *http.Request) bool {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
func internalLogEntryToPb(logEntry *executor.InternalLogEntry) *pb.LogEntry {
|
||||
return &pb.LogEntry{
|
||||
ActionTitle: logEntry.ActionTitle,
|
||||
ActionIcon: logEntry.ActionIcon,
|
||||
ActionId: logEntry.ActionId,
|
||||
DatetimeStarted: logEntry.DatetimeStarted.Format("2006-01-02 15:04:05"),
|
||||
DatetimeFinished: logEntry.DatetimeFinished.Format("2006-01-02 15:04:05"),
|
||||
Output: logEntry.Output,
|
||||
TimedOut: logEntry.TimedOut,
|
||||
Blocked: logEntry.Blocked,
|
||||
ExitCode: logEntry.ExitCode,
|
||||
Tags: logEntry.Tags,
|
||||
ExecutionTrackingId: logEntry.ExecutionTrackingID,
|
||||
ExecutionStarted: logEntry.ExecutionStarted,
|
||||
ExecutionFinished: logEntry.ExecutionFinished,
|
||||
User: logEntry.Username,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,12 +54,13 @@ export function initMarshaller () {
|
|||
|
||||
window.executionDialog = new ExecutionDialog()
|
||||
|
||||
window.logEntries = {}
|
||||
window.logEntries = new Map()
|
||||
window.registeredPaths = new Map()
|
||||
window.breadcrumbNavigation = []
|
||||
|
||||
window.currentPath = ''
|
||||
|
||||
window.addEventListener('EventExecutionStarted', onExecutionStarted)
|
||||
window.addEventListener('EventExecutionFinished', onExecutionFinished)
|
||||
window.addEventListener('EventOutputChunk', onOutputChunk)
|
||||
}
|
||||
|
|
@ -125,6 +126,14 @@ function onOutputChunk (evt) {
|
|||
}
|
||||
}
|
||||
|
||||
function onExecutionStarted (evt) {
|
||||
const logEntry = evt.payload.logEntry
|
||||
|
||||
marshalLogsJsonToHtml({
|
||||
logs: [logEntry]
|
||||
})
|
||||
}
|
||||
|
||||
function onExecutionFinished (evt) {
|
||||
const logEntry = evt.payload.logEntry
|
||||
|
||||
|
|
@ -136,7 +145,9 @@ function onExecutionFinished (evt) {
|
|||
|
||||
switch (actionButton.popupOnStart) {
|
||||
case 'execution-button':
|
||||
document.querySelector('execution-button#execution-' + logEntry.executionTrackingId).onExecutionFinished(logEntry)
|
||||
if (document.querySelector('execution-button#execution-' + logEntry.executionTrackingId) !== null) { // If the button was created in our instance
|
||||
document.querySelector('execution-button#execution-' + logEntry.executionTrackingId).onExecutionFinished(logEntry)
|
||||
}
|
||||
break
|
||||
case 'execution-dialog-stdout-only':
|
||||
case 'execution-dialog':
|
||||
|
|
@ -617,41 +628,46 @@ function marshalDirectory (item, section) {
|
|||
|
||||
export function marshalLogsJsonToHtml (json) {
|
||||
for (const logEntry of json.logs) {
|
||||
const existing = window.logEntries[logEntry.executionTrackingId]
|
||||
let row
|
||||
|
||||
if (existing !== undefined) {
|
||||
continue
|
||||
if (window.logEntries.has(logEntry.executionTrackingId)) {
|
||||
row = window.logEntries.get(logEntry.executionTrackingId).dom
|
||||
} else {
|
||||
const tpl = document.getElementById('tplLogRow')
|
||||
row = tpl.content.querySelector('tr').cloneNode(true)
|
||||
|
||||
row.querySelector('.content').onclick = () => {
|
||||
window.executionDialog.reset()
|
||||
window.executionDialog.show()
|
||||
window.executionDialog.renderExecutionResult({
|
||||
logEntry: window.logEntries.get(logEntry.executionTrackingId)
|
||||
})
|
||||
pushNewNavigationPath('/logs/' + logEntry.executionTrackingId)
|
||||
}
|
||||
|
||||
row.exitCodeDisplay = new ActionStatusDisplay(row.querySelector('.exit-code'))
|
||||
|
||||
logEntry.dom = row
|
||||
|
||||
window.logEntries.set(logEntry.executionTrackingId, logEntry)
|
||||
|
||||
document.querySelector('#logTableBody').prepend(row)
|
||||
}
|
||||
|
||||
window.logEntries[logEntry.executionTrackingId] = logEntry
|
||||
|
||||
const tpl = document.getElementById('tplLogRow')
|
||||
const row = tpl.content.querySelector('tr').cloneNode(true)
|
||||
|
||||
row.querySelector('.timestamp').innerText = logEntry.datetimeStarted
|
||||
row.querySelector('.content').innerText = logEntry.actionTitle
|
||||
row.querySelector('.icon').innerHTML = logEntry.actionIcon
|
||||
row.setAttribute('title', logEntry.actionTitle)
|
||||
|
||||
const exitCodeDisplay = new ActionStatusDisplay(row.querySelector('.exit-code'))
|
||||
exitCodeDisplay.update(logEntry)
|
||||
row.exitCodeDisplay.update(logEntry)
|
||||
|
||||
row.querySelector('.content').onclick = () => {
|
||||
window.executionDialog.reset()
|
||||
window.executionDialog.show()
|
||||
window.executionDialog.renderExecutionResult({
|
||||
logEntry: window.logEntries[logEntry.executionTrackingId]
|
||||
})
|
||||
pushNewNavigationPath('/logs/' + logEntry.executionTrackingId)
|
||||
}
|
||||
row.querySelector('.tags').innerHTML = ''
|
||||
|
||||
for (const tag of logEntry.tags) {
|
||||
row.querySelector('.tags').append(createTag(tag))
|
||||
}
|
||||
|
||||
row.querySelector('.tags').append(createAnnotation('user', logEntry.user))
|
||||
|
||||
document.querySelector('#logTableBody').prepend(row)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ function websocketOnMessage (msg) {
|
|||
case 'EventOutputChunk':
|
||||
case 'EventConfigChanged':
|
||||
case 'EventExecutionFinished':
|
||||
case 'EventExecutionStarted':
|
||||
case 'EventEntityChanged':
|
||||
window.dispatchEvent(e)
|
||||
break
|
||||
|
|
|
|||
Loading…
Reference in New Issue