2023-03-09 17:30:40 +00:00
#!/usr/bin/env bash
#
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (c) 2013-2023 Igor Pecovnik, igor@armbian.com
#
# This file is a part of the Armbian Build Framework
# https://github.com/armbian/build/
2023-01-12 17:58:51 +00:00
function display_alert( ) {
# If asked, avoid any fancy ANSI escapes completely. For python-driven log collection. Formatting could be improved.
# If used, also does not write to logfile even if it exists.
if [ [ " ${ ANSI_COLOR } " = = "none" ] ] ; then
2023-01-15 04:01:49 +00:00
declare extra_profiler = ""
if [ [ " ${ POOR_MAN_PROFILER } " = = "yes" ] ] ; then
poor_man_profiler
fi
2023-07-27 14:32:08 +00:00
echo -e " ${ extra_profiler } ${ 3 } :: ${ 1 } ${ 2 } " | sed 's/\x1b\[[0-9;]*m//g' | sed -z 's|\n|\\n|g' >& 2 # remove ANSI colors and newlines
2023-08-22 11:32:09 +00:00
echo "" >& 2 # newline
2023-01-12 17:58:51 +00:00
return 0
fi
2023-01-12 01:32:21 +00:00
declare message = " ${ 1 } " level = " ${ 3 } " # params
declare level_indicator = "" inline_logs_color = "" extra = "" extra_file = "" ci_log = "" # this log
2023-01-18 21:43:25 +00:00
declare -i skip_screen = ${ display_alert_skip_screen :- 0 } # setting to 1 will not write to screen
2023-01-12 01:32:21 +00:00
declare -i skip_logfile = 0 # setting to 1 will not write to logfile
2023-01-12 17:58:51 +00:00
case " ${ level } " in
2023-01-18 21:43:25 +00:00
debug)
if [ [ " ${ SHOW_DEBUG } " != "yes" ] ] ; then # enable debug for many, many debugging msgs
skip_screen = 1
fi
level_indicator = "🐛"
2024-02-09 04:33:19 +00:00
case " ${ background_dark_or_light } " in
2024-06-22 15:54:22 +00:00
light) inline_logs_color = "\e[1;2;33m" ; ;
*) inline_logs_color = "\e[1;33m" ; ;
2024-02-09 04:33:19 +00:00
esac
2023-01-18 21:43:25 +00:00
skip_logfile = 1
2023-01-12 17:58:51 +00:00
; ;
2023-01-18 21:43:25 +00:00
command )
if [ [ " ${ SHOW_COMMAND } " != "yes" ] ] ; then # enable to log all calls to external cmds
skip_screen = 1
fi
level_indicator = "🐸"
inline_logs_color = "\e[0;36m" # a dim cyan
2023-01-12 17:58:51 +00:00
; ;
info)
level_indicator = "🌱"
2024-02-09 04:33:19 +00:00
case " ${ background_dark_or_light } " in
2024-06-22 15:54:22 +00:00
light) inline_logs_color = "\e[1;2;32m" ; ;
*) inline_logs_color = "\e[1;32m" ; ;
2024-02-09 04:33:19 +00:00
esac
2023-01-12 17:58:51 +00:00
; ;
cleanup | trap )
if [ [ " ${ SHOW_TRAPS } " != "yes" ] ] ; then # enable debug for many, many debugging msgs
skip_screen = 1
fi
level_indicator = "🧽"
2024-02-09 04:33:19 +00:00
case " ${ background_dark_or_light } " in
2024-06-22 15:54:22 +00:00
light) inline_logs_color = "\e[1;2;33m" ; ;
*) inline_logs_color = "\e[1;33m" ; ;
2024-02-09 04:33:19 +00:00
esac
2023-01-12 18:00:06 +00:00
skip_logfile = 1
2023-01-12 17:58:51 +00:00
; ;
group)
if [ [ " ${ SHOW_DEBUG } " != "yes" && " ${ SHOW_GROUPS } " != "yes" ] ] ; then # show when debugging, or when specifically requested
skip_screen = 1
fi
level_indicator = "🦋"
inline_logs_color = "\e[1;34m" # blue; 36 would be cyan
2023-01-12 18:00:06 +00:00
skip_logfile = 1
2023-01-12 17:58:51 +00:00
; ;
timestamp | fasthash)
if [ [ " ${ SHOW_FASTHASH } " != "yes" ] ] ; then # timestamp-related debugging messages, very very verbose
skip_screen = 1
fi
level_indicator = "🐜"
2023-01-12 01:32:21 +00:00
inline_logs_color = " ${ tool_color :- } " # either gray or normal, a bit subdued.
2023-01-12 18:00:06 +00:00
skip_logfile = 1
2023-01-12 17:58:51 +00:00
; ;
extensions)
if [ [ " ${ SHOW_EXTENSIONS } " != "yes" ] ] ; then # enable to log a lot about extensions, hook methos, etc.
skip_screen = 1
fi
level_indicator = "🎣" # fishing pole and "hook"
inline_logs_color = "\e[0;36m" # a dim cyan
2023-01-12 18:00:06 +00:00
skip_logfile = 1
2023-01-12 17:58:51 +00:00
; ;
extensionstrace)
if [ [ " ${ SHOW_EXTENSIONS_TRACE } " != "yes" ] ] ; then # waaaay too verbose, logs traces in extensions
skip_screen = 1
fi
level_indicator = "🐾"
inline_logs_color = "\e[0;36m" # a dim cyan
2023-01-12 18:00:06 +00:00
skip_logfile = 1
2023-01-12 17:58:51 +00:00
; ;
git)
if [ [ " ${ SHOW_GIT } " != "yes" ] ] ; then # git-related debugging messages, very very verbose
skip_screen = 1
fi
level_indicator = "🔖"
inline_logs_color = " ${ tool_color } " # either gray or normal, a bit subdued.
2023-01-12 18:00:06 +00:00
skip_logfile = 1
2023-01-12 17:58:51 +00:00
; ;
ccache)
if [ [ " ${ SHOW_CCACHE } " != "yes" ] ] ; then # ccache-related debugging messages, very very verbose
skip_screen = 1
fi
level_indicator = "🙈"
inline_logs_color = "\e[1;34m" # blue; 36 would be cyan
2023-01-12 18:00:06 +00:00
skip_logfile = 1
2023-01-12 17:58:51 +00:00
; ;
2023-01-18 21:43:25 +00:00
cachehit)
level_indicator = "💖"
inline_logs_color = "\e[0;32m"
; ;
2023-01-12 18:00:06 +00:00
# @TODO this is dead I think
2023-01-12 17:58:51 +00:00
aggregation)
if [ [ " ${ SHOW_AGGREGATION } " != "yes" ] ] ; then # aggregation (PACKAGE LISTS), very very verbose
skip_screen = 1
fi
level_indicator = "📦"
inline_logs_color = "\e[0;32m"
2023-01-12 18:00:06 +00:00
skip_logfile = 1
2023-01-12 17:58:51 +00:00
; ;
2023-01-18 21:43:25 +00:00
err | error | critical)
level = "error"
level_indicator = "💥"
inline_logs_color = "\e[1;31m"
ci_log = "error"
; ;
wrn | warn | warning)
level = "warning"
level_indicator = "🚸"
inline_logs_color = "\e[1;35m"
ci_log = "warning"
; ;
ext)
2023-12-27 23:12:50 +00:00
level_indicator = "✨"
2024-02-09 04:33:19 +00:00
case " ${ background_dark_or_light } " in
2024-06-22 15:54:22 +00:00
light) inline_logs_color = "\e[1;2;32m" ; ;
*) inline_logs_color = "\e[1;32m" ; ;
2024-02-09 04:33:19 +00:00
esac
2023-01-18 21:43:25 +00:00
; ;
2023-12-27 23:12:50 +00:00
change-tracking)
level_indicator = "✅"
inline_logs_color = "\e[1;36m" # cyan
; ;
2023-01-12 17:58:51 +00:00
*)
2023-01-12 01:32:21 +00:00
level = " ${ level :- info } " # for file logging.
2023-01-12 17:58:51 +00:00
level_indicator = "🌿"
2024-02-09 04:33:19 +00:00
case " ${ background_dark_or_light } " in
2024-06-22 15:54:22 +00:00
dark) inline_logs_color = "\e[1;37m" ; ;
*) inline_logs_color = "\e[1;39m" ; ;
2024-02-09 04:33:19 +00:00
esac
2023-01-12 17:58:51 +00:00
; ;
esac
2023-01-12 01:32:21 +00:00
if [ [ -n ${ 2 } ] ] ; then
extra = " [ ${ inline_logs_color } ${ 2 } ${ normal_color :- } ] "
# extra_file=" [${inline_logs_color} ${2} ${normal_color}]" # too much color in logfile
2023-01-18 21:43:25 +00:00
extra_file = " [ ${ inline_logs_color } ${ 2 } ${ normal_color } ] "
2023-01-12 01:32:21 +00:00
fi
2023-01-12 17:58:51 +00:00
# Log to journald, if asked to.
if [ [ " ${ ARMBIAN_LOGS_TO_JOURNAL } " = = "yes" ] ] ; then
echo -e " ${ level } : ${ 1 } [ ${ 2 } ] " | sed 's/\x1b\[[0-9;]*m//g' | systemd-cat --identifier= " ${ ARMBIAN_LOGS_JOURNAL_IDENTIFIER :- armbian } "
fi
local CALLER_PID = " ${ BASHPID } "
2023-01-12 18:00:06 +00:00
# Attention: do not pipe the output before writing to the logfile.
# For example, to remove ansi colors.
# If you do that, "echo" runs in a subshell due to the "sed" pipe (! important !)
# for the future: BASHPID is the current subshell; $$ is parent's?; $_ is the current bashopts
2023-01-12 17:58:51 +00:00
if [ [ -f " ${ CURRENT_LOGFILE } " ] ] ; then
2023-01-12 18:00:06 +00:00
# If not asked to skip, or debugging is enabled, log to file.
if [ [ ${ skip_logfile } -lt 1 || " ${ DEBUG } " = = "yes" ] ] ; then
2023-01-12 01:32:21 +00:00
#echo -e "--> (${SECONDS}) ${level^^}: ${1} [ ${2} ]" >> "${CURRENT_LOGFILE}" # bash ^^ is "to upper case"
echo -e " --> ( ${ SECONDS } ) ${ inline_logs_color } ${ level ^^ } ${ normal_color } : ${ 1 } ${ extra_file } " >> " ${ CURRENT_LOGFILE } " # bash ^^ is "to upper case"
2023-01-12 18:00:06 +00:00
fi
2023-01-12 17:58:51 +00:00
fi
if [ [ ${ skip_screen } -eq 1 ] ] ; then
return 0
fi
local timing_info = ""
if [ [ " ${ SHOW_TIMING } " = = "yes" ] ] ; then
timing_info = " ${ tool_color } ( ${ normal_color } $( printf "%3s" " ${ SECONDS } " ) ${ tool_color } ) " # SECONDS is bash builtin for seconds since start of script.
fi
local pids_info = ""
if [ [ " ${ SHOW_PIDS } " = = "yes" ] ] ; then
pids_info = " ${ tool_color } ( ${ normal_color } $$ - ${ CALLER_PID } ${ tool_color } ) " # BASHPID is the current subshell (should be equal to CALLER_PID here); $$ is parent's?
fi
local bashopts_info = ""
if [ [ " ${ SHOW_BASHOPTS } " = = "yes" ] ] ; then
bashopts_info = " ${ tool_color } ( ${ normal_color } $- ${ tool_color } ) " # $- is the currently active bashopts
fi
2023-01-12 01:32:21 +00:00
echo -e " ${ normal_color } ${ left_marker :- } ${ padding :- } ${ level_indicator } ${ padding } ${ normal_color } ${ right_marker :- } ${ timing_info } ${ pids_info } ${ bashopts_info } ${ normal_color } ${ message } ${ extra } ${ normal_color } " >& 2
2023-01-12 17:58:51 +00:00
# Now write to CI, if we're running on it. Remove ANSI escapes which confuse GitHub Actions.
2023-05-08 12:10:21 +00:00
if [ [ " ${ CI } " = = "true" ] ] && [ [ " ${ ci_log } " != "" ] ] && [ [ " ${ skip_ci_special :- "no" } " != "yes" ] ] ; then
2023-01-12 18:00:06 +00:00
echo -e " :: ${ ci_log } :: " " ${ 1 } ${ 2 } " | sed 's/\x1b\[[0-9;]*m//g' >& 2
2023-01-12 17:58:51 +00:00
fi
return 0 # make sure to exit with success, always
}
function logging_echo_prefix_for_pv( ) {
local what = " $1 "
local indicator = "🤓" # you guess who this is
case $what in
extract_rootfs)
indicator = "💖"
; ;
tool)
indicator = "🔨"
; ;
compile)
indicator = "🐴"
; ;
write_device)
indicator = "💾"
; ;
create_rootfs_archive | decompress | compress_kernel_sources)
indicator = "🤐"
; ;
esac
echo -n -e " ${ normal_color } ${ left_marker } ${ padding } ${ indicator } ${ padding } ${ normal_color } ${ right_marker } "
return 0
}
2023-01-12 01:32:21 +00:00
## Color echo -e command
## Black echo -e "\033[30mBlack\033[0m"
## Bright Black echo -e "\033[90mBright Black\033[0m"
## Red echo -e "\033[31mRed\033[0m"
## Bright Red echo -e "\033[91mBright Red\033[0m"
## Green echo -e "\033[32mGreen\033[0m"
## Bright Green echo -e "\033[92mBright Green\033[0m"
## Yellow echo -e "\033[33mYellow\033[0m"
## Bright Yellow echo -e "\033[93mBright Yellow\033[0m"
## Blue echo -e "\033[34mBlue\033[0m"
## Bright Blue echo -e "\033[94mBright Blue\033[0m"
## Magenta echo -e "\033[35mMagenta\033[0m"
## Bright Magenta echo -e "\033[95mBright Magenta\033[0m"
## Cyan echo -e "\033[36mCyan\033[0m"
## Bright Cyan echo -e "\033[96mBright Cyan\033[0m"
## White echo -e "\033[37mWhite\033[0m"
## Bright White echo -e "\033[97mBright White\033[0m"
2023-01-15 04:01:49 +00:00
# this is slow, unsafe, incorrect, but does help a lot to find slow spots.
# this sets the outer scope variable "extra_profiler"
function poor_man_profiler( ) {
# replace commas with dots in EPOCHREALTIME
declare seconds_dot_micros = " ${ EPOCHREALTIME //,/. } "
# Parse seconds and nanos from seconds_dot_micros, separated by "dot"
declare -i seconds = " ${ seconds_dot_micros %.* } "
declare str_nanos = " ${ seconds_dot_micros #*. } "
# remove all leading zeros, the worst way possible
str_nanos = " ${ str_nanos ##0 } "
str_nanos = " ${ str_nanos ##0 } "
str_nanos = " ${ str_nanos ##0 } "
str_nanos = " ${ str_nanos ##0 } "
declare -i nanos = " ${ str_nanos } "
if [ [ -z " ${ starting_seconds } " ] ] ; then # get an absolute starting point, once.
declare -g -r starting_seconds = " ${ seconds } "
fi
declare -i seconds = $(( seconds - starting_seconds)) # relative secs
# If we have a previous_seconds and previous_nanos, calculate the difference
if [ [ -n " ${ previous_seconds } " && -n " ${ previous_nanos } " ] ] ; then
declare -i diff_seconds = $(( seconds - previous_seconds))
declare -i diff_nanos = $(( nanos - previous_nanos))
if [ [ $diff_seconds -gt 0 ] ] ; then
diff_nanos = $(( ( diff_seconds * 1000 * 1000 ) + diff_nanos))
fi
extra_profiler = " +( ${ diff_nanos } ns) " # sets the outer scope variable
fi
declare -g -i previous_seconds = " ${ seconds } "
declare -g -i previous_nanos = " ${ nanos } "
}