iguazio.dashboard-controls 1.2.13 → 1.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/i18n/en/functions.json +5 -2
- package/dist/js/iguazio.dashboard-controls.js +5690 -5524
- package/dist/less/iguazio.dashboard-controls.less +1576 -1567
- package/package.json +1 -1
- package/src/i18n/en/functions.json +5 -2
- package/src/igz_controls/services/control-panel-logs-data.service.js +0 -53
- package/src/igz_controls/services/execution-logs-data.service.js +200 -0
- package/src/nuclio/functions/version/version-code/function-event-pane/test-events-logs/test-events-logs.tpl.html +1 -1
- package/src/nuclio/functions/version/version-execution-log/version-execution-log.component.js +123 -83
- package/src/nuclio/functions/version/version-execution-log/version-execution-log.less +9 -0
- package/src/nuclio/functions/version/version-execution-log/version-execution-log.tpl.html +14 -5
- package/src/nuclio/functions/version/version.component.js +6 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iguazio.dashboard-controls",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.15",
|
|
4
4
|
"main": "dist/js/iguazio.dashboard-controls.js",
|
|
5
5
|
"description": "Collection of resources (such as CSS styles, fonts and images) and AngularJs 1.x components and services to share among different Iguazio repos.",
|
|
6
6
|
"repository": {
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
"LOGGER_DESTINATION": "Logger destination",
|
|
170
170
|
"LOGGER_LEVEL": "Logger level",
|
|
171
171
|
"LOGGING": "Logging",
|
|
172
|
-
"LOGS_LINES_LIMITATION": "Note: Only the last 10,000 rows are displayed. <br> To download up to 100,000 rows, click
|
|
172
|
+
"LOGS_LINES_LIMITATION": "Note: Only the last 10,000 rows are displayed. <br> To download up to 100,000 rows, click the 'Download' button.",
|
|
173
173
|
"MAX": "Max",
|
|
174
174
|
"MAX_REPLICAS": "Maximum number of replicas (default: {{default}})",
|
|
175
175
|
"MAX_WORKERS": "Max Workers",
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
"NEW_PROJECT": "New project",
|
|
186
186
|
"NO_FUNCTIONS_AVAILABLE": "No functions available",
|
|
187
187
|
"NO_INTERNET_ACCESS": "No internet access",
|
|
188
|
-
"
|
|
188
|
+
"NO_LOGS_WERE_FOUND": "No logs were found...",
|
|
189
189
|
"NODE_SELECTORS": "Node selector",
|
|
190
190
|
"NODE_SELECTORS_MORE_INFO": "If there is a conflict with the function node selector you defined or if the pod cannot be scheduled for some reason, check the project/platform configuration Key:Value combinations to see if there is a node selection causing the issue. If, after consulting with the project/general admin, you want to delete a global setting, enter the Key here, but leave the Value empty.",
|
|
191
191
|
"NORMAL": "Normal",
|
|
@@ -251,6 +251,7 @@
|
|
|
251
251
|
"SEARCH_TEMPLATE": "Search by text, tags and keywords",
|
|
252
252
|
"SEC": "Sec",
|
|
253
253
|
"SELECT_CLASS": "Select class",
|
|
254
|
+
"SELECT_REPLICA": "Select a replica",
|
|
254
255
|
"SELECT_TYPE": "Select type"
|
|
255
256
|
},
|
|
256
257
|
"PODS_PRIORITY": "Pods priority",
|
|
@@ -292,6 +293,7 @@
|
|
|
292
293
|
"SELECT_FUNCTION_CONFIRM": "The function you selected is currently not running. Are you sure you want to use it?",
|
|
293
294
|
"SERVICE_ACCOUNT": "Service Account",
|
|
294
295
|
"SESSION_TOKEN": "Session token",
|
|
296
|
+
"SHOWN_ONLINE_ONLY": "Show online replicas only",
|
|
295
297
|
"SKIP": "Skip",
|
|
296
298
|
"SKIP_TLS_VERIFICATION": "Skip TLS verification",
|
|
297
299
|
"SMALL": "Small",
|
|
@@ -349,6 +351,7 @@
|
|
|
349
351
|
},
|
|
350
352
|
"NEW_TEST": "New test",
|
|
351
353
|
"NO_INTERNET_ACCESS": "Use local Docker images rather than pulling from remote",
|
|
354
|
+
"NO_OFFLINE_REPLICAS": "Only online replicas found",
|
|
352
355
|
"ENRICHED_NODE_SELECTOR": "The node selector of the function, enriched with the project’s and the service’s default node selectors",
|
|
353
356
|
"POD_TOLERATIONS": {
|
|
354
357
|
"ALLOW": "Allow function pods to run on spot nodes. Spot nodes might be tainted, using this option will make sure function pods tolerate these taints.",
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
function ControlPanelLogsDataService($q, lodash, ElasticsearchService) {
|
|
8
8
|
return {
|
|
9
|
-
collectLogs: collectLogs,
|
|
10
9
|
entriesPaginated: search,
|
|
11
10
|
logsPaginated: logsWidthReplicas
|
|
12
11
|
};
|
|
@@ -150,58 +149,6 @@
|
|
|
150
149
|
});
|
|
151
150
|
}
|
|
152
151
|
|
|
153
|
-
/**
|
|
154
|
-
* Collects all the logs using chunks, and saved them as an array of strings.
|
|
155
|
-
* @param {Object} queryParams - additional parameters
|
|
156
|
-
* @param {string} queryParams.query - search query text
|
|
157
|
-
* @param {string} queryParams.timeFrame - selected time period to show results for
|
|
158
|
-
* @returns {Promise.<Array>} a promise resolving to an array of logs.
|
|
159
|
-
*/
|
|
160
|
-
function collectLogs(queryParams) {
|
|
161
|
-
var keepAlive = '5m';
|
|
162
|
-
var size = 10000;
|
|
163
|
-
var downloadLogsData = [];
|
|
164
|
-
var MAX_DOWNLOAD_LOGS = 100000;
|
|
165
|
-
|
|
166
|
-
return createSearch(size, keepAlive, queryParams).then(function (response) {
|
|
167
|
-
var hits = response.hits.hits;
|
|
168
|
-
|
|
169
|
-
if (hits.length > 0) {
|
|
170
|
-
downloadLogsData = downloadLogsData.concat(prepareLogs(hits));
|
|
171
|
-
|
|
172
|
-
return getNextChunk(response._scroll_id);
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
function getNextChunk(scroll) {
|
|
177
|
-
return getNextScrollLogs(keepAlive, scroll)
|
|
178
|
-
.then(function (response) {
|
|
179
|
-
var hits = response.hits.hits;
|
|
180
|
-
|
|
181
|
-
if (hits.length > 0 && downloadLogsData.length < MAX_DOWNLOAD_LOGS - size) {
|
|
182
|
-
downloadLogsData = downloadLogsData.concat(prepareLogs(hits));
|
|
183
|
-
|
|
184
|
-
return getNextChunk(response._scroll_id);
|
|
185
|
-
} else {
|
|
186
|
-
return downloadLogsData;
|
|
187
|
-
}
|
|
188
|
-
}).catch(function (error) {
|
|
189
|
-
throw error;
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function prepareLogs(logs) {
|
|
194
|
-
return logs.map(function (logData) {
|
|
195
|
-
var log = lodash.get(logData, '_source', {});
|
|
196
|
-
var level = log.level ? ' (' + log.level + ') ' : '';
|
|
197
|
-
var name = lodash.get(log, 'kubernetes.pod.name', lodash.get(log, 'name', ''));
|
|
198
|
-
|
|
199
|
-
return log['@timestamp'] + ' ' + name + level +
|
|
200
|
-
lodash.get(log, 'message', '') + ' ' + JSON.stringify(lodash.get(log, 'more', {}));
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
152
|
/**
|
|
206
153
|
* Mocks the real search function without the need for a running Elasticsearch service, for development
|
|
207
154
|
* purposes.
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
angular.module('iguazio.dashboard-controls')
|
|
5
|
+
.factory('ExecutionLogsDataService', ExecutionLogsDataService);
|
|
6
|
+
|
|
7
|
+
function ExecutionLogsDataService($rootScope, $i18next, $q, i18next, lodash, NuclioRestangular) {
|
|
8
|
+
var lng = i18next.language;
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
collectLogs: collectLogs,
|
|
12
|
+
logsPaginated: logsPaginated,
|
|
13
|
+
getReplicasList: getReplicasList
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
//
|
|
17
|
+
// Public methods
|
|
18
|
+
//
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Collects all the logs using chunks, and saved them as an array of strings.
|
|
22
|
+
* @param {Object} queryParams - additional parameters
|
|
23
|
+
* @returns {Promise.<Array>} a promise resolving to an array of logs.
|
|
24
|
+
*/
|
|
25
|
+
function collectLogs(queryParams) {
|
|
26
|
+
var size = 10000;
|
|
27
|
+
var downloadLogsData = [];
|
|
28
|
+
var MAX_DOWNLOAD_LOGS = 100000;
|
|
29
|
+
|
|
30
|
+
return getLogsList(0, size, queryParams).then(function (response) {
|
|
31
|
+
var hits = response.hits.hits;
|
|
32
|
+
|
|
33
|
+
if (hits.length > 0) {
|
|
34
|
+
downloadLogsData = downloadLogsData.concat(prepareLogs(hits));
|
|
35
|
+
|
|
36
|
+
return getNextChunk(lodash.get(lodash.last(hits), 'sort'));
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
function getNextChunk(searchAfter) {
|
|
41
|
+
return getLogsList(0, size, Object.assign(queryParams, {searchAfter}))
|
|
42
|
+
.then(function (response) {
|
|
43
|
+
var hits = response.hits.hits;
|
|
44
|
+
|
|
45
|
+
if (hits.length > 0 && downloadLogsData.length < MAX_DOWNLOAD_LOGS - size) {
|
|
46
|
+
downloadLogsData = downloadLogsData.concat(prepareLogs(hits));
|
|
47
|
+
|
|
48
|
+
return getNextChunk(lodash.get(lodash.last(response.hits.hits), 'sort'));
|
|
49
|
+
} else {
|
|
50
|
+
if (hits.length > 0) {
|
|
51
|
+
downloadLogsData = downloadLogsData.concat(prepareLogs(hits));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return downloadLogsData;
|
|
55
|
+
}
|
|
56
|
+
}).catch(function (error) {
|
|
57
|
+
throw error;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function prepareLogs(logs) {
|
|
62
|
+
return logs.map(function (logData) {
|
|
63
|
+
var log = lodash.get(logData, '_source', {});
|
|
64
|
+
var level = log.level ? ' (' + log.level + ') ' : '';
|
|
65
|
+
var name = lodash.get(log, 'kubernetes.pod.name', lodash.get(log, 'name', ''));
|
|
66
|
+
|
|
67
|
+
return log['@timestamp'] + ' ' + name + level +
|
|
68
|
+
lodash.get(log, 'message', '') + ' ' + JSON.stringify(lodash.get(log, 'more', {}));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get latest log entries (used for pagination)
|
|
75
|
+
* @param {number} page - current page
|
|
76
|
+
* @param {number} perPage - max items count on a page
|
|
77
|
+
* @param {Object} queryParams - additional parameters
|
|
78
|
+
* update
|
|
79
|
+
* @returns {Promise} array of log entries
|
|
80
|
+
*/
|
|
81
|
+
function logsPaginated(page, perPage, queryParams) {
|
|
82
|
+
return getLogsList(page, perPage, queryParams).then(function (response) {
|
|
83
|
+
// Saved log entry can be found in `_source` property
|
|
84
|
+
// For now all additional data from Elasticsearch is not used, so only entries are returned
|
|
85
|
+
var logs = lodash.map(response.hits.hits, '_source')
|
|
86
|
+
|
|
87
|
+
logs.total_logs_count = lodash.get(response, 'hits.total.value', 0);
|
|
88
|
+
logs.total_pages = Math.ceil(lodash.get(response, 'hits.total.value', 0) / perPage);
|
|
89
|
+
|
|
90
|
+
return logs;
|
|
91
|
+
})
|
|
92
|
+
.catch(function (error) {
|
|
93
|
+
return $q.reject(error);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Provides filtered replicas list
|
|
99
|
+
* @param {string} projectId - project name
|
|
100
|
+
* @param {string} funcName - function name
|
|
101
|
+
* @param {Object} queryParams - additional parameters
|
|
102
|
+
* update
|
|
103
|
+
* @returns {Promise} array of log entries
|
|
104
|
+
*/
|
|
105
|
+
function getReplicasList(projectId, funcName, queryParams) {
|
|
106
|
+
var headers = {
|
|
107
|
+
'Cache-Control': 'no-cache',
|
|
108
|
+
'Content-Type': 'application/json',
|
|
109
|
+
'x-nuclio-project-name': projectId
|
|
110
|
+
};
|
|
111
|
+
var requestParams = Object.assign(queryParams, {includeOffline: queryParams.includeOffline});
|
|
112
|
+
|
|
113
|
+
if (queryParams.timeFilter) {
|
|
114
|
+
queryParams.timeFilter = {
|
|
115
|
+
since: queryParams.timeFilter.from,
|
|
116
|
+
until: queryParams.timeFilter.to,
|
|
117
|
+
sort: queryParams.timeFilter.sort
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return NuclioRestangular.one('functions', funcName)
|
|
122
|
+
.one('replicas')
|
|
123
|
+
.get(requestParams, headers)
|
|
124
|
+
.then(function (response) {
|
|
125
|
+
return response.plain();
|
|
126
|
+
})
|
|
127
|
+
.catch(function (error) {
|
|
128
|
+
var errorMessages = {
|
|
129
|
+
'400': $i18next.t('common:ERROR_MSG.PAGINATION.400', { lng: lng }),
|
|
130
|
+
'403': $i18next.t('common:ERROR_MSG.PAGINATION.403', { lng: lng }),
|
|
131
|
+
'500': $i18next.t('common:ERROR_MSG.ERROR_ON_SERVER_SIDE', { lng: lng }),
|
|
132
|
+
'default': $i18next.t('common:ERROR_MSG.UNKNOWN_ERROR', { lng: lng })
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
$rootScope.$broadcast('splash-screen_show-error', {
|
|
136
|
+
alertText: lodash.get(errorMessages, String(error.status), errorMessages.default) +
|
|
137
|
+
' ' + $i18next.t('common:ERROR_MSG.TRY_REFRESHING_THE_PAGE', { lng: lng })
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return $q.reject(error);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
//
|
|
145
|
+
// Private methods
|
|
146
|
+
//
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Gets the list of logs based on parameters
|
|
150
|
+
* @param {number} page - current page
|
|
151
|
+
* @param {number} perPage - max items count on a page
|
|
152
|
+
* @param {Object} queryParams - additional parameters
|
|
153
|
+
* update
|
|
154
|
+
* @returns {Promise} array of log entries
|
|
155
|
+
*/
|
|
156
|
+
function getLogsList(page, perPage, queryParams) {
|
|
157
|
+
var headers = {
|
|
158
|
+
'Cache-Control': 'no-cache',
|
|
159
|
+
'Content-Type': 'application/json',
|
|
160
|
+
'x-nuclio-project-name': queryParams.projectName
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
var sizeParams = {}
|
|
164
|
+
|
|
165
|
+
if (queryParams.searchAfter) {
|
|
166
|
+
queryParams.searchAfter[1] = '"' + queryParams.searchAfter[1] + '"';
|
|
167
|
+
|
|
168
|
+
sizeParams = {
|
|
169
|
+
size: perPage,
|
|
170
|
+
searchAfter: queryParams.searchAfter
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
sizeParams = {
|
|
174
|
+
size: perPage,
|
|
175
|
+
from: page * perPage,
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
var filters = lodash.omitBy(Object.assign(sizeParams, queryParams.filters), function (value) {
|
|
180
|
+
return lodash.isObject(value) || lodash.isString(value) ? lodash.isEmpty(value) : false;
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
if (filters.timeFilter) {
|
|
184
|
+
filters.timeFilter = {
|
|
185
|
+
since: filters.timeFilter.from,
|
|
186
|
+
until: filters.timeFilter.to,
|
|
187
|
+
sort: filters.timeFilter.sort
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return NuclioRestangular.one('functions', queryParams.functionName)
|
|
192
|
+
.one('proxy-logs')
|
|
193
|
+
.get(filters, headers)
|
|
194
|
+
.catch(function (error) {
|
|
195
|
+
return $q.reject(error);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
}
|
|
200
|
+
}());
|
package/src/nuclio/functions/version/version-execution-log/version-execution-log.component.js
CHANGED
|
@@ -28,16 +28,13 @@ such restriction.
|
|
|
28
28
|
controller: NclVersionExecutionLogController
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
function NclVersionExecutionLogController(lodash, $interval, i18next, $i18next, $rootScope,
|
|
32
|
-
|
|
31
|
+
function NclVersionExecutionLogController(lodash, moment, $interval, i18next, $i18next, $rootScope, ExecutionLogsDataService,
|
|
32
|
+
ExportService, LoginService, PaginationService) {
|
|
33
33
|
var ctrl = this;
|
|
34
34
|
var lng = i18next.language;
|
|
35
35
|
|
|
36
|
+
var allReplicas = [];
|
|
36
37
|
var refreshInterval = null;
|
|
37
|
-
var initialTimeRange = {
|
|
38
|
-
from: null,
|
|
39
|
-
to: null
|
|
40
|
-
};
|
|
41
38
|
var initialDatePreset = '7d';
|
|
42
39
|
var initialReplicas = [];
|
|
43
40
|
var defaultFilter = {
|
|
@@ -50,12 +47,15 @@ such restriction.
|
|
|
50
47
|
error: false
|
|
51
48
|
}
|
|
52
49
|
};
|
|
50
|
+
var projectName = '';
|
|
51
|
+
var groupedReplicas = {};
|
|
53
52
|
|
|
53
|
+
ctrl.excludeOffline = false;
|
|
54
|
+
ctrl.excludeOfflineIsDisabled = false;
|
|
54
55
|
ctrl.downloadButtonIsDisabled = false;
|
|
55
56
|
ctrl.isSplashShowed = {
|
|
56
57
|
value: false
|
|
57
58
|
};
|
|
58
|
-
ctrl.lastEntryTimestamp = null;
|
|
59
59
|
ctrl.logs = {};
|
|
60
60
|
ctrl.replicasList = [];
|
|
61
61
|
ctrl.filter = {};
|
|
@@ -69,7 +69,11 @@ such restriction.
|
|
|
69
69
|
};
|
|
70
70
|
ctrl.datePreset = initialDatePreset;
|
|
71
71
|
ctrl.logsAreDownloading = false;
|
|
72
|
-
ctrl.timeRange =
|
|
72
|
+
ctrl.timeRange = {
|
|
73
|
+
from: null,
|
|
74
|
+
to: null,
|
|
75
|
+
sort: 'desc'
|
|
76
|
+
};
|
|
73
77
|
ctrl.searchStates = {};
|
|
74
78
|
ctrl.selectedReplicas = [];
|
|
75
79
|
ctrl.isFiltersShowed = {
|
|
@@ -168,6 +172,7 @@ such restriction.
|
|
|
168
172
|
ctrl.applyFilters = applyFilters;
|
|
169
173
|
ctrl.downloadLogFiles = downloadLogFiles;
|
|
170
174
|
ctrl.onCheckboxChange = onCheckboxChange;
|
|
175
|
+
ctrl.onExcludeOfflineChange = onExcludeOfflineChange;
|
|
171
176
|
ctrl.onRefreshRateChange = onRefreshRateChange;
|
|
172
177
|
ctrl.onTimeRangeChange = onTimeRangeChange;
|
|
173
178
|
ctrl.onQueryChanged = onQueryChanged;
|
|
@@ -187,11 +192,35 @@ such restriction.
|
|
|
187
192
|
defaultFilter.name = ctrl.version.metadata.name;
|
|
188
193
|
ctrl.filter = lodash.cloneDeep(defaultFilter);
|
|
189
194
|
|
|
190
|
-
|
|
195
|
+
projectName = lodash.get(ctrl.version, ['metadata', 'labels', 'nuclio.io/project-name']);
|
|
191
196
|
|
|
192
|
-
ctrl
|
|
197
|
+
PaginationService.addPagination(ctrl, 'logs', 'ExecutionLogsDataService', onChangePageCallback, true);
|
|
193
198
|
|
|
194
|
-
|
|
199
|
+
ctrl.timeRange = getInitialTimeRange();
|
|
200
|
+
|
|
201
|
+
ctrl.isSplashShowed.value = true;
|
|
202
|
+
ExecutionLogsDataService.getReplicasList(projectName, ctrl.version.metadata.name, {
|
|
203
|
+
timeFilter: ctrl.timeRange,
|
|
204
|
+
includeOffline: true
|
|
205
|
+
}).then(function (replicas) {
|
|
206
|
+
groupedReplicas = replicas;
|
|
207
|
+
allReplicas = lodash.get(groupedReplicas, 'replicas.names') ?
|
|
208
|
+
groupedReplicas.replicas.names.concat(replicas.offlineReplicas.names) :
|
|
209
|
+
lodash.get(groupedReplicas, 'names', []);
|
|
210
|
+
ctrl.excludeOfflineIsDisabled = lodash.get(groupedReplicas, 'offlineReplicas.names', []).length === 0;
|
|
211
|
+
ctrl.replicasList = allReplicas.map(function (replica) {
|
|
212
|
+
return {
|
|
213
|
+
label: replica,
|
|
214
|
+
id: replica,
|
|
215
|
+
value: replica,
|
|
216
|
+
checked: true
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
initialReplicas = allReplicas;
|
|
220
|
+
ctrl.selectedReplicas = angular.copy(allReplicas);
|
|
221
|
+
|
|
222
|
+
applyFilters();
|
|
223
|
+
});
|
|
195
224
|
}
|
|
196
225
|
|
|
197
226
|
/**
|
|
@@ -211,7 +240,6 @@ such restriction.
|
|
|
211
240
|
function applyFilters() {
|
|
212
241
|
stopAutoUpdate();
|
|
213
242
|
calcActiveFilters();
|
|
214
|
-
generateFilterQuery();
|
|
215
243
|
searchWithParams(0, ctrl.page.size);
|
|
216
244
|
}
|
|
217
245
|
|
|
@@ -222,7 +250,8 @@ such restriction.
|
|
|
222
250
|
stopAutoUpdate();
|
|
223
251
|
|
|
224
252
|
ctrl.downloadButtonIsDisabled = true;
|
|
225
|
-
|
|
253
|
+
|
|
254
|
+
return ExecutionLogsDataService.collectLogs(queryParams())
|
|
226
255
|
.then(function (response) {
|
|
227
256
|
ExportService.exportLogs(response, ctrl.version.metadata.name);
|
|
228
257
|
}).finally(function () {
|
|
@@ -248,6 +277,33 @@ such restriction.
|
|
|
248
277
|
ctrl.applyIsDisabled = !ctrl.selectedReplicas;
|
|
249
278
|
}
|
|
250
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Triggered when exclude offline checkbox was changed
|
|
282
|
+
*/
|
|
283
|
+
function onExcludeOfflineChange() {
|
|
284
|
+
if (ctrl.excludeOffline) {
|
|
285
|
+
ctrl.replicasList = groupedReplicas.replicas.names.map(function (replica) {
|
|
286
|
+
return {
|
|
287
|
+
label: replica,
|
|
288
|
+
id: replica,
|
|
289
|
+
value: replica,
|
|
290
|
+
checked: true
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
ctrl.selectedReplicas = angular.copy(groupedReplicas.replicas.names);
|
|
294
|
+
} else {
|
|
295
|
+
ctrl.replicasList = allReplicas.map(function (replica) {
|
|
296
|
+
return {
|
|
297
|
+
label: replica,
|
|
298
|
+
id: replica,
|
|
299
|
+
value: replica,
|
|
300
|
+
checked: true
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
ctrl.selectedReplicas = angular.copy(allReplicas);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
251
307
|
/**
|
|
252
308
|
* Handles Refresh Rate dropdown change
|
|
253
309
|
* @param {Object} item - new item
|
|
@@ -273,8 +329,7 @@ such restriction.
|
|
|
273
329
|
ctrl.timeRange = lodash.mapValues(dateTimeRange, function (range) {
|
|
274
330
|
return new Date(range).toISOString();
|
|
275
331
|
});
|
|
276
|
-
|
|
277
|
-
ctrl.lastEntryTimestamp = null;
|
|
332
|
+
ctrl.timeRange.sort = 'desc';
|
|
278
333
|
}
|
|
279
334
|
|
|
280
335
|
/**
|
|
@@ -283,11 +338,34 @@ such restriction.
|
|
|
283
338
|
function refreshLogs() {
|
|
284
339
|
startAutoUpdate();
|
|
285
340
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
341
|
+
ctrl.isSplashShowed.value = true
|
|
342
|
+
|
|
343
|
+
ExecutionLogsDataService.getReplicasList(projectName, ctrl.version.metadata.name, {timeFilter: ctrl.timeRange})
|
|
344
|
+
.then(function (replicas) {
|
|
345
|
+
groupedReplicas = replicas;
|
|
346
|
+
allReplicas = lodash.get(groupedReplicas, 'replicas.names') ?
|
|
347
|
+
groupedReplicas.replicas.names.concat(replicas.offlineReplicas.names) :
|
|
348
|
+
lodash.get(groupedReplicas, 'names', []);
|
|
349
|
+
ctrl.excludeOfflineIsDisabled = lodash.get(groupedReplicas, 'offlineReplicas.names', []).length === 0;
|
|
350
|
+
ctrl.replicasList = allReplicas.map(function (replica) {
|
|
351
|
+
return {
|
|
352
|
+
label: replica,
|
|
353
|
+
id: replica,
|
|
354
|
+
value: replica,
|
|
355
|
+
checked: true
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
initialReplicas = allReplicas;
|
|
359
|
+
|
|
360
|
+
return ExecutionLogsDataService.logsPaginated(ctrl.page.number, ctrl.page.size, queryParams())
|
|
361
|
+
.then(function (logs) {
|
|
362
|
+
if (logs.length > 0) {
|
|
363
|
+
ctrl.logs = lodash.cloneDeep(logs);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
})
|
|
367
|
+
.finally(function () {
|
|
368
|
+
ctrl.isSplashShowed.value = false;
|
|
291
369
|
});
|
|
292
370
|
}
|
|
293
371
|
|
|
@@ -296,9 +374,10 @@ such restriction.
|
|
|
296
374
|
*/
|
|
297
375
|
function resetFilters() {
|
|
298
376
|
ctrl.applyIsDisabled = false;
|
|
299
|
-
ctrl.timeRange =
|
|
377
|
+
ctrl.timeRange = getInitialTimeRange();
|
|
300
378
|
ctrl.datePreset = initialDatePreset;
|
|
301
379
|
ctrl.selectedReplicas = initialReplicas;
|
|
380
|
+
ctrl.excludeOffline = false;
|
|
302
381
|
|
|
303
382
|
lodash.merge(ctrl.filter, defaultFilter);
|
|
304
383
|
$rootScope.$broadcast('search-input_reset');
|
|
@@ -336,7 +415,7 @@ such restriction.
|
|
|
336
415
|
return;
|
|
337
416
|
}
|
|
338
417
|
|
|
339
|
-
|
|
418
|
+
ExecutionLogsDataService.logsPaginated(ctrl.page.number, ctrl.page.size, queryParams())
|
|
340
419
|
.then(function (logs) {
|
|
341
420
|
if (logs.length > 0) {
|
|
342
421
|
ctrl.logs = lodash.cloneDeep(logs);
|
|
@@ -365,79 +444,28 @@ such restriction.
|
|
|
365
444
|
* Updates latest timestamp when new data received and generates replicas list
|
|
366
445
|
*/
|
|
367
446
|
function onChangePageCallback() {
|
|
368
|
-
if (ctrl.logs.length > 0) {
|
|
369
|
-
ctrl.lastEntryTimestamp = ctrl.logs[0].time;
|
|
370
|
-
|
|
371
|
-
if (ctrl.logs.replicas) {
|
|
372
|
-
ctrl.replicasList = ctrl.logs.replicas.map(function (replica) {
|
|
373
|
-
return {
|
|
374
|
-
label: replica,
|
|
375
|
-
id: replica,
|
|
376
|
-
value: replica,
|
|
377
|
-
checked: true
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
ctrl.selectedReplicas = angular.copy(ctrl.logs.replicas);
|
|
381
|
-
initialReplicas = ctrl.logs.replicas;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
447
|
startAutoUpdate();
|
|
386
448
|
}
|
|
387
449
|
|
|
388
|
-
/**
|
|
389
|
-
* Generates query string from all filters
|
|
390
|
-
*/
|
|
391
|
-
function generateFilterQuery() {
|
|
392
|
-
var levels = lodash.chain(ctrl.filter.level).pickBy().keys().join(' OR ').value();
|
|
393
|
-
var projectName = lodash.get(ctrl.version, ['metadata', 'labels', 'nuclio.io/project-name']);
|
|
394
|
-
var projectFilter = '(nuclio.project_name.keyword:' + projectName + ' OR nuclio.project_name:' + projectName + ')';
|
|
395
|
-
var queries = ['system-id:"' + ConfigService.systemId + '"', '_exists_:nuclio', projectFilter];
|
|
396
|
-
|
|
397
|
-
if (ctrl.selectedReplicas.length && ctrl.selectedReplicas.length !== initialReplicas.length) {
|
|
398
|
-
var replicas = ctrl.selectedReplicas.join(' OR ');
|
|
399
|
-
|
|
400
|
-
queries.push('kubernetes.pod.name:(' + replicas + ')');
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
if (!lodash.isEmpty(ctrl.filter.message)) {
|
|
404
|
-
// Escape reserved characters: + - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
|
|
405
|
-
var escapedMessage = ctrl.filter.message.replace(/[+\-=&|!(){}[\]^"~*?:\\/]/g, '\\$&')
|
|
406
|
-
.replace(/<|>/g, '');
|
|
407
|
-
queries.push('(message:' + escapedMessage + ' OR more:' + escapedMessage + ')');
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
if (!lodash.isEmpty(levels)) {
|
|
411
|
-
queries.push('level:(' + levels + ')');
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
ctrl.filterQuery = lodash.join(queries, ' AND ');
|
|
415
|
-
ctrl.filterName = ctrl.version.metadata.name;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
450
|
/**
|
|
419
451
|
* Generates query params for ordinary request, for example, when page was changed
|
|
420
452
|
* @returns {Object}
|
|
421
453
|
*/
|
|
422
454
|
function queryParams() {
|
|
423
455
|
return {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
456
|
+
functionName: ctrl.version.metadata.name,
|
|
457
|
+
projectName,
|
|
458
|
+
filters: {
|
|
459
|
+
substring: ctrl.filter.message.replace(/[+\-=&|!(){}[\]^"~*?:\\/]/g, '\\$&')
|
|
460
|
+
.replace(/<|>/g, ''),
|
|
461
|
+
logLevels: lodash.chain(ctrl.filter.level).pickBy().keys().value(),
|
|
462
|
+
replicaNames: ctrl.selectedReplicas,
|
|
463
|
+
timeFilter: ctrl.timeRange,
|
|
464
|
+
includeOffline: !ctrl.excludeOffline
|
|
465
|
+
}
|
|
428
466
|
};
|
|
429
467
|
}
|
|
430
468
|
|
|
431
|
-
/**
|
|
432
|
-
* Generates query params for auto update request
|
|
433
|
-
* @returns {Object}
|
|
434
|
-
*/
|
|
435
|
-
function queryParamsAutoUpdate() {
|
|
436
|
-
return lodash.defaults(queryParams(), {
|
|
437
|
-
lastEntryTimestamp: ctrl.lastEntryTimestamp
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
|
|
441
469
|
/**
|
|
442
470
|
* Starts auto update process
|
|
443
471
|
* @param {bool} [force] - used for making first update immediately after refreshInterval is created
|
|
@@ -466,5 +494,17 @@ such restriction.
|
|
|
466
494
|
refreshInterval = null;
|
|
467
495
|
}
|
|
468
496
|
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Provides initial time range
|
|
500
|
+
*/
|
|
501
|
+
function getInitialTimeRange() {
|
|
502
|
+
var weekDate = ctrl.customDatePresets['7d'].getRange();
|
|
503
|
+
|
|
504
|
+
return {
|
|
505
|
+
from: weekDate.from.toISOString(),
|
|
506
|
+
sort: 'desc'
|
|
507
|
+
};
|
|
508
|
+
}
|
|
469
509
|
}
|
|
470
510
|
}());
|
|
@@ -103,9 +103,18 @@
|
|
|
103
103
|
padding-left: 15px;
|
|
104
104
|
padding-right: 15px;
|
|
105
105
|
}
|
|
106
|
+
|
|
107
|
+
.checkboxes-dropdown-title {
|
|
108
|
+
text-transform: initial;
|
|
109
|
+
font-size: 14px;
|
|
110
|
+
}
|
|
106
111
|
}
|
|
107
112
|
}
|
|
108
113
|
|
|
114
|
+
.online-replicas__checkbox {
|
|
115
|
+
margin: 5px 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
109
118
|
.igz-multiple-checkboxes {
|
|
110
119
|
.checkboxes-dropdown-container {
|
|
111
120
|
position: unset;
|