import "colors" as colors; def clean_multierror: if . == null then empty else sub("1 error occurred:\n\t\\* "; ""; "mg") | sub("\n+$"; ""; "gm") | sub("\t\\*"; " →"; "g") end; def _local_time: sub("\\.\\d+Z$"; "Z"; "g") | fromdate | strflocaltime("%b %m %I:%M:%S %Z"); def gcp_clean_log: map( (.severity | ascii_downcase) as $level | .timestamp as $ts | .jsonPayload | setpath(["level"]; $level) | setpath(["timestamp"]; $ts | _local_time) | .error?.Error |= clean_multierror ); def lift_payload: map(.jsonPayload); def lift_error: lift_payload | .[]?.error?.Error |= clean_multierror; def level_color: { debug: colors::black, info: colors::blue, warning: colors::yellow, error: colors::red, }; def _show_op: "[" +.Package + " " + .Op + "]"; def _show_stack: .Stack | map(" → " + _show_op + "\t" + .Message) | join("\n"); def _show_error: .error | if .Error then _show_op + " " + .Error + "\n" + _show_stack else . end; def _show_level: ( if .level == "debug" then level_color.debug elif .level == "info" then level_color.info elif .level == "warning" then level_color.warning elif .level == "error" then level_color.error else colors::reset end ) as $color | colors::reset + "[" + $color + (.level | ascii_upcase) + colors::reset + "]"; def _show_props($ignore): ( ["timestamp", "message", "level", "error", "admin_id", "client_id", "service", "source", $ignore] | flatten(1) | join("|") ) as $regex | to_entries | sort_by(.key) | [.[] | select(false == (.key | test("(" + $regex + ")"))) | select(.value) | select(.value != 0) | colors::blue + "\(.key)" + colors::black + "=" + colors::yellow + "\(.value)" + colors::reset ] | join(" "); def show: ["githash", "request_id", "path", "package"] as $ignore | gcp_clean_log | .[] | colors::magenta + .timestamp + colors::reset + " [" + _show_props($ignore) + "]\n" + _show_level + " " + colors::white + .message + ( if .error then "\n" + colors::red + "ERROR" + colors::reset + ": " + _show_error else "" end ) + colors::reset;