* [pve-devel] [PATCH mini-journalreader/http-server/manager] optimize journal api cal @ 2021-11-24 14:47 Dominik Csapak 2021-11-24 14:47 ` [pve-devel] [PATCH mini-journalreader 1/1] add '-j' flag to output json Dominik Csapak ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Dominik Csapak @ 2021-11-24 14:47 UTC (permalink / raw) To: pve-devel this series changes the 'journal' api call to stream the journal to the client, which reduces the memory footprint of the worker processes for very big logs, the web ui may struggle (depending on browser/cpu/etc.). if that turns out to be a common problem, we can further optimize to pagination if necessary proxmox-mini-journalreader: Dominik Csapak (1): add '-j' flag to output json src/mini-journalreader.c | 66 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) http-server: Dominik Csapak (1): http-server: let the api call decide the content-encoding src/PVE/APIServer/AnyEvent.pm | 3 +++ 1 file changed, 3 insertions(+) pve-manager: Dominik Csapak (1): api: journal: stream the journal data to the client PVE/API2/Nodes.pm | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) -- 2.30.2 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] [PATCH mini-journalreader 1/1] add '-j' flag to output json 2021-11-24 14:47 [pve-devel] [PATCH mini-journalreader/http-server/manager] optimize journal api cal Dominik Csapak @ 2021-11-24 14:47 ` Dominik Csapak 2021-11-24 17:17 ` [pve-devel] applied: " Thomas Lamprecht 2021-11-24 14:47 ` [pve-devel] [PATCH http-server 1/1] http-server: let the api call decide the content-encoding Dominik Csapak 2021-11-24 14:47 ` [pve-devel] [PATCH manager 1/1] api: journal: stream the journal data to the client Dominik Csapak 2 siblings, 1 reply; 10+ messages in thread From: Dominik Csapak @ 2021-11-24 14:47 UTC (permalink / raw) To: pve-devel in the format: {"data":[... log lines ...],"success":1} this is chosen so that we can achieve api compatibility when we stream this output to an api client strings are escaped by replacing '"', '\' and all values <= 0x1F by their \uXXXX representation invalid utf8 sequences will be returned as they are (jq and the browser can handle that) Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- src/mini-journalreader.c | 66 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/src/mini-journalreader.c b/src/mini-journalreader.c index 92176ac..7ce7857 100644 --- a/src/mini-journalreader.c +++ b/src/mini-journalreader.c @@ -32,6 +32,8 @@ #define BUFSIZE 4096 static char BUF[BUFSIZE]; +bool json = false; +bool first_line = true; static uint64_t get_timestamp(sd_journal *j) { uint64_t timestamp; @@ -63,8 +65,19 @@ static void print_cursor(sd_journal *j) { fprintf(stderr, "Failed to get cursor: %s\n", strerror(-r)); exit(1); } + if (json) { + if (!first_line) { + print_to_buf(",\"", 2); + } else { + print_to_buf("\"", 1); + } + } print_to_buf(cursor, strlen(cursor)); + if (json) { + print_to_buf("\"", 1); + } print_to_buf("\n", 1); + first_line = false; free(cursor); } @@ -93,7 +106,15 @@ static void print_reboot(sd_journal *j) { if (bootid[0] != '\0') { // we have some bootid if (memcmp(bootid, d, l)) { // a new bootid found memcpy(bootid, d, l); - print_to_buf("-- Reboot --\n", 13); + if (json) { + if (!first_line) { + print_to_buf(",", 1); + } + print_to_buf("\"-- Reboot --\"\n", 15); + first_line = false; + } else { + print_to_buf("-- Reboot --\n", 13); + } } } else { memcpy(bootid, d, l); @@ -149,13 +170,35 @@ static bool print_field(sd_journal *j, const char *field) { size_t fieldlen = strlen(field)+1; d += fieldlen; l -= fieldlen; - print_to_buf(d, l); + + if (json) { + char tmp[7]; + for (size_t i = 0; i < l;i++) { + if (d[i] == '"' || d[i] == '\\' || (d[i] >= 0 && d[i] <= 0x1F)) { + sprintf(tmp, "\\u%04X", d[i]); + print_to_buf(tmp, 6); + } else { + print_to_buf(d+i, 1); + } + } + } else { + print_to_buf(d, l); + } return true; } static void print_line(sd_journal *j) { print_reboot(j); + + if (json) { + if (!first_line) { + print_to_buf(",", 1); + } + print_to_buf("\"", 1); + first_line = false; + } + print_timestamp(j); print_to_buf(" ", 1); print_field(j, "_HOSTNAME"); @@ -167,6 +210,11 @@ static void print_line(sd_journal *j) { print_pid(j); print_to_buf(": ", 2); print_field(j, "MESSAGE"); + + if (json) { + print_to_buf("\"", 1); + } + print_to_buf("\n", 1); } @@ -184,6 +232,7 @@ _Noreturn static void usage(char *error) { " -n <integer>\t\tprint the last number entries logged\n" " -f <cursor>\t\tprint from this cursor\n" " -t <cursor>\t\tprint to this cursor\n" + " -j \t\t\tprint as json" " -h \t\t\tthis help\n" "\n" "Passing no range option will dump all the available journal\n" @@ -217,7 +266,7 @@ int main(int argc, char *argv[]) { progname = argv[0]; - while ((c = (char)getopt (argc, argv, "b:e:d:n:f:t:h")) != -1) { + while ((c = (char)getopt (argc, argv, "b:e:d:n:f:t:jh")) != -1) { switch (c) { case 'b': begin = arg_to_uint64(optarg); @@ -239,6 +288,9 @@ int main(int argc, char *argv[]) { case 't': endcursor = optarg; break; + case 'j': + json = true; + break; case 'h': usage(NULL); case '?': @@ -285,6 +337,10 @@ int main(int argc, char *argv[]) { return 1; } + if (json) { + print_to_buf("{\"data\":[", 9); + } + // if we want to print the last x entries, seek to cursor or end, // then x entries back, print the cursor and finally print the // entries until end or cursor @@ -350,6 +406,10 @@ int main(int argc, char *argv[]) { print_cursor(j); sd_journal_close(j); + if (json) { + print_to_buf("],\"success\":1}", 14); + } + // print remaining buffer fflush_unlocked(stdout); -- 2.30.2 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] applied: [PATCH mini-journalreader 1/1] add '-j' flag to output json 2021-11-24 14:47 ` [pve-devel] [PATCH mini-journalreader 1/1] add '-j' flag to output json Dominik Csapak @ 2021-11-24 17:17 ` Thomas Lamprecht 0 siblings, 0 replies; 10+ messages in thread From: Thomas Lamprecht @ 2021-11-24 17:17 UTC (permalink / raw) To: Proxmox VE development discussion, Dominik Csapak On 24.11.21 15:47, Dominik Csapak wrote: > in the format: > {"data":[... log lines ...],"success":1} > > this is chosen so that we can achieve api compatibility when we stream > this output to an api client > > strings are escaped by replacing '"', '\' and all values <= 0x1F by their > \uXXXX representation > > invalid utf8 sequences will be returned as they are > (jq and the browser can handle that) > > Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> > --- > src/mini-journalreader.c | 66 ++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 63 insertions(+), 3 deletions(-) > > applied, thanks! ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] [PATCH http-server 1/1] http-server: let the api call decide the content-encoding 2021-11-24 14:47 [pve-devel] [PATCH mini-journalreader/http-server/manager] optimize journal api cal Dominik Csapak 2021-11-24 14:47 ` [pve-devel] [PATCH mini-journalreader 1/1] add '-j' flag to output json Dominik Csapak @ 2021-11-24 14:47 ` Dominik Csapak 2021-11-24 17:18 ` [pve-devel] applied: " Thomas Lamprecht 2021-11-24 14:47 ` [pve-devel] [PATCH manager 1/1] api: journal: stream the journal data to the client Dominik Csapak 2 siblings, 1 reply; 10+ messages in thread From: Dominik Csapak @ 2021-11-24 14:47 UTC (permalink / raw) To: pve-devel this is useful if we want to pipe the output of a program e.g. through gzip Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- src/PVE/APIServer/AnyEvent.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/PVE/APIServer/AnyEvent.pm b/src/PVE/APIServer/AnyEvent.pm index c159b8d..31556ce 100644 --- a/src/PVE/APIServer/AnyEvent.pm +++ b/src/PVE/APIServer/AnyEvent.pm @@ -413,6 +413,7 @@ sub send_file_start { if (ref($download) eq 'HASH') { $mime = $download->{'content-type'}; + my $encoding = $download->{'content-encoding'}; if ($download->{path} && $download->{stream} && $reqstate->{request}->header('PVEDisableProxy')) @@ -424,6 +425,7 @@ sub send_file_start { pvestreamfile => $download->{path}, Content_Type => $mime, ); + $header->header('Content-Encoding' => $encoding) if defined($encoding); # we need some data so Content-Length gets set correctly and # the proxy doesn't wait for more data - place a canary my $resp = HTTP::Response->new(200, "OK", $header, "error canary"); @@ -441,6 +443,7 @@ sub send_file_start { if ($download->{stream}) { my $header = HTTP::Headers->new(Content_Type => $mime); + $header->header('Content-Encoding' => $encoding) if defined($encoding); my $resp = HTTP::Response->new(200, "OK", $header); $self->response($reqstate, $resp, undef, 1, 0, $fh); return; -- 2.30.2 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] applied: [PATCH http-server 1/1] http-server: let the api call decide the content-encoding 2021-11-24 14:47 ` [pve-devel] [PATCH http-server 1/1] http-server: let the api call decide the content-encoding Dominik Csapak @ 2021-11-24 17:18 ` Thomas Lamprecht 0 siblings, 0 replies; 10+ messages in thread From: Thomas Lamprecht @ 2021-11-24 17:18 UTC (permalink / raw) To: Proxmox VE development discussion, Dominik Csapak On 24.11.21 15:47, Dominik Csapak wrote: > this is useful if we want to pipe the output of a program e.g. through gzip > > Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> > --- > src/PVE/APIServer/AnyEvent.pm | 3 +++ > 1 file changed, 3 insertions(+) > > applied, thanks! (and congrats to causing the 4.0-4 release ;) ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] [PATCH manager 1/1] api: journal: stream the journal data to the client 2021-11-24 14:47 [pve-devel] [PATCH mini-journalreader/http-server/manager] optimize journal api cal Dominik Csapak 2021-11-24 14:47 ` [pve-devel] [PATCH mini-journalreader 1/1] add '-j' flag to output json Dominik Csapak 2021-11-24 14:47 ` [pve-devel] [PATCH http-server 1/1] http-server: let the api call decide the content-encoding Dominik Csapak @ 2021-11-24 14:47 ` Dominik Csapak 2021-11-24 17:32 ` Stoiko Ivanov 2021-11-24 17:38 ` [pve-devel] applied: " Thomas Lamprecht 2 siblings, 2 replies; 10+ messages in thread From: Dominik Csapak @ 2021-11-24 14:47 UTC (permalink / raw) To: pve-devel instead of accumulating the whole output of 'mini-journalreader' in the api call (this can be quite big), use the download mechanic of the http-server to stream the output to the client. we lose some error handling possibilities, but we do not have to allocate anything here, and since perl does not free memory after allocating[0] this is our desired behaviour. to keep api compatiblitiy, we need to give the journalreader the '-j' flag to let it output json. also tell the http server that the encoding is gzip and pipe the output through it. 0: https://perldoc.perl.org/perlfaq3#How-can-I-free-an-array-or-hash-so-my-program-shrinks? Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- PVE/API2/Nodes.pm | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm index 565cbccc..d57a1937 100644 --- a/PVE/API2/Nodes.pm +++ b/PVE/API2/Nodes.pm @@ -819,19 +819,25 @@ __PACKAGE__->register_method({ my $rpcenv = PVE::RPCEnvironment::get(); my $user = $rpcenv->get_user(); - my $cmd = ["/usr/bin/mini-journalreader"]; + my $cmd = ["/usr/bin/mini-journalreader", "-j"]; push @$cmd, '-n', $param->{lastentries} if $param->{lastentries}; push @$cmd, '-b', $param->{since} if $param->{since}; push @$cmd, '-e', $param->{until} if $param->{until}; - push @$cmd, '-f', $param->{startcursor} if $param->{startcursor}; - push @$cmd, '-t', $param->{endcursor} if $param->{endcursor}; + push @$cmd, '-f', PVE::Tools::shellquote($param->{startcursor}) if $param->{startcursor}; + push @$cmd, '-t', PVE::Tools::shellquote($param->{endcursor}) if $param->{endcursor}; + push @$cmd, ' | gzip '; - my $lines = []; - my $parser = sub { push @$lines, shift }; + open(my $fh, "-|", join(' ', @$cmd)) + or die "could not start mini-journalreader"; - PVE::Tools::run_command($cmd, outfunc => $parser); - - return $lines; + return { + download => { + fh => $fh, + stream => 1, + 'content-type' => 'application/json', + 'content-encoding' => 'gzip', + }, + }, }}); my $sslcert; -- 2.30.2 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [pve-devel] [PATCH manager 1/1] api: journal: stream the journal data to the client 2021-11-24 14:47 ` [pve-devel] [PATCH manager 1/1] api: journal: stream the journal data to the client Dominik Csapak @ 2021-11-24 17:32 ` Stoiko Ivanov 2021-11-24 17:46 ` Thomas Lamprecht 2021-11-24 17:38 ` [pve-devel] applied: " Thomas Lamprecht 1 sibling, 1 reply; 10+ messages in thread From: Stoiko Ivanov @ 2021-11-24 17:32 UTC (permalink / raw) To: Dominik Csapak; +Cc: Proxmox VE development discussion Huge thanks for addressing this so quickly and elegantly! One question/nit: On Wed, 24 Nov 2021 15:47:48 +0100 Dominik Csapak <d.csapak@proxmox.com> wrote: > instead of accumulating the whole output of 'mini-journalreader' in > the api call (this can be quite big), use the download mechanic of the > http-server to stream the output to the client. > > we lose some error handling possibilities, but we do not have > to allocate anything here, and since perl does not free memory after > allocating[0] this is our desired behaviour. > > to keep api compatiblitiy, we need to give the journalreader the '-j' > flag to let it output json. > > also tell the http server that the encoding is gzip and pipe > the output through it. > > 0: https://perldoc.perl.org/perlfaq3#How-can-I-free-an-array-or-hash-so-my-program-shrinks? > > Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> > --- > PVE/API2/Nodes.pm | 22 ++++++++++++++-------- > 1 file changed, 14 insertions(+), 8 deletions(-) > > diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm > index 565cbccc..d57a1937 100644 > --- a/PVE/API2/Nodes.pm > +++ b/PVE/API2/Nodes.pm > @@ -819,19 +819,25 @@ __PACKAGE__->register_method({ > my $rpcenv = PVE::RPCEnvironment::get(); > my $user = $rpcenv->get_user(); > > - my $cmd = ["/usr/bin/mini-journalreader"]; > + my $cmd = ["/usr/bin/mini-journalreader", "-j"]; > push @$cmd, '-n', $param->{lastentries} if $param->{lastentries}; > push @$cmd, '-b', $param->{since} if $param->{since}; > push @$cmd, '-e', $param->{until} if $param->{until}; > - push @$cmd, '-f', $param->{startcursor} if $param->{startcursor}; > - push @$cmd, '-t', $param->{endcursor} if $param->{endcursor}; > + push @$cmd, '-f', PVE::Tools::shellquote($param->{startcursor}) if $param->{startcursor}; > + push @$cmd, '-t', PVE::Tools::shellquote($param->{endcursor}) if $param->{endcursor}; > + push @$cmd, ' | gzip '; Not sure which would be more efficient - but the http-server does support gzipping the result from the API might it make sense to let the worker do the gzip-encoding vs. forking gzip here? > > - my $lines = []; > - my $parser = sub { push @$lines, shift }; > + open(my $fh, "-|", join(' ', @$cmd)) > + or die "could not start mini-journalreader"; > > - PVE::Tools::run_command($cmd, outfunc => $parser); > - > - return $lines; > + return { > + download => { > + fh => $fh, > + stream => 1, > + 'content-type' => 'application/json', > + 'content-encoding' => 'gzip', if yes - I think it would only need to signal it here (maybe compress => 1) and set the '$nocomp' parameter to the response sub in AnyEvent.pm based on that (this last part without trying it out) > + }, > + }, > }}); > > my $sslcert; ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [pve-devel] [PATCH manager 1/1] api: journal: stream the journal data to the client 2021-11-24 17:32 ` Stoiko Ivanov @ 2021-11-24 17:46 ` Thomas Lamprecht 2021-11-24 17:50 ` Stoiko Ivanov 0 siblings, 1 reply; 10+ messages in thread From: Thomas Lamprecht @ 2021-11-24 17:46 UTC (permalink / raw) To: Proxmox VE development discussion, Stoiko Ivanov, Dominik Csapak On 24.11.21 18:32, Stoiko Ivanov wrote: > Huge thanks for addressing this so quickly and elegantly! > > One question/nit: > > On Wed, 24 Nov 2021 15:47:48 +0100 > Dominik Csapak <d.csapak@proxmox.com> wrote: > >> instead of accumulating the whole output of 'mini-journalreader' in >> the api call (this can be quite big), use the download mechanic of the >> http-server to stream the output to the client. >> >> we lose some error handling possibilities, but we do not have >> to allocate anything here, and since perl does not free memory after >> allocating[0] this is our desired behaviour. >> >> to keep api compatiblitiy, we need to give the journalreader the '-j' >> flag to let it output json. >> >> also tell the http server that the encoding is gzip and pipe >> the output through it. >> >> 0: https://perldoc.perl.org/perlfaq3#How-can-I-free-an-array-or-hash-so-my-program-shrinks? >> >> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> >> --- >> PVE/API2/Nodes.pm | 22 ++++++++++++++-------- >> 1 file changed, 14 insertions(+), 8 deletions(-) >> >> diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm >> index 565cbccc..d57a1937 100644 >> --- a/PVE/API2/Nodes.pm >> +++ b/PVE/API2/Nodes.pm >> @@ -819,19 +819,25 @@ __PACKAGE__->register_method({ >> my $rpcenv = PVE::RPCEnvironment::get(); >> my $user = $rpcenv->get_user(); >> >> - my $cmd = ["/usr/bin/mini-journalreader"]; >> + my $cmd = ["/usr/bin/mini-journalreader", "-j"]; >> push @$cmd, '-n', $param->{lastentries} if $param->{lastentries}; >> push @$cmd, '-b', $param->{since} if $param->{since}; >> push @$cmd, '-e', $param->{until} if $param->{until}; >> - push @$cmd, '-f', $param->{startcursor} if $param->{startcursor}; >> - push @$cmd, '-t', $param->{endcursor} if $param->{endcursor}; >> + push @$cmd, '-f', PVE::Tools::shellquote($param->{startcursor}) if $param->{startcursor}; >> + push @$cmd, '-t', PVE::Tools::shellquote($param->{endcursor}) if $param->{endcursor}; >> + push @$cmd, ' | gzip '; > Not sure which would be more efficient - but the http-server does support > gzipping the result from the API It has no api result in that case, it just returns the open file handle and anyevent can then stream that directly, see the response_stream method in PVE::APIServer::AnyEvent. > might it make sense to let the worker do the gzip-encoding vs. forking > gzip here? contrary to our rust infra from PBS we do not have a streaming encoder directly in the server that we can just layer in between, pve-http-server can currently only compress if it has the whole response, and that's, which is what we want to avoid here. The response method explicitly guards for the stream-an-fh case, AnyEvent.pm line 325: if ($content && !$stream_fh) { # ... my $comp = Compress::Zlib::memGzip($content); What we can do though is compress directly in the mini-journal reader, but that'll be way easier once we rewrite in in rust (heh), as then we can reuse our existing infrastructure to just layer that in-between. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [pve-devel] [PATCH manager 1/1] api: journal: stream the journal data to the client 2021-11-24 17:46 ` Thomas Lamprecht @ 2021-11-24 17:50 ` Stoiko Ivanov 0 siblings, 0 replies; 10+ messages in thread From: Stoiko Ivanov @ 2021-11-24 17:50 UTC (permalink / raw) To: Thomas Lamprecht; +Cc: Proxmox VE development discussion, Dominik Csapak On Wed, 24 Nov 2021 18:46:04 +0100 Thomas Lamprecht <t.lamprecht@proxmox.com> wrote: > On 24.11.21 18:32, Stoiko Ivanov wrote: > > Huge thanks for addressing this so quickly and elegantly! > > > > One question/nit: > > > > On Wed, 24 Nov 2021 15:47:48 +0100 > > Dominik Csapak <d.csapak@proxmox.com> wrote: > > > >> instead of accumulating the whole output of 'mini-journalreader' in > >> the api call (this can be quite big), use the download mechanic of the > >> http-server to stream the output to the client. > >> > >> we lose some error handling possibilities, but we do not have > >> to allocate anything here, and since perl does not free memory after > >> allocating[0] this is our desired behaviour. > >> > >> to keep api compatiblitiy, we need to give the journalreader the '-j' > >> flag to let it output json. > >> > >> also tell the http server that the encoding is gzip and pipe > >> the output through it. > >> > >> 0: https://perldoc.perl.org/perlfaq3#How-can-I-free-an-array-or-hash-so-my-program-shrinks? > >> > >> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> > >> --- > >> PVE/API2/Nodes.pm | 22 ++++++++++++++-------- > >> 1 file changed, 14 insertions(+), 8 deletions(-) > >> > >> diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm > >> index 565cbccc..d57a1937 100644 > >> --- a/PVE/API2/Nodes.pm > >> +++ b/PVE/API2/Nodes.pm > >> @@ -819,19 +819,25 @@ __PACKAGE__->register_method({ > >> my $rpcenv = PVE::RPCEnvironment::get(); > >> my $user = $rpcenv->get_user(); > >> > >> - my $cmd = ["/usr/bin/mini-journalreader"]; > >> + my $cmd = ["/usr/bin/mini-journalreader", "-j"]; > >> push @$cmd, '-n', $param->{lastentries} if $param->{lastentries}; > >> push @$cmd, '-b', $param->{since} if $param->{since}; > >> push @$cmd, '-e', $param->{until} if $param->{until}; > >> - push @$cmd, '-f', $param->{startcursor} if $param->{startcursor}; > >> - push @$cmd, '-t', $param->{endcursor} if $param->{endcursor}; > >> + push @$cmd, '-f', PVE::Tools::shellquote($param->{startcursor}) if $param->{startcursor}; > >> + push @$cmd, '-t', PVE::Tools::shellquote($param->{endcursor}) if $param->{endcursor}; > >> + push @$cmd, ' | gzip '; > > Not sure which would be more efficient - but the http-server does support > > gzipping the result from the API > > It has no api result in that case, it just returns the open file handle and anyevent > can then stream that directly, see the response_stream method in PVE::APIServer::AnyEvent. Thanks for the explanation! (and sorry for the noise) > > > might it make sense to let the worker do the gzip-encoding vs. forking > > gzip here? > > contrary to our rust infra from PBS we do not have a streaming encoder directly in > the server that we can just layer in between, pve-http-server can currently only compress > if it has the whole response, and that's, which is what we want to avoid here. > > The response method explicitly guards for the stream-an-fh case, AnyEvent.pm line 325: > > if ($content && !$stream_fh) { > # ... > my $comp = Compress::Zlib::memGzip($content); > > What we can do though is compress directly in the mini-journal reader, but that'll be > way easier once we rewrite in in rust (heh), as then we can reuse our existing > infrastructure to just layer that in-between. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pve-devel] applied: [PATCH manager 1/1] api: journal: stream the journal data to the client 2021-11-24 14:47 ` [pve-devel] [PATCH manager 1/1] api: journal: stream the journal data to the client Dominik Csapak 2021-11-24 17:32 ` Stoiko Ivanov @ 2021-11-24 17:38 ` Thomas Lamprecht 1 sibling, 0 replies; 10+ messages in thread From: Thomas Lamprecht @ 2021-11-24 17:38 UTC (permalink / raw) To: Proxmox VE development discussion, Dominik Csapak On 24.11.21 15:47, Dominik Csapak wrote: > instead of accumulating the whole output of 'mini-journalreader' in > the api call (this can be quite big), use the download mechanic of the > http-server to stream the output to the client. > > we lose some error handling possibilities, but we do not have > to allocate anything here, and since perl does not free memory after > allocating[0] this is our desired behaviour. > > to keep api compatiblitiy, we need to give the journalreader the '-j' > flag to let it output json. > > also tell the http server that the encoding is gzip and pipe > the output through it. > > 0: https://perldoc.perl.org/perlfaq3#How-can-I-free-an-array-or-hash-so-my-program-shrinks? > > Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> > --- > PVE/API2/Nodes.pm | 22 ++++++++++++++-------- > 1 file changed, 14 insertions(+), 8 deletions(-) > > applied, thanks! ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-11-24 17:50 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-11-24 14:47 [pve-devel] [PATCH mini-journalreader/http-server/manager] optimize journal api cal Dominik Csapak 2021-11-24 14:47 ` [pve-devel] [PATCH mini-journalreader 1/1] add '-j' flag to output json Dominik Csapak 2021-11-24 17:17 ` [pve-devel] applied: " Thomas Lamprecht 2021-11-24 14:47 ` [pve-devel] [PATCH http-server 1/1] http-server: let the api call decide the content-encoding Dominik Csapak 2021-11-24 17:18 ` [pve-devel] applied: " Thomas Lamprecht 2021-11-24 14:47 ` [pve-devel] [PATCH manager 1/1] api: journal: stream the journal data to the client Dominik Csapak 2021-11-24 17:32 ` Stoiko Ivanov 2021-11-24 17:46 ` Thomas Lamprecht 2021-11-24 17:50 ` Stoiko Ivanov 2021-11-24 17:38 ` [pve-devel] applied: " Thomas Lamprecht
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox