import _ from 'lodash-es';
import angular from 'angular';
import $allSettled from 'Portainer/services/allSettled';
const colors = ['red', 'orange', 'lime', 'green', 'darkgreen', 'cyan', 'turquoise', 'teal', 'deepskyblue', 'blue', 'darkblue', 'slateblue', 'magenta', 'darkviolet'];
class KubernetesStackLogsController {
/* @ngInject */
constructor($async, $state, $interval, Notifications, KubernetesApplicationService, KubernetesPodService, FileSaver, Blob) {
this.$async = $async;
this.$state = $state;
this.$interval = $interval;
this.Notifications = Notifications;
this.KubernetesApplicationService = KubernetesApplicationService;
this.KubernetesPodService = KubernetesPodService;
this.Blob = Blob;
this.FileSaver = FileSaver;
this.onInit = this.onInit.bind(this);
this.stopRepeater = this.stopRepeater.bind(this);
this.generateLogsPromise = this.generateLogsPromise.bind(this);
this.generateAppPromise = this.generateAppPromise.bind(this);
this.getStackLogsAsync = this.getStackLogsAsync.bind(this);
}
updateAutoRefresh() {
if (this.state.autoRefresh) {
this.setUpdateRepeater();
return;
this.stopRepeater();
stopRepeater() {
if (angular.isDefined(this.repeater)) {
this.$interval.cancel(this.repeater);
this.repeater = null;
setUpdateRepeater() {
this.repeater = this.$interval(this.getStackLogsAsync, this.state.refreshRate);
async generateLogsPromise(pod) {
const res = {
Pod: pod,
Logs: [],
};
res.Logs = await this.KubernetesPodService.logs(pod.Namespace, pod.Name);
return res;
async generateAppPromise(app) {
Application: app,
Pods: [],
const promises = _.map(app.Pods, this.generateLogsPromise);
const result = await $allSettled(promises);
res.Pods = result.fulfilled;
async getStackLogsAsync() {
try {
const applications = await this.KubernetesApplicationService.get(this.state.transition.namespace);
const filteredApplications = _.filter(applications, (app) => app.StackName === this.state.transition.name);
const logsPromises = _.map(filteredApplications, this.generateAppPromise);
const data = await Promise.all(logsPromises);
const logs = _.flatMap(data, (app, index) => {
return _.flatMap(app.Pods, (pod) => {
return _.map(pod.Logs, (line) => {
Color: colors[index % colors.length],
Line: line,
AppName: pod.Pod.Name,
});
this.stackLogs = logs;
} catch (err) {
this.Notifications.error('Failure', err, 'Unable to retrieve application logs');
downloadLogs() {
const data = new this.Blob([(this.dataLogs = _.reduce(this.stackLogs, (acc, log) => acc + '\n' + log.AppName + ' ' + log.Line, ''))]);
this.FileSaver.saveAs(data, this.state.transition.name + '_logs.txt');
async onInit() {
this.state = {
autoRefresh: false,
refreshRate: 30000, // 30 seconds
search: '',
viewReady: false,
transition: {
namespace: this.$transition$.params().namespace,
name: this.$transition$.params().name,
},
this.stackLogs = [];
await this.getStackLogsAsync();
this.Notifications.error('Failure', err, 'Unable to retrieve stack logs');
} finally {
this.state.viewReady = true;
$onInit() {
return this.$async(this.onInit);
$onDestroy() {
export default KubernetesStackLogsController;
angular.module('portainer.kubernetes').controller('KubernetesStackLogsController', KubernetesStackLogsController);