Skip to content
Snippets Groups Projects
Commit f2158bc7 authored by David Bühler's avatar David Bühler
Browse files

Merge branch 'feature/kernel/log-truncation' into 'master'

[kernel] Indicates message truncation, and only truncate messages on terminal.

Closes #1244

See merge request frama-c/frama-c!4911
parents d933d7a3 95ae4335
No related branches found
No related tags found
No related merge requests found
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
, perl , perl
, python3 , python3
, python3Packages , python3Packages
, socat
, swi-prolog , swi-prolog
, time , time
, unixtools , unixtools
...@@ -128,6 +129,7 @@ stdenvNoCC.mkDerivation rec { ...@@ -128,6 +129,7 @@ stdenvNoCC.mkDerivation rec {
python3 python3
python3Packages.jsonschema python3Packages.jsonschema
python3Packages.pyaml python3Packages.pyaml
socat
swi-prolog swi-prolog
time time
unixtools.getopt unixtools.getopt
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
, jq , jq
, perl , perl
, python3Packages , python3Packages
, socat
, stdenvNoCC , stdenvNoCC
, time , time
, unixtools , unixtools
...@@ -65,6 +66,7 @@ stdenvNoCC.mkDerivation { ...@@ -65,6 +66,7 @@ stdenvNoCC.mkDerivation {
perl perl
python3Packages.jsonschema python3Packages.jsonschema
python3Packages.pyaml python3Packages.pyaml
socat
time time
unixtools.getopt unixtools.getopt
which which
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
(* *) (* *)
(**************************************************************************) (**************************************************************************)
(* Messages longer than N characters are truncated when printed on terminal. *)
let max_message_length = 10000
type kind = Result | Feedback | Debug | Warning | Error | Failure type kind = Result | Feedback | Debug | Warning | Error | Failure
[@@@ warning "-32"] [@@@ warning "-32"]
...@@ -467,6 +470,7 @@ let logtransient channel text = ...@@ -467,6 +470,7 @@ let logtransient channel text =
try try
Format.pp_print_newline fmt () ; Format.pp_print_newline fmt () ;
Format.pp_print_flush fmt () ; Format.pp_print_flush fmt () ;
ignore (Rich_text.truncate buffer max_message_length) ;
let p,q = Rich_text.trim buffer in let p,q = Rich_text.trim buffer in
do_transient channel.terminal (Rich_text.contents buffer) p q ; do_transient channel.terminal (Rich_text.contents buffer) p q ;
close_buffer channel close_buffer channel
...@@ -497,11 +501,19 @@ let logwithfinal finally channel ...@@ -497,11 +501,19 @@ let logwithfinal finally channel
Format.pp_close_box fmt () ; Format.pp_close_box fmt () ;
Format.pp_print_newline fmt () ; Format.pp_print_newline fmt () ;
Format.pp_print_flush fmt () ; Format.pp_print_flush fmt () ;
let truncated =
if channel.terminal.isatty
then Rich_text.truncate buffer max_message_length
else false
in
let p,q = Rich_text.trim buffer in let p,q = Rich_text.trim buffer in
let output = let output =
if p <= q then if p <= q then
let source = get_source current source in let source = get_source current source in
let message = Rich_text.range buffer p q in let message = Rich_text.range buffer p q in
let message =
if truncated then "(truncated message) " ^ message else message
in
let event = { let event = {
evt_kind = kind ; evt_kind = kind ;
evt_plugin = channel.plugin ; evt_plugin = channel.plugin ;
......
...@@ -106,8 +106,6 @@ let pretty ?vbox fmt message = ...@@ -106,8 +106,6 @@ let pretty ?vbox fmt message =
(* -------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------- *)
let min_buffer = 128 (* initial size of buffer *) let min_buffer = 128 (* initial size of buffer *)
let max_buffer = 2097152 (* maximal size of buffer *)
let tgr_buffer = 3145728 (* elasticity (internal overhead) *)
type buffer = { type buffer = {
mutable formatter : Format.formatter ; (* formatter on self (recursive) *) mutable formatter : Format.formatter ; (* formatter on self (recursive) *)
...@@ -136,7 +134,8 @@ let shrink buffer = ...@@ -136,7 +134,8 @@ let shrink buffer =
if Buffer.length buffer.content > min_buffer then if Buffer.length buffer.content > min_buffer then
Buffer.reset buffer.content Buffer.reset buffer.content
let truncate_text buffer size = let truncate buffer size =
let truncated = ref false in
if Buffer.length buffer.content > size then if Buffer.length buffer.content > size then
begin begin
let p = trim_begin buffer in let p = trim_begin buffer in
...@@ -147,23 +146,21 @@ let truncate_text buffer size = ...@@ -147,23 +146,21 @@ let truncate_text buffer size =
else if n <= size then else if n <= size then
Buffer.blit buffer.content p (Buffer.to_bytes buffer.content) 0 n Buffer.blit buffer.content p (Buffer.to_bytes buffer.content) 0 n
else else
begin let n_left = size / 2 - 3 in
let n_left = size / 2 - 3 in let n_right = size - n_left - 5 in
let n_right = size - n_left - 5 in if p > 0 then
if p > 0 then Buffer.blit buffer.content p (Buffer.to_bytes buffer.content) 0 n_left;
Buffer.blit buffer.content p (Buffer.to_bytes buffer.content) 0 n_left; let buf_right = Buffer.sub buffer.content (q-n_right+1) n_right in
let buf_right = Buffer.sub buffer.content (q-n_right+1) n_right in Buffer.truncate buffer.content n_left;
Buffer.truncate buffer.content n_left; Buffer.add_string buffer.content "[...]";
Buffer.add_string buffer.content "[...]"; Buffer.add_string buffer.content buf_right;
Buffer.add_string buffer.content buf_right; truncated := true;
end end;
end !truncated
(* All text added shall go through this function *) (* All text added shall go through this function *)
let append buffer s k n = let append buffer s k n =
Buffer.add_substring buffer.content s k n ; Buffer.add_substring buffer.content s k n
if Buffer.length buffer.content > tgr_buffer then
truncate_text buffer max_buffer
let push_tag buffer _tag = let push_tag buffer _tag =
let p = Buffer.length buffer.content in let p = Buffer.length buffer.content in
...@@ -219,13 +216,12 @@ let create ?indent ?margin () = ...@@ -219,13 +216,12 @@ let create ?indent ?margin () =
buffer buffer
let trim buffer = let trim buffer =
truncate_text buffer max_buffer ;
let p = trim_begin buffer in let p = trim_begin buffer in
let q = trim_end buffer in let q = trim_end buffer in
p , q p , q
let contents buffer = let contents buffer =
truncate_text buffer max_buffer ; Buffer.contents buffer.content Buffer.contents buffer.content
let message buffer = let message buffer =
( Buffer.contents buffer.content , List.rev buffer.revtags ) ( Buffer.contents buffer.content , List.rev buffer.revtags )
...@@ -247,7 +243,6 @@ let to_string ?(indent=20) ?(margin=40) ?(trim=true) pp data = ...@@ -247,7 +243,6 @@ let to_string ?(indent=20) ?(margin=40) ?(trim=true) pp data =
let fmt = formatter buffer in let fmt = formatter buffer in
pp fmt data ; pp fmt data ;
Format.pp_print_flush fmt () ; Format.pp_print_flush fmt () ;
truncate_text buffer max_buffer ;
if trim then if trim then
let p = trim_begin buffer in let p = trim_begin buffer in
let q = trim_end buffer in let q = trim_end buffer in
......
...@@ -106,6 +106,10 @@ val trim : buffer -> int * int ...@@ -106,6 +106,10 @@ val trim : buffer -> int * int
(** Resize the buffer to roughly fit its actual content. *) (** Resize the buffer to roughly fit its actual content. *)
val shrink : buffer -> unit val shrink : buffer -> unit
(** [truncate buffer size] truncates the content of [buffer] if longer than
[size] characters. Returns true if the bufffer has been truncated. *)
val truncate : buffer -> int -> bool
(* -------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------- *)
(** Printer *) (** Printer *)
(* -------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------- *)
......
...@@ -8,3 +8,8 @@ ...@@ -8,3 +8,8 @@
(enabled_if %{bin-available:gcc}) (enabled_if %{bin-available:gcc})
(deps pragma-pack.c pragma-pack-utils.h) (deps pragma-pack.c pragma-pack-utils.h)
) )
(cram
(applies_to log-truncation)
(enabled_if %{bin-available:socat})
)
(executable
(name "log_truncation")
(modules "log_truncation")
(modes plugin)
(libraries frama-c.init.cmdline frama-c.kernel)
(flags -open Frama_c_kernel :standard)
(promote (until-clean))
)
(lang dune 3.13)
(name frama-c-log-truncation)
(package (name frama-c-log-truncation))
let run () =
(* This can be filtered to avoid too long test oracles. *)
let very_long_line = String.make 5000 '#' in
let line = "begin_line <-----" ^ very_long_line ^ "-----> end_line" in
let middle_text =
"[ This text should only appear in the log if is is redirected to a file. ]"
in
Kernel.warning
"This is a very, very long message intended to test the truncation \
of the Frama-C log: \n\
@[<v>%s@;%s@;%s@]" line middle_text line
let () = Boot.Main.extend run
Compilation of the log_truncation.ml file.
$ dune build --cache=disabled --root . _build/default/log_truncation.cmxs
$ frama-c -no-autoload-plugins -load-module log_truncation.cmxs > file-log.txt
The message should not be truncated as the output was redireted to a file.
$ cat file-log.txt | tr -d '#'
[kernel] Warning: This is a very, very long message intended to test the truncation of the Frama-C log:
begin_line <----------> end_line
[ This text should only appear in the log if is is redirected to a file. ]
begin_line <----------> end_line
$ socat EXEC:"frama-c -no-autoload-plugins -load-module log_truncation.cmxs",pty GOPEN:terminal-log.txt
The message should be truncated.
$ cat terminal-log.txt | tr -d '#'
[kernel] Warning: (truncated message) This is a very, very long message intended to test the truncation of the Frama-C log:
begin_line <-----[...]-----> end_line
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment