mirror of
https://github.com/cuigh/swirl
synced 2024-12-28 14:51:57 +00:00
Implement event pruning
This commit is contained in:
parent
e70d907c06
commit
d0eb101aee
@ -2,7 +2,6 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/cuigh/auxo/data"
|
"github.com/cuigh/auxo/data"
|
||||||
"github.com/cuigh/auxo/errors"
|
|
||||||
"github.com/cuigh/auxo/net/web"
|
"github.com/cuigh/auxo/net/web"
|
||||||
"github.com/cuigh/swirl/biz"
|
"github.com/cuigh/swirl/biz"
|
||||||
"github.com/cuigh/swirl/dao"
|
"github.com/cuigh/swirl/dao"
|
||||||
@ -47,15 +46,13 @@ func eventSearch(b biz.EventBiz) web.HandlerFunc {
|
|||||||
|
|
||||||
func eventPrune(b biz.EventBiz) web.HandlerFunc {
|
func eventPrune(b biz.EventBiz) web.HandlerFunc {
|
||||||
type Args struct {
|
type Args struct {
|
||||||
Date string `json:"date"`
|
Days int32 `json:"days"`
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(ctx web.Context) (err error) {
|
return func(ctx web.Context) (err error) {
|
||||||
var args = &Args{}
|
var args = &Args{}
|
||||||
if err = ctx.Bind(args); err == nil {
|
if err = ctx.Bind(args); err == nil {
|
||||||
// TODO
|
err = b.Prune(args.Days)
|
||||||
//err = b.Prune(args.Date)
|
|
||||||
err = errors.NotImplemented
|
|
||||||
}
|
}
|
||||||
return ajax(ctx, err)
|
return ajax(ctx, err)
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@ package biz
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/cuigh/auxo/data"
|
"github.com/cuigh/auxo/data"
|
||||||
|
"github.com/cuigh/auxo/ext/times"
|
||||||
"github.com/cuigh/auxo/log"
|
"github.com/cuigh/auxo/log"
|
||||||
"github.com/cuigh/auxo/net/web"
|
"github.com/cuigh/auxo/net/web"
|
||||||
"github.com/cuigh/swirl/dao"
|
"github.com/cuigh/swirl/dao"
|
||||||
@ -47,6 +49,7 @@ const (
|
|||||||
|
|
||||||
type EventBiz interface {
|
type EventBiz interface {
|
||||||
Search(args *dao.EventSearchArgs) (events []*dao.Event, total int, err error)
|
Search(args *dao.EventSearchArgs) (events []*dao.Event, total int, err error)
|
||||||
|
Prune(days int32) (err error)
|
||||||
CreateRegistry(action EventAction, id, name string, user web.User)
|
CreateRegistry(action EventAction, id, name string, user web.User)
|
||||||
CreateNode(action EventAction, id, name string, user web.User)
|
CreateNode(action EventAction, id, name string, user web.User)
|
||||||
CreateNetwork(action EventAction, id, name string, user web.User)
|
CreateNetwork(action EventAction, id, name string, user web.User)
|
||||||
@ -75,6 +78,10 @@ func (b *eventBiz) Search(args *dao.EventSearchArgs) (events []*dao.Event, total
|
|||||||
return b.d.EventSearch(context.TODO(), args)
|
return b.d.EventSearch(context.TODO(), args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *eventBiz) Prune(days int32) (err error) {
|
||||||
|
return b.d.EventPrune(context.TODO(), time.Now().Add(-times.Days(days)))
|
||||||
|
}
|
||||||
|
|
||||||
func (b *eventBiz) create(et EventType, ea EventAction, args data.Map, user web.User) {
|
func (b *eventBiz) create(et EventType, ea EventAction, args data.Map, user web.User) {
|
||||||
event := &dao.Event{
|
event := &dao.Event{
|
||||||
ID: primitive.NewObjectID(),
|
ID: primitive.NewObjectID(),
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/boltdb/bolt"
|
||||||
"github.com/cuigh/auxo/util/cast"
|
"github.com/cuigh/auxo/util/cast"
|
||||||
"github.com/cuigh/swirl/dao"
|
"github.com/cuigh/swirl/dao"
|
||||||
"github.com/cuigh/swirl/misc"
|
"github.com/cuigh/swirl/misc"
|
||||||
@ -47,3 +48,16 @@ func (d *Dao) EventSearch(ctx context.Context, args *dao.EventSearchArgs) (event
|
|||||||
func (d *Dao) EventCreate(ctx context.Context, event *dao.Event) (err error) {
|
func (d *Dao) EventCreate(ctx context.Context, event *dao.Event) (err error) {
|
||||||
return d.replace(Event, event.ID.Hex(), event)
|
return d.replace(Event, event.ID.Hex(), event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Dao) EventPrune(ctx context.Context, end time.Time) (err error) {
|
||||||
|
return d.db.Update(func(tx *bolt.Tx) (err error) {
|
||||||
|
b := tx.Bucket([]byte(Event))
|
||||||
|
return b.ForEach(func(k, v []byte) error {
|
||||||
|
event := &dao.Event{}
|
||||||
|
if err = decode(v, event); err == nil && time.Time(event.Time).Before(end) {
|
||||||
|
err = b.Delete(k)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -61,6 +61,7 @@ type Interface interface {
|
|||||||
|
|
||||||
EventSearch(ctx context.Context, args *EventSearchArgs) (events []*Event, count int, err error)
|
EventSearch(ctx context.Context, args *EventSearchArgs) (events []*Event, count int, err error)
|
||||||
EventCreate(ctx context.Context, event *Event) error
|
EventCreate(ctx context.Context, event *Event) error
|
||||||
|
EventPrune(ctx context.Context, end time.Time) (err error)
|
||||||
|
|
||||||
SettingGet(ctx context.Context, id string) (*Setting, error)
|
SettingGet(ctx context.Context, id string) (*Setting, error)
|
||||||
SettingGetAll(ctx context.Context) (settings []*Setting, err error)
|
SettingGetAll(ctx context.Context) (settings []*Setting, err error)
|
||||||
|
@ -2,6 +2,7 @@ package mongo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/cuigh/swirl/dao"
|
"github.com/cuigh/swirl/dao"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
@ -26,3 +27,9 @@ func (d *Dao) EventSearch(ctx context.Context, args *dao.EventSearchArgs) (event
|
|||||||
func (d *Dao) EventCreate(ctx context.Context, event *dao.Event) (err error) {
|
func (d *Dao) EventCreate(ctx context.Context, event *dao.Event) (err error) {
|
||||||
return d.create(ctx, Event, event)
|
return d.create(ctx, Event, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Dao) EventPrune(ctx context.Context, end time.Time) (err error) {
|
||||||
|
filter := bson.M{"time": bson.M{"$lt": end}}
|
||||||
|
_, err = d.db.Collection(Event).DeleteMany(ctx, filter)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -28,6 +28,10 @@ export class EventApi {
|
|||||||
search(args: SearchArgs) {
|
search(args: SearchArgs) {
|
||||||
return ajax.get<SearchResult>('/event/search', args)
|
return ajax.get<SearchResult>('/event/search', args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prune(days: number) {
|
||||||
|
return ajax.post<Result<Object>>('/event/prune', { days })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new EventApi
|
export default new EventApi
|
||||||
|
@ -247,6 +247,10 @@ export default {
|
|||||||
"title": "Prune volume",
|
"title": "Prune volume",
|
||||||
"body": "Are you sure you want to clean up unused data volumes?",
|
"body": "Are you sure you want to clean up unused data volumes?",
|
||||||
},
|
},
|
||||||
|
"prune_event": {
|
||||||
|
"title": "Prune event",
|
||||||
|
"label": "Retention days",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"objects": {
|
"objects": {
|
||||||
"registry": "Registry | Registries",
|
"registry": "Registry | Registries",
|
||||||
|
@ -247,6 +247,10 @@ export default {
|
|||||||
"title": "清理数据卷",
|
"title": "清理数据卷",
|
||||||
"body": "是否确实要清理未使用的数据卷?",
|
"body": "是否确实要清理未使用的数据卷?",
|
||||||
},
|
},
|
||||||
|
"prune_event": {
|
||||||
|
"title": "清理事件",
|
||||||
|
"label": "保留天数",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"objects": {
|
"objects": {
|
||||||
"registry": "镜像仓库",
|
"registry": "镜像仓库",
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive } from "vue";
|
import { h, reactive, ref } from "vue";
|
||||||
import {
|
import {
|
||||||
NSpace,
|
NSpace,
|
||||||
NButton,
|
NButton,
|
||||||
@ -53,6 +53,8 @@ import {
|
|||||||
NSelect,
|
NSelect,
|
||||||
NInput,
|
NInput,
|
||||||
NIcon,
|
NIcon,
|
||||||
|
NFormItem,
|
||||||
|
NInputNumber,
|
||||||
} from "naive-ui";
|
} from "naive-ui";
|
||||||
import { CloseOutline as CloseIcon } from "@vicons/ionicons5";
|
import { CloseOutline as CloseIcon } from "@vicons/ionicons5";
|
||||||
import XPageHeader from "@/components/PageHeader.vue";
|
import XPageHeader from "@/components/PageHeader.vue";
|
||||||
@ -61,7 +63,6 @@ import type { Event } from "@/api/event";
|
|||||||
import { useDataTable } from "@/utils/data-table";
|
import { useDataTable } from "@/utils/data-table";
|
||||||
import { renderLink, renderTag, renderTime } from "@/utils/render";
|
import { renderLink, renderTag, renderTime } from "@/utils/render";
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import type { RouteLocationRaw } from "vue-router";
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const filter = reactive({
|
const filter = reactive({
|
||||||
@ -225,6 +226,21 @@ function renderObject(e: Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function prune() {
|
function prune() {
|
||||||
window.message.info("TODO...")
|
const days = ref(7) as any
|
||||||
|
window.dialog.warning({
|
||||||
|
title: t('dialogs.prune_event.title'),
|
||||||
|
content: () => h(
|
||||||
|
NFormItem,
|
||||||
|
{ label: t('dialogs.prune_event.label'), labelPlacement: 'top', showFeedback: false },
|
||||||
|
{ default: () => h(NInputNumber, { min: 0, defaultValue: days, style: 'width: 100%' }) }
|
||||||
|
),
|
||||||
|
positiveText: t('buttons.confirm'),
|
||||||
|
negativeText: t('buttons.cancel'),
|
||||||
|
onPositiveClick: async () => {
|
||||||
|
eventApi.prune(days.value);
|
||||||
|
window.message.success(t('texts.action_success'))
|
||||||
|
fetchData()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
Loading…
Reference in New Issue
Block a user