Skip to content

Commit

Permalink
fix: fixes merged view and incorrect base. fixes #3248 (#3249)
Browse files Browse the repository at this point in the history
  • Loading branch information
amir20 authored Sep 3, 2024
1 parent 42e423f commit 2a3af94
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 39 deletions.
5 changes: 2 additions & 3 deletions assets/components/HostMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@

<router-link
:to="{
name: '/merged/[name]',
query: { id: containers.map(({ id }) => id) },
params: { name: label.replace('label.', '') },
name: '/merged/[ids]',
params: { ids: containers.map(({ id }) => id).join(',') },
}"
class="btn btn-square btn-outline btn-primary btn-xs"
active-class="btn-active"
Expand Down
6 changes: 4 additions & 2 deletions assets/components/MultiContainerViewer/MultiContainerLog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</div>
</div>
<MultiContainerStat class="ml-auto" :containers="containers" />
<MultiContainerActionToolbar class="mobile-hidden" @clear="viewer?.clear()" />
</div>
</template>
<template #default>
Expand All @@ -24,16 +25,17 @@
<script lang="ts" setup>
import ViewerWithSource from "@/components/LogViewer/ViewerWithSource.vue";
import { ComponentExposed } from "vue-component-type-helpers";
const { ids = [], scrollable = false } = defineProps<{
ids?: string[];
scrollable?: boolean;
}>();
const containerStore = useContainerStore();
const viewer = ref<ComponentExposed<typeof ViewerWithSource>>();
const { allContainersById, ready } = storeToRefs(containerStore);
const containers = computed(() => ids.map((id) => allContainersById.value[id]));
provideLoggingContext(containers);
</script>
33 changes: 8 additions & 25 deletions assets/composable/eventStreams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,47 +20,30 @@ function parseMessage(data: string): LogEntry<string | JSONObject> {
}

export function useContainerStream(container: Ref<Container>): LogStreamSource {
const url = computed(() =>
withBase(`/api/hosts/${container.value.host}/containers/${container.value.id}/logs/stream`),
);

const loadMoreUrl = computed(() =>
withBase(`/api/hosts/${container.value.host}/containers/${container.value.id}/logs`),
);

const url = computed(() => `/api/hosts/${container.value.host}/containers/${container.value.id}/logs/stream`);
const loadMoreUrl = computed(() => `/api/hosts/${container.value.host}/containers/${container.value.id}/logs`);
return useLogStream(url, loadMoreUrl);
}

export function useStackStream(stack: Ref<Stack>): LogStreamSource {
const url = computed(() => withBase(`/api/stacks/${stack.value.name}/logs/stream`));
return useLogStream(url);
return useLogStream(computed(() => `/api/stacks/${stack.value.name}/logs/stream`));
}

export function useGroupedStream(group: Ref<GroupedContainers>): LogStreamSource {
const url = computed(() => withBase(`/api/groups/${group.value.name}/logs/stream`));
return useLogStream(url);
return useLogStream(computed(() => `/api/groups/${group.value.name}/logs/stream`));
}

export function useMergedStream(containers: Ref<Container[]>): LogStreamSource {
const url = computed(() => {
const ids = containers.value.map((c) => ["id", c.id]).join(",");
return withBase(`/api/hosts/${containers.value[0].host}/logs/mergedStream/${ids}`);
const ids = containers.value.map((c) => c.id).join(",");
return `/api/hosts/${containers.value[0].host}/logs/mergedStream/${ids}`;
});

return useLogStream(url);
}

export function useServiceStream(service: Ref<Service>): LogStreamSource {
const { streamConfig } = useLoggingContext();

const url = computed(() => {
const params = Object.entries(toValue(streamConfig))
.filter(([, value]) => value)
.reduce((acc, [key]) => ({ ...acc, [key]: "1" }), {});
return withBase(`/api/services/${service.value.name}/logs/stream?${new URLSearchParams(params).toString()}`);
});

return useLogStream(url);
return useLogStream(computed(() => `/api/services/${service.value.name}/logs/stream`));
}

export type LogStreamSource = ReturnType<typeof useLogStream>;
Expand Down Expand Up @@ -187,7 +170,7 @@ function useLogStream(url: Ref<string>, loadMoreUrl?: Ref<string>) {
const stopWatcher = watchOnce(url, () => abortController.abort("stream changed"));
const moreParams = { ...params.value, from: from.toISOString(), to: to.toISOString(), fill: "1" };
const logs = await (
await fetch(`${loadMoreUrl.value}?${new URLSearchParams(moreParams).toString()}`, { signal })
await fetch(withBase(`${loadMoreUrl.value}?${new URLSearchParams(moreParams).toString()}`), { signal })
).text();
stopWatcher();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
const containerStore = useContainerStore();
const { ready } = storeToRefs(containerStore);
const route = useRoute("/merged/[name]");
const route = useRoute("/merged/[ids]");
const pinnedLogsStore = usePinnedLogsStore();
const { pinnedLogs } = storeToRefs(pinnedLogsStore);
const ids = toRef(() => route.query.id as string[]);
const ids = toRef(() => route.params.ids.split(","));
watchEffect(() => {
if (ready.value) {
Expand Down
2 changes: 1 addition & 1 deletion assets/typed-router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ declare module 'vue-router/auto-routes' {
'/container/[id]': RouteRecordInfo<'/container/[id]', '/container/:id', { id: ParamValue<true> }, { id: ParamValue<false> }>,
'/group/[name]': RouteRecordInfo<'/group/[name]', '/group/:name', { name: ParamValue<true> }, { name: ParamValue<false> }>,
'/login': RouteRecordInfo<'/login', '/login', Record<never, never>, Record<never, never>>,
'/merged/[name]': RouteRecordInfo<'/merged/[name]', '/merged/:name', { name: ParamValue<true> }, { name: ParamValue<false> }>,
'/merged/[ids]': RouteRecordInfo<'/merged/[ids]', '/merged/:ids', { ids: ParamValue<true> }, { ids: ParamValue<false> }>,
'/service/[name]': RouteRecordInfo<'/service/[name]', '/service/:name', { name: ParamValue<true> }, { name: ParamValue<false> }>,
'/settings': RouteRecordInfo<'/settings', '/settings', Record<never, never>, Record<never, never>>,
'/show': RouteRecordInfo<'/show', '/show', Record<never, never>, Record<never, never>>,
Expand Down
7 changes: 2 additions & 5 deletions internal/web/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,10 @@ func (h *handler) streamContainerLogs(w http.ResponseWriter, r *http.Request) {
}

func (h *handler) streamLogsMerged(w http.ResponseWriter, r *http.Request) {
if !r.URL.Query().Has("id") {
http.Error(w, "ids query parameter is required", http.StatusBadRequest)
return
}
idsSplit := strings.Split(chi.URLParam(r, "ids"), ",")

ids := make(map[string]bool)
for _, id := range r.URL.Query()["id"] {
for _, id := range idsSplit {
ids[id] = true
}

Expand Down
2 changes: 1 addition & 1 deletion internal/web/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func createRouter(h *handler) *chi.Mux {
r.Get("/api/hosts/{host}/containers/{id}/logs/stream", h.streamContainerLogs)
r.Get("/api/hosts/{host}/containers/{id}/logs/download", h.downloadLogs)
r.Get("/api/hosts/{host}/containers/{id}/logs", h.fetchLogsBetweenDates)
r.Get("/api/hosts/{host}/logs/mergedStream", h.streamLogsMerged)
r.Get("/api/hosts/{host}/logs/mergedStream/{ids}", h.streamLogsMerged)
r.Get("/api/stacks/{stack}/logs/stream", h.streamStackLogs)
r.Get("/api/services/{service}/logs/stream", h.streamServiceLogs)
r.Get("/api/groups/{group}/logs/stream", h.streamGroupedLogs)
Expand Down

0 comments on commit 2a3af94

Please sign in to comment.