tazwok view libtazwok/libtazwok-modules/report @ rev 555

Add libtazwok (old libtaz) - Lib taz is unmaintained and report only used by tazwok. Also for the future we need a better libtaz (now in slitaz-base-files)
author Christophe Lincoln <pankso@slitaz.org>
date Wed Apr 11 02:02:59 2012 +0200 (2012-04-11)
parents
children 4e53898ed66c
line source
2 # Usage : use_report functions/commands
3 # 'use_report' execute functions/commands and redirect the output.
4 # You can use 'report' function to display messages, steps, blocs and
5 # status in the terminal and organize the display of the log.
7 report_verbosity_opt=all
9 report_display()
10 {
11 while read out; do
12 [ "$out" = €øß ] && report_stop_display && return
13 echo -e " ...\n ~~~~~~~~~~~~~~~~~~~~ Messages ~~~~~~~~~~~~~~~~~~~~ "
14 echo "$out"
15 break
16 done
17 while read out; do
18 [ "$out" = €øß ] && report_stop_display && return
19 echo "$out"
20 done
21 }
23 report_create_html()
24 {
25 mkdir -p "${log_opt%/*}"
26 echo '<div id="report">' >> "$log_opt"
28 echo -e "<strong>$(basename "$log_command")</strong>\n<em>$(date)</em>" >> "$log_opt"
29 }
31 report_start()
32 {
33 # Create the temporary directory if needed.
34 ! [ -d /tmp/libtaz/ ] && mkdir -p /tmp/libtaz
35 ! [ -d $SLITAZ_LOG ] && mkdir -p $SLITAZ_LOG
37 # Give permissions to all users if user is root.
38 if test $(id -u) = 0 ; then
39 chmod 777 /tmp/libtaz
40 chmod -R 777 $SLITAZ_LOG
41 fi
43 # Get a random logfile name.
44 if [ "$report_pid" ]; then
45 log_tmp=/tmp/libtaz/$report_pid
46 embeded_mode=enabled
47 initial_bloc_level=$bloc_level
48 if [ "$open_bloc" ]; then
49 initial_bloc_level=$(($bloc_level+1))
50 embeded_open_bloc=yes
51 fi
52 if [ -p $log_tmp.stdout ] && ! [ "$open_bloc" = yes ]; then
53 report_step_status
54 fi
55 else
56 log_tmp=/tmp/libtaz/$$
57 report_pid=$$
58 fi
60 # Use the default logfile if no logfile was specified by the main script.
61 [ ! "$log_opt" ] && [ "$report_log_all" = yes ] && \
62 log_opt="$SLITAZ_LOG/`basename $0`/$(date -Iseconds).html"
63 export report_pid log_opt
65 #if [ "$embeded_mode" != enabled ]; then
67 # Initialize html logfile if needed, or prepare it to be edited.
68 [ "$log_opt" ] && { [ ! "$embeded_mode" ] || [ ! -f "$log_opt" ]; } && report_create_html
70 echo -n "" > $log_tmp
72 # Initialize named pipes & set I/O redirections.
73 [ "$embeded_mode" ] || exec 3>&1 4>&2
75 # Start debugging if the option is enabled.
76 if [ "$debug_opt" ]; then
77 exec 2>$log_tmp.stdout
78 set -vx
79 echo "[--------------------------/!\ DEBUG MODE ENABLED /!\--------------------------]"
80 fi
82 # Theses variable are used to configure the display of steps in a terminal.
83 bloc1_delimiter="================================================================================"
84 bloc1_display=" "
85 bloc2_delimiter="----------------------------------------------------------------------------"
86 bloc2_display=" > "
87 bloc3_delimiter="* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
88 bloc3_display=" * "
90 # Use a trap to exit cleanly if app is killed.
91 trap "report_exit $(basename $0) killed by user" SIGINT SIGTERM
93 # Use another display function if quiet is enabled.
94 [ "$report_verbosity_opt" = "none" ] && report_display()
95 {
96 while read out; do
97 [ "$out" = €øß ] && report_stop_display && return
98 done
99 }
100 }
102 report_stop_display()
103 {
104 rm $log_tmp.stderr $log_tmp.stdout
105 sed '/^€øß$/d' -i $log_tmp
106 touch $log_tmp.end
107 }
109 report_listen()
110 {
111 mkfifo $log_tmp.stderr $log_tmp.stdout
112 {
113 { tee -a $log_tmp $log_tmp.error <$log_tmp.stderr | while read line; do echo -e "\\033[1;31m${line}\\033[0m"; done; }&
114 { tee -a $log_tmp <$log_tmp.stdout; }&
115 } | report_display&
116 usleep 10000
117 exec 1>>$log_tmp.stdout 2>>$log_tmp.stderr
118 }
120 report_stop_listen()
121 {
122 if [ -p $log_tmp.stdout ]; then
123 [ -f $log_tmp.end ] && rm $log_tmp.end
124 usleep 10000 && echo €øß
125 while ! [ -f $log_tmp.end ]; do
126 usleep 10000
127 done
128 exec 1>&3 2>&4
129 rm $log_tmp.end
130 fi
131 }
133 report_stop()
134 {
135 ! [ "$report_pid" ] && exit
136 # End step and close blocs.
137 [ "$step_running" ] && report end-step
138 while [ $(($bloc_level)) -gt $(($initial_bloc_level)) ]; do
139 report close-bloc
140 done
142 if [ "$embeded_mode" = enabled ]; then
143 [ "$bloc_level" ] && echo $(eval echo \$bloc${bloc_level}_status) > $log_tmp.status
144 if [ "$embeded_open_bloc" = opened ]; then
145 touch $log_tmp.eob
146 fi
147 else
148 [ "$log_opt" ] && echo '</div>' >> "$log_opt"
149 exec 3>&- 4>&-
150 rm -f $log_tmp*
151 unset report_pid log_opt
153 # Stop debugging
154 [ "$debug_opt" ] && set +vx
155 fi
156 }
158 # Use this to stop a program with an error.
159 report_exit()
160 {
161 # Log&display error message.
162 echo -e "$@" >&2
164 # Close step as failed.
165 if [ "$step_running" ]; then
166 (exit 1)
167 report end-step
168 fi
170 # Set blocs as failed, report and exit.
171 bloc1_status="failed"
172 bloc2_status="failed"
173 bloc3_status="failed"
174 report_stop
175 exit 1
176 }
178 # Usage : report [command] [message]
179 #
180 # type :message simply display the message.
181 # step name the step and display status when ended.
182 # end-step display status of the step, it's done automatically when
183 # starting a new step, closing a bloc or stopping a report.
184 # open-bloc open the list of steps in the operation.
185 # close-bloc close the current bloc.
186 report()
187 {
188 # First : get status before it is changed by other commands.
189 check_status=$?
190 case "$1" in
191 start)
192 report_start
193 ;;
194 stop)
195 report_stop
196 ;;
197 exit)
198 shift && report_exit "$@"
199 ;;
200 # TODO : Code displaying a message during a step run.
201 message)
202 shift
203 echo -e "${current_bloc_display}$@"
204 report_message="$@"
205 [ "$log_opt" ] && echo -e "<div class=\"message\">$report_message</div>" >> "$log_opt"
206 ;;
207 step)
208 [ "$log_step" ] && echo "$2" > $log_step
209 [ "$open_bloc" ] && report_open_bloc
210 [ "$step_running" ] && report_step_status
211 echo -ne "$current_bloc_display$2\\033[70G[ \\033[1;32mR\\033[33mU\\033[31mN\\033[0;39m ]" >&3
212 [ "$log_opt" ] && echo -e "<div class=\"$2\">\n<strong>$2</strong>" >> "$log_opt"
213 export step_running="$2"
214 report_listen
215 ;;
216 end-step)
217 if ! [ "$step_running" ]; then
218 report_return_code=$check_status
219 else
220 report_step_status
221 fi
222 ;;
223 open-bloc)
224 export open_bloc=yes
225 ;;
226 close-bloc)
227 if [ -f "$log_tmp.eob" ]; then
228 report_open_bloc
229 check_status=$(cat $log_tmp.status)
230 rm $log_tmp.status
231 report_set_bloc_status
232 elif [ "$step_running" ]; then
233 report_step_status
234 fi
236 # Then close the bloc and report status if it was open.
237 if ! [ "$open_bloc" ]; then
238 export current_bloc_display="$(eval echo \"\$bloc$((${bloc_level}-1))_display\")"
239 [ "$(eval echo \"\$bloc${bloc_level}_delimiter\")" ] && \
240 echo -e "$current_bloc_display$(eval echo \"\$bloc${bloc_level}_delimiter\")" >&3
241 echo -en "$current_bloc_display... $(eval echo \"\$bloc${bloc_level}_running\")" >&3
242 check_status=$(eval echo \$bloc${bloc_level}_status)
243 report_display_status
245 # Set the bloc status in the log file.
246 if [ "$log_opt" ]; then
247 sed "s~<div class=\"bloc_level$bloc_level\">~<div class=\"$check_status\">~" -i "$log_opt"
248 echo "</div>" >> "$log_opt"
249 fi
250 echo "" >&3
251 export bloc_level=$(($bloc_level-1))
252 [ "$bloc_level" = 0 ] && unset bloc_level
253 else
254 unset open_bloc
255 fi
256 ;;
257 sublog)
258 shift
259 ! [ "$log_list" ] && log_list="$log_opt"
260 export log_list="$1 $log_list"
261 export log_opt="$1"
262 report_create_html
263 ;;
264 end-sublog)
265 [ "$log_opt" ] || continue
266 export log_list="${log_list#* }"
267 echo '</div>' >> "$log_opt"
268 # Grep the summary of sublog (main action + status) and put
269 # it in the main log, plus a link.
270 [ "$log_list" ] && { sed -n '/<div id="report">/,$p' $log_opt | \
271 grep -A1 -F '<div class=' | sed 1,2!d &&
272 echo '<a class="sublog" href="'$log_opt'">SubLog</a>' && \
273 echo "</div>"
274 } >> ${log_list%% *}
275 export log_opt="${log_list%% *}"
276 report_step_status
277 ;;
278 esac
279 return $report_return_code
280 }
282 # Open a bloc of substeps in a terminal and log.
283 report_open_bloc()
284 {
285 unset open_bloc
286 [ "$embeded_open_bloc" = "yes" ] && embeded_open_bloc=opened
287 [ -f "$log_tmp.eob" ] && rm $log_tmp.eob
288 export bloc_level=$(($bloc_level+1))
289 export bloc${bloc_level}_running="$step_running"
290 if [ -p $log_tmp.stdout ]; then
291 if [ -s $log_tmp ]; then
292 prebloc=yes
293 report_step_status
294 prebloc=
295 else
296 report_stop_listen
297 echo ' ...' >&3
298 fi
299 [ "$(eval echo \$bloc${bloc_level}_delimiter)" ] && \
300 echo "$current_bloc_display$(eval echo \"\$bloc${bloc_level}_delimiter\")" >&3
301 [ "$log_opt" ] && sed "s~<div class=\"$step_running\">~<div class=\"bloc_level$bloc_level\">~" -i "$log_opt"
302 else
303 exec 1>&3 2>&4
304 fi
305 export current_bloc_display="$(eval echo \"\$bloc${bloc_level}_display\")"
306 unset bloc${bloc_level}_status
307 unset step_running
308 }
310 # These are the two new status functions used by the report tool.
311 # States are : ok - no error since the start of the step
312 # warning - there was an error(s) since the start of the step
313 # failed - the last executed command has exited abnormally
314 report_step_status()
315 {
316 unset report_return_code
317 if [ -p $log_tmp.stdout ]; then
318 report_stop_listen
320 # Close message bloc if opened.
321 if [ -s $log_tmp -a "$report_verbosity_opt" = all ] || \
322 [ -s $log_tmp.error -a "$report_verbosity_opt" != none ]; then
323 echo " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ " >&3
324 ! [ "$prebloc" ] && echo -en "$current_bloc_display... $step_running" >&3 && report_addemptyline="yes"
325 fi
327 # Check, display and log the status of the step.
328 if ! [ "$check_status" = "0" ]; then
329 check_status=failed
330 else
331 [ -s "$log_tmp.error" ] && check_status=warning || check_status=ok
332 fi
333 ! [ "$prebloc" ] && report_display_status
334 [ "$report_addemptyline" ] && echo "" >&3 && unset report_addemptyline
335 [ "$log_opt" ] && report_rec_log
336 fi
338 [ -f "$log_tmp.eob" ] && rm $log_tmp.eob
340 # Set blocs status if needed.
341 [ -f $log_tmp.status ] && check_status=$(cat $log_tmp.status) && rm $log_tmp.status
342 [ "$bloc_level" ] && report_set_bloc_status
344 # Clear variables / temporary logs.
345 ! [ "$prebloc" ] && export step_running=""
346 check_status=""
347 echo -n "" > $log_tmp.error
348 echo -n "" > $log_tmp
349 }
351 report_display_status()
352 {
353 [ "$report_return_code" = 1 ] && check_status=failed
354 echo -en "\\033[70G " >&3
355 echo -en "\\033[70G[ " >&3
356 [ "$check_status" = ok ] && report_return_code=0 && echo -en "\\033[1;32mOK" >&3
357 [ "$check_status" = warning ] && report_return_code=0 && echo -en "\\033[1;33mWarning" >&3
358 [ "$check_status" = failed ] && report_return_code=1 && echo -en "\\033[1;31mFailed" >&3
359 echo -e "\\033[0;39m ]" >&3
360 }
362 report_term_to_html()
363 {
364 report_decolorize | sed -e 's~<~\&lt;~' -e 's~>~\&gt;~' -e 's~STDERR: \(.*\)~<span class="error">\1<\/span>~' -e 's~ ~\&nbsp;\&nbsp;\&nbsp;\&nbsp;~'
365 }
367 report_decolorize()
368 {
369 tr -d '\e' | sed -r "s/\[([0-9]{1,3}(;[0-9]{1,3})*)[m|G]//g"
370 }
372 report_rec_log()
373 {
374 ! [ "$prebloc" ] && sed "s~<div class=\"$step_running\">~<div class=\"$check_status\">~" -i "$log_opt"
375 if [ -s "$log_tmp" ]; then
376 if [ -s "$log_tmp.error" ]; then
377 cat $log_tmp.error | sort -u | while read line; do
378 # Format line to avoid sed errors :
379 line=$(echo "$line" | sed -e 's~\*~\\\*~g' -e 's~\[~\\\[~g' -e 's~\]~\\\]~g')
380 sed "s~^$line$~STDERR: $line~" -i $log_tmp
381 done
382 fi
383 echo -n "<pre>" >> "$log_opt"
384 cat $log_tmp | report_term_to_html >> "$log_opt"
385 echo "</pre>" >> "$log_opt"
386 fi
387 ! [ "$prebloc" ] && echo "</div>" >> "$log_opt"
388 }
390 # These variables keep the status of the blocs.
391 # A bloc is reported as ok if all child steps are ok and has failed
392 # if all child steps are failed (or if a fatal error occurs).
393 # In other cases the bloc is reported as a warning.
394 report_set_bloc_status()
395 {
396 bloc_status=$(eval echo \$bloc${bloc_level}_status)
397 for n in $(seq $bloc_level -1 1); do
398 ! [ "$(eval echo \$bloc${n}_status)" ] && eval bloc${n}_status=$check_status
399 ! [ "$(eval echo \$bloc${n}_status)" = "$check_status" ] && \
400 eval bloc${n}_status=warning
401 done
402 }