Skip to content

Commit

Permalink
feat: downloads visible streams only instead of all (#2924)
Browse files Browse the repository at this point in the history
  • Loading branch information
amir20 committed Apr 30, 2024
1 parent 448341c commit cc8e715
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
18 changes: 14 additions & 4 deletions assets/components/LogViewer/LogActionsToolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
</a>
</li>
<li>
<a :href="`${base}/api/hosts/${container.host}/containers/${container.id}/logs/download`" download>
<octicon:download-24 /> {{ $t("toolbar.download") }}
</a>
<a :href="downloadUrl" download> <octicon:download-24 /> {{ $t("toolbar.download") }} </a>
</li>
<li>
<a @click.prevent="showSearch = true">
Expand Down Expand Up @@ -104,7 +102,7 @@

<script lang="ts" setup>
const { showSearch } = useSearchFilter();
const { base, enableActions } = config;
const { enableActions } = config;
const clear = defineEmit();
Expand All @@ -113,6 +111,18 @@ const { container, streamConfig } = useContainerContext();
// container context is provided in the parent component: <LogContainer>
const { actionStates, start, stop, restart } = useContainerActions();
const downloadParams = computed(() =>
Object.entries(streamConfig)
.filter(([, value]) => value)
.reduce((acc, [key]) => ({ ...acc, [key]: "1" }), {}),
);
const downloadUrl = computed(() =>
withBase(
`/api/hosts/${container.value.host}/containers/${container.value.id}/logs/download?${new URLSearchParams(downloadParams.value).toString()}`,
),
);
const disableRestart = computed(() => {
return actionStates.stop || actionStates.start || actionStates.restart;
});
Expand Down
4 changes: 2 additions & 2 deletions internal/web/download_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ import (

func Test_handler_download_logs(t *testing.T) {
id := "123456"
req, err := http.NewRequest("GET", "/api/hosts/localhost/containers/"+id+"/logs/download", nil)
req, err := http.NewRequest("GET", "/api/hosts/localhost/containers/"+id+"/logs/download?stdout=1", nil)
require.NoError(t, err, "NewRequest should not return an error.")

mockedClient := new(MockedClient)

data := makeMessage("INFO Testing logs...", docker.STDOUT)

mockedClient.On("FindContainer", id).Return(docker.Container{ID: id, Tty: false}, nil)
mockedClient.On("ContainerLogsBetweenDates", mock.Anything, id, mock.Anything, mock.Anything, docker.STDALL).Return(io.NopCloser(bytes.NewReader(data)), nil)
mockedClient.On("ContainerLogsBetweenDates", mock.Anything, id, mock.Anything, mock.Anything, docker.STDOUT).Return(io.NopCloser(bytes.NewReader(data)), nil)

handler := createDefaultHandler(mockedClient)
rr := httptest.NewRecorder()
Expand Down
15 changes: 14 additions & 1 deletion internal/web/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,26 @@ func (h *handler) downloadLogs(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/gzip")
}

var stdTypes docker.StdType
if r.URL.Query().Has("stdout") {
stdTypes |= docker.STDOUT
}
if r.URL.Query().Has("stderr") {
stdTypes |= docker.STDERR
}

if stdTypes == 0 {
http.Error(w, "stdout or stderr is required", http.StatusBadRequest)
return
}

zw := gzip.NewWriter(w)
defer zw.Close()
zw.Name = fmt.Sprintf("%s-%s.log", container.Name, nowFmt)
zw.Comment = "Logs generated by Dozzle"
zw.ModTime = now

reader, err := h.clientFromRequest(r).ContainerLogsBetweenDates(r.Context(), id, time.Time{}, now, docker.STDALL)
reader, err := h.clientFromRequest(r).ContainerLogsBetweenDates(r.Context(), id, time.Time{}, now, stdTypes)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
Expand Down

0 comments on commit cc8e715

Please sign in to comment.