1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-31 14:08:06 +08:00

fix: 容器日志兼并显示 stdout 与 stderr

This commit is contained in:
ssongliu 2023-03-09 18:42:17 +08:00 committed by ssongliu
parent ab8a440c12
commit 6da43d7eb0
4 changed files with 15 additions and 34 deletions

View File

@ -1,12 +1,11 @@
package service package service
import ( import (
"bytes"
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"os/exec"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -20,7 +19,6 @@ import (
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
v1 "github.com/opencontainers/image-spec/specs-go/v1" v1 "github.com/opencontainers/image-spec/specs-go/v1"
) )
@ -221,32 +219,15 @@ func (u *ContainerService) ContainerOperation(req dto.ContainerOperation) error
} }
func (u *ContainerService) ContainerLogs(req dto.ContainerLog) (string, error) { func (u *ContainerService) ContainerLogs(req dto.ContainerLog) (string, error) {
var ( cmd := exec.Command("docker", "logs", req.ContainerID)
options types.ContainerLogsOptions if req.Mode != "all" {
logs io.ReadCloser cmd = exec.Command("docker", "logs", req.ContainerID, "--since", req.Mode)
buf *bytes.Buffer }
err error stdout, err := cmd.CombinedOutput()
)
client, err := docker.NewDockerClient()
if err != nil { if err != nil {
return "", err return "", err
} }
options = types.ContainerLogsOptions{ return string(stdout), nil
ShowStdout: true,
Timestamps: true,
}
if req.Mode != "all" {
options.Since = req.Mode
}
if logs, err = client.ContainerLogs(context.Background(), req.ContainerID, options); err != nil {
return "", err
}
defer logs.Close()
buf = new(bytes.Buffer)
if _, err = stdcopy.StdCopy(buf, nil, logs); err != nil {
return "", err
}
return buf.String(), nil
} }
func (u *ContainerService) ContainerStats(id string) (*dto.ContainterStats, error) { func (u *ContainerService) ContainerStats(id string) (*dto.ContainterStats, error) {

View File

@ -72,19 +72,19 @@ const timeOptions = ref([
{ label: i18n.global.t('container.all'), value: 'all' }, { label: i18n.global.t('container.all'), value: 'all' },
{ {
label: i18n.global.t('container.lastDay'), label: i18n.global.t('container.lastDay'),
value: new Date(new Date().getTime() - 3600 * 1000 * 24 * 1).getTime() / 1000 + '', value: '24h',
}, },
{ {
label: i18n.global.t('container.last4Hour'), label: i18n.global.t('container.last4Hour'),
value: new Date(new Date().getTime() - 3600 * 1000 * 4).getTime() / 1000 + '', value: '4h',
}, },
{ {
label: i18n.global.t('container.lastHour'), label: i18n.global.t('container.lastHour'),
value: new Date(new Date().getTime() - 3600 * 1000).getTime() / 1000 + '', value: '1h',
}, },
{ {
label: i18n.global.t('container.last10Min'), label: i18n.global.t('container.last10Min'),
value: new Date(new Date().getTime() - 600 * 1000).getTime() / 1000 + '', value: '10m',
}, },
]); ]);

View File

@ -73,7 +73,7 @@
<el-form-item <el-form-item
:label="$t('setting.sessionTimeout')" :label="$t('setting.sessionTimeout')"
:rules="Rules.number" :rules="[Rules.number, checkNumberRange(300, 864000)]"
prop="sessionTimeout" prop="sessionTimeout"
> >
<el-input v-model.number="form.sessionTimeout"> <el-input v-model.number="form.sessionTimeout">
@ -125,7 +125,7 @@ import { ref, reactive, onMounted, computed } from 'vue';
import { ElForm, ElMessageBox } from 'element-plus'; import { ElForm, ElMessageBox } from 'element-plus';
import LayoutContent from '@/layout/layout-content.vue'; import LayoutContent from '@/layout/layout-content.vue';
import { syncTime, getSettingInfo, updateSetting } from '@/api/modules/setting'; import { syncTime, getSettingInfo, updateSetting } from '@/api/modules/setting';
import { Rules } from '@/global/form-rules'; import { Rules, checkNumberRange } from '@/global/form-rules';
import { GlobalStore } from '@/store'; import { GlobalStore } from '@/store';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useTheme } from '@/hooks/use-theme'; import { useTheme } from '@/hooks/use-theme';

View File

@ -114,7 +114,7 @@
<DrawerHeader :header="$t('setting.expirationTime')" :back="handleClose" /> <DrawerHeader :header="$t('setting.expirationTime')" :back="handleClose" />
</template> </template>
<el-form ref="timeoutFormRef" label-position="top" :model="timeoutForm"> <el-form ref="timeoutFormRef" label-position="top" :model="timeoutForm">
<el-form-item :label="$t('setting.days')" prop="days" :rules="Rules.number"> <el-form-item :label="$t('setting.days')" prop="days" :rules="[Rules.number, checkNumberRange(0, 60)]">
<el-input clearable v-model.number="timeoutForm.days" /> <el-input clearable v-model.number="timeoutForm.days" />
<span class="input-help">{{ $t('setting.expirationHelper') }}</span> <span class="input-help">{{ $t('setting.expirationHelper') }}</span>
</el-form-item> </el-form-item>
@ -139,7 +139,7 @@ import LayoutContent from '@/layout/layout-content.vue';
import DrawerHeader from '@/components/drawer-header/index.vue'; import DrawerHeader from '@/components/drawer-header/index.vue';
import { updateSetting, getMFA, bindMFA, getSettingInfo, updatePort } from '@/api/modules/setting'; import { updateSetting, getMFA, bindMFA, getSettingInfo, updatePort } from '@/api/modules/setting';
import i18n from '@/lang'; import i18n from '@/lang';
import { Rules } from '@/global/form-rules'; import { Rules, checkNumberRange } from '@/global/form-rules';
import { dateFormatSimple } from '@/utils/util'; import { dateFormatSimple } from '@/utils/util';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';