feat: 增加容器日志清理功能 (#1111)

This commit is contained in:
ssongliu 2023-05-23 15:43:51 +08:00 committed by GitHub
parent 0d084861e0
commit 5ac9298db0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 491 additions and 32 deletions

View file

@ -179,6 +179,32 @@ func (b *BaseApi) ContainerCreate(c *gin.Context) {
helper.SuccessWithData(c, nil) helper.SuccessWithData(c, nil)
} }
// @Tags Container
// @Summary Clean container log
// @Description 清理容器日志
// @Accept json
// @Param request body dto.OperationWithName true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /containers/clean/log [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"清理容器 [name] 日志","formatEN":"clean container [name] logs"}
func (b *BaseApi) CleanContainerLog(c *gin.Context) {
var req dto.OperationWithName
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := containerService.ContainerLogClean(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Container // @Tags Container
// @Summary Operate Container // @Summary Operate Container
// @Description 容器操作 // @Description 容器操作

View file

@ -189,7 +189,7 @@ func (b *BaseApi) HandlePasswordExpired(c *gin.Context) {
// @Tags System Setting // @Tags System Setting
// @Summary Load time zone options // @Summary Load time zone options
// @Description 加载系统可用时区 // @Description 加载系统可用时区
// @Success 200 {string} // @Success 200
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Router /settings/time/option [get] // @Router /settings/time/option [get]
func (b *BaseApi) LoadTimeZone(c *gin.Context) { func (b *BaseApi) LoadTimeZone(c *gin.Context) {

View file

@ -6,6 +6,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"os"
"os/exec" "os/exec"
"sort" "sort"
"strconv" "strconv"
@ -39,6 +40,7 @@ type IContainerService interface {
CreateCompose(req dto.ComposeCreate) (string, error) CreateCompose(req dto.ComposeCreate) (string, error)
ComposeOperation(req dto.ComposeOperation) error ComposeOperation(req dto.ComposeOperation) error
ContainerCreate(req dto.ContainerCreate) error ContainerCreate(req dto.ContainerCreate) error
ContainerLogClean(req dto.OperationWithName) error
ContainerOperation(req dto.ContainerOperation) error ContainerOperation(req dto.ContainerOperation) error
ContainerLogs(param dto.ContainerLog) (string, error) ContainerLogs(param dto.ContainerLog) (string, error)
ContainerStats(id string) (*dto.ContainterStats, error) ContainerStats(id string) (*dto.ContainterStats, error)
@ -263,6 +265,27 @@ func (u *ContainerService) ContainerOperation(req dto.ContainerOperation) error
return err return err
} }
func (u *ContainerService) ContainerLogClean(req dto.OperationWithName) error {
client, err := docker.NewDockerClient()
if err != nil {
return err
}
container, err := client.ContainerInspect(context.Background(), req.Name)
if err != nil {
return err
}
file, err := os.OpenFile(container.LogPath, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
return err
}
defer file.Close()
if err = file.Truncate(0); err != nil {
return err
}
_, _ = file.Seek(0, 0)
return nil
}
func (u *ContainerService) ContainerLogs(req dto.ContainerLog) (string, error) { func (u *ContainerService) ContainerLogs(req dto.ContainerLog) (string, error) {
cmd := exec.Command("docker", "logs", req.ContainerID) cmd := exec.Command("docker", "logs", req.ContainerID)
if req.Mode != "all" { if req.Mode != "all" {

View file

@ -21,6 +21,7 @@ func (s *ContainerRouter) InitContainerRouter(Router *gin.RouterGroup) {
baRouter.POST("", baseApi.ContainerCreate) baRouter.POST("", baseApi.ContainerCreate)
baRouter.POST("/search", baseApi.SearchContainer) baRouter.POST("/search", baseApi.SearchContainer)
baRouter.POST("/search/log", baseApi.ContainerLogs) baRouter.POST("/search/log", baseApi.ContainerLogs)
baRouter.POST("/clean/log", baseApi.CleanContainerLog)
baRouter.POST("/inspect", baseApi.Inspect) baRouter.POST("/inspect", baseApi.Inspect)
baRouter.POST("/operate", baseApi.ContainerOperation) baRouter.POST("/operate", baseApi.ContainerOperation)

View file

@ -937,6 +937,48 @@ var doc = `{
} }
} }
}, },
"/containers/clean/log": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "清理容器日志",
"consumes": [
"application/json"
],
"tags": [
"Container"
],
"summary": "Clean container log",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithName"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"name"
],
"formatEN": "clean container [name] logs",
"formatZH": "清理容器 [name] 日志",
"paramKeys": []
}
}
},
"/containers/compose": { "/containers/compose": {
"post": { "post": {
"security": [ "security": [
@ -7750,6 +7792,25 @@ var doc = `{
} }
} }
}, },
"/settings/time/option": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "加载系统可用时区",
"tags": [
"System Setting"
],
"summary": "Load time zone options",
"responses": {
"200": {
"description": ""
}
}
}
},
"/settings/time/sync": { "/settings/time/sync": {
"post": { "post": {
"security": [ "security": [
@ -7758,10 +7819,24 @@ var doc = `{
} }
], ],
"description": "系统时间同步", "description": "系统时间同步",
"consumes": [
"application/json"
],
"tags": [ "tags": [
"System Setting" "System Setting"
], ],
"summary": "Sync system time", "summary": "Sync system time",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.SyncTimeZone"
}
}
],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK",
@ -7772,9 +7847,12 @@ var doc = `{
}, },
"x-panel-log": { "x-panel-log": {
"BeforeFuntions": [], "BeforeFuntions": [],
"bodyKeys": [], "bodyKeys": [
"formatEN": "sync system time", "ntpSite",
"formatZH": "系统时间同步", "timeZone"
],
"formatEN": "sync system time [ntpSite]-[timeZone]",
"formatZH": "系统时间同步[ntpSite]-[timeZone]",
"paramKeys": [] "paramKeys": []
} }
} }
@ -10689,6 +10767,12 @@ var doc = `{
"liveRestore": { "liveRestore": {
"type": "boolean" "type": "boolean"
}, },
"logMaxFile": {
"type": "string"
},
"logMaxSize": {
"type": "string"
},
"registryMirrors": { "registryMirrors": {
"type": "array", "type": "array",
"items": { "items": {
@ -10898,12 +10982,6 @@ var doc = `{
"restart", "restart",
"stop" "stop"
] ]
},
"stopService": {
"type": "boolean"
},
"stopSocket": {
"type": "boolean"
} }
} }
}, },
@ -11728,6 +11806,17 @@ var doc = `{
} }
} }
}, },
"dto.OperationWithName": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
}
}
},
"dto.PageContainer": { "dto.PageContainer": {
"type": "object", "type": "object",
"required": [ "required": [
@ -12292,12 +12381,18 @@ var doc = `{
"dto.SettingInfo": { "dto.SettingInfo": {
"type": "object", "type": "object",
"properties": { "properties": {
"allowIPs": {
"type": "string"
},
"appStoreLastModified": { "appStoreLastModified": {
"type": "string" "type": "string"
}, },
"appStoreVersion": { "appStoreVersion": {
"type": "string" "type": "string"
}, },
"bindDomain": {
"type": "string"
},
"complexityVerification": { "complexityVerification": {
"type": "string" "type": "string"
}, },
@ -12337,6 +12432,9 @@ var doc = `{
"monitorStoreDays": { "monitorStoreDays": {
"type": "string" "type": "string"
}, },
"ntpSite": {
"type": "string"
},
"panelName": { "panelName": {
"type": "string" "type": "string"
}, },
@ -12364,6 +12462,9 @@ var doc = `{
"theme": { "theme": {
"type": "string" "type": "string"
}, },
"timeZone": {
"type": "string"
},
"userName": { "userName": {
"type": "string" "type": "string"
}, },
@ -12444,6 +12545,17 @@ var doc = `{
} }
} }
}, },
"dto.SyncTimeZone": {
"type": "object",
"properties": {
"ntpSite": {
"type": "string"
},
"timeZone": {
"type": "string"
}
}
},
"dto.UpdateDescription": { "dto.UpdateDescription": {
"type": "object", "type": "object",
"required": [ "required": [
@ -12968,6 +13080,12 @@ var doc = `{
"cpuQuota": { "cpuQuota": {
"type": "number" "type": "number"
}, },
"dockerCompose": {
"type": "string"
},
"editCompose": {
"type": "boolean"
},
"memoryLimit": { "memoryLimit": {
"type": "number" "type": "number"
}, },
@ -13071,6 +13189,12 @@ var doc = `{
"cpuQuota": { "cpuQuota": {
"type": "number" "type": "number"
}, },
"dockerCompose": {
"type": "string"
},
"editCompose": {
"type": "boolean"
},
"installId": { "installId": {
"type": "integer" "type": "integer"
}, },
@ -13417,6 +13541,12 @@ var doc = `{
"cpuQuota": { "cpuQuota": {
"type": "number" "type": "number"
}, },
"dockerCompose": {
"type": "string"
},
"editCompose": {
"type": "boolean"
},
"memoryLimit": { "memoryLimit": {
"type": "number" "type": "number"
}, },
@ -14323,6 +14453,9 @@ var doc = `{
"id": { "id": {
"type": "integer" "type": "integer"
}, },
"installed": {
"type": "boolean"
},
"key": { "key": {
"type": "string" "type": "string"
}, },
@ -14388,6 +14521,9 @@ var doc = `{
"createdAt": { "createdAt": {
"type": "string" "type": "string"
}, },
"dockerCompose": {
"type": "string"
},
"downloadCallBackUrl": { "downloadCallBackUrl": {
"type": "string" "type": "string"
}, },

View file

@ -923,6 +923,48 @@
} }
} }
}, },
"/containers/clean/log": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "清理容器日志",
"consumes": [
"application/json"
],
"tags": [
"Container"
],
"summary": "Clean container log",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithName"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"name"
],
"formatEN": "clean container [name] logs",
"formatZH": "清理容器 [name] 日志",
"paramKeys": []
}
}
},
"/containers/compose": { "/containers/compose": {
"post": { "post": {
"security": [ "security": [
@ -7736,6 +7778,25 @@
} }
} }
}, },
"/settings/time/option": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "加载系统可用时区",
"tags": [
"System Setting"
],
"summary": "Load time zone options",
"responses": {
"200": {
"description": ""
}
}
}
},
"/settings/time/sync": { "/settings/time/sync": {
"post": { "post": {
"security": [ "security": [
@ -7744,10 +7805,24 @@
} }
], ],
"description": "系统时间同步", "description": "系统时间同步",
"consumes": [
"application/json"
],
"tags": [ "tags": [
"System Setting" "System Setting"
], ],
"summary": "Sync system time", "summary": "Sync system time",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.SyncTimeZone"
}
}
],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK",
@ -7758,9 +7833,12 @@
}, },
"x-panel-log": { "x-panel-log": {
"BeforeFuntions": [], "BeforeFuntions": [],
"bodyKeys": [], "bodyKeys": [
"formatEN": "sync system time", "ntpSite",
"formatZH": "系统时间同步", "timeZone"
],
"formatEN": "sync system time [ntpSite]-[timeZone]",
"formatZH": "系统时间同步[ntpSite]-[timeZone]",
"paramKeys": [] "paramKeys": []
} }
} }
@ -10675,6 +10753,12 @@
"liveRestore": { "liveRestore": {
"type": "boolean" "type": "boolean"
}, },
"logMaxFile": {
"type": "string"
},
"logMaxSize": {
"type": "string"
},
"registryMirrors": { "registryMirrors": {
"type": "array", "type": "array",
"items": { "items": {
@ -10884,12 +10968,6 @@
"restart", "restart",
"stop" "stop"
] ]
},
"stopService": {
"type": "boolean"
},
"stopSocket": {
"type": "boolean"
} }
} }
}, },
@ -11714,6 +11792,17 @@
} }
} }
}, },
"dto.OperationWithName": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
}
}
},
"dto.PageContainer": { "dto.PageContainer": {
"type": "object", "type": "object",
"required": [ "required": [
@ -12278,12 +12367,18 @@
"dto.SettingInfo": { "dto.SettingInfo": {
"type": "object", "type": "object",
"properties": { "properties": {
"allowIPs": {
"type": "string"
},
"appStoreLastModified": { "appStoreLastModified": {
"type": "string" "type": "string"
}, },
"appStoreVersion": { "appStoreVersion": {
"type": "string" "type": "string"
}, },
"bindDomain": {
"type": "string"
},
"complexityVerification": { "complexityVerification": {
"type": "string" "type": "string"
}, },
@ -12323,6 +12418,9 @@
"monitorStoreDays": { "monitorStoreDays": {
"type": "string" "type": "string"
}, },
"ntpSite": {
"type": "string"
},
"panelName": { "panelName": {
"type": "string" "type": "string"
}, },
@ -12350,6 +12448,9 @@
"theme": { "theme": {
"type": "string" "type": "string"
}, },
"timeZone": {
"type": "string"
},
"userName": { "userName": {
"type": "string" "type": "string"
}, },
@ -12430,6 +12531,17 @@
} }
} }
}, },
"dto.SyncTimeZone": {
"type": "object",
"properties": {
"ntpSite": {
"type": "string"
},
"timeZone": {
"type": "string"
}
}
},
"dto.UpdateDescription": { "dto.UpdateDescription": {
"type": "object", "type": "object",
"required": [ "required": [
@ -12954,6 +13066,12 @@
"cpuQuota": { "cpuQuota": {
"type": "number" "type": "number"
}, },
"dockerCompose": {
"type": "string"
},
"editCompose": {
"type": "boolean"
},
"memoryLimit": { "memoryLimit": {
"type": "number" "type": "number"
}, },
@ -13057,6 +13175,12 @@
"cpuQuota": { "cpuQuota": {
"type": "number" "type": "number"
}, },
"dockerCompose": {
"type": "string"
},
"editCompose": {
"type": "boolean"
},
"installId": { "installId": {
"type": "integer" "type": "integer"
}, },
@ -13403,6 +13527,12 @@
"cpuQuota": { "cpuQuota": {
"type": "number" "type": "number"
}, },
"dockerCompose": {
"type": "string"
},
"editCompose": {
"type": "boolean"
},
"memoryLimit": { "memoryLimit": {
"type": "number" "type": "number"
}, },
@ -14309,6 +14439,9 @@
"id": { "id": {
"type": "integer" "type": "integer"
}, },
"installed": {
"type": "boolean"
},
"key": { "key": {
"type": "string" "type": "string"
}, },
@ -14374,6 +14507,9 @@
"createdAt": { "createdAt": {
"type": "string" "type": "string"
}, },
"dockerCompose": {
"type": "string"
},
"downloadCallBackUrl": { "downloadCallBackUrl": {
"type": "string" "type": "string"
}, },

View file

@ -485,6 +485,10 @@ definitions:
type: boolean type: boolean
liveRestore: liveRestore:
type: boolean type: boolean
logMaxFile:
type: string
logMaxSize:
type: string
registryMirrors: registryMirrors:
items: items:
type: string type: string
@ -622,10 +626,6 @@ definitions:
- restart - restart
- stop - stop
type: string type: string
stopService:
type: boolean
stopSocket:
type: boolean
required: required:
- operation - operation
type: object type: object
@ -1180,6 +1180,13 @@ definitions:
required: required:
- id - id
type: object type: object
dto.OperationWithName:
properties:
name:
type: string
required:
- name
type: object
dto.PageContainer: dto.PageContainer:
properties: properties:
filters: filters:
@ -1556,10 +1563,14 @@ definitions:
type: object type: object
dto.SettingInfo: dto.SettingInfo:
properties: properties:
allowIPs:
type: string
appStoreLastModified: appStoreLastModified:
type: string type: string
appStoreVersion: appStoreVersion:
type: string type: string
bindDomain:
type: string
complexityVerification: complexityVerification:
type: string type: string
dingVars: dingVars:
@ -1586,6 +1597,8 @@ definitions:
type: string type: string
monitorStoreDays: monitorStoreDays:
type: string type: string
ntpSite:
type: string
panelName: panelName:
type: string type: string
port: port:
@ -1604,6 +1617,8 @@ definitions:
type: string type: string
theme: theme:
type: string type: string
timeZone:
type: string
userName: userName:
type: string type: string
weChatVars: weChatVars:
@ -1658,6 +1673,13 @@ definitions:
required: required:
- id - id
type: object type: object
dto.SyncTimeZone:
properties:
ntpSite:
type: string
timeZone:
type: string
type: object
dto.UpdateDescription: dto.UpdateDescription:
properties: properties:
description: description:
@ -2000,6 +2022,10 @@ definitions:
type: string type: string
cpuQuota: cpuQuota:
type: number type: number
dockerCompose:
type: string
editCompose:
type: boolean
memoryLimit: memoryLimit:
type: number type: number
memoryUnit: memoryUnit:
@ -2069,6 +2095,10 @@ definitions:
type: string type: string
cpuQuota: cpuQuota:
type: number type: number
dockerCompose:
type: string
editCompose:
type: boolean
installId: installId:
type: integer type: integer
memoryLimit: memoryLimit:
@ -2304,6 +2334,10 @@ definitions:
type: string type: string
cpuQuota: cpuQuota:
type: number type: number
dockerCompose:
type: string
editCompose:
type: boolean
memoryLimit: memoryLimit:
type: number type: number
memoryUnit: memoryUnit:
@ -2915,6 +2949,8 @@ definitions:
type: string type: string
id: id:
type: integer type: integer
installed:
type: boolean
key: key:
type: string type: string
lastModified: lastModified:
@ -2958,6 +2994,8 @@ definitions:
type: integer type: integer
createdAt: createdAt:
type: string type: string
dockerCompose:
type: string
downloadCallBackUrl: downloadCallBackUrl:
type: string type: string
downloadUrl: downloadUrl:
@ -3809,6 +3847,33 @@ paths:
formatEN: create container [name][image] formatEN: create container [name][image]
formatZH: 创建容器 [name][image] formatZH: 创建容器 [name][image]
paramKeys: [] paramKeys: []
/containers/clean/log:
post:
consumes:
- application/json
description: 清理容器日志
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.OperationWithName'
responses:
"200":
description: ""
security:
- ApiKeyAuth: []
summary: Clean container log
tags:
- Container
x-panel-log:
BeforeFuntions: []
bodyKeys:
- name
formatEN: clean container [name] logs
formatZH: 清理容器 [name] 日志
paramKeys: []
/containers/compose: /containers/compose:
post: post:
consumes: consumes:
@ -8139,9 +8204,29 @@ paths:
formatEN: update system ssl => [ssl] formatEN: update system ssl => [ssl]
formatZH: 修改系统 ssl => [ssl] formatZH: 修改系统 ssl => [ssl]
paramKeys: [] paramKeys: []
/settings/time/option:
get:
description: 加载系统可用时区
responses:
"200":
description: ""
security:
- ApiKeyAuth: []
summary: Load time zone options
tags:
- System Setting
/settings/time/sync: /settings/time/sync:
post: post:
consumes:
- application/json
description: 系统时间同步 description: 系统时间同步
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.SyncTimeZone'
responses: responses:
"200": "200":
description: OK description: OK
@ -8154,9 +8239,11 @@ paths:
- System Setting - System Setting
x-panel-log: x-panel-log:
BeforeFuntions: [] BeforeFuntions: []
bodyKeys: [] bodyKeys:
formatEN: sync system time - ntpSite
formatZH: 系统时间同步 - timeZone
formatEN: sync system time [ntpSite]-[timeZone]
formatZH: 系统时间同步[ntpSite]-[timeZone]
paramKeys: [] paramKeys: []
/settings/update: /settings/update:
post: post:

View file

@ -11,6 +11,9 @@ export const createContainer = (params: Container.ContainerCreate) => {
export const logContainer = (params: Container.ContainerLogSearch) => { export const logContainer = (params: Container.ContainerLogSearch) => {
return http.post<string>(`/containers/search/log`, params, 400000); return http.post<string>(`/containers/search/log`, params, 400000);
}; };
export const cleanContainerLog = (containerName: string) => {
return http.post(`/containers/clean/log`, { name: containerName });
};
export const ContainerStats = (id: string) => { export const ContainerStats = (id: string) => {
return http.get<Container.ContainerStats>(`/containers/stats/${id}`); return http.get<Container.ContainerStats>(`/containers/stats/${id}`);
}; };

View file

@ -4,12 +4,15 @@
<el-select @change="searchLogs" style="width: 10%; float: left" v-model="logSearch.mode"> <el-select @change="searchLogs" style="width: 10%; float: left" v-model="logSearch.mode">
<el-option v-for="item in timeOptions" :key="item.label" :value="item.value" :label="item.label" /> <el-option v-for="item in timeOptions" :key="item.label" :value="item.value" :label="item.label" />
</el-select> </el-select>
<div style="margin-left: 20px; float: left"> <div class="margin-button" style="float: left">
<el-checkbox border v-model="logSearch.isWatch">{{ $t('commons.button.watch') }}</el-checkbox> <el-checkbox border v-model="logSearch.isWatch">{{ $t('commons.button.watch') }}</el-checkbox>
</div> </div>
<el-button style="margin-left: 20px" @click="onDownload" icon="Download"> <el-button class="margin-button" @click="onDownload" icon="Download">
{{ $t('file.download') }} {{ $t('file.download') }}
</el-button> </el-button>
<el-button class="margin-button" @click="onClean" icon="Delete">
{{ $t('commons.button.clean') }}
</el-button>
</div> </div>
<codemirror <codemirror
@ -31,13 +34,14 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { logContainer } from '@/api/modules/container'; import { cleanContainerLog, logContainer } from '@/api/modules/container';
import i18n from '@/lang'; import i18n from '@/lang';
import { dateFormatForName } from '@/utils/util'; import { dateFormatForName } from '@/utils/util';
import { nextTick, onBeforeUnmount, reactive, ref, shallowRef } from 'vue'; import { nextTick, onBeforeUnmount, reactive, ref, shallowRef } from 'vue';
import { Codemirror } from 'vue-codemirror'; import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark'; import { oneDark } from '@codemirror/theme-one-dark';
import { MsgSuccess } from '@/utils/message';
const extensions = [javascript(), oneDark]; const extensions = [javascript(), oneDark];
@ -115,6 +119,18 @@ const acceptParams = (props: DialogProps): void => {
}, 1000 * 5); }, 1000 * 5);
}; };
const onClean = async () => {
ElMessageBox.confirm(i18n.global.t('commons.msg.clean'), i18n.global.t('container.cleanLog'), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(async () => {
await cleanContainerLog(logSearch.container);
searchLogs();
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
});
};
onBeforeUnmount(() => { onBeforeUnmount(() => {
clearInterval(Number(timer)); clearInterval(Number(timer));
timer = null; timer = null;
@ -124,3 +140,9 @@ defineExpose({
acceptParams, acceptParams,
}); });
</script> </script>
<style scoped lang="scss">
.margin-button {
margin-left: 20px;
}
</style>

View file

@ -444,6 +444,7 @@ const message = {
last4Hour: 'Last 4 Hours', last4Hour: 'Last 4 Hours',
lastHour: 'Last Hour', lastHour: 'Last Hour',
last10Min: 'Last 10 Minutes', last10Min: 'Last 10 Minutes',
cleanLog: 'Clean log',
newName: 'New name', newName: 'New name',
source: 'Resource rate', source: 'Resource rate',

View file

@ -463,6 +463,7 @@ const message = {
last4Hour: '最近 4 小时', last4Hour: '最近 4 小时',
lastHour: '最近 1 小时', lastHour: '最近 1 小时',
last10Min: '最近 10 分钟', last10Min: '最近 10 分钟',
cleanLog: '清空日志',
newName: '新名称', newName: '新名称',
source: '资源使用率', source: '资源使用率',

View file

@ -8,12 +8,15 @@
<el-select @change="searchLogs" style="width: 30%; float: left" v-model="logSearch.mode"> <el-select @change="searchLogs" style="width: 30%; float: left" v-model="logSearch.mode">
<el-option v-for="item in timeOptions" :key="item.label" :value="item.value" :label="item.label" /> <el-option v-for="item in timeOptions" :key="item.label" :value="item.value" :label="item.label" />
</el-select> </el-select>
<div style="margin-left: 20px; float: left"> <div class="margin-button" style="float: left">
<el-checkbox border v-model="logSearch.isWatch">{{ $t('commons.button.watch') }}</el-checkbox> <el-checkbox border v-model="logSearch.isWatch">{{ $t('commons.button.watch') }}</el-checkbox>
</div> </div>
<el-button style="margin-left: 20px" @click="onDownload" icon="Download"> <el-button class="margin-button" @click="onDownload" icon="Download">
{{ $t('file.download') }} {{ $t('file.download') }}
</el-button> </el-button>
<el-button class="margin-button" @click="onClean" icon="Delete">
{{ $t('commons.button.clean') }}
</el-button>
</div> </div>
<codemirror <codemirror
@ -41,7 +44,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { logContainer } from '@/api/modules/container'; import { cleanContainerLog, logContainer } from '@/api/modules/container';
import i18n from '@/lang'; import i18n from '@/lang';
import { dateFormatForName } from '@/utils/util'; import { dateFormatForName } from '@/utils/util';
import { nextTick, onBeforeUnmount, reactive, ref, shallowRef } from 'vue'; import { nextTick, onBeforeUnmount, reactive, ref, shallowRef } from 'vue';
@ -49,6 +52,8 @@ import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark'; import { oneDark } from '@codemirror/theme-one-dark';
import DrawerHeader from '@/components/drawer-header/index.vue'; import DrawerHeader from '@/components/drawer-header/index.vue';
import { ElMessageBox } from 'element-plus';
import { MsgSuccess } from '@/utils/message';
const extensions = [javascript(), oneDark]; const extensions = [javascript(), oneDark];
@ -116,6 +121,18 @@ const onDownload = async () => {
a.dispatchEvent(event); a.dispatchEvent(event);
}; };
const onClean = async () => {
ElMessageBox.confirm(i18n.global.t('commons.msg.clean'), i18n.global.t('container.cleanLog'), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(async () => {
await cleanContainerLog(logSearch.container);
searchLogs();
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
});
};
interface DialogProps { interface DialogProps {
container: string; container: string;
containerID: string; containerID: string;
@ -144,3 +161,9 @@ defineExpose({
acceptParams, acceptParams,
}); });
</script> </script>
<style scoped lang="scss">
.margin-button {
margin-left: 20px;
}
</style>