wok view libtaz/stuff/libtaz-modules/report @ rev 8822

Put libtaz stuff into wok
author Antoine Bodin <gokhlayeh@slitaz.org>
date Thu Feb 24 00:23:25 2011 +0100 (2011-02-24)
parents
children
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 message, 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 if ! [ -f "$log_opt" ]; then
26 mkdir -p "${log_opt%/*}"
27 cp /usr/share/slitaz/web/template.html "$log_opt"
28 sed -e "s/xml:lang=\"us\" lang=\"us\"/xml:lang=\"${LANG%%_*}\" lang=\"${LANG%%_*}\"/" \
29 -e "s~Title of the page~SliTaz GNU/Linux - Log: $0~" \
30 -e "s~Second Title~Log: $0~" -i "$log_opt"
31 echo '<div id="report">' >> "$log_opt"
32 else
33 sed 's~</div></body></html>~~' -i "$log_opt"
34 fi
36 echo -e "<h1>$(basename "$log_command")</h1>\n<em>$(date)</em>" >> "$log_opt"
37 [ -L "${log_opt%/*}/web" ] || ln -s /usr/share/slitaz/web "${log_opt%/*}/web"
38 }
40 report_start()
41 {
42 # Create the temporary directory if needed.
43 ! [ -d /tmp/libtaz/ ] && mkdir -p /tmp/libtaz
44 ! [ -d $SLITAZ_LOG ] && mkdir -p $SLITAZ_LOG
46 # Give permissions to all users if user is root.
47 if test $(id -u) = 0 ; then
48 chmod 777 /tmp/libtaz
49 chmod -R 777 $SLITAZ_LOG
50 fi
52 # Get a random logfile name.
53 if [ "$report_pid" ]; then
54 log_tmp=/tmp/libtaz/$report_pid
55 embeded_mode=enabled
56 initial_bloc_level=$bloc_level
57 if [ "$open_bloc" ]; then
58 initial_bloc_level=$(($bloc_level+1))
59 embeded_open_bloc=yes
60 fi
61 if [ -p $log_tmp.stdout ] && ! [ "$open_bloc" = yes ]; then
62 report_step_status
63 fi
64 else
65 log_tmp=/tmp/libtaz/$$
66 report_pid=$$
67 fi
69 # Use the default logfile if there's no logfile was specified by the main script.
70 [ ! "$log_opt" ] && [ "$report_log_all" = yes ] && \
71 log_opt="$SLITAZ_LOG/`basename $0`/$(date -Iseconds).html"
72 export report_pid log_opt
74 #if [ "$embeded_mode" != enabled ]; then
76 # Initialize html logfile if needed, or prepare it to be edited.
77 [ "$log_opt" ] && { [ ! "$embeded_mode" ] || [ ! -f "$log_opt" ]; } && report_create_html
79 echo -n "" > $log_tmp
81 # Initialize named pipes & set I/O redirections.
82 [ "$embeded_mode" ] || exec 3>&1 4>&2
84 # Start debugging if the option is enabled.
85 if [ "$debug_opt" ]; then
86 exec 2>$log_tmp.stdout
87 set -vx
88 echo "[--------------------------/!\ DEBUG MODE ENABLED /!\--------------------------]"
89 fi
91 # Theses variable are used to configure the display of steps in terminal.
92 bloc1_delimiter="================================================================================"
93 bloc1_display=" "
94 bloc2_delimiter="----------------------------------------------------------------------------"
95 bloc2_display=" > "
96 bloc3_delimiter="* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
97 bloc3_display=" * "
99 # Use a trap to exit cleanly if app is killed.
100 trap "report_exit $(basename $0) killed by user" SIGINT SIGTERM
102 # Use another display function if quiet is enable.
103 [ "$report_verbosity_opt" = "none" ] && report_display()
104 {
105 while read out; do
106 [ "$out" = €øß ] && report_stop_display && return
107 done
108 }
109 }
111 report_stop_display()
112 {
113 rm $log_tmp.stderr $log_tmp.stdout
114 sed '/^€øß$/d' -i $log_tmp
115 touch $log_tmp.end
116 }
118 report_listen()
119 {
120 mkfifo $log_tmp.stderr $log_tmp.stdout
121 {
122 { tee -a $log_tmp $log_tmp.error <$log_tmp.stderr | while read line; do echo -e "\\033[1;31m${line}\\033[0m"; done; }&
123 { tee -a $log_tmp <$log_tmp.stdout; }&
124 } | report_display&
125 usleep 10000
126 exec 1>>$log_tmp.stdout 2>>$log_tmp.stderr
127 }
129 report_stop_listen()
130 {
131 if [ -p $log_tmp.stdout ]; then
132 [ -f $log_tmp.end ] && rm $log_tmp.end
133 usleep 10000 && echo €øß
134 while ! [ -f $log_tmp.end ]; do
135 usleep 10000
136 done
137 exec 1>&3 2>&4
138 rm $log_tmp.end
139 fi
140 }
142 report_stop()
143 {
144 ! [ "$report_pid" ] && exit
145 # End step and close blocs.
146 [ "$step_running" ] && report end-step
147 while [ $(($bloc_level)) -gt $(($initial_bloc_level)) ]; do
148 report close-bloc
149 done
151 if [ "$embeded_mode" = enabled ]; then
152 [ "$bloc_level" ] && echo $(eval echo \$bloc${bloc_level}_status) > $log_tmp.status
153 if [ "$embeded_open_bloc" = opened ]; then
154 touch $log_tmp.eob
155 fi
156 else
157 [ "$log_opt" ] && echo '</div></body></html>' >> "$log_opt"
158 exec 3>&- 4>&-
159 rm -f $log_tmp*
160 unset report_pid log_opt
162 # Stop debugging
163 [ "$debug_opt" ] && set +vx
164 [ "$report_log_all" ] && create_log_index
165 fi
166 }
168 # Use this to stop a program with error.
169 report_exit()
170 {
171 # Log&display error message.
172 echo -e "$@" >&2
174 # Close step as failed.
175 if [ "$step_running" ]; then
176 (exit 1)
177 report end-step
178 fi
180 # Set blocs as failed, report and exit.
181 bloc1_status="failed"
182 bloc2_status="failed"
183 bloc3_status="failed"
184 report_stop
185 exit 1
186 }
188 # Usage : report [command] [message]
189 #
190 # type :message - simply display the message.
191 # step - name the step and display status when ended.
192 # end-step - display status of the step, it's done automaticaly when
193 # starting a new step, closing a bloc or stop report.
194 # open-bloc - open the list of steps in the operation;
195 # close-bloc- close the current bloc.
196 report()
197 {
198 # First : get status before it is changed by other commands.
199 check_status=$?
200 case "$1" in
201 start)
202 report_start
203 ;;
204 stop)
205 report_stop
206 ;;
207 exit)
208 shift && report_exit "$@"
209 ;;
210 # TODO : Code displaying a message during a step run.
211 message)
212 shift
213 echo -e "${current_bloc_display}$@"
214 report_message=$(echo "$@" | sed "s~$~<br />~g")
215 [ "$log_opt" ] && echo -e "<div class=\"message\">$report_message</div>" >> "$log_opt"
216 ;;
217 step)
218 [ "$log_step" ] && echo "$2" > $log_step
219 [ "$open_bloc" ] && report_open_bloc
220 [ "$step_running" ] && report_step_status
221 echo -ne "$current_bloc_display$2\\033[70G[ \\033[1;32mR\\033[33mU\\033[31mN\\033[0;39m ]" >&3
222 [ "$log_opt" ] && echo -e "<div class=\"$2\">\n<h$(($bloc_level+2))>$2</h$(($bloc_level+2))>" >> "$log_opt"
223 export step_running="$2"
224 report_listen
225 ;;
226 end-step)
227 [ -s $(dirname $log_opt)/step ] && rm -f $(dirname $log_opt)/step
228 if ! [ "$step_running" ]; then
229 report_return_code=$check_status
230 else
231 report_step_status
232 fi
233 ;;
234 open-bloc)
235 export open_bloc=yes
236 ;;
237 close-bloc)
238 if [ -f "$log_tmp.eob" ]; then
239 report_open_bloc
240 check_status=$(cat $log_tmp.status)
241 rm $log_tmp.status
242 report_set_bloc_status
243 elif [ "$step_running" ]; then
244 report_step_status
245 fi
247 # Then close the bloc and report status if it was open.
248 if ! [ "$open_bloc" ]; then
249 export current_bloc_display="$(eval echo \"\$bloc$((${bloc_level}-1))_display\")"
250 [ "$(eval echo \"\$bloc${bloc_level}_delimiter\")" ] && \
251 echo -e "$current_bloc_display$(eval echo \"\$bloc${bloc_level}_delimiter\")" >&3
252 echo -en "$current_bloc_display... $(eval echo \"\$bloc${bloc_level}_running\")" >&3
253 check_status=$(eval echo \$bloc${bloc_level}_status)
254 report_display_status
256 # Set the bloc status in the log file.
257 if [ "$log_opt" ]; then
258 sed "s~<div class=\"bloc_level$bloc_level\">~<div class=\"$check_status\">~" -i "$log_opt"
259 echo "</div>" >> "$log_opt"
260 fi
261 echo "" >&3
262 export bloc_level=$(($bloc_level-1))
263 [ "$bloc_level" = 0 ] && unset bloc_level
264 else
265 unset open_bloc
266 fi
267 ;;
268 sublog)
269 shift
270 ! [ "$log_list" ] && log_list="$log_opt"
271 export log_list="$1 $log_list"
272 export log_opt="$1"
273 report_create_html
274 ;;
275 end-sublog)
276 [ "$log_opt" ] || continue
277 export log_list="${log_list#* }"
278 echo '</div></body></html>' >> "$log_opt"
279 # Grep the summary of sublog (main action + status) and put
280 # it in the main log, plus a link.
281 [ "$log_list" ] && { sed -n '/<div id="report">/,$p' $log_opt | \
282 grep -A1 -F '<div class=' | sed 1,2!d &&
283 echo '<a class="sublog" href="'$log_opt'">SubLog</a>' && \
284 echo "</div>"
285 } >> ${log_list%% *}
286 export log_opt="${log_list%% *}"
287 report_step_status
288 ;;
289 esac
290 return $report_return_code
291 }
293 # Open a bloc of substeps in terminal and log.
294 report_open_bloc()
295 {
296 unset open_bloc
297 [ "$embeded_open_bloc" = "yes" ] && embeded_open_bloc=opened
298 [ -f "$log_tmp.eob" ] && rm $log_tmp.eob
299 export bloc_level=$(($bloc_level+1))
300 export bloc${bloc_level}_running="$step_running"
301 if [ -p $log_tmp.stdout ]; then
302 if [ -s $log_tmp ]; then
303 prebloc=yes
304 report_step_status
305 prebloc=
306 else
307 report_stop_listen
308 echo ' ...' >&3
309 fi
310 [ "$(eval echo \$bloc${bloc_level}_delimiter)" ] && \
311 echo "$current_bloc_display$(eval echo \"\$bloc${bloc_level}_delimiter\")" >&3
312 [ "$log_opt" ] && sed "s~<div class=\"$step_running\">~<div class=\"bloc_level$bloc_level\">~" -i "$log_opt"
313 else
314 exec 1>&3 2>&4
315 fi
316 export current_bloc_display="$(eval echo \"\$bloc${bloc_level}_display\")"
317 unset bloc${bloc_level}_status
318 unset step_running
319 }
321 # This is the two new status function used by the report tool.
322 # States are : ok - no error since the start of the step
323 # warning - there was error(s) since the start of the step
324 # failed - the last executed command has exiting anormally
325 report_step_status()
326 {
327 unset report_return_code
328 if [ -p $log_tmp.stdout ]; then
329 report_stop_listen
331 #Close message bloc if opened.
332 if [ -s $log_tmp -a "$report_verbosity_opt" = all ] || \
333 [ -s $log_tmp.error -a "$report_verbosity_opt" != none ]; then
334 echo " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ " >&3
335 ! [ "$prebloc" ] && echo -en "$current_bloc_display... $step_running" >&3 && report_addemptyline="yes"
336 fi
338 # Check, display and log the status of the step.
339 if ! [ "$check_status" = "0" ]; then
340 check_status=failed
341 else
342 [ -s "$log_tmp.error" ] && check_status=warning || check_status=ok
343 fi
344 ! [ "$prebloc" ] && report_display_status
345 [ "$report_addemptyline" ] && echo "" >&3 && unset report_addemptyline
346 [ "$log_opt" ] && report_rec_log
347 fi
349 [ -f "$log_tmp.eob" ] && rm $log_tmp.eob
351 # Set blocs status if needed.
352 [ -f $log_tmp.status ] && check_status=$(cat $log_tmp.status) && rm $log_tmp.status
353 [ "$bloc_level" ] && report_set_bloc_status
355 # Clear variables / temporary logs.
356 ! [ "$prebloc" ] && export step_running=""
357 check_status=""
358 echo -n "" > $log_tmp.error
359 echo -n "" > $log_tmp
360 }
362 report_display_status()
363 {
364 [ "$report_return_code" = 1 ] && check_status=failed
365 echo -en "\\033[70G " >&3
366 echo -en "\\033[70G[ " >&3
367 [ "$check_status" = ok ] && report_return_code=0 && echo -en "\\033[1;32mOK" >&3
368 [ "$check_status" = warning ] && report_return_code=0 && echo -en "\\033[1;33mWarning" >&3
369 [ "$check_status" = failed ] && report_return_code=1 && echo -en "\\033[1;31mFailed" >&3
370 echo -e "\\033[0;39m ]" >&3
371 }
373 report_term_to_html()
374 {
375 report_decolorize | sed -e 's~<~\&lt;~' -e 's~>~\&gt;~' -e 's/$/<br \/>/' -e 's~STDERR: \(.*\)~<span class="error">\1<\/span>~' -e 's~ ~\&nbsp;\&nbsp;\&nbsp;\&nbsp;~'
376 }
378 report_decolorize()
379 {
380 tr -d '\e' | sed -r "s/\[([0-9]{1,3}(;[0-9]{1,3})*)[m|G]//g"
381 }
383 report_rec_log()
384 {
385 ! [ "$prebloc" ] && sed "s~<div class=\"$step_running\">~<div class=\"$check_status\">~" -i "$log_opt"
386 if [ -s "$log_tmp" ]; then
387 if [ -s "$log_tmp.error" ]; then
388 cat $log_tmp.error | sort -u | while read line; do
389 # Format line to avoid sed errors :
390 line=$(echo "$line" | sed -e 's~\*~\\\*~g' -e 's~\[~\\\[~g' -e 's~\]~\\\]~g')
391 sed "s~^$line$~STDERR: $line~" -i $log_tmp
392 done
393 fi
394 echo -n "<pre>" >> "$log_opt"
395 cat $log_tmp | report_term_to_html >> "$log_opt"
396 echo "</pre>" >> "$log_opt"
397 fi
398 ! [ "$prebloc" ] && echo "</div>" >> "$log_opt"
399 }
401 # Theses variables keep the status of the blocs.
402 # A bloc is reported as ok if all child steps are ok and as failed
403 # if all child steps are failed (or if a fatal error occurs).
404 # In other cases the bloc is reported as warning.
405 report_set_bloc_status()
406 {
407 bloc_status=$(eval echo \$bloc${bloc_level}_status)
408 for n in $(seq $bloc_level -1 1); do
409 ! [ "$(eval echo \$bloc${n}_status)" ] && eval bloc${n}_status=$check_status
410 ! [ "$(eval echo \$bloc${n}_status)" = "$check_status" ] && \
411 eval bloc${n}_status=warning
412 done
413 }
415 create_log_index()
416 {
417 cd $SLITAZ_LOG
418 cp -f /usr/share/slitaz/web/template.html index.html
419 sed -e "s/xml:lang=\"us\" lang=\"us\"/xml:lang=\"${LANG%%_*}\" lang=\"${LANG%%_*}\"/" \
420 -e "s~Title of the page~SliTaz GNU/Linux - Logs Index~" \
421 -e "s~Second Title~Logs Index~" -i index.html
422 echo '<div id="report">' >> index.html
423 for log in $(ls -t */*); do
424 log_title=$(grep '<h1>.*</h1>' $log | sed 's~<h1>\(.*\)</h1>~\1~')
425 log_date=$(date -r $log)
426 log_status=$(grep '<div class=".*">' $log | sed -e 1!d -e 's~<.*"\(.*\)">~\1~')
427 echo -e " <a href=\"$log\"><div class=\"$log_status\">$log_date: $log_title</div></a>" >> index.html
428 done
429 echo -e '</div></body></html>' >> index.html
430 chmod 666 index.html
431 }